summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yaml27
-rw-r--r--autobuild.xml228
-rwxr-xr-xbuild.sh1
-rwxr-xr-xdoc/contributions.txt1
-rw-r--r--doc/testplans/RenderMaxTextureResolution.md16
-rw-r--r--doc/testplans/hdri_local_preview.md21
-rw-r--r--doc/testplans/material_preview.md83
-rw-r--r--doc/testplans/pbr_terrain_appearance.md35
-rw-r--r--doc/testplans/pbr_terrain_composition.md76
-rw-r--r--doc/testplans/terrain_loading.md29
-rw-r--r--indra/cmake/CMakeLists.txt2
-rw-r--r--indra/cmake/TinyEXR.cmake7
-rw-r--r--indra/llcommon/indra_constants.cpp57
-rw-r--r--indra/llcommon/indra_constants.h340
-rw-r--r--indra/llcommon/llcoros.cpp12
-rw-r--r--indra/llcommon/llstrider.h62
-rw-r--r--indra/llimage/llimage.cpp3464
-rw-r--r--indra/llimage/llimage.h426
-rw-r--r--indra/llinventory/llsettingssky.cpp170
-rw-r--r--indra/llinventory/llsettingssky.h21
-rw-r--r--indra/llmath/llcamera.h325
-rw-r--r--indra/llmath/llmatrix4a.h224
-rw-r--r--indra/llmath/llvolume.cpp11407
-rw-r--r--indra/llmath/llvolume.h1697
-rw-r--r--indra/llmath/llvolumeoctree.cpp374
-rw-r--r--indra/llmath/llvolumeoctree.h223
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp1728
-rw-r--r--indra/llprimitive/llgltfmaterial.h33
-rw-r--r--indra/llprimitive/llprimitive.cpp2905
-rw-r--r--indra/llprimitive/llprimitive.h895
-rw-r--r--indra/llprimitive/lltextureentry.cpp713
-rw-r--r--indra/llprimitive/tests/llgltfmaterial_test.cpp16
-rw-r--r--indra/llrender/llglslshader.cpp62
-rw-r--r--indra/llrender/llglslshader.h13
-rw-r--r--indra/llrender/llgltexture.cpp331
-rw-r--r--indra/llrender/llgltexture.h257
-rw-r--r--indra/llrender/llrender.cpp2642
-rw-r--r--indra/llrender/llrendertarget.cpp87
-rw-r--r--indra/llrender/llrendertarget.h175
-rw-r--r--indra/llrender/llshadermgr.cpp1887
-rw-r--r--indra/llrender/llshadermgr.h83
-rw-r--r--indra/llrender/llvertexbuffer.cpp691
-rw-r--r--indra/llrender/llvertexbuffer.h289
-rw-r--r--indra/newview/CMakeLists.txt17
-rw-r--r--indra/newview/app_settings/settings.xml360
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl47
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl207
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/globalF.glsl45
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl71
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl26
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl347
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl473
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl96
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeV.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl (renamed from indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl)29
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl76
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl150
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpF.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpV.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl75
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl26
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl206
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl41
-rw-r--r--indra/newview/featuretable.txt59
-rw-r--r--indra/newview/featuretable_mac.txt60
-rw-r--r--indra/newview/gltf/accessor.cpp66
-rw-r--r--indra/newview/gltf/accessor.h95
-rw-r--r--indra/newview/gltf/animation.cpp287
-rw-r--r--indra/newview/gltf/animation.h181
-rw-r--r--indra/newview/gltf/asset.cpp664
-rw-r--r--indra/newview/gltf/asset.h264
-rw-r--r--indra/newview/gltf/buffer_util.h402
-rw-r--r--indra/newview/gltf/primitive.cpp400
-rw-r--r--indra/newview/gltf/primitive.h93
-rw-r--r--indra/newview/gltfscenemanager.cpp564
-rw-r--r--indra/newview/gltfscenemanager.h69
-rw-r--r--indra/newview/llagentbenefits.cpp268
-rw-r--r--indra/newview/llagentbenefits.h81
-rw-r--r--indra/newview/llagentcamera.cpp4594
-rw-r--r--indra/newview/llappviewer.cpp7000
-rw-r--r--indra/newview/lldrawable.h503
-rw-r--r--indra/newview/lldrawpool.cpp431
-rw-r--r--indra/newview/lldrawpool.h384
-rw-r--r--indra/newview/lldrawpoolalpha.cpp183
-rw-r--r--indra/newview/lldrawpoolbump.cpp1383
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp15
-rw-r--r--indra/newview/lldrawpoolterrain.cpp1442
-rw-r--r--indra/newview/lldrawpoolterrain.h76
-rw-r--r--indra/newview/lldrawpooltree.cpp73
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp209
-rw-r--r--indra/newview/lldynamictexture.cpp308
-rw-r--r--indra/newview/llenvironment.cpp104
-rw-r--r--indra/newview/llface.cpp3360
-rw-r--r--indra/newview/llfeaturemanager.cpp972
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp71
-rw-r--r--indra/newview/llfetchedgltfmaterial.h19
-rw-r--r--indra/newview/llfilepicker.cpp2083
-rw-r--r--indra/newview/llfilepicker.h207
-rw-r--r--indra/newview/llfloaterimagepreview.cpp1318
-rw-r--r--indra/newview/llfloaterimagepreview.h142
-rw-r--r--indra/newview/llfloaternamedesc.h50
-rw-r--r--indra/newview/llfloaterregioninfo.cpp5331
-rw-r--r--indra/newview/llfloaterregioninfo.h620
-rw-r--r--indra/newview/llgltfmateriallist.cpp25
-rw-r--r--indra/newview/llgltfmateriallist.h6
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp590
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.h78
-rw-r--r--indra/newview/llheroprobemanager.cpp632
-rw-r--r--indra/newview/llheroprobemanager.h156
-rw-r--r--indra/newview/llmanip.cpp870
-rw-r--r--indra/newview/llmaniprotate.cpp3413
-rw-r--r--indra/newview/llmaniptranslate.cpp4171
-rw-r--r--indra/newview/llmaterialeditor.cpp117
-rw-r--r--indra/newview/llpanelface.cpp3937
-rw-r--r--indra/newview/llpanelface.h807
-rw-r--r--indra/newview/llpanelmaininventory.cpp2198
-rw-r--r--indra/newview/llpanelvolume.cpp1555
-rw-r--r--indra/newview/llreflectionmap.cpp23
-rw-r--r--indra/newview/llreflectionmap.h19
-rw-r--r--indra/newview/llreflectionmapmanager.cpp195
-rw-r--r--indra/newview/llreflectionmapmanager.h16
-rw-r--r--indra/newview/llselectmgr.cpp11716
-rw-r--r--indra/newview/llselectmgr.h1525
-rw-r--r--indra/newview/llsettingsvo.cpp117
-rw-r--r--indra/newview/llspatialpartition.cpp5973
-rw-r--r--indra/newview/llsurface.cpp2024
-rw-r--r--indra/newview/llsurface.h274
-rw-r--r--indra/newview/llsurfacepatch.cpp1781
-rw-r--r--indra/newview/llsurfacepatch.h257
-rw-r--r--indra/newview/lltexturectrl.cpp2335
-rw-r--r--indra/newview/lltexturectrl.h553
-rw-r--r--indra/newview/lltinygltfhelper.cpp61
-rw-r--r--indra/newview/lltinygltfhelper.h9
-rw-r--r--indra/newview/lltooldraganddrop.cpp4732
-rw-r--r--indra/newview/lltoolselect.cpp390
-rw-r--r--indra/newview/llviewerassetupload.cpp170
-rw-r--r--indra/newview/llviewercamera.cpp1370
-rw-r--r--indra/newview/llviewercontrol.cpp526
-rw-r--r--indra/newview/llviewerdisplay.cpp2442
-rw-r--r--indra/newview/llviewermenu.cpp12076
-rw-r--r--indra/newview/llviewermenufile.cpp1475
-rw-r--r--indra/newview/llviewerobject.cpp10169
-rw-r--r--indra/newview/llviewerobject.h1442
-rwxr-xr-xindra/newview/llviewerregion.cpp4375
-rw-r--r--indra/newview/llviewerregion.h944
-rw-r--r--indra/newview/llviewershadermgr.cpp2914
-rw-r--r--indra/newview/llviewershadermgr.h382
-rw-r--r--indra/newview/llviewertexture.cpp5430
-rw-r--r--indra/newview/llviewertexture.h1128
-rw-r--r--indra/newview/llviewerwindow.cpp8871
-rw-r--r--indra/newview/llviewerwindow.h897
-rw-r--r--indra/newview/llvlcomposition.cpp1131
-rw-r--r--indra/newview/llvlcomposition.h149
-rw-r--r--indra/newview/llvoavatar.cpp14439
-rw-r--r--indra/newview/llvoavatarself.cpp4108
-rw-r--r--indra/newview/llvocache.cpp2542
-rw-r--r--indra/newview/llvocache.h427
-rw-r--r--indra/newview/llvosurfacepatch.cpp1705
-rw-r--r--indra/newview/llvosurfacepatch.h170
-rw-r--r--indra/newview/llvovolume.cpp8320
-rw-r--r--indra/newview/llvovolume.h598
-rw-r--r--indra/newview/llxmlrpclistener.cpp162
-rw-r--r--indra/newview/pipeline.cpp12377
-rw-r--r--indra/newview/pipeline.h1531
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml201
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml57
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml83
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml100
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml124
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_terrain.xml2
218 files changed, 116913 insertions, 106720 deletions
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 44f32c1c5d..4785273b78 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -5,7 +5,7 @@ on:
pull_request:
push:
branches: ["main", "release/*", "project/*"]
- tags: ["Second_Life_*"]
+ tags: ["Second_Life*"]
jobs:
build:
@@ -176,16 +176,22 @@ jobs:
# seen before, so numerous tests don't know about it.
[[ "$arch" == "MINGW6" ]] && arch=CYGWIN
export AUTOBUILD="$(which autobuild)"
- # Build with a tag like "Second_Life_Project_Shiny#abcdef0" to get a
- # viewer channel "Second Life Project Shiny" (ignoring "#hash",
- # needed to disambiguate tags).
- if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]]
- then viewer_channel="${GITHUB_REF_NAME%#*}"
- export viewer_channel="${viewer_channel//_/ }"
- else export viewer_channel="Second Life Test"
+
+ # determine the viewer channel from the branch name
+ branch=$AUTOBUILD_VCS_BRANCH
+ IFS='/' read -ra ba <<< $branch
+ prefix=${ba[0]}
+ if [ "$prefix" == "project" ]; then
+ IFS='_' read -ra prj <<< "${ba[1]}"
+ # uppercase first letter of each word
+ export viewer_channel="Second Life Project ${prj[*]^}"
+ elif [[ "$prefix" == "release" || "$prefix" == "main" ]];
+ then
+ export viewer_channel="Second Life Release"
+ else
+ export viewer_channel="Second Life Test"
fi
echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT"
-
# On windows we need to point the build to the correct python
# as neither CMake's FindPython nor our custom Python.cmake module
# will resolve the correct interpreter location.
@@ -354,7 +360,8 @@ jobs:
release:
needs: [build, sign-and-package-windows, sign-and-package-mac]
runs-on: ubuntu-latest
- if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_')
+ # Build with a tag like "Second_Life#abcdef0" to generate a release page (used for builds we are planning to deploy).
+ if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life')
steps:
- uses: actions/download-artifact@v4
with:
diff --git a/autobuild.xml b/autobuild.xml
index 13c9e7ec35..8642d74b0f 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -455,18 +455,6 @@
</map>
<key>emoji_shortcodes</key>
<map>
- <key>canonical_repo</key>
- <string>https://github.com/secondlife/3p-emoji-shortcodes</string>
- <key>copyright</key>
- <string>Copyright 2017-2019 Miles Johnson.</string>
- <key>description</key>
- <string>Emoji shortcodes</string>
- <key>license</key>
- <string>MIT</string>
- <key>license_file</key>
- <string>LICENSES/emojibase-license.txt</string>
- <key>name</key>
- <string>emoji_shortcodes</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -494,8 +482,20 @@
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>MIT</string>
+ <key>license_file</key>
+ <string>LICENSES/emojibase-license.txt</string>
+ <key>copyright</key>
+ <string>Copyright 2017-2019 Miles Johnson.</string>
<key>version</key>
<string>6.1.0.579438</string>
+ <key>name</key>
+ <string>emoji_shortcodes</string>
+ <key>canonical_repo</key>
+ <string>https://github.com/secondlife/3p-emoji-shortcodes</string>
+ <key>description</key>
+ <string>Emoji shortcodes</string>
</map>
<key>expat</key>
<map>
@@ -655,16 +655,6 @@
</map>
<key>freetype</key>
<map>
- <key>copyright</key>
- <string>Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
- <key>description</key>
- <string>Font rendering library</string>
- <key>license</key>
- <string>FreeType</string>
- <key>license_file</key>
- <string>LICENSES/freetype.txt</string>
- <key>name</key>
- <string>freetype</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -724,8 +714,18 @@
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>FreeType</string>
+ <key>license_file</key>
+ <string>LICENSES/freetype.txt</string>
+ <key>copyright</key>
+ <string>Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
<key>version</key>
<string>2.12.1.557becd</string>
+ <key>name</key>
+ <string>freetype</string>
+ <key>description</key>
+ <string>Font rendering library</string>
</map>
<key>glext</key>
<map>
@@ -957,18 +957,6 @@
</map>
<key>icu4c</key>
<map>
- <key>canonical_repo</key>
- <string>https://bitbucket.org/lindenlab/3p-icu4c</string>
- <key>copyright</key>
- <string>Copyright (c) 1995-2011 International Business Machines Corporation and others &lt;http://source.icu-project.org&gt;</string>
- <key>description</key>
- <string>ICU is a mature, widely used set of C/C++ and Java libraries providing Unicode and Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms and between C/C++ and Java software.</string>
- <key>license</key>
- <string>ICU, permissive non-copyleft free software license</string>
- <key>license_file</key>
- <string>LICENSES/icu.txt</string>
- <key>name</key>
- <string>icu4c</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -1000,8 +988,20 @@
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>ICU, permissive non-copyleft free software license</string>
+ <key>license_file</key>
+ <string>LICENSES/icu.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 1995-2011 International Business Machines Corporation and others &lt;http://source.icu-project.org&gt;</string>
<key>version</key>
<string>4.8.1-7d08d82</string>
+ <key>name</key>
+ <string>icu4c</string>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-icu4c</string>
+ <key>description</key>
+ <string>ICU is a mature, widely used set of C/C++ and Java libraries providing Unicode and Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms and between C/C++ and Java software.</string>
</map>
<key>jpegencoderbasic</key>
<map>
@@ -1547,15 +1547,6 @@
</map>
<key>llca</key>
<map>
- <key>copyright</key>
- <string>Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
- </string>
- <key>license</key>
- <string>mit</string>
- <key>license_file</key>
- <string>LICENSES/ca-license.txt</string>
- <key>name</key>
- <string>llca</string>
<key>platforms</key>
<map>
<key>common</key>
@@ -1573,8 +1564,17 @@
<string>common</string>
</map>
</map>
+ <key>license</key>
+ <string>mit</string>
+ <key>license_file</key>
+ <string>LICENSES/ca-license.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
+ </string>
<key>version</key>
<string>202402012004.0</string>
+ <key>name</key>
+ <string>llca</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@@ -1808,6 +1808,18 @@
</map>
<key>mikktspace</key>
<map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
+ <key>copyright</key>
+ <string>Copyright (C) 2011 by Morten S. Mikkelsen, Copyright (C) 2022 Blender Authors</string>
+ <key>description</key>
+ <string>Mikktspace Tangent Generator</string>
+ <key>license</key>
+ <string>Apache 2.0</string>
+ <key>license_file</key>
+ <string>mikktspace.txt</string>
+ <key>name</key>
+ <string>mikktspace</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -1815,58 +1827,46 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6cc1585dba85b0226a2e7033a7e2a2ceaae7c983</string>
+ <string>65edf85c36a10001e32bdee582bec4732137208b</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-darwin64-5cee1f4.tar.zst</string>
+ <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-darwin64-8756084692.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>windows64</key>
+ <key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>6b7d01ad54e4a88a001f66840c32329cedb28202</string>
+ <string>fa9dcee4584df7e7271fdf69c08e6fd3122a47fc</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-windows64-5cee1f4.tar.zst</string>
+ <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-linux64-8756084692.tar.zst</string>
</map>
<key>name</key>
- <string>windows64</string>
+ <string>linux64</string>
</map>
- <key>linux64</key>
+ <key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>edc9782bf209e17ad1845498b42f16d733582082</string>
+ <string>130b33a70bdb3a8a188376c6a91840bdb61380a8</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-linux64-5cee1f4.tar.zst</string>
+ <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-windows64-8756084692.tar.zst</string>
</map>
<key>name</key>
- <string>linux64</string>
+ <string>windows64</string>
</map>
</map>
- <key>license</key>
- <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
- <key>license_file</key>
- <string>mikktspace.txt</string>
- <key>copyright</key>
- <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
<key>version</key>
<string>1</string>
- <key>name</key>
- <string>mikktspace</string>
- <key>canonical_repo</key>
- <string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
- <key>description</key>
- <string>Mikktspace Tangent Generator</string>
</map>
<key>minizip-ng</key>
<map>
@@ -1932,18 +1932,6 @@
</map>
<key>nanosvg</key>
<map>
- <key>canonical_repo</key>
- <string>https://bitbucket.org/lindenlab/3p-nanosvg</string>
- <key>copyright</key>
- <string>Copyright (c) 2013-14 Mikko Mononen</string>
- <key>description</key>
- <string>NanoSVG is a simple single-header-file SVG parser and rasterizer</string>
- <key>license</key>
- <string>Zlib</string>
- <key>license_file</key>
- <string>LICENSES/nanosvg.txt</string>
- <key>name</key>
- <string>nanosvg</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -1983,8 +1971,20 @@
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>Zlib</string>
+ <key>license_file</key>
+ <string>LICENSES/nanosvg.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2013-14 Mikko Mononen</string>
<key>version</key>
<string>2022.09.27</string>
+ <key>name</key>
+ <string>nanosvg</string>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-nanosvg</string>
+ <key>description</key>
+ <string>NanoSVG is a simple single-header-file SVG parser and rasterizer</string>
</map>
<key>nghttp2</key>
<map>
@@ -2400,14 +2400,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<map>
<key>archive</key>
<map>
- <key>creds</key>
- <string>github</string>
<key>hash</key>
- <string>cc7c5bf53f83cff81d874ad66394df0991bd432c</string>
+ <string>1e70b06fe6eb9796097010871b32d8e95167e373</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://api.github.com/repos/secondlife/3p-slvoice/releases/assets/108299352</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/gh/secondlife/3p-slvoice/slvoice-4.10.0000.32327.5fc3fe7c.5942f08-darwin64-5942f08.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2428,14 +2426,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<map>
<key>archive</key>
<map>
- <key>creds</key>
- <string>github</string>
<key>hash</key>
- <string>0c205371bb1731a9812b00556037729fdc057cbc</string>
+ <string>ddfb7c30d9756915e8b26f44e2ee3a69ee87fb9a</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://api.github.com/repos/secondlife/3p-slvoice/releases/assets/108299356</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/gh/secondlife/3p-slvoice/slvoice-4.10.0000.32327.5fc3fe7c.5942f08-windows64-5942f08.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2448,7 +2444,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C)</string>
<key>version</key>
- <string>4.10.0000.32327.5fc3fe7c.571099</string>
+ <string>4.10.0000.32327.5fc3fe7c.5942f08</string>
<key>name</key>
<string>slvoice</string>
<key>description</key>
@@ -2694,16 +2690,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>viewer-fonts</key>
<map>
- <key>copyright</key>
- <string>Copyright 2016-2022 Brad Erickson CC-BY-4.0/MIT, Copyright 2016-2022 Twitter, Inc. CC-BY-4.0, Copyright 2013 Joe Loughry and Terence Eden MIT</string>
- <key>description</key>
- <string>Viewer fonts</string>
- <key>license</key>
- <string>Various open source</string>
- <key>license_file</key>
- <string>LICENSES/fonts.txt</string>
- <key>name</key>
- <string>viewer-fonts</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -2731,8 +2717,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>Various open source</string>
+ <key>license_file</key>
+ <string>LICENSES/fonts.txt</string>
+ <key>copyright</key>
+ <string>Copyright 2016-2022 Brad Erickson CC-BY-4.0/MIT, Copyright 2016-2022 Twitter, Inc. CC-BY-4.0, Copyright 2013 Joe Loughry and Terence Eden MIT</string>
<key>version</key>
<string>1.579464</string>
+ <key>name</key>
+ <string>viewer-fonts</string>
+ <key>description</key>
+ <string>Viewer fonts</string>
</map>
<key>viewer-manager</key>
<map>
@@ -3030,6 +3026,46 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>description</key>
<string>zlib data compression library for the next generation systems</string>
</map>
+ <key>tinyexr</key>
+ <map>
+ <key>platforms</key>
+ <map>
+ <key>common</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>9e0092c6a3aed1cb40a9e26df689c42c68142c9d</string>
+ <key>hash_algorithm</key>
+ <string>sha1</string>
+ <key>url</key>
+ <string>https://github.com/secondlife/3p-tinyexr/releases/download/v1.0.8-r1/tinyexr-v1.0.8-common-8755737750.tar.zst</string>
+ </map>
+ <key>name</key>
+ <string>common</string>
+ </map>
+ </map>
+ <key>license</key>
+ <string>3-clause BSD</string>
+ <key>license_file</key>
+ <string>LICENSES/tinyexr_license.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors.</string>
+ <key>version</key>
+ <string>v1.0.8</string>
+ <key>name</key>
+ <string>tinyexr</string>
+ <key>vcs_branch</key>
+ <string>dependabot/github_actions/secondlife/action-autobuild-4</string>
+ <key>vcs_revision</key>
+ <string>4dc4d1d90d82a22843e2adf5130f9ecb5ee5769e</string>
+ <key>vcs_url</key>
+ <string>https://github.com/secondlife/3p-tinyexr</string>
+ <key>description</key>
+ <string>tinyexr import library</string>
+ <key>source_type</key>
+ <string>git</string>
+ </map>
</map>
<key>package_description</key>
<map>
diff --git a/build.sh b/build.sh
index 46a287ea32..e025b73170 100755
--- a/build.sh
+++ b/build.sh
@@ -178,6 +178,7 @@ pre_build()
"$autobuild" configure --quiet -c $variant \
${eval_autobuild_configure_parameters:---} \
+ -DLL_TESTS:BOOL=ON \
-DPACKAGE:BOOL=ON \
-DHAVOK:BOOL="$HAVOK" \
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
diff --git a/doc/contributions.txt b/doc/contributions.txt
index a14ffa24fd..15aec5e282 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -245,6 +245,7 @@ Ansariel Hiller
SL-19623
SL-4126
SL-20224
+ https://github.com/secondlife/viewer/issues/1051
Aralara Rajal
Arare Chantilly
CHUIBUG-191
diff --git a/doc/testplans/RenderMaxTextureResolution.md b/doc/testplans/RenderMaxTextureResolution.md
new file mode 100644
index 0000000000..2b117050c7
--- /dev/null
+++ b/doc/testplans/RenderMaxTextureResolution.md
@@ -0,0 +1,16 @@
+The Setting RenderMaxTextureResolution controls the maximum resolution of non-boosted textures as displayed by the viewer.
+
+Valid values are 512-2048 (clamped in C++).
+
+![image](https://github.com/secondlife/viewer/assets/23218274/d0f889fc-8135-41d2-9d83-871ad4eebed5)
+
+![image](https://github.com/secondlife/viewer/assets/23218274/19950828-7eb1-4bb2-85d7-f35c63b34294)
+
+![image](https://github.com/secondlife/viewer/assets/23218274/249afc83-4de6-488d-a05e-4877d08573b1)
+
+Test Asset available on beta grid:
+Object: 'Damaged Helmet', AssetID 0623e759-11b5-746c-a75e-7ba1caa6eb0e
+
+
+
+
diff --git a/doc/testplans/hdri_local_preview.md b/doc/testplans/hdri_local_preview.md
new file mode 100644
index 0000000000..ba4f085100
--- /dev/null
+++ b/doc/testplans/hdri_local_preview.md
@@ -0,0 +1,21 @@
+A resident may swap out their sky for an EXR format HDRI for the purposes of previewing how their object would render in Second Life in an environment that matches the supplied HDRI. This should aid in matching inworld lighting with external tools so artists can know if their content has imported properly.
+
+To load an HDRI, click Develop->Render Tests->HDRI Preview:
+
+![image](https://github.com/secondlife/viewer/assets/23218274/fbdeab5f-dc1f-4406-be19-0c9ee7437b3f)
+
+Choose an EXR image. A library of publicly available HDRIs can be found here: https://polyhaven.com/hdris
+
+The Personal Lighting floater will open, and the sky will be replaced with the HDRI you chose. Reflection Probes will reset, and the scene will be illuminated by the HDRI.
+
+Three debug settings affect how the HDRI is displayed:
+
+RenderHDRIExposure - Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10.
+RenderHDRIRotation - Rotation (in degrees) of environment when previewing an HDRI.
+RenderHDRISplitScreen - What percentage of screen to render using HDRI vs EEP sky.
+
+Exposure and Rotation should behave similarly to the rotation and exposure controls in Substance Painter.
+
+Split Screen can be used to display an EEP sky side-by-side with an HDRI sky to aid in authoring an EEP sky that matches an HDRI sky. It is currently expected that EEP sun disc, moon, clouds, and stars do not render when previewing an HDRI, but that may change in the future.
+
+
diff --git a/doc/testplans/material_preview.md b/doc/testplans/material_preview.md
new file mode 100644
index 0000000000..6d2768f72a
--- /dev/null
+++ b/doc/testplans/material_preview.md
@@ -0,0 +1,83 @@
+# Material Preview
+
+## Overview
+
+Material preview is a UI feature which displays a lit spherical preview of a PBR material. It can be found in the following UIs:
+
+- The material picker swatch
+ - In the build floater, in the Texture tab, when applying a PBR material
+ - (If the feature is enabled) In the Region/Estate floater, in the Terrain tab, when applying PBR materials to terrain
+- In the floater to select a material from inventory, which can be opened by clicking the material picker swatch
+
+## Known Issues
+
+These are known issues that the current implementation of this feature does not address:
+
+- The material preview in the build floater is a preview of the base material ID only, and ignores other properties on the prim face like material overrides (https://github.com/secondlife/viewer/issues/865)
+- Alpha mask previews as alpha blend (https://github.com/secondlife/viewer/issues/866)
+- Double-sided previews as single-sided (https://github.com/secondlife/viewer/issues/867)
+- Material preview inherits some of its lighting from the current environment, and reflections from the default reflection probe (https://github.com/secondlife/viewer/issues/868)
+
+## General Regression Testing
+
+- Check that the material preview swatch looks OK with different materials selected
+- Check that the material preview swatch runs reasonably well on different systems, especially when the select material from inventory floater is also open
+ - In particular: AMD, MacOS, minimum spec machines
+- Watch out for regressions in rendering caused by opening a floater with a material preview swatch
+
+## Bug Fixes
+
+### Disappearing Objects Fix Test
+
+This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
+
+#### Symptoms
+
+When the bug occurs, one or more of following types of objects could randomly disappear in the world, permanently until relog:
+
+- Objects
+- Water level in current region
+- Adjacent region/void water
+
+Note: Disappearing objects in reflections have a different root cause and are not covered by the fix.
+
+#### Bug Reproduction Steps
+
+Verify the disappearing objects bug does not reproduce, given the following steps:
+
+- Runtime prerequisites: Material preview swatch may not be available in your viewer or region if this feature is still behind a feature flag. It is safe to enable this feature manually by setting, "UIPreviewMaterial" to True in the advanced settings. The setting will persist for the current session.
+- Region prerequisites: Unknown, but a region with lots of objects in it seems to increase repro rate. The following locations have been known to easily reproduce the bug, as of 2024-02-16:
+ - http://maps.secondlife.com/secondlife/LindenWorld%20B/161/75/47
+ - [secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24](secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24)
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Ensure "Apply now" is checked in the inventory selection floater
+- Alternate between different materials from the inventory selection floater
+- Look around the world and check for permanently disappeared objects.
+
+### Dynamic Exposure Influence Fix Test
+
+This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed.
+
+#### Symptoms
+
+Dynamic exposure in the world could be influenced by the material preview being displayed. If a material preview was being generated in a given frame, then, depending on the current environment, the user would observe an unpleasant flashing effect in the environment:
+
+- The world view could suddenly get darker and then fade back to normal exposure levels
+- The world view could suddenly get brighter and then fade back to normal exposure levels
+
+#### Bug Reproduction Steps
+
+Verify the dynamic exposure influence bug does not reproduce. Test using a few environment presets such as Default Midday, Sunset, and Midnight.
+
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Alternate between different materials from the inventory selection floater
+
+#### Regression Testing
+
+Dynamic exposure in the world should continue to work correctly. In particular:
+
+- Exposure should fade gradually from high exposure to low exposure and back as needed
+- Exposure should decrease in brighter environments
+- Exposure should increase in darker environments
diff --git a/doc/testplans/pbr_terrain_appearance.md b/doc/testplans/pbr_terrain_appearance.md
new file mode 100644
index 0000000000..4f0ee5c943
--- /dev/null
+++ b/doc/testplans/pbr_terrain_appearance.md
@@ -0,0 +1,35 @@
+# PBR Terrain Appearance
+
+## Tiling
+
+If two adjacent regions have the same PBR terrain settings, then:
+
+- There should not be seams between the two regions at their shared border
+- The ground should not suddenly slide beneath the avatar when moving between regions (except due to movement of the avatar, which is not covered by this test plan)
+
+## Feature Gating
+
+PBR terrain should have lower detail on lower graphics settings. PBR terrain will also not show emissive textures on some machines (like Macs) which do not support more than 16 textures.
+
+### Triplanar Mapping
+
+Triplanar mapping improves the texture repeats on the sides of terrain slopes.
+
+Availability of Triplanar mapping:
+
+- Medium-High and below: No triplanar mapping
+- High and above: Triplanar mapping
+
+### PBR Textures
+
+At the highest graphics support level, PBR terrain supports all PBR textures.
+
+Availability of PBR textures varies by machine and graphics setting:
+
+- Low: Base color only (looks similar to texture terrain)
+- Medium-Low, and machines that do not support greater than 16 textures such as Macs: All PBR textures enabled except emissive textures.
+- Medium: All PBR textures enabled
+
+### PBR Alpha
+
+PBR terrain does not support materials with alpha blend or double-sided. In addition, the viewer does not make any guarantees about what will render behind the terrain if alpha is used.
diff --git a/doc/testplans/pbr_terrain_composition.md b/doc/testplans/pbr_terrain_composition.md
new file mode 100644
index 0000000000..aadd97a94b
--- /dev/null
+++ b/doc/testplans/pbr_terrain_composition.md
@@ -0,0 +1,76 @@
+# PBR Terrain Composition
+
+## Feature Availability
+
+PBR Terrain is visible for all viewers with the PBR Terrain feature, regardless of if the feature flag is enabled.
+
+There is only one set of four asset IDs applied to the terrain. In other words, unlike PBR materials on prims, there is no fallback texture set for viewers that do not support PBR terrain. Viewers without support will view terrain as blank (solid grey or white).
+
+## Editing Terrain Composition
+
+All tests in this section assume the PBR terrain feature flag is enabled, and that the user has appropriate permissions to modify the terrain textures.
+
+### Feature Availability
+
+On the client, the advanced setting `RenderTerrainPBREnabled` is the PBR terrain feature flag.
+
+The PBR terrain feature flag should be set automatically when logging in/teleporting to a new region.
+
+- The flag should be enabled on regions where the PBR terrain feature is enabled
+- Otherwise the flag should be disabled
+
+When the PBR terrain feature flag is disabled:
+
+- The "PBR Metallic Roughness" checkbox should not be visible
+- The user should not be able to apply PBR terrain to the region, only textures.
+
+When the PBR terrain feature flag is enabled:
+
+- The "PBR Metallic Roughness" checkbox should be visible
+- The user should be able to apply PBR terrain or textures to the region, depending on if the "PBR Metallic Roughness" checkbox is checked.
+
+### Current Composition Type
+
+When the Region/Estate floater is opened to the terrain Tab, the current terrain should be shown in the four swatches, and the "PBR Metallic Roughness" checkbox should be checked or unchecked accordingly.
+
+- If it is texture terrain, the "PBR Metallic Roughness" checkbox should be unchecked, and the floater should display the four textures applied to the terrain.
+- If it is material terrain, the "PBR Metallic Roughness" checkbox should be checked, and the floater should display the four materials applied to the terrain.
+
+In addition, where possible, textual labels and descriptions in the tab should make sense given the current value of the "PBR Metallic Roughness" checkbox. If the checkbox is unchecked, the labels should refer to textures. If the checkbox is checked, the labels should refer to materials.
+
+### Toggling Composition Type
+
+When toggling the "PBR Metallic Roughness" checkbox to the opposite value, which does not correspond to the current terrain type, one of the following sets of four terrain swatches will be displayed:
+
+- The default textures/materials
+ - For textures, this is the default terrain texture set
+ - For materials, this is all blank materials, but this is subject to change
+- The previously applied texture/material set
+ - History is available on a best-effort basis only. In particular, the history does not persist on viewer restart.
+
+When toggling back the "PBR Metallic Roughness" checkbox to the original value, assuming nothing else has changed, then the current terrain should be shown in the four swatches again.
+
+### Saving Composition
+
+A user with appropriate permissions can change and save the textures or materials to the terrain. If the "PBR Metallic Roughness" checkbox is checked, the user applies materials, otherwise the user applies textures.
+
+The user should not be allowed to set the texture or material swatches to null.
+
+Saving may fail for the following reasons:
+
+- A terrain or material texture is invalid
+- A terrain texture is greater than the max texture upload resolution
+
+If saving the terrain fails for any reason, the terrain should not be updated.
+
+Unlike a viewer without PBR terrain support, the new viewer will no longer treat textures with alpha channels as invalid.
+
+## Graphics Features
+
+Texture terrain with transparency is not permitted to be applied in the viewer.
+
+See [PBR Terrain Appearance](./pbr_terrain_appearance.md) for supported PBR terrain features.
+
+## Minimap
+
+The minimap should display the terrain with appropriate textures and colors.
diff --git a/doc/testplans/terrain_loading.md b/doc/testplans/terrain_loading.md
new file mode 100644
index 0000000000..c1b170fcf8
--- /dev/null
+++ b/doc/testplans/terrain_loading.md
@@ -0,0 +1,29 @@
+# Terrain Loading
+
+## Behavior overview
+
+- Texture terrain should load if textures are applied to the region, and no PBR Metallic Roughness materials are applied.
+- PBR terrain should load if PBR materials are applied to the region, even if the RenderTerrainPBREnabled feature flag is disabled in debug settings. This setting only disables the display of PBR materials in the Region / Estate > Terrain UI.
+- Related subsystem: A change to the PBR terrain loading system may affect the texture terrain loading system and vice-versa
+- Related subsystem: Minimap should load if terrain loads
+ - They may not finish loading at the same time
+
+## Implementation details
+
+This section is provided mainly for clarification of how the terrain loading system works.
+
+The simulator sends 4 terrain composition UUIDs to the viewer for the region. The viewer does not know ahead-of-time if the terrain composition uses textures or materials. Therefore, to expedite terrain loading, the viewer makes up to 8 "top-level" asset requests simultaneously:
+
+- Up to 4 texture asset requests, one for each UUID
+- Up to 4 material asset requests, one for each UUID
+
+It is therefore expected that half of these asset lookups will fail.
+
+The viewer inspects the load success of these top-level assets to make the binary decision of whether to render all 4 texture assets or all 4 material assets. This determines the choice of composition for terrain both in-world and on the minimap.
+
+The minimap also attempts to wait for textures to partially load before it can render a tile for a given region:
+
+- When rendering texture terrain, the minimap attempts to wait for top-level texture assets to partially load
+- When rendering PBR material terrain, the minimap attempts to wait for any base color/emissive textures in the materials to partially load, if they are present
+
+We don't make guarantees that the minimap tile will render for the region if any aforementioned required textures/materials fail to sufficiently load. However, the minimap may make a best-effort attempt to render the region by ignoring or replacing data.
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 05c51c018d..da7e4be464 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -56,6 +56,8 @@ set(cmake_SOURCE_FILES
PulseAudio.cmake
Python.cmake
TemplateCheck.cmake
+ TinyEXR.cmake
+ TinyGLTF.cmake
Tut.cmake
UI.cmake
UnixInstall.cmake
diff --git a/indra/cmake/TinyEXR.cmake b/indra/cmake/TinyEXR.cmake
new file mode 100644
index 0000000000..e6d142d19d
--- /dev/null
+++ b/indra/cmake/TinyEXR.cmake
@@ -0,0 +1,7 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+use_prebuilt_binary(tinyexr)
+
+set(TINYEXR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tinyexr)
+
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index d24a221671..39e232e480 100644
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file indra_constants.cpp
* @brief some useful short term constants for Indra
*
* $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$
*/
@@ -38,39 +38,39 @@ const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
// Maintenance's group id.
const LLUUID MAINTENANCE_GROUP_ID("dc7b21cd-3c89-fcaa-31c8-25f9ffd224cd");
// Grass Images
-const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER
+const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER
-const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER
+const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER
-const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver
-const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver
-const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver
-const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver
-const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver
+const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver
+const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver
+const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver
+const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver
+const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver
const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector
const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver
-const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver
+const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver
const LLUUID IMG_WHITE ("5748decc-f629-461c-9a36-a35a221fe21f"); // dataserver
-const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver
-const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver
-const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver
-const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver
-const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver
+const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver
+const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver
+const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver
+const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver
+const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver
-const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver
-const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver
+const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver
+const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver
-const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEWER
-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_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEWER
+const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER
+const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // 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
-const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // 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
+const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER
-const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
+const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
const LLUUID DEFAULT_OBJECT_TEXTURE ("89556747-24cb-43ed-920b-47caed15465f"); // On dataserver
const LLUUID DEFAULT_OBJECT_SPECULAR ("87e0e8f7-8729-1ea8-cfc9-8915773009db"); // On dataserver
@@ -89,3 +89,4 @@ const LLUUID IMG_USE_BAKED_AUX1 ("9742065b-19b5-297c-858a-29711d539043");
const LLUUID IMG_USE_BAKED_AUX2 ("03642e83-2bd1-4eb9-34b4-4c47ed586d2d");
const LLUUID IMG_USE_BAKED_AUX3 ("edd51b77-fc10-ce7a-4b3d-011dfc349e4f");
+const LLUUID BLANK_MATERIAL_ASSET_ID ("968cbad0-4dad-d64e-71b5-72bf13ad051a");
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 811313e56e..a4b2efef98 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file indra_constants.h
* @brief some useful short term constants for Indra
*
* $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$
*/
@@ -37,21 +37,21 @@ static const U32 REGION_WIDTH_U32 = 256;
const F32 REGION_HEIGHT_METERS = 4096.f;
-const F32 DEFAULT_AGENT_DEPTH = 0.45f;
-const F32 DEFAULT_AGENT_WIDTH = 0.60f;
-const F32 DEFAULT_AGENT_HEIGHT = 1.9f;
+const F32 DEFAULT_AGENT_DEPTH = 0.45f;
+const F32 DEFAULT_AGENT_WIDTH = 0.60f;
+const F32 DEFAULT_AGENT_HEIGHT = 1.9f;
enum ETerrainBrushType
{
- // the valid brush numbers cannot be reordered, because they
- // are used in the binary LSL format as arguments to llModifyLand()
- E_LANDBRUSH_LEVEL = 0,
- E_LANDBRUSH_RAISE = 1,
- E_LANDBRUSH_LOWER = 2,
- E_LANDBRUSH_SMOOTH = 3,
- E_LANDBRUSH_NOISE = 4,
- E_LANDBRUSH_REVERT = 5,
- E_LANDBRUSH_INVALID = 6
+ // the valid brush numbers cannot be reordered, because they
+ // are used in the binary LSL format as arguments to llModifyLand()
+ E_LANDBRUSH_LEVEL = 0,
+ E_LANDBRUSH_RAISE = 1,
+ E_LANDBRUSH_LOWER = 2,
+ E_LANDBRUSH_SMOOTH = 3,
+ E_LANDBRUSH_NOISE = 4,
+ E_LANDBRUSH_REVERT = 5,
+ E_LANDBRUSH_INVALID = 6
};
enum EMouseClickType{
@@ -67,101 +67,101 @@ enum EMouseClickType{
// keys
// Bit masks for various keyboard modifier keys.
-const MASK MASK_NONE = 0x0000;
-const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
-const MASK MASK_ALT = 0x0002;
-const MASK MASK_SHIFT = 0x0004;
+const MASK MASK_NONE = 0x0000;
+const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
+const MASK MASK_ALT = 0x0002;
+const MASK MASK_SHIFT = 0x0004;
const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
-const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
-const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
+const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
+const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
// Special keys go into >128
-const KEY KEY_SPECIAL = 0x80; // special keys start here
-const KEY KEY_RETURN = 0x81;
-const KEY KEY_LEFT = 0x82;
-const KEY KEY_RIGHT = 0x83;
-const KEY KEY_UP = 0x84;
-const KEY KEY_DOWN = 0x85;
-const KEY KEY_ESCAPE = 0x86;
+const KEY KEY_SPECIAL = 0x80; // special keys start here
+const KEY KEY_RETURN = 0x81;
+const KEY KEY_LEFT = 0x82;
+const KEY KEY_RIGHT = 0x83;
+const KEY KEY_UP = 0x84;
+const KEY KEY_DOWN = 0x85;
+const KEY KEY_ESCAPE = 0x86;
const KEY KEY_BACKSPACE =0x87;
-const KEY KEY_DELETE = 0x88;
-const KEY KEY_SHIFT = 0x89;
-const KEY KEY_CONTROL = 0x8A;
-const KEY KEY_ALT = 0x8B;
-const KEY KEY_HOME = 0x8C;
-const KEY KEY_END = 0x8D;
+const KEY KEY_DELETE = 0x88;
+const KEY KEY_SHIFT = 0x89;
+const KEY KEY_CONTROL = 0x8A;
+const KEY KEY_ALT = 0x8B;
+const KEY KEY_HOME = 0x8C;
+const KEY KEY_END = 0x8D;
const KEY KEY_PAGE_UP = 0x8E;
const KEY KEY_PAGE_DOWN = 0x8F;
const KEY KEY_HYPHEN = 0x90;
const KEY KEY_EQUALS = 0x91;
const KEY KEY_INSERT = 0x92;
const KEY KEY_CAPSLOCK = 0x93;
-const KEY KEY_TAB = 0x94;
-const KEY KEY_ADD = 0x95;
+const KEY KEY_TAB = 0x94;
+const KEY KEY_ADD = 0x95;
const KEY KEY_SUBTRACT =0x96;
const KEY KEY_MULTIPLY =0x97;
-const KEY KEY_DIVIDE = 0x98;
-const KEY KEY_F1 = 0xA1;
-const KEY KEY_F2 = 0xA2;
-const KEY KEY_F3 = 0xA3;
-const KEY KEY_F4 = 0xA4;
-const KEY KEY_F5 = 0xA5;
-const KEY KEY_F6 = 0xA6;
-const KEY KEY_F7 = 0xA7;
-const KEY KEY_F8 = 0xA8;
-const KEY KEY_F9 = 0xA9;
-const KEY KEY_F10 = 0xAA;
-const KEY KEY_F11 = 0xAB;
-const KEY KEY_F12 = 0xAC;
-
-const KEY KEY_PAD_UP = 0xC0;
-const KEY KEY_PAD_DOWN = 0xC1;
-const KEY KEY_PAD_LEFT = 0xC2;
-const KEY KEY_PAD_RIGHT = 0xC3;
-const KEY KEY_PAD_HOME = 0xC4;
-const KEY KEY_PAD_END = 0xC5;
-const KEY KEY_PAD_PGUP = 0xC6;
-const KEY KEY_PAD_PGDN = 0xC7;
-const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
-const KEY KEY_PAD_INS = 0xC9;
-const KEY KEY_PAD_DEL = 0xCA;
-const KEY KEY_PAD_RETURN = 0xCB;
-const KEY KEY_PAD_ADD = 0xCC; // not used
-const KEY KEY_PAD_SUBTRACT = 0xCD; // not used
+const KEY KEY_DIVIDE = 0x98;
+const KEY KEY_F1 = 0xA1;
+const KEY KEY_F2 = 0xA2;
+const KEY KEY_F3 = 0xA3;
+const KEY KEY_F4 = 0xA4;
+const KEY KEY_F5 = 0xA5;
+const KEY KEY_F6 = 0xA6;
+const KEY KEY_F7 = 0xA7;
+const KEY KEY_F8 = 0xA8;
+const KEY KEY_F9 = 0xA9;
+const KEY KEY_F10 = 0xAA;
+const KEY KEY_F11 = 0xAB;
+const KEY KEY_F12 = 0xAC;
+
+const KEY KEY_PAD_UP = 0xC0;
+const KEY KEY_PAD_DOWN = 0xC1;
+const KEY KEY_PAD_LEFT = 0xC2;
+const KEY KEY_PAD_RIGHT = 0xC3;
+const KEY KEY_PAD_HOME = 0xC4;
+const KEY KEY_PAD_END = 0xC5;
+const KEY KEY_PAD_PGUP = 0xC6;
+const KEY KEY_PAD_PGDN = 0xC7;
+const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
+const KEY KEY_PAD_INS = 0xC9;
+const KEY KEY_PAD_DEL = 0xCA;
+const KEY KEY_PAD_RETURN = 0xCB;
+const KEY KEY_PAD_ADD = 0xCC; // not used
+const KEY KEY_PAD_SUBTRACT = 0xCD; // not used
const KEY KEY_PAD_MULTIPLY = 0xCE; // not used
-const KEY KEY_PAD_DIVIDE = 0xCF; // not used
-
-const KEY KEY_BUTTON0 = 0xD0;
-const KEY KEY_BUTTON1 = 0xD1;
-const KEY KEY_BUTTON2 = 0xD2;
-const KEY KEY_BUTTON3 = 0xD3;
-const KEY KEY_BUTTON4 = 0xD4;
-const KEY KEY_BUTTON5 = 0xD5;
-const KEY KEY_BUTTON6 = 0xD6;
-const KEY KEY_BUTTON7 = 0xD7;
-const KEY KEY_BUTTON8 = 0xD8;
-const KEY KEY_BUTTON9 = 0xD9;
-const KEY KEY_BUTTON10 = 0xDA;
-const KEY KEY_BUTTON11 = 0xDB;
-const KEY KEY_BUTTON12 = 0xDC;
-const KEY KEY_BUTTON13 = 0xDD;
-const KEY KEY_BUTTON14 = 0xDE;
-const KEY KEY_BUTTON15 = 0xDF;
-
-const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
+const KEY KEY_PAD_DIVIDE = 0xCF; // not used
+
+const KEY KEY_BUTTON0 = 0xD0;
+const KEY KEY_BUTTON1 = 0xD1;
+const KEY KEY_BUTTON2 = 0xD2;
+const KEY KEY_BUTTON3 = 0xD3;
+const KEY KEY_BUTTON4 = 0xD4;
+const KEY KEY_BUTTON5 = 0xD5;
+const KEY KEY_BUTTON6 = 0xD6;
+const KEY KEY_BUTTON7 = 0xD7;
+const KEY KEY_BUTTON8 = 0xD8;
+const KEY KEY_BUTTON9 = 0xD9;
+const KEY KEY_BUTTON10 = 0xDA;
+const KEY KEY_BUTTON11 = 0xDB;
+const KEY KEY_BUTTON12 = 0xDC;
+const KEY KEY_BUTTON13 = 0xDD;
+const KEY KEY_BUTTON14 = 0xDE;
+const KEY KEY_BUTTON15 = 0xDF;
+
+const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
const S32 KEY_COUNT = 256;
-const F32 DEFAULT_WATER_HEIGHT = 20.0f;
+const F32 DEFAULT_WATER_HEIGHT = 20.0f;
// Maturity ratings for simulators
-const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
-const U8 SIM_ACCESS_PG = 13;
-const U8 SIM_ACCESS_MATURE = 21;
-const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
-const U8 SIM_ACCESS_DOWN = 254;
-const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
+const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
+const U8 SIM_ACCESS_PG = 13;
+const U8 SIM_ACCESS_MATURE = 21;
+const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
+const U8 SIM_ACCESS_DOWN = 254;
+const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
// attachment constants
const U8 ATTACHMENT_ADD = 0x80;
@@ -236,6 +236,8 @@ LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_SPECULAR;
LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_NORMAL;
LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL;
+LL_COMMON_API extern const LLUUID BLANK_MATERIAL_ASSET_ID;
+
// radius within which a chat message is fully audible
const F32 CHAT_NORMAL_RADIUS = 20.f;
@@ -258,84 +260,84 @@ const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13;
const S32 CHAT_CHANNEL_DEBUG = S32_MAX;
// agent constants
-const U32 CONTROL_AT_POS_INDEX = 0;
-const U32 CONTROL_AT_NEG_INDEX = 1;
-const U32 CONTROL_LEFT_POS_INDEX = 2;
-const U32 CONTROL_LEFT_NEG_INDEX = 3;
-const U32 CONTROL_UP_POS_INDEX = 4;
-const U32 CONTROL_UP_NEG_INDEX = 5;
-const U32 CONTROL_PITCH_POS_INDEX = 6;
-const U32 CONTROL_PITCH_NEG_INDEX = 7;
-const U32 CONTROL_YAW_POS_INDEX = 8;
-const U32 CONTROL_YAW_NEG_INDEX = 9;
-const U32 CONTROL_FAST_AT_INDEX = 10;
-const U32 CONTROL_FAST_LEFT_INDEX = 11;
-const U32 CONTROL_FAST_UP_INDEX = 12;
-const U32 CONTROL_FLY_INDEX = 13;
-const U32 CONTROL_STOP_INDEX = 14;
-const U32 CONTROL_FINISH_ANIM_INDEX = 15;
-const U32 CONTROL_STAND_UP_INDEX = 16;
-const U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
-const U32 CONTROL_MOUSELOOK_INDEX = 18;
-const U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
-const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
-const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
-const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
-const U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
-const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
-const U32 CONTROL_TURN_LEFT_INDEX = 25;
-const U32 CONTROL_TURN_RIGHT_INDEX = 26;
-const U32 CONTROL_AWAY_INDEX = 27;
-const U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
-const U32 CONTROL_LBUTTON_UP_INDEX = 29;
-const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
-const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
-const U32 TOTAL_CONTROLS = 32;
-
-const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
-const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
-const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
-const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
-const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
-const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
-const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
-const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
-const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
-const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
-
-const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
-const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
-const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
-
-const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
-const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
-const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
-const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
-const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
-const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
-
-const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
-const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
-const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
-const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
-const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
-const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
-const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
-const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
-
-const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
-
-const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
-const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
-const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
-const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
-
-// move these up so that we can hide them in "State" for object updates
+const U32 CONTROL_AT_POS_INDEX = 0;
+const U32 CONTROL_AT_NEG_INDEX = 1;
+const U32 CONTROL_LEFT_POS_INDEX = 2;
+const U32 CONTROL_LEFT_NEG_INDEX = 3;
+const U32 CONTROL_UP_POS_INDEX = 4;
+const U32 CONTROL_UP_NEG_INDEX = 5;
+const U32 CONTROL_PITCH_POS_INDEX = 6;
+const U32 CONTROL_PITCH_NEG_INDEX = 7;
+const U32 CONTROL_YAW_POS_INDEX = 8;
+const U32 CONTROL_YAW_NEG_INDEX = 9;
+const U32 CONTROL_FAST_AT_INDEX = 10;
+const U32 CONTROL_FAST_LEFT_INDEX = 11;
+const U32 CONTROL_FAST_UP_INDEX = 12;
+const U32 CONTROL_FLY_INDEX = 13;
+const U32 CONTROL_STOP_INDEX = 14;
+const U32 CONTROL_FINISH_ANIM_INDEX = 15;
+const U32 CONTROL_STAND_UP_INDEX = 16;
+const U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
+const U32 CONTROL_MOUSELOOK_INDEX = 18;
+const U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
+const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
+const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
+const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
+const U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
+const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
+const U32 CONTROL_TURN_LEFT_INDEX = 25;
+const U32 CONTROL_TURN_RIGHT_INDEX = 26;
+const U32 CONTROL_AWAY_INDEX = 27;
+const U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
+const U32 CONTROL_LBUTTON_UP_INDEX = 29;
+const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
+const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
+const U32 TOTAL_CONTROLS = 32;
+
+const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
+const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
+const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
+const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
+const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
+const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
+const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
+const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
+const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
+const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
+
+const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
+const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
+const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
+
+const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
+const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
+const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
+const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
+const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
+const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
+
+const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
+const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
+const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
+const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
+const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
+const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
+const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
+const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
+
+const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
+
+const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
+const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
+const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
+const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
+
+// move these up so that we can hide them in "State" for object updates
// (for now)
-const U32 AGENT_ATTACH_OFFSET = 4;
-const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
+const U32 AGENT_ATTACH_OFFSET = 4;
+const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
-// RN: this method swaps the upper and lower nibbles to maintain backward
+// RN: this method swaps the upper and lower nibbles to maintain backward
// compatibility with old objects that only used the upper nibble
#define ATTACHMENT_ID_FROM_STATE(state) ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4)))
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 20340397db..8612f9353f 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -3,25 +3,25 @@
* @author Nat Goodspeed
* @date 2009-06-03
* @brief Implementation for llcoros.
- *
+ *
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -123,7 +123,7 @@ LLCoros::LLCoros():
// Previously we used
// boost::context::guarded_stack_allocator::default_stacksize();
// empirically this is insufficient.
- mStackSize(900*1024),
+ mStackSize(1024*1024),
// mCurrent does NOT own the current CoroData instance -- it simply
// points to it. So initialize it with a no-op deleter.
mCurrent{ [](CoroData*){} }
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index 6c76ab8104..e7522484e6 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -1,24 +1,24 @@
-/**
+/**
* @file llstrider.h
*
* $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$
*/
@@ -30,38 +30,38 @@
template <class Object> class LLStrider
{
- union
- {
- Object* mObjectp;
- U8* mBytep;
- };
- U32 mSkip;
+ union
+ {
+ Object* mObjectp;
+ U8* mBytep;
+ };
+ U32 mSkip;
public:
+ LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
+ LLStrider(Object* first) { mObjectp = first; mSkip = sizeof(Object); }
+ ~LLStrider() { }
- LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
- ~LLStrider() { }
-
- const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
- void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
+ const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
+ void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
- LLStrider<Object> operator+(const S32& index)
- {
- LLStrider<Object> ret;
- ret.mBytep = mBytep + mSkip*index;
- ret.mSkip = mSkip;
+ LLStrider<Object> operator+(const S32& index)
+ {
+ LLStrider<Object> ret;
+ ret.mBytep = mBytep + mSkip*index;
+ ret.mSkip = mSkip;
- return ret;
- }
+ return ret;
+ }
- void skip(const U32 index) { mBytep += mSkip*index;}
- U32 getSkip() const { return mSkip; }
- Object* get() { return mObjectp; }
- Object* operator->() { return mObjectp; }
- Object& operator *() { return *mObjectp; }
- Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
- Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
+ void skip(const U32 index) { mBytep += mSkip*index;}
+ U32 getSkip() const { return mSkip; }
+ Object* get() { return mObjectp; }
+ Object* operator->() { return mObjectp; }
+ Object& operator *() { return *mObjectp; }
+ Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
+ Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
- Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
+ Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
};
#endif // LL_LLSTRIDER_H
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 196ec7805a..ed8f36286f 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llimage.cpp
* @brief Base class for images.
*
* $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$
*/
@@ -31,6 +31,7 @@
#include "llmath.h"
#include "v4coloru.h"
+#include "v3color.h"
#include "llimagebmp.h"
#include "llimagetga.h"
@@ -53,40 +54,40 @@
#define _UNROL_GEN_TPL_comma_1 BOOST_PP_COMMA()
//..................................................................................
#define _UNROL_GEN_TPL_ARGS_macro(z,n,seq) \
- BOOST_PP_CAT(_UNROL_GEN_TPL_arg_, BOOST_PP_MOD(n, 2))(BOOST_PP_SEQ_ELEM(n, seq)) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq))))
+ BOOST_PP_CAT(_UNROL_GEN_TPL_arg_, BOOST_PP_MOD(n, 2))(BOOST_PP_SEQ_ELEM(n, seq)) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq))))
#define _UNROL_GEN_TPL_ARGS(seq) \
- BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_ARGS_macro, seq)
+ BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_ARGS_macro, seq)
//..................................................................................
#define _UNROL_GEN_TPL_TYPE_ARGS_macro(z,n,seq) \
- BOOST_PP_SEQ_ELEM(n, seq) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq))))
+ BOOST_PP_SEQ_ELEM(n, seq) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq))))
#define _UNROL_GEN_TPL_TYPE_ARGS(seq) \
- BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_TYPE_ARGS_macro, seq)
+ BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_TYPE_ARGS_macro, seq)
//..................................................................................
#define _UNROLL_GEN_TPL_foreach_ee(z, n, seq) \
- executor<n>(_UNROL_GEN_TPL_ARGS(seq));
+ executor<n>(_UNROL_GEN_TPL_ARGS(seq));
#define _UNROLL_GEN_TPL(name, args_seq, operation, spec) \
- template<> struct name<spec> { \
- private: \
- template<S32 _idx> inline void executor(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \
- BOOST_PP_SEQ_ENUM(operation) ; \
- } \
- public: \
- inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \
- BOOST_PP_REPEAT(spec, _UNROLL_GEN_TPL_foreach_ee, args_seq) \
- } \
+ template<> struct name<spec> { \
+ private: \
+ template<S32 _idx> inline void executor(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \
+ BOOST_PP_SEQ_ENUM(operation) ; \
+ } \
+ public: \
+ inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \
+ BOOST_PP_REPEAT(spec, _UNROLL_GEN_TPL_foreach_ee, args_seq) \
+ } \
};
//..................................................................................
#define _UNROLL_GEN_TPL_foreach_seq_macro(r, data, elem) \
- _UNROLL_GEN_TPL(BOOST_PP_SEQ_ELEM(0, data), BOOST_PP_SEQ_ELEM(1, data), BOOST_PP_SEQ_ELEM(2, data), elem)
+ _UNROLL_GEN_TPL(BOOST_PP_SEQ_ELEM(0, data), BOOST_PP_SEQ_ELEM(1, data), BOOST_PP_SEQ_ELEM(2, data), elem)
#define UNROLL_GEN_TPL(name, args_seq, operation, spec_seq) \
- /*general specialization - should not be implemented!*/ \
- template<U8> struct name { inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { /*static_assert(!"Should not be instantiated.");*/ } }; \
- BOOST_PP_SEQ_FOR_EACH(_UNROLL_GEN_TPL_foreach_seq_macro, (name)(args_seq)(operation), spec_seq)
+ /*general specialization - should not be implemented!*/ \
+ template<U8> struct name { inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { /*static_assert(!"Should not be instantiated.");*/ } }; \
+ BOOST_PP_SEQ_FOR_EACH(_UNROLL_GEN_TPL_foreach_seq_macro, (name)(args_seq)(operation), spec_seq)
//..................................................................................
//..................................................................................
@@ -122,460 +123,460 @@ UNROLL_GEN_TPL(uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff, (U8 *&)(dptr)(S3
template<U8 ch>
-struct scale_info
+struct scale_info
{
public:
- std::vector<S32> xpoints;
- std::vector<const U8*> ystrides;
- std::vector<S32> xapoints, yapoints;
- S32 xup_yup;
+ std::vector<S32> xpoints;
+ std::vector<const U8*> ystrides;
+ std::vector<S32> xapoints, yapoints;
+ S32 xup_yup;
public:
- //unrolling loop types declaration
- typedef uroll_zeroze_cx_comp<ch> uroll_zeroze_cx_comp_t;
- typedef uroll_comp_rshftasgn_constval<ch> uroll_comp_rshftasgn_constval_t;
- typedef uroll_comp_asgn_cx_rshft_cval_all_mul_val<ch> uroll_comp_asgn_cx_rshft_cval_all_mul_val_t;
- typedef uroll_comp_plusasgn_cx_rshft_cval_all_mul_val<ch> uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t;
- typedef uroll_inp_plusasgn_pix_mul_val<ch> uroll_inp_plusasgn_pix_mul_val_t;
- typedef uroll_inp_asgn_pix_mul_val<ch> uroll_inp_asgn_pix_mul_val_t;
- typedef uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r<ch> uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t;
- typedef uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r<ch> uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t;
- typedef uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r<ch> uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t;
- typedef uroll_uref_dptr_inc_asgn_comp_and_ff<ch> uroll_uref_dptr_inc_asgn_comp_and_ff_t;
- typedef uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff<ch> uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t;
- typedef uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff<ch> uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t;
+ //unrolling loop types declaration
+ typedef uroll_zeroze_cx_comp<ch> uroll_zeroze_cx_comp_t;
+ typedef uroll_comp_rshftasgn_constval<ch> uroll_comp_rshftasgn_constval_t;
+ typedef uroll_comp_asgn_cx_rshft_cval_all_mul_val<ch> uroll_comp_asgn_cx_rshft_cval_all_mul_val_t;
+ typedef uroll_comp_plusasgn_cx_rshft_cval_all_mul_val<ch> uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t;
+ typedef uroll_inp_plusasgn_pix_mul_val<ch> uroll_inp_plusasgn_pix_mul_val_t;
+ typedef uroll_inp_asgn_pix_mul_val<ch> uroll_inp_asgn_pix_mul_val_t;
+ typedef uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r<ch> uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t;
+ typedef uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r<ch> uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t;
+ typedef uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r<ch> uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t;
+ typedef uroll_uref_dptr_inc_asgn_comp_and_ff<ch> uroll_uref_dptr_inc_asgn_comp_and_ff_t;
+ typedef uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff<ch> uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t;
+ typedef uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff<ch> uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t;
public:
- scale_info(const U8 *src, U32 srcW, U32 srcH, U32 dstW, U32 dstH, U32 srcStride)
- : xup_yup((dstW >= srcW) + ((dstH >= srcH) << 1))
- {
- calc_x_points(srcW, dstW);
- calc_y_strides(src, srcStride, srcH, dstH);
- calc_aa_points(srcW, dstW, xup_yup&1, xapoints);
- calc_aa_points(srcH, dstH, xup_yup&2, yapoints);
- }
+ scale_info(const U8 *src, U32 srcW, U32 srcH, U32 dstW, U32 dstH, U32 srcStride)
+ : xup_yup((dstW >= srcW) + ((dstH >= srcH) << 1))
+ {
+ calc_x_points(srcW, dstW);
+ calc_y_strides(src, srcStride, srcH, dstH);
+ calc_aa_points(srcW, dstW, xup_yup&1, xapoints);
+ calc_aa_points(srcH, dstH, xup_yup&2, yapoints);
+ }
private:
- //...........................................................................................
- void calc_x_points(U32 srcW, U32 dstW)
- {
- xpoints.resize(dstW+1);
-
- S32 val = dstW >= srcW ? 0x8000 * srcW / dstW - 0x8000 : 0;
- S32 inc = (srcW << 16) / dstW;
-
- for(U32 i = 0, j = 0; i < dstW; ++i, ++j, val += inc)
- {
- xpoints[j] = llmax(0, val >> 16);
- }
- }
- //...........................................................................................
- void calc_y_strides(const U8 *src, U32 srcStride, U32 srcH, U32 dstH)
- {
- ystrides.resize(dstH+1);
-
- S32 val = dstH >= srcH ? 0x8000 * srcH / dstH - 0x8000 : 0;
- S32 inc = (srcH << 16) / dstH;
-
- for(U32 i = 0, j = 0; i < dstH; ++i, ++j, val += inc)
- {
- ystrides[j] = src + llmax(0, val >> 16) * srcStride;
- }
- }
- //...........................................................................................
- void calc_aa_points(U32 srcSz, U32 dstSz, bool scale_up, std::vector<S32> &vp)
- {
- vp.resize(dstSz);
-
- if(scale_up)
- {
- S32 val = 0x8000 * srcSz / dstSz - 0x8000;
- S32 inc = (srcSz << 16) / dstSz;
- U32 pos;
-
- for(U32 i = 0, j = 0; i < dstSz; ++i, ++j, val += inc)
- {
- pos = val >> 16;
-
- if (pos >= (srcSz - 1))
- vp[j] = 0;
- else
- vp[j] = (val >> 8) - ((val >> 8) & 0xffffff00);
- }
- }
- else
- {
- S32 inc = (srcSz << 16) / dstSz;
- S32 Cp = ((dstSz << 14) / srcSz) + 1;
- S32 ap;
-
- for(U32 i = 0, j = 0, val = 0; i < dstSz; ++i, ++j, val += inc)
- {
- ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
- vp[j] = ap | (Cp << 16);
- }
- }
- }
+ //...........................................................................................
+ void calc_x_points(U32 srcW, U32 dstW)
+ {
+ xpoints.resize(dstW+1);
+
+ S32 val = dstW >= srcW ? 0x8000 * srcW / dstW - 0x8000 : 0;
+ S32 inc = (srcW << 16) / dstW;
+
+ for(U32 i = 0, j = 0; i < dstW; ++i, ++j, val += inc)
+ {
+ xpoints[j] = llmax(0, val >> 16);
+ }
+ }
+ //...........................................................................................
+ void calc_y_strides(const U8 *src, U32 srcStride, U32 srcH, U32 dstH)
+ {
+ ystrides.resize(dstH+1);
+
+ S32 val = dstH >= srcH ? 0x8000 * srcH / dstH - 0x8000 : 0;
+ S32 inc = (srcH << 16) / dstH;
+
+ for(U32 i = 0, j = 0; i < dstH; ++i, ++j, val += inc)
+ {
+ ystrides[j] = src + llmax(0, val >> 16) * srcStride;
+ }
+ }
+ //...........................................................................................
+ void calc_aa_points(U32 srcSz, U32 dstSz, bool scale_up, std::vector<S32> &vp)
+ {
+ vp.resize(dstSz);
+
+ if(scale_up)
+ {
+ S32 val = 0x8000 * srcSz / dstSz - 0x8000;
+ S32 inc = (srcSz << 16) / dstSz;
+ U32 pos;
+
+ for(U32 i = 0, j = 0; i < dstSz; ++i, ++j, val += inc)
+ {
+ pos = val >> 16;
+
+ if (pos >= (srcSz - 1))
+ vp[j] = 0;
+ else
+ vp[j] = (val >> 8) - ((val >> 8) & 0xffffff00);
+ }
+ }
+ else
+ {
+ S32 inc = (srcSz << 16) / dstSz;
+ S32 Cp = ((dstSz << 14) / srcSz) + 1;
+ S32 ap;
+
+ for(U32 i = 0, j = 0, val = 0; i < dstSz; ++i, ++j, val += inc)
+ {
+ ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
+ vp[j] = ap | (Cp << 16);
+ }
+ }
+ }
};
template<U8 ch>
inline void bilinear_scale(
- const U8 *src, U32 srcW, U32 srcH, U32 srcStride
- , U8 *dst, U32 dstW, U32 dstH, U32 dstStride
- )
-{
- typedef scale_info<ch> scale_info_t;
-
- scale_info_t info(src, srcW, srcH, dstW, dstH, srcStride);
-
- const U8 *sptr;
- U8 *dptr;
- U32 x, y;
- const U8 *pix;
-
- S32 cx[ch], comp[ch];
-
-
- if(3 == info.xup_yup)
- { //scale x/y - up
- for(y = 0; y < dstH; ++y)
- {
- dptr = dst + (y * dstStride);
- sptr = info.ystrides[y];
-
- if(0 < info.yapoints[y])
- {
- for(x = 0; x < dstW; ++x)
- {
- //for(c = 0; c < ch; ++c) cx[c] = comp[c] = 0;
- typename scale_info_t::uroll_zeroze_cx_comp_t()(cx, comp);
-
- if(0 < info.xapoints[x])
- {
- pix = info.ystrides[y] + info.xpoints[x] * ch;
-
- //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.xapoints[x]);
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]);
-
- pix += ch;
-
- //for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x];
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, info.xapoints[x]);
-
- pix += srcStride;
-
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x];
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, info.xapoints[x]);
-
- pix -= ch;
-
- //for(c = 0; c < ch; ++c) {
- // cx[c] += pix[c] * (256 - info.xapoints[x]);
- // comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16;
- // *dptr++ = comp[c]&0xff;
- //}
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, 256 - info.xapoints[x]);
- typename scale_info_t::uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t()(comp, cx, info.yapoints[y]);
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
- }
- else
- {
- pix = info.ystrides[y] + info.xpoints[x] * ch;
-
- //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.yapoints[y]);
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256-info.yapoints[y]);
-
- pix += srcStride;
-
- //for(c = 0; c < ch; ++c) {
- // comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8;
- // *dptr++ = comp[c]&0xff;
- //}
- typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.yapoints[y]);
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
- }
- }
- }
- else
- {
- for(x = 0; x < dstW; ++x)
- {
- if(0 < info.xapoints[x])
- {
- pix = info.ystrides[y] + info.xpoints[x] * ch;
-
- //for(c = 0; c < ch; ++c) {
- // comp[c] = pix[c] * (256 - info.xapoints[x]);
- // comp[c] = (comp[c] + pix[c] * info.xapoints[x]) >> 8;
- // *dptr++ = comp[c]&0xff;
- //}
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]);
- typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.xapoints[x]);
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
- }
- else
- {
- //for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff;
- typename scale_info_t::uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t()(dptr, sptr, info.xpoints[x]*ch);
- }
- }
- }
- }
- }
- else if(info.xup_yup == 1)
- { //scaling down vertically
- S32 Cy, j;
- S32 yap;
-
- for(y = 0; y < dstH; y++)
- {
- Cy = info.yapoints[y] >> 16;
- yap = info.yapoints[y] & 0xffff;
-
- dptr = dst + (y * dstStride);
-
- for(x = 0; x < dstW; x++)
- {
- pix = info.ystrides[y] + info.xpoints[x] * ch;
-
- //for(c = 0; c < ch; ++c) comp[c] = pix[c] * yap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, yap);
-
- pix += srcStride;
-
- for(j = (1 << 14) - yap; j > Cy; j -= Cy, pix += srcStride)
- {
- //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cy;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cy);
- }
-
- if(j > 0)
- {
- //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j);
- }
-
- if(info.xapoints[x] > 0)
- {
- pix = info.ystrides[y] + info.xpoints[x]*ch + ch;
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * yap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, yap);
-
- pix += srcStride;
- for(j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cy;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cy);
- pix += srcStride;
- }
-
- if(j > 0)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j);
- }
-
- //for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12;
- typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.xapoints[x], cx);
- }
- else
- {
- //for(c = 0; c < ch; ++c) comp[c] >>= 4;
- typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4);
- }
-
- //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff;
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10);
- }
- }
- }
- else if(info.xup_yup == 2)
- { // scaling down horizontally
- S32 Cx, j;
- S32 xap;
-
- for(y = 0; y < dstH; y++)
- {
- dptr = dst + (y * dstStride);
-
- for(x = 0; x < dstW; x++)
- {
- Cx = info.xapoints[x] >> 16;
- xap = info.xapoints[x] & 0xffff;
-
- pix = info.ystrides[y] + info.xpoints[x] * ch;
-
- //for(c = 0; c < ch; ++c) comp[c] = pix[c] * xap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, xap);
-
- pix+=ch;
- for(j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cx;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cx);
- pix+=ch;
- }
-
- if(j > 0)
- {
- //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j);
- }
-
- if(info.yapoints[y] > 0)
- {
- pix = info.ystrides[y] + info.xpoints[x]*ch + srcStride;
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
-
- pix+=ch;
- for(j = (1 << 14) - xap; j > Cx; j -= Cx)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
- pix+=ch;
- }
-
- if(j > 0)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j);
- }
-
- //for(c = 0; c < ch; ++c) comp[c] = ((comp[c] * (256 - info.yapoints[y])) + ((cx[c] * info.yapoints[y]))) >> 12;
- typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.yapoints[y], cx);
- }
- else
- {
- //for(c = 0; c < ch; ++c) comp[c] >>= 4;
- typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4);
- }
-
- //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff;
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10);
- }
- }
- }
- else
- { //scale x/y - down
- S32 Cx, Cy, i, j;
- S32 xap, yap;
-
- for(y = 0; y < dstH; y++)
- {
- Cy = info.yapoints[y] >> 16;
- yap = info.yapoints[y] & 0xffff;
-
- dptr = dst + (y * dstStride);
- for(x = 0; x < dstW; x++)
- {
- Cx = info.xapoints[x] >> 16;
- xap = info.xapoints[x] & 0xffff;
-
- sptr = info.ystrides[y] + info.xpoints[x] * ch;
- pix = sptr;
- sptr += srcStride;
-
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
-
- pix+=ch;
- for(i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
- pix+=ch;
- }
-
- if(i > 0)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
- }
-
- //for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap;
- typename scale_info_t::uroll_comp_asgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, yap);
-
- for(j = (1 << 14) - yap; j > Cy; j -= Cy)
- {
- pix = sptr;
- sptr += srcStride;
-
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
-
- pix+=ch;
- for(i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
- pix+=ch;
- }
-
- if(i > 0)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
- }
-
- //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy;
- typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, Cy);
- }
-
- if(j > 0)
- {
- pix = sptr;
- sptr += srcStride;
-
- //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
- typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
-
- pix+=ch;
- for(i = (1 << 14) - xap; i > Cx; i -= Cx)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
- pix+=ch;
- }
-
- if(i > 0)
- {
- //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
- typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
- }
-
- //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * j;
- typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, j);
- }
-
- //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>23)&0xff;
- typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 23);
- }
- }
- } //else
+ const U8 *src, U32 srcW, U32 srcH, U32 srcStride
+ , U8 *dst, U32 dstW, U32 dstH, U32 dstStride
+ )
+{
+ typedef scale_info<ch> scale_info_t;
+
+ scale_info_t info(src, srcW, srcH, dstW, dstH, srcStride);
+
+ const U8 *sptr;
+ U8 *dptr;
+ U32 x, y;
+ const U8 *pix;
+
+ S32 cx[ch], comp[ch];
+
+
+ if(3 == info.xup_yup)
+ { //scale x/y - up
+ for(y = 0; y < dstH; ++y)
+ {
+ dptr = dst + (y * dstStride);
+ sptr = info.ystrides[y];
+
+ if(0 < info.yapoints[y])
+ {
+ for(x = 0; x < dstW; ++x)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] = comp[c] = 0;
+ typename scale_info_t::uroll_zeroze_cx_comp_t()(cx, comp);
+
+ if(0 < info.xapoints[x])
+ {
+ pix = info.ystrides[y] + info.xpoints[x] * ch;
+
+ //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.xapoints[x]);
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]);
+
+ pix += ch;
+
+ //for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x];
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, info.xapoints[x]);
+
+ pix += srcStride;
+
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x];
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, info.xapoints[x]);
+
+ pix -= ch;
+
+ //for(c = 0; c < ch; ++c) {
+ // cx[c] += pix[c] * (256 - info.xapoints[x]);
+ // comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16;
+ // *dptr++ = comp[c]&0xff;
+ //}
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, 256 - info.xapoints[x]);
+ typename scale_info_t::uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t()(comp, cx, info.yapoints[y]);
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
+ }
+ else
+ {
+ pix = info.ystrides[y] + info.xpoints[x] * ch;
+
+ //for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.yapoints[y]);
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256-info.yapoints[y]);
+
+ pix += srcStride;
+
+ //for(c = 0; c < ch; ++c) {
+ // comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8;
+ // *dptr++ = comp[c]&0xff;
+ //}
+ typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.yapoints[y]);
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
+ }
+ }
+ }
+ else
+ {
+ for(x = 0; x < dstW; ++x)
+ {
+ if(0 < info.xapoints[x])
+ {
+ pix = info.ystrides[y] + info.xpoints[x] * ch;
+
+ //for(c = 0; c < ch; ++c) {
+ // comp[c] = pix[c] * (256 - info.xapoints[x]);
+ // comp[c] = (comp[c] + pix[c] * info.xapoints[x]) >> 8;
+ // *dptr++ = comp[c]&0xff;
+ //}
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]);
+ typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.xapoints[x]);
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp);
+ }
+ else
+ {
+ //for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff;
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t()(dptr, sptr, info.xpoints[x]*ch);
+ }
+ }
+ }
+ }
+ }
+ else if(info.xup_yup == 1)
+ { //scaling down vertically
+ S32 Cy, j;
+ S32 yap;
+
+ for(y = 0; y < dstH; y++)
+ {
+ Cy = info.yapoints[y] >> 16;
+ yap = info.yapoints[y] & 0xffff;
+
+ dptr = dst + (y * dstStride);
+
+ for(x = 0; x < dstW; x++)
+ {
+ pix = info.ystrides[y] + info.xpoints[x] * ch;
+
+ //for(c = 0; c < ch; ++c) comp[c] = pix[c] * yap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, yap);
+
+ pix += srcStride;
+
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy, pix += srcStride)
+ {
+ //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cy;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cy);
+ }
+
+ if(j > 0)
+ {
+ //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j);
+ }
+
+ if(info.xapoints[x] > 0)
+ {
+ pix = info.ystrides[y] + info.xpoints[x]*ch + ch;
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * yap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, yap);
+
+ pix += srcStride;
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cy;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cy);
+ pix += srcStride;
+ }
+
+ if(j > 0)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j);
+ }
+
+ //for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12;
+ typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.xapoints[x], cx);
+ }
+ else
+ {
+ //for(c = 0; c < ch; ++c) comp[c] >>= 4;
+ typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4);
+ }
+
+ //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff;
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10);
+ }
+ }
+ }
+ else if(info.xup_yup == 2)
+ { // scaling down horizontally
+ S32 Cx, j;
+ S32 xap;
+
+ for(y = 0; y < dstH; y++)
+ {
+ dptr = dst + (y * dstStride);
+
+ for(x = 0; x < dstW; x++)
+ {
+ Cx = info.xapoints[x] >> 16;
+ xap = info.xapoints[x] & 0xffff;
+
+ pix = info.ystrides[y] + info.xpoints[x] * ch;
+
+ //for(c = 0; c < ch; ++c) comp[c] = pix[c] * xap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, xap);
+
+ pix+=ch;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ //for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cx;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cx);
+ pix+=ch;
+ }
+
+ if(j > 0)
+ {
+ //for(c = 0; c < ch; ++c) comp[c] += pix[c] * j;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j);
+ }
+
+ if(info.yapoints[y] > 0)
+ {
+ pix = info.ystrides[y] + info.xpoints[x]*ch + srcStride;
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
+
+ pix+=ch;
+ for(j = (1 << 14) - xap; j > Cx; j -= Cx)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
+ pix+=ch;
+ }
+
+ if(j > 0)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * j;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j);
+ }
+
+ //for(c = 0; c < ch; ++c) comp[c] = ((comp[c] * (256 - info.yapoints[y])) + ((cx[c] * info.yapoints[y]))) >> 12;
+ typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.yapoints[y], cx);
+ }
+ else
+ {
+ //for(c = 0; c < ch; ++c) comp[c] >>= 4;
+ typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4);
+ }
+
+ //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff;
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10);
+ }
+ }
+ }
+ else
+ { //scale x/y - down
+ S32 Cx, Cy, i, j;
+ S32 xap, yap;
+
+ for(y = 0; y < dstH; y++)
+ {
+ Cy = info.yapoints[y] >> 16;
+ yap = info.yapoints[y] & 0xffff;
+
+ dptr = dst + (y * dstStride);
+ for(x = 0; x < dstW; x++)
+ {
+ Cx = info.xapoints[x] >> 16;
+ xap = info.xapoints[x] & 0xffff;
+
+ sptr = info.ystrides[y] + info.xpoints[x] * ch;
+ pix = sptr;
+ sptr += srcStride;
+
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
+
+ pix+=ch;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
+ pix+=ch;
+ }
+
+ if(i > 0)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
+ }
+
+ //for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap;
+ typename scale_info_t::uroll_comp_asgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, yap);
+
+ for(j = (1 << 14) - yap; j > Cy; j -= Cy)
+ {
+ pix = sptr;
+ sptr += srcStride;
+
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
+
+ pix+=ch;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
+ pix+=ch;
+ }
+
+ if(i > 0)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
+ }
+
+ //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy;
+ typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, Cy);
+ }
+
+ if(j > 0)
+ {
+ pix = sptr;
+ sptr += srcStride;
+
+ //for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap;
+ typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap);
+
+ pix+=ch;
+ for(i = (1 << 14) - xap; i > Cx; i -= Cx)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx);
+ pix+=ch;
+ }
+
+ if(i > 0)
+ {
+ //for(c = 0; c < ch; ++c) cx[c] += pix[c] * i;
+ typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i);
+ }
+
+ //for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * j;
+ typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, j);
+ }
+
+ //for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>23)&0xff;
+ typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 23);
+ }
+ }
+ } //else
}
//wrapper
static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 srcStride, U8 *dst, U32 dstW, U32 dstH, U32 dstCh, U32 dstStride)
{
- llassert(srcCh == dstCh);
+ llassert(srcCh == dstCh);
- switch(srcCh)
- {
- case 1:
- bilinear_scale<1>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
- break;
- case 3:
- bilinear_scale<3>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
- break;
- case 4:
- bilinear_scale<4>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
- break;
- default:
- llassert(!"Implement if need");
- break;
- }
+ switch(srcCh)
+ {
+ case 1:
+ bilinear_scale<1>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
+ break;
+ case 3:
+ bilinear_scale<3>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
+ break;
+ case 4:
+ bilinear_scale<4>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride);
+ break;
+ default:
+ llassert(!"Implement if need");
+ break;
+ }
}
@@ -592,30 +593,30 @@ S32 LLImage::sMinimalReverseByteRangePercent = 75;
//static
void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
{
- sUseNewByteRange = use_new_byte_range;
+ sUseNewByteRange = use_new_byte_range;
sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
- sMutex = new LLMutex();
+ sMutex = new LLMutex();
}
//static
void LLImage::cleanupClass()
{
- delete sMutex;
- sMutex = NULL;
+ delete sMutex;
+ sMutex = NULL;
}
//static
const std::string& LLImage::getLastError()
{
- static const std::string noerr("No Error");
- return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
+ static const std::string noerr("No Error");
+ return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
}
//static
void LLImage::setLastError(const std::string& message)
{
- LLMutexLock m(sMutex);
- sLastErrorMessage = message;
+ LLMutexLock m(sMutex);
+ sLastErrorMessage = message;
}
//---------------------------------------------------------------------------
@@ -623,175 +624,175 @@ void LLImage::setLastError(const std::string& message)
//---------------------------------------------------------------------------
LLImageBase::LLImageBase()
-: mData(NULL),
- mDataSize(0),
- mWidth(0),
- mHeight(0),
- mComponents(0),
- mBadBufferAllocation(false),
- mAllowOverSize(false)
+: mData(NULL),
+ mDataSize(0),
+ mWidth(0),
+ mHeight(0),
+ mComponents(0),
+ mBadBufferAllocation(false),
+ mAllowOverSize(false)
{}
// virtual
LLImageBase::~LLImageBase()
{
- deleteData(); // virtual
+ deleteData(); // virtual
}
// virtual
void LLImageBase::dump()
{
- LL_INFOS() << "LLImageBase mComponents " << mComponents
- << " mData " << mData
- << " mDataSize " << mDataSize
- << " mWidth " << mWidth
- << " mHeight " << mHeight
- << LL_ENDL;
+ LL_INFOS() << "LLImageBase mComponents " << mComponents
+ << " mData " << mData
+ << " mDataSize " << mDataSize
+ << " mWidth " << mWidth
+ << " mHeight " << mHeight
+ << LL_ENDL;
}
// virtual
void LLImageBase::sanityCheck()
{
- if (mWidth > MAX_IMAGE_SIZE
- || mHeight > MAX_IMAGE_SIZE
- || mDataSize > (S32)MAX_IMAGE_DATA_SIZE
- || mComponents > (S8)MAX_IMAGE_COMPONENTS
- )
- {
- LL_ERRS() << "Failed LLImageBase::sanityCheck "
- << "width " << mWidth
- << "height " << mHeight
- << "datasize " << mDataSize
- << "components " << mComponents
- << "data " << mData
- << LL_ENDL;
- }
+ if (mWidth > MAX_IMAGE_SIZE
+ || mHeight > MAX_IMAGE_SIZE
+ || mDataSize > (S32)MAX_IMAGE_DATA_SIZE
+ || mComponents > (S8)MAX_IMAGE_COMPONENTS
+ )
+ {
+ LL_ERRS() << "Failed LLImageBase::sanityCheck "
+ << "width " << mWidth
+ << "height " << mHeight
+ << "datasize " << mDataSize
+ << "components " << mComponents
+ << "data " << mData
+ << LL_ENDL;
+ }
}
// virtual
void LLImageBase::deleteData()
{
- ll_aligned_free_16(mData);
- mDataSize = 0;
- mData = NULL;
+ ll_aligned_free_16(mData);
+ mDataSize = 0;
+ mData = NULL;
}
// virtual
U8* LLImageBase::allocateData(S32 size)
{
- //make this function thread-safe.
- static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16; //256 MB
- mBadBufferAllocation = false;
-
- if (size < 0)
- {
- size = mWidth * mHeight * mComponents;
- if (size <= 0)
- {
- LL_WARNS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL;
- mBadBufferAllocation = true;
- }
- }
-
- if (!mBadBufferAllocation && (size < 1 || size > MAX_BUFFER_SIZE))
- {
- LL_INFOS() << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << LL_ENDL ;
- if(mAllowOverSize)
- {
- LL_INFOS() << "Oversize: " << size << LL_ENDL ;
- }
- else
- {
- LL_WARNS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL;
- mBadBufferAllocation = true;
- }
- }
-
- if (!mBadBufferAllocation && (!mData || size != mDataSize))
- {
- deleteData(); // virtual
- mData = (U8*)ll_aligned_malloc_16(size);
- if (!mData)
- {
- LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL;
- mBadBufferAllocation = true;
- }
- }
-
- if (mBadBufferAllocation)
- {
- size = 0;
- mWidth = mHeight = 0;
- if (mData)
- {
- deleteData(); // virtual
- mData = NULL;
- }
- }
- mDataSize = size;
-
- return mData;
+ //make this function thread-safe.
+ static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16; //256 MB
+ mBadBufferAllocation = false;
+
+ if (size < 0)
+ {
+ size = mWidth * mHeight * mComponents;
+ if (size <= 0)
+ {
+ LL_WARNS() << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << LL_ENDL;
+ mBadBufferAllocation = true;
+ }
+ }
+
+ if (!mBadBufferAllocation && (size < 1 || size > MAX_BUFFER_SIZE))
+ {
+ LL_INFOS() << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << LL_ENDL ;
+ if(mAllowOverSize)
+ {
+ LL_INFOS() << "Oversize: " << size << LL_ENDL ;
+ }
+ else
+ {
+ LL_WARNS() << "LLImageBase::allocateData: bad size: " << size << LL_ENDL;
+ mBadBufferAllocation = true;
+ }
+ }
+
+ if (!mBadBufferAllocation && (!mData || size != mDataSize))
+ {
+ deleteData(); // virtual
+ mData = (U8*)ll_aligned_malloc_16(size);
+ if (!mData)
+ {
+ LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL;
+ mBadBufferAllocation = true;
+ }
+ }
+
+ if (mBadBufferAllocation)
+ {
+ size = 0;
+ mWidth = mHeight = 0;
+ if (mData)
+ {
+ deleteData(); // virtual
+ mData = NULL;
+ }
+ }
+ mDataSize = size;
+
+ return mData;
}
// virtual
U8* LLImageBase::reallocateData(S32 size)
{
- U8 *new_datap = (U8*)ll_aligned_malloc_16(size);
- if (!new_datap)
- {
- LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL;
- return 0;
- }
- if (mData)
- {
- S32 bytes = llmin(mDataSize, size);
- memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */
- ll_aligned_free_16(mData) ;
- }
- mData = new_datap;
- mDataSize = size;
- mBadBufferAllocation = false;
- return mData;
-}
-
-const U8* LLImageBase::getData() const
-{
- if(mBadBufferAllocation)
- {
- LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ;
- return NULL;
- }
-
- return mData;
+ U8 *new_datap = (U8*)ll_aligned_malloc_16(size);
+ if (!new_datap)
+ {
+ LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL;
+ return 0;
+ }
+ if (mData)
+ {
+ S32 bytes = llmin(mDataSize, size);
+ memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */
+ ll_aligned_free_16(mData) ;
+ }
+ mData = new_datap;
+ mDataSize = size;
+ mBadBufferAllocation = false;
+ return mData;
+}
+
+const U8* LLImageBase::getData() const
+{
+ if(mBadBufferAllocation)
+ {
+ LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ;
+ return NULL;
+ }
+
+ return mData;
} // read only
-U8* LLImageBase::getData()
-{
- if(mBadBufferAllocation)
- {
- LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL;
- return NULL;
- }
+U8* LLImageBase::getData()
+{
+ if(mBadBufferAllocation)
+ {
+ LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL;
+ return NULL;
+ }
- return mData;
+ return mData;
}
bool LLImageBase::isBufferInvalid() const
{
- return mBadBufferAllocation || mData == NULL ;
+ return mBadBufferAllocation || mData == NULL ;
}
void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents)
{
- mWidth = width;
- mHeight = height;
- mComponents = ncomponents;
+ mWidth = width;
+ mHeight = height;
+ mComponents = ncomponents;
}
U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size)
{
- setSize(width, height, ncomponents);
- return allocateData(size); // virtual
+ setSize(width, height, ncomponents);
+ return allocateData(size); // virtual
}
//---------------------------------------------------------------------------
@@ -801,17 +802,17 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si
S32 LLImageRaw::sRawImageCount = 0;
LLImageRaw::LLImageRaw()
- : LLImageBase()
+ : LLImageBase()
{
- ++sRawImageCount;
+ ++sRawImageCount;
}
LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
- : LLImageBase()
+ : LLImageBase()
{
- //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
- allocateDataSize(width, height, components);
- ++sRawImageCount;
+ //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
+ allocateDataSize(width, height, components);
+ ++sRawImageCount;
}
LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components)
@@ -824,45 +825,45 @@ LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components)
}
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
- : LLImageBase()
+ : LLImageBase()
{
- if(no_copy)
- {
- setDataAndSize(data, width, height, components);
- }
- else if(allocateDataSize(width, height, components))
- {
- memcpy(getData(), data, width*height*components);
- }
- ++sRawImageCount;
+ if(no_copy)
+ {
+ setDataAndSize(data, width, height, components);
+ }
+ else if(allocateDataSize(width, height, components))
+ {
+ memcpy(getData(), data, width*height*components);
+ }
+ ++sRawImageCount;
}
//LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only)
-// : LLImageBase()
+// : LLImageBase()
//{
-// createFromFile(filename, j2c_lowest_mip_only);
+// createFromFile(filename, j2c_lowest_mip_only);
//}
LLImageRaw::~LLImageRaw()
{
- // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
- // NOT LLImageRaw::deleteData()
- deleteData();
- --sRawImageCount;
+ // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
+ // NOT LLImageRaw::deleteData()
+ deleteData();
+ --sRawImageCount;
}
// virtual
U8* LLImageRaw::allocateData(S32 size)
{
- U8* res = LLImageBase::allocateData(size);
- return res;
+ U8* res = LLImageBase::allocateData(size);
+ return res;
}
// virtual
U8* LLImageRaw::reallocateData(S32 size)
{
- U8* res = LLImageBase::reallocateData(size);
- return res;
+ U8* res = LLImageBase::reallocateData(size);
+ return res;
}
void LLImageRaw::releaseData()
@@ -874,121 +875,143 @@ void LLImageRaw::releaseData()
// virtual
void LLImageRaw::deleteData()
{
- LLImageBase::deleteData();
+ LLImageBase::deleteData();
}
-void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
-{
- if(data == getData())
- {
- return ;
- }
+void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
+{
+ if(data == getData())
+ {
+ return ;
+ }
- deleteData();
+ deleteData();
- LLImageBase::setSize(width, height, components) ;
- LLImageBase::setDataAndSize(data, width * height * components) ;
+ LLImageBase::setSize(width, height, components) ;
+ LLImageBase::setDataAndSize(data, width * height * components) ;
}
bool LLImageRaw::resize(U16 width, U16 height, S8 components)
{
- if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid())
- {
- return true;
- }
- // Reallocate the data buffer.
- deleteData();
+ if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid())
+ {
+ return true;
+ }
+ // Reallocate the data buffer.
+ deleteData();
- allocateDataSize(width,height,components);
+ allocateDataSize(width,height,components);
- return !isBufferInvalid();
+ return !isBufferInvalid();
}
bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
- const U8 *data, U32 stride, bool reverse_y)
+ const U8 *data, U32 stride, bool reverse_y)
{
- if (!getData())
- {
- return false;
- }
- if (!data)
- {
- return false;
- }
+ if (!getData())
+ {
+ return false;
+ }
+ if (!data)
+ {
+ return false;
+ }
- // Should do some simple bounds checking
+ // Should do some simple bounds checking
- U32 i;
- for (i = 0; i < height; i++)
- {
- const U32 row = reverse_y ? height - 1 - i : i;
- const U32 from_offset = row * ((stride == 0) ? width*getComponents() : stride);
- const U32 to_offset = (y_pos + i)*getWidth() + x_pos;
- memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */
- data + from_offset, getComponents()*width);
- }
+ U32 i;
+ for (i = 0; i < height; i++)
+ {
+ const U32 row = reverse_y ? height - 1 - i : i;
+ const U32 from_offset = row * ((stride == 0) ? width*getComponents() : stride);
+ const U32 to_offset = (y_pos + i)*getWidth() + x_pos;
+ memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */
+ data + from_offset, getComponents()*width);
+ }
- return true;
+ return true;
}
void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
{
- llassert( getComponents() <= 4 );
- // This is fairly bogus, but it'll do for now.
- if (isBufferInvalid())
+ llassert( getComponents() <= 4 );
+ // This is fairly bogus, but it'll do for now.
+ if (isBufferInvalid())
+ {
+ LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+ return;
+ }
+
+ U8 *pos = getData();
+ U32 x, y;
+ for (x = 0; x < getWidth(); x++)
+ {
+ for (y = 0; y < getHeight(); y++)
+ {
+ *pos = r;
+ pos++;
+ if (getComponents() == 1)
+ {
+ continue;
+ }
+ *pos = g;
+ pos++;
+ if (getComponents() == 2)
+ {
+ continue;
+ }
+ *pos = b;
+ pos++;
+ if (getComponents() == 3)
+ {
+ continue;
+ }
+ *pos = a;
+ pos++;
+ }
+ }
+}
+
+// Reverses the order of the rows in the image
+void LLImageRaw::verticalFlip()
+{
+ S32 row_bytes = getWidth() * getComponents();
+ llassert(row_bytes > 0);
+ std::vector<U8> line_buffer(row_bytes);
+ S32 mid_row = getHeight() / 2;
+ for( S32 row = 0; row < mid_row; row++ )
+ {
+ U8* row_a_data = getData() + row * row_bytes;
+ U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes;
+ memcpy( &line_buffer[0], row_a_data, row_bytes );
+ memcpy( row_a_data, row_b_data, row_bytes );
+ memcpy( row_b_data, &line_buffer[0], row_bytes );
+ }
+}
+
+
+bool LLImageRaw::checkHasTransparentPixels()
+{
+ if (getComponents() != 4)
{
- LL_WARNS() << "Invalid image buffer" << LL_ENDL;
- return;
+ return false;
}
- U8 *pos = getData();
- U32 x, y;
- for (x = 0; x < getWidth(); x++)
+ U8* data = getData();
+ U32 pixels = getWidth() * getHeight();
+
+ // check alpha channel for all 255
+ for (U32 i = 0; i < pixels; ++i)
{
- for (y = 0; y < getHeight(); y++)
+ if (data[i * 4 + 3] != 255)
{
- *pos = r;
- pos++;
- if (getComponents() == 1)
- {
- continue;
- }
- *pos = g;
- pos++;
- if (getComponents() == 2)
- {
- continue;
- }
- *pos = b;
- pos++;
- if (getComponents() == 3)
- {
- continue;
- }
- *pos = a;
- pos++;
+ return true;
}
}
-}
-// Reverses the order of the rows in the image
-void LLImageRaw::verticalFlip()
-{
- S32 row_bytes = getWidth() * getComponents();
- llassert(row_bytes > 0);
- std::vector<U8> line_buffer(row_bytes);
- S32 mid_row = getHeight() / 2;
- for( S32 row = 0; row < mid_row; row++ )
- {
- U8* row_a_data = getData() + row * row_bytes;
- U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes;
- memcpy( &line_buffer[0], row_a_data, row_bytes );
- memcpy( row_a_data, row_b_data, row_bytes );
- memcpy( row_b_data, &line_buffer[0], row_bytes );
- }
+ return false;
}
-
bool LLImageRaw::optimizeAwayAlpha()
{
if (getComponents() == 4)
@@ -1026,432 +1049,484 @@ bool LLImageRaw::optimizeAwayAlpha()
return false;
}
+bool LLImageRaw::makeAlpha()
+{
+ if (getComponents() == 3)
+ {
+ U8* data = getData();
+ U32 pixels = getWidth() * getHeight();
+
+ // alpha channel doesn't exist, make a new copy of data with alpha channel
+ U8* new_data = (U8*) ll_aligned_malloc_16(getWidth() * getHeight() * 4);
+
+ for (U32 i = 0; i < pixels; ++i)
+ {
+ U32 di = i * 4;
+ U32 si = i * 3;
+ for (U32 j = 0; j < 3; ++j)
+ {
+ new_data[di+j] = data[si+j];
+ }
+ }
+
+ setDataAndSize(new_data, getWidth(), getHeight(), 3);
+
+ return true;
+ }
+
+ return false;
+}
+
void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)
{
- // Find new sizes
- S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim);
- S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim);
+ // Find new sizes
+ S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim);
+ S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim);
- scale( new_width, new_height, scale_image );
+ scale( new_width, new_height, scale_image );
}
void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image)
{
- // Find new sizes
- S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE);
- S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE);
+ // Find new sizes
+ S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE);
+ S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE);
- scale( new_width, new_height, scale_image );
+ scale( new_width, new_height, scale_image );
}
// static
S32 LLImageRaw::biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim)
{
- // Strong bias towards rounding down (to save bandwidth)
- // No bias would mean THRESHOLD == 1.5f;
- const F32 THRESHOLD = 1.75f;
-
- // Find new sizes
- S32 larger_dim = max_dim; // 2^n >= curr_dim
- S32 smaller_dim = max_dim; // 2^(n-1) <= curr_dim
- while( (smaller_dim > curr_dim) && (smaller_dim > MIN_IMAGE_SIZE) )
- {
- larger_dim = smaller_dim;
- smaller_dim >>= 1;
- }
- return ( ((F32)curr_dim / (F32)smaller_dim) > THRESHOLD ) ? larger_dim : smaller_dim;
+ // Strong bias towards rounding down (to save bandwidth)
+ // No bias would mean THRESHOLD == 1.5f;
+ const F32 THRESHOLD = 1.75f;
+
+ // Find new sizes
+ S32 larger_dim = max_dim; // 2^n >= curr_dim
+ S32 smaller_dim = max_dim; // 2^(n-1) <= curr_dim
+ while( (smaller_dim > curr_dim) && (smaller_dim > MIN_IMAGE_SIZE) )
+ {
+ larger_dim = smaller_dim;
+ smaller_dim >>= 1;
+ }
+ return ( ((F32)curr_dim / (F32)smaller_dim) > THRESHOLD ) ? larger_dim : smaller_dim;
}
// static
S32 LLImageRaw::expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim)
{
- S32 new_dim = MIN_IMAGE_SIZE;
- while( (new_dim < curr_dim) && (new_dim < max_dim) )
- {
- new_dim <<= 1;
- }
+ S32 new_dim = MIN_IMAGE_SIZE;
+ while( (new_dim < curr_dim) && (new_dim < max_dim) )
+ {
+ new_dim <<= 1;
+ }
return new_dim;
}
// static
S32 LLImageRaw::contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim)
{
- S32 new_dim = MAX_IMAGE_SIZE;
- while( (new_dim > curr_dim) && (new_dim > min_dim) )
- {
- new_dim >>= 1;
- }
+ S32 new_dim = MAX_IMAGE_SIZE;
+ while( (new_dim > curr_dim) && (new_dim > min_dim) )
+ {
+ new_dim >>= 1;
+ }
return new_dim;
}
void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
{
- // Find new sizes
- S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim);
- S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim);
+ // Find new sizes
+ S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim);
+ S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim);
- scale( new_width, new_height );
+ scale( new_width, new_height );
}
// Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f). Thanks, Jim Blinn!
inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )
{
- U32 i = a * b + 128;
- return U8((i + (i>>8)) >> 8);
+ U32 i = a * b + 128;
+ return U8((i + (i>>8)) >> 8);
}
void LLImageRaw::composite( LLImageRaw* src )
{
- LLImageRaw* dst = this; // Just for clarity.
-
- if (!validateSrcAndDst("LLImageRaw::composite", src, dst))
- {
- return;
- }
-
- llassert(3 == src->getComponents());
- llassert(3 == dst->getComponents());
-
- if( 3 == dst->getComponents() )
- {
- if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
- {
- // No scaling needed
- if( 3 == src->getComponents() )
- {
- copyUnscaled( src ); // alpha is one so just copy the data.
- }
- else
- {
- compositeUnscaled4onto3( src );
- }
- }
- else
- {
- if( 3 == src->getComponents() )
- {
- copyScaled( src ); // alpha is one so just copy the data.
- }
- else
- {
- compositeScaled4onto3( src );
- }
- }
- }
+ LLImageRaw* dst = this; // Just for clarity.
+
+ if (!validateSrcAndDst("LLImageRaw::composite", src, dst))
+ {
+ return;
+ }
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert(3 == dst->getComponents());
+
+ if( 3 == dst->getComponents() )
+ {
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ // No scaling needed
+ if( 3 == src->getComponents() )
+ {
+ copyUnscaled( src ); // alpha is one so just copy the data.
+ }
+ else
+ {
+ compositeUnscaled4onto3( src );
+ }
+ }
+ else
+ {
+ if( 3 == src->getComponents() )
+ {
+ copyScaled( src ); // alpha is one so just copy the data.
+ }
+ else
+ {
+ compositeScaled4onto3( src );
+ }
+ }
+ }
}
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
- LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;
+ LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;
- LLImageRaw* dst = this; // Just for clarity.
+ LLImageRaw* dst = this; // Just for clarity.
- llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
+ llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
- S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
- llassert_always(temp_data_size > 0);
- std::vector<U8> temp_buffer(temp_data_size);
+ S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
+ llassert_always(temp_data_size > 0);
+ std::vector<U8> temp_buffer(temp_data_size);
- // Vertical: scale but no composite
- for( S32 col = 0; col < src->getWidth(); col++ )
- {
- copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
- }
+ // Vertical: scale but no composite
+ for( S32 col = 0; col < src->getWidth(); col++ )
+ {
+ copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
+ }
- // Horizontal: scale and composite
- for( S32 row = 0; row < dst->getHeight(); row++ )
- {
- compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
- }
+ // Horizontal: scale and composite
+ for( S32 row = 0; row < dst->getHeight(); row++ )
+ {
+ compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
+ }
}
// Src and dst are same size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
{
- LLImageRaw* dst = this; // Just for clarity.
-
- llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
- llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
-
- U8* src_data = src->getData();
- U8* dst_data = dst->getData();
- S32 pixels = getWidth() * getHeight();
- while( pixels-- )
- {
- U8 alpha = src_data[3];
- if( alpha )
- {
- if( 255 == alpha )
- {
- dst_data[0] = src_data[0];
- dst_data[1] = src_data[1];
- dst_data[2] = src_data[2];
- }
- else
- {
-
- U8 transparency = 255 - alpha;
- dst_data[0] = fastFractionalMult( dst_data[0], transparency ) + fastFractionalMult( src_data[0], alpha );
- dst_data[1] = fastFractionalMult( dst_data[1], transparency ) + fastFractionalMult( src_data[1], alpha );
- dst_data[2] = fastFractionalMult( dst_data[2], transparency ) + fastFractionalMult( src_data[2], alpha );
- }
- }
-
- src_data += 4;
- dst_data += 3;
- }
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ S32 pixels = getWidth() * getHeight();
+ while( pixels-- )
+ {
+ U8 alpha = src_data[3];
+ if( alpha )
+ {
+ if( 255 == alpha )
+ {
+ dst_data[0] = src_data[0];
+ dst_data[1] = src_data[1];
+ dst_data[2] = src_data[2];
+ }
+ else
+ {
+
+ U8 transparency = 255 - alpha;
+ dst_data[0] = fastFractionalMult( dst_data[0], transparency ) + fastFractionalMult( src_data[0], alpha );
+ dst_data[1] = fastFractionalMult( dst_data[1], transparency ) + fastFractionalMult( src_data[1], alpha );
+ dst_data[2] = fastFractionalMult( dst_data[2], transparency ) + fastFractionalMult( src_data[2], alpha );
+ }
+ }
+
+ src_data += 4;
+ dst_data += 3;
+ }
}
void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
{
- LLImageRaw* dst = this; // Just for clarity.
+ LLImageRaw* dst = this; // Just for clarity.
- if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))
- {
- return;
- }
+ if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))
+ {
+ return;
+ }
- llassert( 1 == src->getComponents() );
- llassert( 4 == dst->getComponents() );
- llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+ llassert( 1 == src->getComponents() );
+ llassert( 4 == dst->getComponents() );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
- S32 pixels = getWidth() * getHeight();
- U8* src_data = src->getData();
- U8* dst_data = dst->getData();
- for ( S32 i = 0; i < pixels; i++ )
- {
- dst_data[0] = fill.mV[0];
- dst_data[1] = fill.mV[1];
- dst_data[2] = fill.mV[2];
- dst_data[3] = src_data[0];
- src_data += 1;
- dst_data += 4;
- }
+ S32 pixels = getWidth() * getHeight();
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ for ( S32 i = 0; i < pixels; i++ )
+ {
+ dst_data[0] = fill.mV[0];
+ dst_data[1] = fill.mV[1];
+ dst_data[2] = fill.mV[2];
+ dst_data[3] = src_data[0];
+ src_data += 1;
+ dst_data += 4;
+ }
}
// Fill the buffer with a constant color
void LLImageRaw::fill( const LLColor4U& color )
{
- if (isBufferInvalid())
- {
- LL_WARNS() << "Invalid image buffer" << LL_ENDL;
- return;
- }
-
- S32 pixels = getWidth() * getHeight();
- if( 4 == getComponents() )
+ if (isBufferInvalid())
+ {
+ LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+ return;
+ }
+
+ S32 pixels = getWidth() * getHeight();
+ if( 4 == getComponents() )
+ {
+ U32* data = (U32*) getData();
+ U32 rgbaColor = color.asRGBA();
+ for( S32 i = 0; i < pixels; i++ )
+ {
+ data[ i ] = rgbaColor;
+ }
+ }
+ else
+ if( 3 == getComponents() )
+ {
+ U8* data = getData();
+ for( S32 i = 0; i < pixels; i++ )
+ {
+ data[0] = color.mV[0];
+ data[1] = color.mV[1];
+ data[2] = color.mV[2];
+ data += 3;
+ }
+ }
+}
+
+void LLImageRaw::tint( const LLColor3& color )
+{
+ llassert( (3 == getComponents()) || (4 == getComponents()) );
+ if (isBufferInvalid())
+ {
+ LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+ return;
+ }
+
+ S32 pixels = getWidth() * getHeight();
+ const S32 components = getComponents();
+ U8* data = getData();
+ for( S32 i = 0; i < pixels; i++ )
{
- U32* data = (U32*) getData();
- U32 rgbaColor = color.asRGBA();
- for( S32 i = 0; i < pixels; i++ )
- {
- data[ i ] = rgbaColor;
- }
- }
- else
- if( 3 == getComponents() )
- {
- U8* data = getData();
- for( S32 i = 0; i < pixels; i++ )
- {
- data[0] = color.mV[0];
- data[1] = color.mV[1];
- data[2] = color.mV[2];
- data += 3;
- }
+ const float c0 = data[0] * color.mV[0];
+ const float c1 = data[1] * color.mV[1];
+ const float c2 = data[2] * color.mV[2];
+ data[0] = llclamp((U8)c0, 0, 255);
+ data[1] = llclamp((U8)c1, 0, 255);
+ data[2] = llclamp((U8)c2, 0, 255);
+ data += components;
}
}
LLPointer<LLImageRaw> LLImageRaw::duplicate()
{
- if(getNumRefs() < 2)
- {
- return this; //nobody else refences to this image, no need to duplicate.
- }
+ if(getNumRefs() < 2)
+ {
+ return this; //nobody else refences to this image, no need to duplicate.
+ }
- //make a duplicate
- LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
- return dup;
+ //make a duplicate
+ LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
+ return dup;
}
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void LLImageRaw::copy(LLImageRaw* src)
{
- LLImageRaw* dst = this; // Just for clarity.
-
- if (!validateSrcAndDst("LLImageRaw::copy", src, dst))
- {
- return;
- }
-
- if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
- {
- // No scaling needed
- if( src->getComponents() == dst->getComponents() )
- {
- copyUnscaled( src );
- }
- else
- if( 3 == src->getComponents() )
- {
- copyUnscaled3onto4( src );
- }
- else
- {
- // 4 == src->getComponents()
- copyUnscaled4onto3( src );
- }
- }
- else
- {
- // Scaling needed
- // No scaling needed
- if( src->getComponents() == dst->getComponents() )
- {
- copyScaled( src );
- }
- else
- if( 3 == src->getComponents() )
- {
- copyScaled3onto4( src );
- }
- else
- {
- // 4 == src->getComponents()
- copyScaled4onto3( src );
- }
- }
+ LLImageRaw* dst = this; // Just for clarity.
+
+ if (!validateSrcAndDst("LLImageRaw::copy", src, dst))
+ {
+ return;
+ }
+
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ // No scaling needed
+ if( src->getComponents() == dst->getComponents() )
+ {
+ copyUnscaled( src );
+ }
+ else
+ if( 3 == src->getComponents() )
+ {
+ copyUnscaled3onto4( src );
+ }
+ else
+ {
+ // 4 == src->getComponents()
+ copyUnscaled4onto3( src );
+ }
+ }
+ else
+ {
+ // Scaling needed
+ // No scaling needed
+ if( src->getComponents() == dst->getComponents() )
+ {
+ copyScaled( src );
+ }
+ else
+ if( 3 == src->getComponents() )
+ {
+ copyScaled3onto4( src );
+ }
+ else
+ {
+ // 4 == src->getComponents()
+ copyScaled4onto3( src );
+ }
+ }
}
// Src and dst are same size. Src and dst have same number of components.
void LLImageRaw::copyUnscaled(LLImageRaw* src)
{
- LLImageRaw* dst = this; // Just for clarity.
+ LLImageRaw* dst = this; // Just for clarity.
- llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
- llassert( src->getComponents() == dst->getComponents() );
- llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+ llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
+ llassert( src->getComponents() == dst->getComponents() );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
- memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
+ memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
}
// Src and dst can be any size. Src has 3 components. Dst has 4 components.
void LLImageRaw::copyScaled3onto4(LLImageRaw* src)
{
- llassert( (3 == src->getComponents()) && (4 == getComponents()) );
+ llassert( (3 == src->getComponents()) && (4 == getComponents()) );
- // Slow, but simple. Optimize later if needed.
- LLImageRaw temp( src->getWidth(), src->getHeight(), 4);
- temp.copyUnscaled3onto4( src );
- copyScaled( &temp );
+ // Slow, but simple. Optimize later if needed.
+ LLImageRaw temp( src->getWidth(), src->getHeight(), 4);
+ temp.copyUnscaled3onto4( src );
+ copyScaled( &temp );
}
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::copyScaled4onto3(LLImageRaw* src)
{
- llassert( (4 == src->getComponents()) && (3 == getComponents()) );
+ llassert( (4 == src->getComponents()) && (3 == getComponents()) );
- // Slow, but simple. Optimize later if needed.
- LLImageRaw temp( src->getWidth(), src->getHeight(), 3);
- temp.copyUnscaled4onto3( src );
- copyScaled( &temp );
+ // Slow, but simple. Optimize later if needed.
+ LLImageRaw temp( src->getWidth(), src->getHeight(), 3);
+ temp.copyUnscaled4onto3( src );
+ copyScaled( &temp );
}
// Src and dst are same size. Src has 4 components. Dst has 3 components.
void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src )
{
- LLImageRaw* dst = this; // Just for clarity.
+ LLImageRaw* dst = this; // Just for clarity.
- llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) );
- llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+ llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
- S32 pixels = getWidth() * getHeight();
- U8* src_data = src->getData();
- U8* dst_data = dst->getData();
- for( S32 i=0; i<pixels; i++ )
- {
- dst_data[0] = src_data[0];
- dst_data[1] = src_data[1];
- dst_data[2] = src_data[2];
- src_data += 4;
- dst_data += 3;
- }
+ S32 pixels = getWidth() * getHeight();
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ for( S32 i=0; i<pixels; i++ )
+ {
+ dst_data[0] = src_data[0];
+ dst_data[1] = src_data[1];
+ dst_data[2] = src_data[2];
+ src_data += 4;
+ dst_data += 3;
+ }
}
// Src and dst are same size. Src has 3 components. Dst has 4 components.
void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
{
- LLImageRaw* dst = this; // Just for clarity.
- llassert( 3 == src->getComponents() );
- llassert( 4 == dst->getComponents() );
- llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+ LLImageRaw* dst = this; // Just for clarity.
+ llassert( 3 == src->getComponents() );
+ llassert( 4 == dst->getComponents() );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
- S32 pixels = getWidth() * getHeight();
- U8* src_data = src->getData();
- U8* dst_data = dst->getData();
- for( S32 i=0; i<pixels; i++ )
- {
- dst_data[0] = src_data[0];
- dst_data[1] = src_data[1];
- dst_data[2] = src_data[2];
- dst_data[3] = 255;
- src_data += 3;
- dst_data += 4;
- }
+ S32 pixels = getWidth() * getHeight();
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ for( S32 i=0; i<pixels; i++ )
+ {
+ dst_data[0] = src_data[0];
+ dst_data[1] = src_data[1];
+ dst_data[2] = src_data[2];
+ dst_data[3] = 255;
+ src_data += 3;
+ dst_data += 4;
+ }
}
// Src and dst can be any size. Src and dst have same number of components.
void LLImageRaw::copyScaled( LLImageRaw* src )
{
- LLImageRaw* dst = this; // Just for clarity.
+ LLImageRaw* dst = this; // Just for clarity.
- if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))
- {
- return;
- }
+ if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))
+ {
+ return;
+ }
- llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
- llassert_always( src->getComponents() == dst->getComponents() );
+ llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
+ llassert_always( src->getComponents() == dst->getComponents() );
- if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
- {
- memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
- return;
- }
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
+ return;
+ }
- bilinear_scale(
- src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), src->getWidth()*src->getComponents()
- , dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents(), dst->getWidth()*dst->getComponents()
- );
+ bilinear_scale(
+ src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), src->getWidth()*src->getComponents()
+ , dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents(), dst->getWidth()*dst->getComponents()
+ );
- /*
- S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
- llassert_always(temp_data_size > 0);
- std::vector<U8> temp_buffer(temp_data_size);
+ /*
+ S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
+ llassert_always(temp_data_size > 0);
+ std::vector<U8> temp_buffer(temp_data_size);
- // Vertical
- for( S32 col = 0; col < src->getWidth(); col++ )
- {
- copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
- }
+ // Vertical
+ for( S32 col = 0; col < src->getWidth(); col++ )
+ {
+ copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
+ }
- // Horizontal
- for( S32 row = 0; row < dst->getHeight(); row++ )
- {
- copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
- }
- */
+ // Horizontal
+ for( S32 row = 0; row < dst->getHeight(); row++ )
+ {
+ copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
+ }
+ */
}
@@ -1464,79 +1539,79 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
return false;
}
- if (isBufferInvalid())
- {
- LL_WARNS() << "Invalid image buffer" << LL_ENDL;
- return false;
- }
-
- S32 old_width = getWidth();
- S32 old_height = getHeight();
+ if (isBufferInvalid())
+ {
+ LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+ return false;
+ }
- if( (old_width == new_width) && (old_height == new_height) )
- {
- return true; // Nothing to do.
- }
+ S32 old_width = getWidth();
+ S32 old_height = getHeight();
+
+ if( (old_width == new_width) && (old_height == new_height) )
+ {
+ return true; // Nothing to do.
+ }
- // Reallocate the data buffer.
+ // Reallocate the data buffer.
- if (scale_image_data)
- {
- S32 new_data_size = new_width * new_height * components;
+ if (scale_image_data)
+ {
+ S32 new_data_size = new_width * new_height * components;
- if (new_data_size > 0)
+ if (new_data_size > 0)
{
- U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size);
- if(NULL == new_data)
+ U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size);
+ if(NULL == new_data)
{
- return false;
+ return false;
}
bilinear_scale(getData(), old_width, old_height, components, old_width*components, new_data, new_width, new_height, components, new_width*components);
- setDataAndSize(new_data, new_width, new_height, components);
- }
- }
- else try
- {
- // copy out existing image data
- S32 temp_data_size = old_width * old_height * components;
- std::vector<U8> temp_buffer(temp_data_size);
- memcpy(&temp_buffer[0], getData(), temp_data_size);
-
- // allocate new image data, will delete old data
- U8* new_buffer = allocateDataSize(new_width, new_height, components);
+ setDataAndSize(new_data, new_width, new_height, components);
+ }
+ }
+ else try
+ {
+ // copy out existing image data
+ S32 temp_data_size = old_width * old_height * components;
+ std::vector<U8> temp_buffer(temp_data_size);
+ memcpy(&temp_buffer[0], getData(), temp_data_size);
+
+ // allocate new image data, will delete old data
+ U8* new_buffer = allocateDataSize(new_width, new_height, components);
if (!new_buffer)
{
LL_WARNS() << "Failed to allocate new image data buffer" << LL_ENDL;
return false;
}
-
- for( S32 row = 0; row < new_height; row++ )
+
+ for( S32 row = 0; row < new_height; row++ )
{
- if (row < old_height)
+ if (row < old_height)
{
- memcpy(new_buffer + (new_width * row * components), &temp_buffer[0] + (old_width * row * components), components * llmin(old_width, new_width));
- if (old_width < new_width)
+ memcpy(new_buffer + (new_width * row * components), &temp_buffer[0] + (old_width * row * components), components * llmin(old_width, new_width));
+ if (old_width < new_width)
{
- // pad out rest of row with black
- memset(new_buffer + (components * ((new_width * row) + old_width)), 0, components * (new_width - old_width));
+ // pad out rest of row with black
+ memset(new_buffer + (components * ((new_width * row) + old_width)), 0, components * (new_width - old_width));
}
}
else
{
// pad remaining rows with black
- memset(new_buffer + (new_width * row * components), 0, new_width * components);
+ memset(new_buffer + (new_width * row * components), 0, new_width * components);
}
}
- }
+ }
catch (std::bad_alloc&) // for temp_buffer
{
LL_WARNS() << "Failed to allocate temporary image buffer" << LL_ENDL;
return false;
}
- return true ;
+ return true ;
}
LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)
@@ -1590,372 +1665,439 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)
void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )
{
- const S32 components = getComponents();
- llassert( components >= 1 && components <= 4 );
-
- const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
- const F32 norm_factor = 1.f / ratio;
-
- S32 goff = components >= 2 ? 1 : 0;
- S32 boff = components >= 3 ? 2 : 0;
- for( S32 x = 0; x < out_pixel_len; x++ )
- {
- // Sample input pixels in range from sample0 to sample1.
- // Avoid floating point accumulation error... don't just add ratio each time. JC
- const F32 sample0 = x * ratio;
- const F32 sample1 = (x+1) * ratio;
- const S32 index0 = llfloor(sample0); // left integer (floor)
- const S32 index1 = llfloor(sample1); // right integer (floor)
- const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
- const F32 fract1 = sample1 - F32(index1); // spill-over on right
-
- if( index0 == index1 )
- {
- // Interval is embedded in one input pixel
- S32 t0 = x * out_pixel_step * components;
- S32 t1 = index0 * in_pixel_step * components;
- U8* outp = out + t0;
- U8* inp = in + t1;
- for (S32 i = 0; i < components; ++i)
- {
- *outp = *inp;
- ++outp;
- ++inp;
- }
- }
- else
- {
- // Left straddle
- S32 t1 = index0 * in_pixel_step * components;
- F32 r = in[t1 + 0] * fract0;
- F32 g = in[t1 + goff] * fract0;
- F32 b = in[t1 + boff] * fract0;
- F32 a = 0;
- if( components == 4)
- {
- a = in[t1 + 3] * fract0;
- }
-
- // Central interval
- if (components < 4)
- {
- for( S32 u = index0 + 1; u < index1; u++ )
- {
- S32 t2 = u * in_pixel_step * components;
- r += in[t2 + 0];
- g += in[t2 + goff];
- b += in[t2 + boff];
- }
- }
- else
- {
- for( S32 u = index0 + 1; u < index1; u++ )
- {
- S32 t2 = u * in_pixel_step * components;
- r += in[t2 + 0];
- g += in[t2 + 1];
- b += in[t2 + 2];
- a += in[t2 + 3];
- }
- }
-
- // right straddle
- // Watch out for reading off of end of input array.
- if( fract1 && index1 < in_pixel_len )
- {
- S32 t3 = index1 * in_pixel_step * components;
- if (components < 4)
- {
- U8 in0 = in[t3 + 0];
- U8 in1 = in[t3 + goff];
- U8 in2 = in[t3 + boff];
- r += in0 * fract1;
- g += in1 * fract1;
- b += in2 * fract1;
- }
- else
- {
- U8 in0 = in[t3 + 0];
- U8 in1 = in[t3 + 1];
- U8 in2 = in[t3 + 2];
- U8 in3 = in[t3 + 3];
- r += in0 * fract1;
- g += in1 * fract1;
- b += in2 * fract1;
- a += in3 * fract1;
- }
- }
-
- r *= norm_factor;
- g *= norm_factor;
- b *= norm_factor;
- a *= norm_factor; // skip conditional
-
- S32 t4 = x * out_pixel_step * components;
- out[t4 + 0] = U8(ll_round(r));
- if (components >= 2)
- out[t4 + 1] = U8(ll_round(g));
- if (components >= 3)
- out[t4 + 2] = U8(ll_round(b));
- if( components == 4)
- out[t4 + 3] = U8(ll_round(a));
- }
- }
+ const S32 components = getComponents();
+ llassert( components >= 1 && components <= 4 );
+
+ const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
+ const F32 norm_factor = 1.f / ratio;
+
+ S32 goff = components >= 2 ? 1 : 0;
+ S32 boff = components >= 3 ? 2 : 0;
+ for( S32 x = 0; x < out_pixel_len; x++ )
+ {
+ // Sample input pixels in range from sample0 to sample1.
+ // Avoid floating point accumulation error... don't just add ratio each time. JC
+ const F32 sample0 = x * ratio;
+ const F32 sample1 = (x+1) * ratio;
+ const S32 index0 = llfloor(sample0); // left integer (floor)
+ const S32 index1 = llfloor(sample1); // right integer (floor)
+ const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
+ const F32 fract1 = sample1 - F32(index1); // spill-over on right
+
+ if( index0 == index1 )
+ {
+ // Interval is embedded in one input pixel
+ S32 t0 = x * out_pixel_step * components;
+ S32 t1 = index0 * in_pixel_step * components;
+ U8* outp = out + t0;
+ U8* inp = in + t1;
+ for (S32 i = 0; i < components; ++i)
+ {
+ *outp = *inp;
+ ++outp;
+ ++inp;
+ }
+ }
+ else
+ {
+ // Left straddle
+ S32 t1 = index0 * in_pixel_step * components;
+ F32 r = in[t1 + 0] * fract0;
+ F32 g = in[t1 + goff] * fract0;
+ F32 b = in[t1 + boff] * fract0;
+ F32 a = 0;
+ if( components == 4)
+ {
+ a = in[t1 + 3] * fract0;
+ }
+
+ // Central interval
+ if (components < 4)
+ {
+ for( S32 u = index0 + 1; u < index1; u++ )
+ {
+ S32 t2 = u * in_pixel_step * components;
+ r += in[t2 + 0];
+ g += in[t2 + goff];
+ b += in[t2 + boff];
+ }
+ }
+ else
+ {
+ for( S32 u = index0 + 1; u < index1; u++ )
+ {
+ S32 t2 = u * in_pixel_step * components;
+ r += in[t2 + 0];
+ g += in[t2 + 1];
+ b += in[t2 + 2];
+ a += in[t2 + 3];
+ }
+ }
+
+ // right straddle
+ // Watch out for reading off of end of input array.
+ if( fract1 && index1 < in_pixel_len )
+ {
+ S32 t3 = index1 * in_pixel_step * components;
+ if (components < 4)
+ {
+ U8 in0 = in[t3 + 0];
+ U8 in1 = in[t3 + goff];
+ U8 in2 = in[t3 + boff];
+ r += in0 * fract1;
+ g += in1 * fract1;
+ b += in2 * fract1;
+ }
+ else
+ {
+ U8 in0 = in[t3 + 0];
+ U8 in1 = in[t3 + 1];
+ U8 in2 = in[t3 + 2];
+ U8 in3 = in[t3 + 3];
+ r += in0 * fract1;
+ g += in1 * fract1;
+ b += in2 * fract1;
+ a += in3 * fract1;
+ }
+ }
+
+ r *= norm_factor;
+ g *= norm_factor;
+ b *= norm_factor;
+ a *= norm_factor; // skip conditional
+
+ S32 t4 = x * out_pixel_step * components;
+ out[t4 + 0] = U8(ll_round(r));
+ if (components >= 2)
+ out[t4 + 1] = U8(ll_round(g));
+ if (components >= 3)
+ out[t4 + 2] = U8(ll_round(b));
+ if( components == 4)
+ out[t4 + 3] = U8(ll_round(a));
+ }
+ }
}
void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len )
{
- llassert( getComponents() == 3 );
-
- const S32 IN_COMPONENTS = 4;
- const S32 OUT_COMPONENTS = 3;
-
- const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
- const F32 norm_factor = 1.f / ratio;
-
- for( S32 x = 0; x < out_pixel_len; x++ )
- {
- // Sample input pixels in range from sample0 to sample1.
- // Avoid floating point accumulation error... don't just add ratio each time. JC
- const F32 sample0 = x * ratio;
- const F32 sample1 = (x+1) * ratio;
- const S32 index0 = S32(sample0); // left integer (floor)
- const S32 index1 = S32(sample1); // right integer (floor)
- const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
- const F32 fract1 = sample1 - F32(index1); // spill-over on right
-
- U8 in_scaled_r;
- U8 in_scaled_g;
- U8 in_scaled_b;
- U8 in_scaled_a;
-
- if( index0 == index1 )
+ llassert( getComponents() == 3 );
+
+ const S32 IN_COMPONENTS = 4;
+ const S32 OUT_COMPONENTS = 3;
+
+ const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
+ const F32 norm_factor = 1.f / ratio;
+
+ for( S32 x = 0; x < out_pixel_len; x++ )
+ {
+ // Sample input pixels in range from sample0 to sample1.
+ // Avoid floating point accumulation error... don't just add ratio each time. JC
+ const F32 sample0 = x * ratio;
+ const F32 sample1 = (x+1) * ratio;
+ const S32 index0 = S32(sample0); // left integer (floor)
+ const S32 index1 = S32(sample1); // right integer (floor)
+ const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
+ const F32 fract1 = sample1 - F32(index1); // spill-over on right
+
+ U8 in_scaled_r;
+ U8 in_scaled_g;
+ U8 in_scaled_b;
+ U8 in_scaled_a;
+
+ if( index0 == index1 )
+ {
+ // Interval is embedded in one input pixel
+ S32 t1 = index0 * IN_COMPONENTS;
+ in_scaled_r = in[t1 + 0];
+ in_scaled_g = in[t1 + 0];
+ in_scaled_b = in[t1 + 0];
+ in_scaled_a = in[t1 + 0];
+ }
+ else
+ {
+ // Left straddle
+ S32 t1 = index0 * IN_COMPONENTS;
+ F32 r = in[t1 + 0] * fract0;
+ F32 g = in[t1 + 1] * fract0;
+ F32 b = in[t1 + 2] * fract0;
+ F32 a = in[t1 + 3] * fract0;
+
+ // Central interval
+ for( S32 u = index0 + 1; u < index1; u++ )
+ {
+ S32 t2 = u * IN_COMPONENTS;
+ r += in[t2 + 0];
+ g += in[t2 + 1];
+ b += in[t2 + 2];
+ a += in[t2 + 3];
+ }
+
+ // right straddle
+ // Watch out for reading off of end of input array.
+ if( fract1 && index1 < in_pixel_len )
+ {
+ S32 t3 = index1 * IN_COMPONENTS;
+ r += in[t3 + 0] * fract1;
+ g += in[t3 + 1] * fract1;
+ b += in[t3 + 2] * fract1;
+ a += in[t3 + 3] * fract1;
+ }
+
+ r *= norm_factor;
+ g *= norm_factor;
+ b *= norm_factor;
+ a *= norm_factor;
+
+ in_scaled_r = U8(ll_round(r));
+ in_scaled_g = U8(ll_round(g));
+ in_scaled_b = U8(ll_round(b));
+ in_scaled_a = U8(ll_round(a));
+ }
+
+ if( in_scaled_a )
+ {
+ if( 255 == in_scaled_a )
+ {
+ out[0] = in_scaled_r;
+ out[1] = in_scaled_g;
+ out[2] = in_scaled_b;
+ }
+ else
+ {
+ U8 transparency = 255 - in_scaled_a;
+ out[0] = fastFractionalMult( out[0], transparency ) + fastFractionalMult( in_scaled_r, in_scaled_a );
+ out[1] = fastFractionalMult( out[1], transparency ) + fastFractionalMult( in_scaled_g, in_scaled_a );
+ out[2] = fastFractionalMult( out[2], transparency ) + fastFractionalMult( in_scaled_b, in_scaled_a );
+ }
+ }
+ out += OUT_COMPONENTS;
+ }
+}
+
+
+void LLImageRaw::addEmissive(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ if (!validateSrcAndDst(__FUNCTION__, src, dst))
+ {
+ return;
+ }
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert(3 == dst->getComponents());
+
+ if( 3 == dst->getComponents() )
+ {
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ addEmissiveUnscaled(src);
+ }
+ else
+ {
+ addEmissiveScaled(src);
+ }
+ }
+}
+
+void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert((3 == dst->getComponents()) || (4 == dst->getComponents()));
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ U8* const src_data = src->getData();
+ U8* const dst_data = dst->getData();
+ for(S32 y = 0; y < dst->getHeight(); ++y)
+ {
+ const S32 src_row_offset = src->getComponents() * src->getWidth() * y;
+ const S32 dst_row_offset = dst->getComponents() * dst->getWidth() * y;
+ for (S32 x = 0; x < dst->getWidth(); ++x)
{
- // Interval is embedded in one input pixel
- S32 t1 = index0 * IN_COMPONENTS;
- in_scaled_r = in[t1 + 0];
- in_scaled_g = in[t1 + 0];
- in_scaled_b = in[t1 + 0];
- in_scaled_a = in[t1 + 0];
+ const S32 src_offset = src_row_offset + (x * src->getComponents());
+ const S32 dst_offset = dst_row_offset + (x * dst->getComponents());
+ U8* const src_pixel = src_data + src_offset;
+ U8* const dst_pixel = dst_data + dst_offset;
+ dst_pixel[0] = llmin(255, dst_pixel[0] + src_pixel[0]);
+ dst_pixel[1] = llmin(255, dst_pixel[1] + src_pixel[1]);
+ dst_pixel[2] = llmin(255, dst_pixel[2] + src_pixel[2]);
}
- else
- {
- // Left straddle
- S32 t1 = index0 * IN_COMPONENTS;
- F32 r = in[t1 + 0] * fract0;
- F32 g = in[t1 + 1] * fract0;
- F32 b = in[t1 + 2] * fract0;
- F32 a = in[t1 + 3] * fract0;
-
- // Central interval
- for( S32 u = index0 + 1; u < index1; u++ )
- {
- S32 t2 = u * IN_COMPONENTS;
- r += in[t2 + 0];
- g += in[t2 + 1];
- b += in[t2 + 2];
- a += in[t2 + 3];
- }
+ }
+}
- // right straddle
- // Watch out for reading off of end of input array.
- if( fract1 && index1 < in_pixel_len )
- {
- S32 t3 = index1 * IN_COMPONENTS;
- r += in[t3 + 0] * fract1;
- g += in[t3 + 1] * fract1;
- b += in[t3 + 2] * fract1;
- a += in[t3 + 3] * fract1;
- }
+void LLImageRaw::addEmissiveScaled(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
- r *= norm_factor;
- g *= norm_factor;
- b *= norm_factor;
- a *= norm_factor;
+ llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
- in_scaled_r = U8(ll_round(r));
- in_scaled_g = U8(ll_round(g));
- in_scaled_b = U8(ll_round(b));
- in_scaled_a = U8(ll_round(a));
- }
+ LLImageRaw temp(dst->getWidth(), dst->getHeight(), dst->getComponents());
+ llassert_always(temp.getDataSize() > 0);
+ temp.copyScaled(src);
- if( in_scaled_a )
- {
- if( 255 == in_scaled_a )
- {
- out[0] = in_scaled_r;
- out[1] = in_scaled_g;
- out[2] = in_scaled_b;
- }
- else
- {
- U8 transparency = 255 - in_scaled_a;
- out[0] = fastFractionalMult( out[0], transparency ) + fastFractionalMult( in_scaled_r, in_scaled_a );
- out[1] = fastFractionalMult( out[1], transparency ) + fastFractionalMult( in_scaled_g, in_scaled_a );
- out[2] = fastFractionalMult( out[2], transparency ) + fastFractionalMult( in_scaled_b, in_scaled_a );
- }
- }
- out += OUT_COMPONENTS;
- }
+ dst->addEmissiveUnscaled(&temp);
}
+
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
{
- if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
- {
- LL_WARNS() << func << ": Source: ";
- if (!src) LL_CONT << "Null pointer";
- else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer";
- else LL_CONT << "OK";
+ if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
+ {
+ LL_WARNS() << func << ": Source: ";
+ if (!src) LL_CONT << "Null pointer";
+ else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer";
+ else LL_CONT << "OK";
- LL_CONT << "; Destination: ";
- if (!dst) LL_CONT << "Null pointer";
- else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer";
- else LL_CONT << "OK";
- LL_CONT << "." << LL_ENDL;
+ LL_CONT << "; Destination: ";
+ if (!dst) LL_CONT << "Null pointer";
+ else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer";
+ else LL_CONT << "OK";
+ LL_CONT << "." << LL_ENDL;
- return false;
- }
- return true;
+ return false;
+ }
+ return true;
}
//----------------------------------------------------------------------------
static struct
{
- const char* exten;
- EImageCodec codec;
+ const char* exten;
+ EImageCodec codec;
}
file_extensions[] =
{
- { "bmp", IMG_CODEC_BMP },
- { "tga", IMG_CODEC_TGA },
- { "j2c", IMG_CODEC_J2C },
- { "jp2", IMG_CODEC_J2C },
- { "texture", IMG_CODEC_J2C },
- { "jpg", IMG_CODEC_JPEG },
- { "jpeg", IMG_CODEC_JPEG },
- { "mip", IMG_CODEC_DXT },
- { "dxt", IMG_CODEC_DXT },
- { "png", IMG_CODEC_PNG }
+ { "bmp", IMG_CODEC_BMP },
+ { "tga", IMG_CODEC_TGA },
+ { "j2c", IMG_CODEC_J2C },
+ { "jp2", IMG_CODEC_J2C },
+ { "texture", IMG_CODEC_J2C },
+ { "jpg", IMG_CODEC_JPEG },
+ { "jpeg", IMG_CODEC_JPEG },
+ { "mip", IMG_CODEC_DXT },
+ { "dxt", IMG_CODEC_DXT },
+ { "png", IMG_CODEC_PNG }
};
#define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions)
#if 0
static std::string find_file(std::string &name, S8 *codec)
{
- std::string tname;
- for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++)
- {
- tname = name + "." + std::string(file_extensions[i].exten);
- llifstream ifs(tname.c_str(), llifstream::binary);
- if (ifs.is_open())
- {
- ifs.close();
- if (codec)
- *codec = file_extensions[i].codec;
- return std::string(file_extensions[i].exten);
- }
- }
- return std::string("");
+ std::string tname;
+ for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++)
+ {
+ tname = name + "." + std::string(file_extensions[i].exten);
+ llifstream ifs(tname.c_str(), llifstream::binary);
+ if (ifs.is_open())
+ {
+ ifs.close();
+ if (codec)
+ *codec = file_extensions[i].codec;
+ return std::string(file_extensions[i].exten);
+ }
+ }
+ return std::string("");
}
#endif
EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
{
- if (!exten.empty())
- {
- for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++)
- {
- if (exten == file_extensions[i].exten)
- return file_extensions[i].codec;
- }
- }
- return IMG_CODEC_INVALID;
+ if (!exten.empty())
+ {
+ for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++)
+ {
+ if (exten == file_extensions[i].exten)
+ return file_extensions[i].codec;
+ }
+ }
+ return IMG_CODEC_INVALID;
}
#if 0
bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)
{
- std::string name = filename;
- size_t dotidx = name.rfind('.');
- S8 codec = IMG_CODEC_INVALID;
- std::string exten;
-
- deleteData(); // delete any existing data
-
- if (dotidx != std::string::npos)
- {
- exten = name.substr(dotidx+1);
- LLStringUtil::toLower(exten);
- codec = getCodecFromExtension(exten);
- }
- else
- {
- exten = find_file(name, &codec);
- name = name + "." + exten;
- }
- if (codec == IMG_CODEC_INVALID)
- {
- return false; // format not recognized
- }
-
- llifstream ifs(name.c_str(), llifstream::binary);
- if (!ifs.is_open())
- {
- // SJB: changed from LL_INFOS() to LL_DEBUGS() to reduce spam
- LL_DEBUGS() << "Unable to open image file: " << name << LL_ENDL;
- return false;
- }
-
- ifs.seekg (0, std::ios::end);
- int length = ifs.tellg();
- if (j2c_lowest_mip_only && length > 2048)
- {
- length = 2048;
- }
- ifs.seekg (0, std::ios::beg);
-
- if (!length)
- {
- LL_INFOS() << "Zero length file file: " << name << LL_ENDL;
- return false;
- }
-
- LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
- llassert(image.notNull());
-
- U8 *buffer = image->allocateData(length);
- ifs.read ((char*)buffer, length);
- ifs.close();
-
- bool success;
-
- success = image->updateData();
- if (success)
- {
- if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
- {
- S32 width = image->getWidth();
- S32 height = image->getHeight();
- S32 discard_level = 0;
- while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
- {
- width >>= 1;
- height >>= 1;
- discard_level++;
- }
- ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
- }
- success = image->decode(this, 100000.0f);
- }
-
- image = NULL; // deletes image
- if (!success)
- {
- deleteData();
- LL_WARNS() << "Unable to decode image" << name << LL_ENDL;
- return false;
- }
-
- return true;
+ std::string name = filename;
+ size_t dotidx = name.rfind('.');
+ S8 codec = IMG_CODEC_INVALID;
+ std::string exten;
+
+ deleteData(); // delete any existing data
+
+ if (dotidx != std::string::npos)
+ {
+ exten = name.substr(dotidx+1);
+ LLStringUtil::toLower(exten);
+ codec = getCodecFromExtension(exten);
+ }
+ else
+ {
+ exten = find_file(name, &codec);
+ name = name + "." + exten;
+ }
+ if (codec == IMG_CODEC_INVALID)
+ {
+ return false; // format not recognized
+ }
+
+ llifstream ifs(name.c_str(), llifstream::binary);
+ if (!ifs.is_open())
+ {
+ // SJB: changed from LL_INFOS() to LL_DEBUGS() to reduce spam
+ LL_DEBUGS() << "Unable to open image file: " << name << LL_ENDL;
+ return false;
+ }
+
+ ifs.seekg (0, std::ios::end);
+ int length = ifs.tellg();
+ if (j2c_lowest_mip_only && length > 2048)
+ {
+ length = 2048;
+ }
+ ifs.seekg (0, std::ios::beg);
+
+ if (!length)
+ {
+ LL_INFOS() << "Zero length file file: " << name << LL_ENDL;
+ return false;
+ }
+
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
+ llassert(image.notNull());
+
+ U8 *buffer = image->allocateData(length);
+ ifs.read ((char*)buffer, length);
+ ifs.close();
+
+ bool success;
+
+ success = image->updateData();
+ if (success)
+ {
+ if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
+ {
+ S32 width = image->getWidth();
+ S32 height = image->getHeight();
+ S32 discard_level = 0;
+ while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
+ {
+ width >>= 1;
+ height >>= 1;
+ discard_level++;
+ }
+ ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
+ }
+ success = image->decode(this, 100000.0f);
+ }
+
+ image = NULL; // deletes image
+ if (!success)
+ {
+ deleteData();
+ LL_WARNS() << "Unable to decode image" << name << LL_ENDL;
+ return false;
+ }
+
+ return true;
}
#endif
//---------------------------------------------------------------------------
@@ -1966,21 +2108,21 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
S32 LLImageFormatted::sGlobalFormattedMemory = 0;
LLImageFormatted::LLImageFormatted(S8 codec)
- : LLImageBase(),
- mCodec(codec),
- mDecoding(0),
- mDecoded(0),
- mDiscardLevel(-1),
- mLevels(0)
+ : LLImageBase(),
+ mCodec(codec),
+ mDecoding(0),
+ mDecoded(0),
+ mDiscardLevel(-1),
+ mLevels(0)
{
}
// virtual
LLImageFormatted::~LLImageFormatted()
{
- // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
- // NOT LLImageFormatted::deleteData()
- deleteData();
+ // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
+ // NOT LLImageFormatted::deleteData()
+ deleteData();
}
//----------------------------------------------------------------------------
@@ -1988,16 +2130,16 @@ LLImageFormatted::~LLImageFormatted()
//virtual
void LLImageFormatted::resetLastError()
{
- LLImage::setLastError("");
+ LLImage::setLastError("");
}
//virtual
void LLImageFormatted::setLastError(const std::string& message, const std::string& filename)
{
- std::string error = message;
- if (!filename.empty())
- error += std::string(" FILE: ") + filename;
- LLImage::setLastError(error);
+ std::string error = message;
+ if (!filename.empty())
+ error += std::string(" FILE: ") + filename;
+ LLImage::setLastError(error);
}
//----------------------------------------------------------------------------
@@ -2005,97 +2147,97 @@ void LLImageFormatted::setLastError(const std::string& message, const std::strin
// static
LLImageFormatted* LLImageFormatted::createFromType(S8 codec)
{
- LLImageFormatted* image;
- switch(codec)
- {
- case IMG_CODEC_BMP:
- image = new LLImageBMP();
- break;
- case IMG_CODEC_TGA:
- image = new LLImageTGA();
- break;
- case IMG_CODEC_JPEG:
- image = new LLImageJPEG();
- break;
- case IMG_CODEC_PNG:
- image = new LLImagePNG();
- break;
- case IMG_CODEC_J2C:
- image = new LLImageJ2C();
- break;
- case IMG_CODEC_DXT:
- image = new LLImageDXT();
- break;
- default:
- image = NULL;
- break;
- }
- return image;
+ LLImageFormatted* image;
+ switch(codec)
+ {
+ case IMG_CODEC_BMP:
+ image = new LLImageBMP();
+ break;
+ case IMG_CODEC_TGA:
+ image = new LLImageTGA();
+ break;
+ case IMG_CODEC_JPEG:
+ image = new LLImageJPEG();
+ break;
+ case IMG_CODEC_PNG:
+ image = new LLImagePNG();
+ break;
+ case IMG_CODEC_J2C:
+ image = new LLImageJ2C();
+ break;
+ case IMG_CODEC_DXT:
+ image = new LLImageDXT();
+ break;
+ default:
+ image = NULL;
+ break;
+ }
+ return image;
}
// static
LLImageFormatted* LLImageFormatted::createFromExtension(const std::string& instring)
{
- std::string exten;
- size_t dotidx = instring.rfind('.');
- if (dotidx != std::string::npos)
- {
- exten = instring.substr(dotidx+1);
- }
- else
- {
- exten = instring;
- }
- S8 codec = getCodecFromExtension(exten);
- return createFromType(codec);
+ std::string exten;
+ size_t dotidx = instring.rfind('.');
+ if (dotidx != std::string::npos)
+ {
+ exten = instring.substr(dotidx+1);
+ }
+ else
+ {
+ exten = instring;
+ }
+ S8 codec = getCodecFromExtension(exten);
+ return createFromType(codec);
}
//----------------------------------------------------------------------------
// virtual
void LLImageFormatted::dump()
{
- LLImageBase::dump();
+ LLImageBase::dump();
- LL_INFOS() << "LLImageFormatted"
- << " mDecoding " << mDecoding
- << " mCodec " << S32(mCodec)
- << " mDecoded " << mDecoded
- << LL_ENDL;
+ LL_INFOS() << "LLImageFormatted"
+ << " mDecoding " << mDecoding
+ << " mCodec " << S32(mCodec)
+ << " mDecoded " << mDecoded
+ << LL_ENDL;
}
//----------------------------------------------------------------------------
S32 LLImageFormatted::calcDataSize(S32 discard_level)
{
- if (discard_level < 0)
- {
- discard_level = mDiscardLevel;
- }
- S32 w = getWidth() >> discard_level;
- S32 h = getHeight() >> discard_level;
- w = llmax(w, 1);
- h = llmax(h, 1);
- return w * h * getComponents();
+ if (discard_level < 0)
+ {
+ discard_level = mDiscardLevel;
+ }
+ S32 w = getWidth() >> discard_level;
+ S32 h = getHeight() >> discard_level;
+ w = llmax(w, 1);
+ h = llmax(h, 1);
+ return w * h * getComponents();
}
S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes)
{
- llassert(bytes >= 0);
- S32 discard_level = 0;
- while (1)
- {
- S32 bytes_needed = calcDataSize(discard_level); // virtual
- if (bytes_needed <= bytes)
- {
- break;
- }
- discard_level++;
- if (discard_level > MAX_IMAGE_MIP)
- {
- return -1;
- }
- }
- return discard_level;
+ llassert(bytes >= 0);
+ S32 discard_level = 0;
+ while (1)
+ {
+ S32 bytes_needed = calcDataSize(discard_level); // virtual
+ if (bytes_needed <= bytes)
+ {
+ break;
+ }
+ discard_level++;
+ if (discard_level > MAX_IMAGE_MIP)
+ {
+ return -1;
+ }
+ }
+ return discard_level;
}
@@ -2104,34 +2246,34 @@ S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes)
// Subclasses that can handle more than 4 channels should override this function.
bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32 decode_time, S32 first_channel, S32 max_channel)
{
- llassert( (first_channel == 0) && (max_channel == 4) );
- return decode( raw_image, decode_time ); // Loads first 4 channels by default.
-}
+ llassert( (first_channel == 0) && (max_channel == 4) );
+ return decode( raw_image, decode_time ); // Loads first 4 channels by default.
+}
//----------------------------------------------------------------------------
// virtual
U8* LLImageFormatted::allocateData(S32 size)
{
- U8* res = LLImageBase::allocateData(size); // calls deleteData()
- sGlobalFormattedMemory += getDataSize();
- return res;
+ U8* res = LLImageBase::allocateData(size); // calls deleteData()
+ sGlobalFormattedMemory += getDataSize();
+ return res;
}
// virtual
U8* LLImageFormatted::reallocateData(S32 size)
{
- sGlobalFormattedMemory -= getDataSize();
- U8* res = LLImageBase::reallocateData(size);
- sGlobalFormattedMemory += getDataSize();
- return res;
+ sGlobalFormattedMemory -= getDataSize();
+ U8* res = LLImageBase::reallocateData(size);
+ sGlobalFormattedMemory += getDataSize();
+ return res;
}
// virtual
void LLImageFormatted::deleteData()
{
- sGlobalFormattedMemory -= getDataSize();
- LLImageBase::deleteData();
+ sGlobalFormattedMemory -= getDataSize();
+ LLImageBase::deleteData();
}
//----------------------------------------------------------------------------
@@ -2139,196 +2281,196 @@ void LLImageFormatted::deleteData()
// virtual
void LLImageFormatted::sanityCheck()
{
- LLImageBase::sanityCheck();
+ LLImageBase::sanityCheck();
- if (mCodec >= IMG_CODEC_EOF)
- {
- LL_ERRS() << "Failed LLImageFormatted::sanityCheck "
- << "decoding " << S32(mDecoding)
- << "decoded " << S32(mDecoded)
- << "codec " << S32(mCodec)
- << LL_ENDL;
- }
+ if (mCodec >= IMG_CODEC_EOF)
+ {
+ LL_ERRS() << "Failed LLImageFormatted::sanityCheck "
+ << "decoding " << S32(mDecoding)
+ << "decoded " << S32(mDecoded)
+ << "codec " << S32(mCodec)
+ << LL_ENDL;
+ }
}
//----------------------------------------------------------------------------
bool LLImageFormatted::copyData(U8 *data, S32 size)
{
- if ( data && ((data != getData()) || (size != getDataSize())) )
- {
- deleteData();
- allocateData(size);
- memcpy(getData(), data, size); /* Flawfinder: ignore */
- }
- return true;
+ if ( data && ((data != getData()) || (size != getDataSize())) )
+ {
+ deleteData();
+ allocateData(size);
+ memcpy(getData(), data, size); /* Flawfinder: ignore */
+ }
+ return true;
}
// LLImageFormatted becomes the owner of data
void LLImageFormatted::setData(U8 *data, S32 size)
{
- if (data && data != getData())
- {
- deleteData();
- setDataAndSize(data, size); // Access private LLImageBase members
+ if (data && data != getData())
+ {
+ deleteData();
+ setDataAndSize(data, size); // Access private LLImageBase members
- sGlobalFormattedMemory += getDataSize();
- }
+ sGlobalFormattedMemory += getDataSize();
+ }
}
void LLImageFormatted::appendData(U8 *data, S32 size)
{
- if (data)
- {
- if (!getData())
- {
- setData(data, size);
- }
- else
- {
- S32 cursize = getDataSize();
- S32 newsize = cursize + size;
- reallocateData(newsize);
- memcpy(getData() + cursize, data, size);
- ll_aligned_free_16(data);
- }
- }
+ if (data)
+ {
+ if (!getData())
+ {
+ setData(data, size);
+ }
+ else
+ {
+ S32 cursize = getDataSize();
+ S32 newsize = cursize + size;
+ reallocateData(newsize);
+ memcpy(getData() + cursize, data, size);
+ ll_aligned_free_16(data);
+ }
+ }
}
//----------------------------------------------------------------------------
bool LLImageFormatted::load(const std::string &filename, int load_size)
{
- resetLastError();
-
- S32 file_size = 0;
- LLAPRFile infile ;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
- apr_file_t* apr_file = infile.getFileHandle();
- if (!apr_file)
- {
- setLastError("Unable to open file for reading", filename);
- return false;
- }
- if (file_size == 0)
- {
- setLastError("File is empty",filename);
- return false;
- }
-
- // Constrain the load size to acceptable values
- if ((load_size == 0) || (load_size > file_size))
- {
- load_size = file_size;
- }
- bool res;
- U8 *data = allocateData(load_size);
- if (data)
- {
- apr_size_t bytes_read = load_size;
- apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
- if (s != APR_SUCCESS || (S32) bytes_read != load_size)
- {
- deleteData();
- setLastError("Unable to read file",filename);
- res = false;
- }
- else
- {
- res = updateData();
- }
- }
- else
- {
- setLastError("Allocation failure", filename);
- res = false;
- }
-
- return res;
+ resetLastError();
+
+ S32 file_size = 0;
+ LLAPRFile infile ;
+ infile.open(filename, LL_APR_RB, NULL, &file_size);
+ apr_file_t* apr_file = infile.getFileHandle();
+ if (!apr_file)
+ {
+ setLastError("Unable to open file for reading", filename);
+ return false;
+ }
+ if (file_size == 0)
+ {
+ setLastError("File is empty",filename);
+ return false;
+ }
+
+ // Constrain the load size to acceptable values
+ if ((load_size == 0) || (load_size > file_size))
+ {
+ load_size = file_size;
+ }
+ bool res;
+ U8 *data = allocateData(load_size);
+ if (data)
+ {
+ apr_size_t bytes_read = load_size;
+ apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
+ if (s != APR_SUCCESS || (S32) bytes_read != load_size)
+ {
+ deleteData();
+ setLastError("Unable to read file",filename);
+ res = false;
+ }
+ else
+ {
+ res = updateData();
+ }
+ }
+ else
+ {
+ setLastError("Allocation failure", filename);
+ res = false;
+ }
+
+ return res;
}
bool LLImageFormatted::save(const std::string &filename)
{
- resetLastError();
-
- LLAPRFile outfile ;
- outfile.open(filename, LL_APR_WB);
- if (!outfile.getFileHandle())
- {
- setLastError("Unable to open file for writing", filename);
- return false;
- }
-
- S32 result = outfile.write(getData(), getDataSize());
- outfile.close() ;
+ resetLastError();
+
+ LLAPRFile outfile ;
+ outfile.open(filename, LL_APR_WB);
+ if (!outfile.getFileHandle())
+ {
+ setLastError("Unable to open file for writing", filename);
+ return false;
+ }
+
+ S32 result = outfile.write(getData(), getDataSize());
+ outfile.close() ;
return (result != 0);
}
S8 LLImageFormatted::getCodec() const
{
- return mCodec;
+ return mCodec;
}
static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
{
- dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
- dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
- dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
- dst[3] = (U8)(((U32)(a[3]) + b[3] + c[3] + d[3])>>2);
+ dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
+ dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
+ dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
+ dst[3] = (U8)(((U32)(a[3]) + b[3] + c[3] + d[3])>>2);
}
static void avg4_colors3(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
{
- dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
- dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
- dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
+ dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
+ dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
+ dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
}
static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
{
- dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
- dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
+ dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
+ dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
}
void LLImageBase::setDataAndSize(U8 *data, S32 size)
-{
- ll_assert_aligned(data, 16);
- mData = data;
- mDataSize = size;
-}
+{
+ ll_assert_aligned(data, 16);
+ mData = data;
+ mDataSize = size;
+}
//static
void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
{
- llassert(width > 0 && height > 0);
- U8* data = mipdata;
- S32 in_width = width*2;
- for (S32 h=0; h<height; h++)
- {
- for (S32 w=0; w<width; w++)
- {
- switch(nchannels)
- {
- case 4:
- avg4_colors4(indata, indata+4, indata+4*in_width, indata+4*in_width+4, data);
- break;
- case 3:
- avg4_colors3(indata, indata+3, indata+3*in_width, indata+3*in_width+3, data);
- break;
- case 2:
- avg4_colors2(indata, indata+2, indata+2*in_width, indata+2*in_width+2, data);
- break;
- case 1:
- *(U8*)data = (U8)(((U32)(indata[0]) + indata[1] + indata[in_width] + indata[in_width+1])>>2);
- break;
- default:
- LL_ERRS() << "generateMmip called with bad num channels" << LL_ENDL;
- }
- indata += nchannels*2;
- data += nchannels;
- }
- indata += nchannels*in_width; // skip odd lines
- }
+ llassert(width > 0 && height > 0);
+ U8* data = mipdata;
+ S32 in_width = width*2;
+ for (S32 h=0; h<height; h++)
+ {
+ for (S32 w=0; w<width; w++)
+ {
+ switch(nchannels)
+ {
+ case 4:
+ avg4_colors4(indata, indata+4, indata+4*in_width, indata+4*in_width+4, data);
+ break;
+ case 3:
+ avg4_colors3(indata, indata+3, indata+3*in_width, indata+3*in_width+3, data);
+ break;
+ case 2:
+ avg4_colors2(indata, indata+2, indata+2*in_width, indata+2*in_width+2, data);
+ break;
+ case 1:
+ *(U8*)data = (U8)(((U32)(indata[0]) + indata[1] + indata[in_width] + indata[in_width+1])>>2);
+ break;
+ default:
+ LL_ERRS() << "generateMmip called with bad num channels" << LL_ENDL;
+ }
+ indata += nchannels*2;
+ data += nchannels;
+ }
+ indata += nchannels*in_width; // skip odd lines
+ }
}
@@ -2337,69 +2479,69 @@ void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 heig
//static
F32 LLImageBase::calc_download_priority(F32 virtual_size, F32 visible_pixels, S32 bytes_sent)
{
- F32 w_priority;
-
- F32 bytes_weight = 1.f;
- if (!bytes_sent)
- {
- bytes_weight = 20.f;
- }
- else if (bytes_sent < 1000)
- {
- bytes_weight = 1.f;
- }
- else if (bytes_sent < 2000)
- {
- bytes_weight = 1.f/1.5f;
- }
- else if (bytes_sent < 4000)
- {
- bytes_weight = 1.f/3.f;
- }
- else if (bytes_sent < 8000)
- {
- bytes_weight = 1.f/6.f;
- }
- else if (bytes_sent < 16000)
- {
- bytes_weight = 1.f/12.f;
- }
- else if (bytes_sent < 32000)
- {
- bytes_weight = 1.f/20.f;
- }
- else if (bytes_sent < 64000)
- {
- bytes_weight = 1.f/32.f;
- }
- else
- {
- bytes_weight = 1.f/64.f;
- }
- bytes_weight *= bytes_weight;
-
-
- //LL_INFOS() << "VS: " << virtual_size << LL_ENDL;
- F32 virtual_size_factor = virtual_size / (10.f*10.f);
-
- // The goal is for weighted priority to be <= 0 when we've reached a point where
- // we've sent enough data.
- //LL_INFOS() << "BytesSent: " << bytes_sent << LL_ENDL;
- //LL_INFOS() << "BytesWeight: " << bytes_weight << LL_ENDL;
- //LL_INFOS() << "PreLog: " << bytes_weight * virtual_size_factor << LL_ENDL;
- w_priority = (F32)log10(bytes_weight * virtual_size_factor);
-
- //LL_INFOS() << "PreScale: " << w_priority << LL_ENDL;
-
- // We don't want to affect how MANY bytes we send based on the visible pixels, but the order
- // in which they're sent. We post-multiply so we don't change the zero point.
- if (w_priority > 0.f)
- {
- F32 pixel_weight = (F32)log10(visible_pixels + 1)*3.0f;
- w_priority *= pixel_weight;
- }
-
- return w_priority;
+ F32 w_priority;
+
+ F32 bytes_weight = 1.f;
+ if (!bytes_sent)
+ {
+ bytes_weight = 20.f;
+ }
+ else if (bytes_sent < 1000)
+ {
+ bytes_weight = 1.f;
+ }
+ else if (bytes_sent < 2000)
+ {
+ bytes_weight = 1.f/1.5f;
+ }
+ else if (bytes_sent < 4000)
+ {
+ bytes_weight = 1.f/3.f;
+ }
+ else if (bytes_sent < 8000)
+ {
+ bytes_weight = 1.f/6.f;
+ }
+ else if (bytes_sent < 16000)
+ {
+ bytes_weight = 1.f/12.f;
+ }
+ else if (bytes_sent < 32000)
+ {
+ bytes_weight = 1.f/20.f;
+ }
+ else if (bytes_sent < 64000)
+ {
+ bytes_weight = 1.f/32.f;
+ }
+ else
+ {
+ bytes_weight = 1.f/64.f;
+ }
+ bytes_weight *= bytes_weight;
+
+
+ //LL_INFOS() << "VS: " << virtual_size << LL_ENDL;
+ F32 virtual_size_factor = virtual_size / (10.f*10.f);
+
+ // The goal is for weighted priority to be <= 0 when we've reached a point where
+ // we've sent enough data.
+ //LL_INFOS() << "BytesSent: " << bytes_sent << LL_ENDL;
+ //LL_INFOS() << "BytesWeight: " << bytes_weight << LL_ENDL;
+ //LL_INFOS() << "PreLog: " << bytes_weight * virtual_size_factor << LL_ENDL;
+ w_priority = (F32)log10(bytes_weight * virtual_size_factor);
+
+ //LL_INFOS() << "PreScale: " << w_priority << LL_ENDL;
+
+ // We don't want to affect how MANY bytes we send based on the visible pixels, but the order
+ // in which they're sent. We post-multiply so we don't change the zero point.
+ if (w_priority > 0.f)
+ {
+ F32 pixel_weight = (F32)log10(visible_pixels + 1)*3.0f;
+ w_priority *= pixel_weight;
+ }
+
+ return w_priority;
}
//============================================================================
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 32e0781fae..c49184e338 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llimage.h
* @brief Object for managing images and their textures.
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -33,30 +33,30 @@
#include "lltrace.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
-const S32 MAX_IMAGE_MIP = 11; // 2048x2048
+const S32 MAX_IMAGE_MIP = 12; // 4096x4096
-// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number
+// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number
// of levels is read from the header's file, not inferred from its size.
const S32 MAX_DISCARD_LEVEL = 5;
// JPEG2000 size constraints
// Those are declared here as they are germane to other image constraints used in the viewer
// and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL.
-const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
-const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
-const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_SIZE
-const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
-const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
-const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
-const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
-const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
+const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
+const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
+const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE
+const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
+const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
+const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
+const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
+const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
-const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
+const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 4096
const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE;
const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
const S32 MAX_IMAGE_COMPONENTS = 8;
-const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 * 2048 * 8 = 16 MB
+const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //4096 * 4096 * 8 = 128 MB
// Note! These CANNOT be changed without modifying simulator code
// *TODO: change both to 1024 when SIM texture fetching is deprecated
@@ -71,18 +71,19 @@ const S32 HTTP_PACKET_SIZE = 1496;
class LLImageFormatted;
class LLImageRaw;
class LLColor4U;
+class LLColor3;
typedef enum e_image_codec
{
- IMG_CODEC_INVALID = 0,
- IMG_CODEC_RGB = 1,
- IMG_CODEC_J2C = 2,
- IMG_CODEC_BMP = 3,
- IMG_CODEC_TGA = 4,
- IMG_CODEC_JPEG = 5,
- IMG_CODEC_DXT = 6,
- IMG_CODEC_PNG = 7,
- IMG_CODEC_EOF = 8
+ IMG_CODEC_INVALID = 0,
+ IMG_CODEC_RGB = 1,
+ IMG_CODEC_J2C = 2,
+ IMG_CODEC_BMP = 3,
+ IMG_CODEC_TGA = 4,
+ IMG_CODEC_JPEG = 5,
+ IMG_CODEC_DXT = 6,
+ IMG_CODEC_PNG = 7,
+ IMG_CODEC_EOF = 8
} EImageCodec;
//============================================================================
@@ -92,198 +93,211 @@ typedef enum e_image_codec
class LLImage
{
public:
- static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
- static void cleanupClass();
-
- static const std::string& getLastError();
- static void setLastError(const std::string& message);
-
- static bool useNewByteRange() { return sUseNewByteRange; }
- static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
-
+ static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
+ static void cleanupClass();
+
+ static const std::string& getLastError();
+ static void setLastError(const std::string& message);
+
+ static bool useNewByteRange() { return sUseNewByteRange; }
+ static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
+
protected:
- static LLMutex* sMutex;
- static std::string sLastErrorMessage;
- static bool sUseNewByteRange;
+ static LLMutex* sMutex;
+ static std::string sLastErrorMessage;
+ static bool sUseNewByteRange;
static S32 sMinimalReverseByteRangePercent;
};
//============================================================================
// Image base class
-class LLImageBase
-: public LLThreadSafeRefCount
+class LLImageBase
+: public LLThreadSafeRefCount
{
protected:
- virtual ~LLImageBase();
-
+ virtual ~LLImageBase();
+
public:
- LLImageBase();
+ LLImageBase();
- enum
- {
- TYPE_NORMAL = 0,
- TYPE_AVATAR_BAKE = 1,
- };
+ enum
+ {
+ TYPE_NORMAL = 0,
+ TYPE_AVATAR_BAKE = 1,
+ };
- virtual void deleteData();
- virtual U8* allocateData(S32 size = -1);
- virtual U8* reallocateData(S32 size = -1);
+ virtual void deleteData();
+ virtual U8* allocateData(S32 size = -1);
+ virtual U8* reallocateData(S32 size = -1);
- virtual void dump();
- virtual void sanityCheck();
+ virtual void dump();
+ virtual void sanityCheck();
- U16 getWidth() const { return mWidth; }
- U16 getHeight() const { return mHeight; }
- S8 getComponents() const { return mComponents; }
- S32 getDataSize() const { return mDataSize; }
+ U16 getWidth() const { return mWidth; }
+ U16 getHeight() const { return mHeight; }
+ S8 getComponents() const { return mComponents; }
+ S32 getDataSize() const { return mDataSize; }
- const U8 *getData() const ;
- U8 *getData() ;
- bool isBufferInvalid() const;
+ const U8 *getData() const ;
+ U8 *getData() ;
+ bool isBufferInvalid() const;
- void setSize(S32 width, S32 height, S32 ncomponents);
- U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData()
- void enableOverSize() {mAllowOverSize = true ;}
- void disableOverSize() {mAllowOverSize = false; }
+ void setSize(S32 width, S32 height, S32 ncomponents);
+ U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData()
+ void enableOverSize() {mAllowOverSize = true ;}
+ void disableOverSize() {mAllowOverSize = false; }
protected:
- // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
- void setDataAndSize(U8 *data, S32 size);
-
+ // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
+ void setDataAndSize(U8 *data, S32 size);
+
public:
- static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
-
- // Function for calculating the download priority for textures
- // <= 0 priority means that there's no need for more data.
- static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
+ static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
+
+ // Function for calculating the download priority for textures
+ // <= 0 priority means that there's no need for more data.
+ static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
- static EImageCodec getCodecFromExtension(const std::string& exten);
+ static EImageCodec getCodecFromExtension(const std::string& exten);
- //static LLTrace::MemStatHandle sMemStat;
+ //static LLTrace::MemStatHandle sMemStat;
private:
- U8 *mData;
- S32 mDataSize;
+ U8 *mData;
+ S32 mDataSize;
- U16 mWidth;
- U16 mHeight;
+ U16 mWidth;
+ U16 mHeight;
- S8 mComponents;
+ S8 mComponents;
- bool mBadBufferAllocation ;
- bool mAllowOverSize ;
+ bool mBadBufferAllocation ;
+ bool mAllowOverSize ;
};
// Raw representation of an image (used for textures, and other uncompressed formats
class LLImageRaw : public LLImageBase
{
protected:
- /*virtual*/ ~LLImageRaw();
-
+ /*virtual*/ ~LLImageRaw();
+
public:
- LLImageRaw();
- LLImageRaw(U16 width, U16 height, S8 components);
+ LLImageRaw();
+ LLImageRaw(U16 width, U16 height, S8 components);
LLImageRaw(const U8* data, U16 width, U16 height, S8 components);
- LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
- // Construct using createFromFile (used by tools)
- //LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
+ LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
+ // Construct using createFromFile (used by tools)
+ //LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
- /*virtual*/ void deleteData();
- /*virtual*/ U8* allocateData(S32 size = -1);
- /*virtual*/ U8* reallocateData(S32 size);
+ /*virtual*/ void deleteData();
+ /*virtual*/ U8* allocateData(S32 size = -1);
+ /*virtual*/ U8* reallocateData(S32 size);
// use in conjunction with "no_copy" constructor to release data pointer before deleting
- // so that deletion of this LLImageRaw will not free the memory at the "data" parameter
+ // so that deletion of this LLImageRaw will not free the memory at the "data" parameter
// provided to "no_copy" constructor
void releaseData();
+
+ bool resize(U16 width, U16 height, S8 components);
- bool resize(U16 width, U16 height, S8 components);
-
- //U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
- bool setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
- const U8 *data, U32 stride = 0, bool reverse_y = false);
-
- void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255);
+ //U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
+ bool setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
+ const U8 *data, U32 stride = 0, bool reverse_y = false);
- void verticalFlip();
+ void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255);
+ void verticalFlip();
+
+ // Returns true if the image is not fully opaque
+ bool checkHasTransparentPixels();
// if the alpha channel is all 100% opaque, delete it
// returns true if alpha channel was deleted
bool optimizeAwayAlpha();
+ // Create an alpha channel if this image doesn't have one
+ bool makeAlpha();
static S32 biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
static S32 expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
static S32 contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim = MIN_IMAGE_SIZE);
- void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
- void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
- void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
- bool scale(S32 new_width, S32 new_height, bool scale_image = true);
+ void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
+ void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
+ void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
+ bool scale(S32 new_width, S32 new_height, bool scale_image = true);
LLPointer<LLImageRaw> scaled(S32 new_width, S32 new_height);
+
+ // Fill the buffer with a constant color
+ void fill( const LLColor4U& color );
- // Fill the buffer with a constant color
- void fill( const LLColor4U& color );
-
- // Copy operations
-
- //duplicate this raw image if refCount > 1.
- LLPointer<LLImageRaw> duplicate();
+ // Multiply this raw image by the given color
+ void tint( const LLColor3& color );
- // Src and dst can be any size. Src and dst can each have 3 or 4 components.
- void copy( LLImageRaw* src );
+ // Copy operations
+
+ //duplicate this raw image if refCount > 1.
+ LLPointer<LLImageRaw> duplicate();
- // Src and dst are same size. Src and dst have same number of components.
- void copyUnscaled( LLImageRaw* src );
+ // Src and dst can be any size. Src and dst can each have 3 or 4 components.
+ void copy( LLImageRaw* src );
- // Src and dst are same size. Src has 4 components. Dst has 3 components.
- void copyUnscaled4onto3( LLImageRaw* src );
+ // Src and dst are same size. Src and dst have same number of components.
+ void copyUnscaled( LLImageRaw* src );
+
+ // Src and dst are same size. Src has 4 components. Dst has 3 components.
+ void copyUnscaled4onto3( LLImageRaw* src );
- // Src and dst are same size. Src has 3 components. Dst has 4 components.
- void copyUnscaled3onto4( LLImageRaw* src );
+ // Src and dst are same size. Src has 3 components. Dst has 4 components.
+ void copyUnscaled3onto4( LLImageRaw* src );
- // Src and dst are same size. Src has 1 component. Dst has 4 components.
- // Alpha component is set to source alpha mask component.
- // RGB components are set to fill color.
- void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
+ // Src and dst are same size. Src has 1 component. Dst has 4 components.
+ // Alpha component is set to source alpha mask component.
+ // RGB components are set to fill color.
+ void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
- // Src and dst can be any size. Src and dst have same number of components.
- void copyScaled( LLImageRaw* src );
+ // Src and dst can be any size. Src and dst have same number of components.
+ void copyScaled( LLImageRaw* src );
- // Src and dst can be any size. Src has 3 components. Dst has 4 components.
- void copyScaled3onto4( LLImageRaw* src );
+ // Src and dst can be any size. Src has 3 components. Dst has 4 components.
+ void copyScaled3onto4( LLImageRaw* src );
- // Src and dst can be any size. Src has 4 components. Dst has 3 components.
- void copyScaled4onto3( LLImageRaw* src );
+ // Src and dst can be any size. Src has 4 components. Dst has 3 components.
+ void copyScaled4onto3( LLImageRaw* src );
- // Composite operations
+ // Composite operations
- // Src and dst can be any size. Src and dst can each have 3 or 4 components.
- void composite( LLImageRaw* src );
+ // Src and dst can be any size. Src and dst can each have 3 or 4 components.
+ void composite( LLImageRaw* src );
- // Src and dst can be any size. Src has 4 components. Dst has 3 components.
- void compositeScaled4onto3( LLImageRaw* src );
+ // Src and dst can be any size. Src has 4 components. Dst has 3 components.
+ void compositeScaled4onto3( LLImageRaw* src );
- // Src and dst are same size. Src has 4 components. Dst has 3 components.
- void compositeUnscaled4onto3( LLImageRaw* src );
+ // Src and dst are same size. Src has 4 components. Dst has 3 components.
+ void compositeUnscaled4onto3( LLImageRaw* src );
+ // Emissive operations used by minimap
+ // Roughly emulates GLTF emissive texture, but is not GLTF-compliant
+ // *TODO: Remove in favor of shader
+ void addEmissive(LLImageRaw* src);
+ void addEmissiveScaled(LLImageRaw* src);
+ void addEmissiveUnscaled(LLImageRaw* src);
protected:
- // Create an image from a local file (generally used in tools)
- //bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
+ // Create an image from a local file (generally used in tools)
+ //bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
- void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
- void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
+ void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
+ void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
- U8 fastFractionalMult(U8 a,U8 b);
+ U8 fastFractionalMult(U8 a,U8 b);
- void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
+ void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
public:
- static S32 sRawImageCount;
+ static S32 sRawImageCount;
private:
- bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
+ bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
};
// Compressed representation of image.
@@ -291,74 +305,74 @@ private:
class LLImageFormatted : public LLImageBase
{
public:
- static LLImageFormatted* createFromType(S8 codec);
- static LLImageFormatted* createFromExtension(const std::string& instring);
+ static LLImageFormatted* createFromType(S8 codec);
+ static LLImageFormatted* createFromExtension(const std::string& instring);
protected:
- /*virtual*/ ~LLImageFormatted();
-
+ /*virtual*/ ~LLImageFormatted();
+
public:
- LLImageFormatted(S8 codec);
-
- // LLImageBase
- /*virtual*/ void deleteData();
- /*virtual*/ U8* allocateData(S32 size = -1);
- /*virtual*/ U8* reallocateData(S32 size);
-
- /*virtual*/ void dump();
- /*virtual*/ void sanityCheck();
-
- // New methods
- // subclasses must return a prefered file extension (lowercase without a leading dot)
- virtual std::string getExtension() = 0;
- // calcHeaderSize() returns the maximum size of header;
- // 0 indicates we don't have a header and have to read the entire file
- virtual S32 calcHeaderSize() { return 0; };
- // calcDataSize() returns how many bytes to read to load discard_level (including header)
- virtual S32 calcDataSize(S32 discard_level);
- // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes
- virtual S32 calcDiscardLevelBytes(S32 bytes);
- // getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
- virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
-
- bool load(const std::string& filename, int load_size = 0);
- bool save(const std::string& filename);
-
- virtual bool updateData() = 0; // pure virtual
- void setData(U8 *data, S32 size);
- void appendData(U8 *data, S32 size);
-
- // Loads first 4 channels.
- virtual bool decode(LLImageRaw* raw_image, F32 decode_time) = 0;
- // Subclasses that can handle more than 4 channels should override this function.
- virtual bool decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
-
- virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0;
-
- S8 getCodec() const;
- bool isDecoding() const { return mDecoding; }
- bool isDecoded() const { return mDecoded; }
- void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
- S8 getDiscardLevel() const { return mDiscardLevel; }
- S8 getLevels() const { return mLevels; }
- void setLevels(S8 nlevels) { mLevels = nlevels; }
-
- // setLastError needs to be deferred for J2C images since it may be called from a DLL
- virtual void resetLastError();
- virtual void setLastError(const std::string& message, const std::string& filename = std::string());
-
+ LLImageFormatted(S8 codec);
+
+ // LLImageBase
+ /*virtual*/ void deleteData();
+ /*virtual*/ U8* allocateData(S32 size = -1);
+ /*virtual*/ U8* reallocateData(S32 size);
+
+ /*virtual*/ void dump();
+ /*virtual*/ void sanityCheck();
+
+ // New methods
+ // subclasses must return a prefered file extension (lowercase without a leading dot)
+ virtual std::string getExtension() = 0;
+ // calcHeaderSize() returns the maximum size of header;
+ // 0 indicates we don't have a header and have to read the entire file
+ virtual S32 calcHeaderSize() { return 0; };
+ // calcDataSize() returns how many bytes to read to load discard_level (including header)
+ virtual S32 calcDataSize(S32 discard_level);
+ // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes
+ virtual S32 calcDiscardLevelBytes(S32 bytes);
+ // getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
+ virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
+
+ bool load(const std::string& filename, int load_size = 0);
+ bool save(const std::string& filename);
+
+ virtual bool updateData() = 0; // pure virtual
+ void setData(U8 *data, S32 size);
+ void appendData(U8 *data, S32 size);
+
+ // Loads first 4 channels.
+ virtual bool decode(LLImageRaw* raw_image, F32 decode_time) = 0;
+ // Subclasses that can handle more than 4 channels should override this function.
+ virtual bool decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
+
+ virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0;
+
+ S8 getCodec() const;
+ bool isDecoding() const { return mDecoding; }
+ bool isDecoded() const { return mDecoded; }
+ void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
+ S8 getDiscardLevel() const { return mDiscardLevel; }
+ S8 getLevels() const { return mLevels; }
+ void setLevels(S8 nlevels) { mLevels = nlevels; }
+
+ // setLastError needs to be deferred for J2C images since it may be called from a DLL
+ virtual void resetLastError();
+ virtual void setLastError(const std::string& message, const std::string& filename = std::string());
+
protected:
- bool copyData(U8 *data, S32 size); // calls updateData()
-
+ bool copyData(U8 *data, S32 size); // calls updateData()
+
protected:
- S8 mCodec;
- S8 mDecoding;
- S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
- S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
- S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
-
+ S8 mCodec;
+ S8 mDecoding;
+ S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
+ S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
+ S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
+
public:
- static S32 sGlobalFormattedMemory;
+ static S32 sGlobalFormattedMemory;
};
#endif
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index c699bcf577..6688dadd3a 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -51,9 +51,9 @@ namespace {
F32 cosPhi = cos(altitude);
LLVector3 dir;
- // +x right, +z up, +y at...
+ // +x right, +z up, +y at...
dir.mV[0] = cosTheta * cosPhi;
- dir.mV[1] = sinTheta * cosPhi;
+ dir.mV[1] = sinTheta * cosPhi;
dir.mV[2] = sinPhi;
LLVector3 axis = LLVector3::x_axis % dir;
@@ -156,23 +156,23 @@ LLSettingsSky::validation_list_t legacyHazeValidationList()
static LLSettingsBase::validation_list_t legacyHazeValidation;
if (legacyHazeValidation.empty())
{
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
- legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 2.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 1000.0f))));
@@ -185,19 +185,19 @@ 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,
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
- rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
-
- rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
- rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
- rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return rayleighValidation;
@@ -208,19 +208,19 @@ 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,
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
- absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
-
- absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
- absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
- absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return absorptionValidation;
@@ -231,22 +231,22 @@ 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,
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
- mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
-
- mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
- mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
- mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
- mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return mieValidation;
@@ -296,7 +296,7 @@ bool validateRayleighLayers(LLSD &value, U32 flags)
}
}
return allGood;
- }
+ }
llassert(value.type() == LLSD::TypeMap);
LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations, flags);
if (result["errors"].size() > 0)
@@ -317,7 +317,7 @@ bool validateAbsorptionLayers(LLSD &value, U32 flags)
LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList();
if (value.isArray())
{
- bool allGood = true;
+ bool allGood = true;
for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf)
{
LLSD& layerConfig = (*itf);
@@ -407,7 +407,6 @@ LLSettingsSky::LLSettingsSky(const LLSD &data) :
mNextRainbowTextureId(),
mNextHaloTextureId()
{
- mCanAutoAdjust = !data.has(SETTING_REFLECTION_PROBE_AMBIANCE);
}
LLSettingsSky::LLSettingsSky():
@@ -430,8 +429,6 @@ void LLSettingsSky::replaceSettings(LLSD settings)
mNextBloomTextureId.setNull();
mNextRainbowTextureId.setNull();
mNextHaloTextureId.setNull();
-
- mCanAutoAdjust = !settings.has(SETTING_REFLECTION_PROBE_AMBIANCE);
}
void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
@@ -444,10 +441,9 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
mNextBloomTextureId = pother->mNextBloomTextureId;
mNextRainbowTextureId = pother->mNextRainbowTextureId;
mNextHaloTextureId = pother->mNextHaloTextureId;
- mCanAutoAdjust = pother->mCanAutoAdjust;
}
-void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
+void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;
llassert(getSettingsType() == end->getSettingsType());
@@ -533,8 +529,8 @@ LLSettingsSky::stringset_t LLSettingsSky::getSkipInterpolateKeys() const
return skipSet;
}
-LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const
-{
+LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const
+{
static stringset_t slepSet;
if (slepSet.empty())
@@ -561,53 +557,53 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID));
- validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 1.0f, "*"))));
- validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 3.0f, "*"))));
- validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 1.0f, "*"))));
- validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.001f, 3.0f))));
- validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(-50.0f, -50.0f),
llsd::array(50.0f, 50.0f))));
- validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
- validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
- validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
- validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 2000.0f))));
- validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f))));
- validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.2f, "*", -10.0f, "*"),
llsd::array(40.0f, "*", 10.0f, "*"))));
-
- validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
+
+ validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(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, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
- validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
- validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 500.0f))));
- validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
+ validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
@@ -616,25 +612,25 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(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,
+ validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
- validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
- validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
- validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 0.1f))));
- validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
- validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(5.0f, 1000.0f))));
- validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
+ validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal,
@@ -724,7 +720,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
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
+ // 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();
@@ -737,7 +733,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
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_MOON_BRIGHTNESS] = LLSD::Real(0.5f);
@@ -781,7 +777,7 @@ LLSD LLSettingsSky::translateLegacyHazeSettings(const LLSD& legacy)
// AdvancedAtmospherics TODO
// These need to be translated into density profile info in the new settings format...
-// LEGACY_ATMOSPHERICS
+// LEGACY_ATMOSPHERICS
if (legacy.has(SETTING_AMBIENT))
{
legacyhazesettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue();
@@ -871,7 +867,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal());
converted_something |= true;
}
-
+
if (legacy.has(SETTING_GAMMA))
{
@@ -929,7 +925,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
// 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);
@@ -1146,7 +1142,6 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level)
void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance)
{
- mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust
setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance);
}
@@ -1245,9 +1240,9 @@ LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in,const F32 &gamma) const
}
LLColor3 color = in * 2.0f;
- color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors...
- componentPow(color, gamma);
- color = smear(1.f) - color;
+ color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors...
+ componentPow(color, gamma);
+ color = smear(1.f) - color;
return color;
}
@@ -1357,7 +1352,7 @@ void LLSettingsSky::calculateLightSettings() const
mSunAmbient = tmpAmbient;
F32 haze_horizon = getHazeHorizon();
-
+
sunlight *= 1.0 - cloud_shadow;
sunlight += tmpAmbient;
@@ -1448,24 +1443,6 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const
return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
}
-F32 LLSettingsSky::getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust) const
-{
-#if 0
- // feed cloud shadow back into reflection probe ambiance to mimic pre-reflection-probe behavior
- // without brightening dark/interior spaces
- F32 probe_ambiance = getReflectionProbeAmbiance(auto_adjust);
-
- if (probe_ambiance > 0.f && probe_ambiance < 1.f)
- {
- probe_ambiance += (1.f - probe_ambiance) * getCloudShadow() * cloud_shadow_scale;
- }
-
- return probe_ambiance;
-#else
- return getReflectionProbeAmbiance(auto_adjust);
-#endif
-}
-
F32 LLSettingsSky::getSkyBottomRadius() const
{
return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
@@ -1485,7 +1462,7 @@ F32 LLSettingsSky::getMieAnisotropy() const
{
return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal();
}
-
+
LLSD LLSettingsSky::getRayleighConfig() const
{
LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray());
@@ -1503,7 +1480,7 @@ LLSD LLSettingsSky::getAbsorptionConfig() const
LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray());
return copy;
}
-
+
LLSD LLSettingsSky::getRayleighConfigs() const
{
return mSettings[SETTING_RAYLEIGH_CONFIG];
@@ -1645,13 +1622,13 @@ void LLSettingsSky::setCloudVariance(F32 val)
F32 LLSettingsSky::getDomeOffset() const
{
//return mSettings[SETTING_DOME_OFFSET].asReal();
- return DOME_OFFSET;
+ return DOME_OFFSET;
}
F32 LLSettingsSky::getDomeRadius() const
{
//return mSettings[SETTING_DOME_RADIUS].asReal();
- return DOME_RADIUS;
+ return DOME_RADIUS;
}
F32 LLSettingsSky::getGamma() const
@@ -1680,7 +1657,7 @@ F32 LLSettingsSky::getMaxY() const
return mSettings[SETTING_MAX_Y].asReal();
}
-void LLSettingsSky::setMaxY(F32 val)
+void LLSettingsSky::setMaxY(F32 val)
{
setValue(SETTING_MAX_Y, val);
}
@@ -1764,7 +1741,7 @@ LLQuaternion LLSettingsSky::getSunRotation() const
return LLQuaternion(mSettings[SETTING_SUN_ROTATION]);
}
-void LLSettingsSky::setSunRotation(const LLQuaternion &val)
+void LLSettingsSky::setSunRotation(const LLQuaternion &val)
{
setValue(SETTING_SUN_ROTATION, val);
}
@@ -1785,7 +1762,7 @@ LLUUID LLSettingsSky::getSunTextureId() const
return mSettings[SETTING_SUN_TEXTUREID].asUUID();
}
-void LLSettingsSky::setSunTextureId(LLUUID id)
+void LLSettingsSky::setSunTextureId(LLUUID id)
{
setValue(SETTING_SUN_TEXTUREID, id);
}
@@ -1810,3 +1787,8 @@ LLUUID LLSettingsSky::getNextBloomTextureId() const
return mNextBloomTextureId;
}
+// if true, this sky is a candidate for auto-adjustment
+bool LLSettingsSky::canAutoAdjust() const
+{
+ return !mSettings.has(SETTING_REFLECTION_PROBE_AMBIANCE);
+}
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index 8aade96484..222ab040cb 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -62,7 +62,7 @@ public:
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_GLOW;
static const std::string SETTING_LIGHT_NORMAL;
static const std::string SETTING_MAX_Y;
static const std::string SETTING_MOON_ROTATION;
@@ -92,7 +92,7 @@ public:
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_SKY_MOISTURE_LEVEL;
static const std::string SETTING_SKY_DROPLET_RADIUS;
static const std::string SETTING_SKY_ICE_LEVEL;
@@ -117,7 +117,7 @@ public:
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
+ // Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
@@ -129,7 +129,7 @@ public:
F32 getSkyBottomRadius() const;
F32 getSkyTopRadius() const;
F32 getSunArcRadians() const;
- F32 getMieAnisotropy() const;
+ F32 getMieAnisotropy() const;
F32 getSkyMoistureLevel() const;
F32 getSkyDropletRadius() const;
@@ -139,10 +139,6 @@ public:
// auto_adjust - if true and canAutoAdjust() is true, return 1.0
F32 getReflectionProbeAmbiance(bool auto_adjust = false) const;
- // get the probe ambiance setting to use for rendering (adjusted by cloud shadow, aka cloud coverage)
- // auto_adjust - if true and canAutoAdjust() is true, return 1.0
- F32 getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust = false) const;
-
// Return first (only) profile layer represented in LLSD
LLSD getRayleighConfig() const;
LLSD getMieConfig() const;
@@ -200,7 +196,7 @@ public:
F32 getCloudShadow() const;
void setCloudShadow(F32 val);
-
+
F32 getCloudVariance() const;
void setCloudVariance(F32 val);
@@ -299,7 +295,7 @@ public:
// color based on brightness
LLColor3 getMoonlightColor() const;
-
+
LLColor4 getMoonAmbient() const;
LLColor3 getMoonDiffuse() const;
LLColor4 getSunAmbient() const;
@@ -340,7 +336,7 @@ public:
virtual void updateSettings() SETTINGS_OVERRIDE;
// if true, this sky is a candidate for auto-adjustment
- bool canAutoAdjust() const { return mCanAutoAdjust; }
+ bool canAutoAdjust() const;
protected:
static const std::string SETTING_LEGACY_EAST_ANGLE;
@@ -385,9 +381,6 @@ private:
mutable LLColor4 mTotalAmbient;
mutable LLColor4 mHazeColor;
- // if true, this sky is a candidate for auto adjustment
- bool mCanAutoAdjust = true;
-
typedef std::map<std::string, S32> mapNameToUniformId_t;
static mapNameToUniformId_t sNameToUniformMapping;
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 3b52810855..e1d3536f66 100644
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llcamera.h
* @brief Header file for the LLCamera class.
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -33,26 +33,26 @@
#include "llplane.h"
#include "llvector4a.h"
-const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD;
-const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f;
-const F32 DEFAULT_NEAR_PLANE = 0.25f;
-const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions
+const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD;
+const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f;
+const F32 DEFAULT_NEAR_PLANE = 0.25f;
+const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions
-const F32 MAX_ASPECT_RATIO = 50.0f;
-const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends
-const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though.
-const F32 MAX_FAR_CLIP = 512.0f;
+const F32 MAX_ASPECT_RATIO = 50.0f;
+const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends
+const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though.
+const F32 MAX_FAR_CLIP = 512.0f;
-const F32 MIN_ASPECT_RATIO = 0.02f;
-const F32 MIN_NEAR_PLANE = 0.1f;
-const F32 MIN_FAR_PLANE = 0.2f;
+const F32 MIN_ASPECT_RATIO = 0.02f;
+const F32 MIN_NEAR_PLANE = 0.1f;
+const F32 MIN_FAR_PLANE = 0.2f;
// Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio.
static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;
static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
// An LLCamera is an LLCoorFrame with a view frustum.
-// This means that it has several methods for moving it around
+// This means that it has several methods for moving it around
// that are inherited from the LLCoordFrame() class :
//
// setOrigin(), setAxes()
@@ -62,163 +62,162 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
LL_ALIGN_PREFIX(16)
class LLCamera
-: public LLCoordFrame
+: public LLCoordFrame
{
public:
-
- LLCamera(const LLCamera& rhs)
- {
- *this = rhs;
- }
-
- enum {
- PLANE_LEFT = 0,
- PLANE_RIGHT = 1,
- PLANE_BOTTOM = 2,
- PLANE_TOP = 3,
- PLANE_NUM = 4,
- PLANE_MASK_NONE = 0xff // Disable this plane
- };
- enum {
- PLANE_LEFT_MASK = (1<<PLANE_LEFT),
- PLANE_RIGHT_MASK = (1<<PLANE_RIGHT),
- PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM),
- PLANE_TOP_MASK = (1<<PLANE_TOP),
- PLANE_ALL_MASK = 0xf,
- };
-
- enum
- { // Indexes to mAgentPlanes[] and mPlaneMask[]
- AGENT_PLANE_LEFT = 0,
- AGENT_PLANE_RIGHT = 1,
- AGENT_PLANE_NEAR = 2,
- AGENT_PLANE_BOTTOM = 3,
- AGENT_PLANE_TOP = 4,
- AGENT_PLANE_FAR = 5,
- AGENT_PLANE_USER_CLIP = 6
- };
- enum
- { // Sizes for mAgentPlanes[]. 7th entry is special case for user clip
- AGENT_PLANE_NO_USER_CLIP_NUM = 6,
- AGENT_PLANE_USER_CLIP_NUM = 7,
- PLANE_MASK_NUM = 8 // 7 actually used, 8 is for alignment
- };
-
- enum
- {
- AGENT_FRUSTRUM_NUM = 8
- };
-
- enum {
- HORIZ_PLANE_LEFT = 0,
- HORIZ_PLANE_RIGHT = 1,
- HORIZ_PLANE_NUM = 2
- };
- enum {
- HORIZ_PLANE_LEFT_MASK = (1<<HORIZ_PLANE_LEFT),
- HORIZ_PLANE_RIGHT_MASK = (1<<HORIZ_PLANE_RIGHT),
- HORIZ_PLANE_ALL_MASK = 0x3
- };
+ LLCamera(const LLCamera& rhs)
+ {
+ *this = rhs;
+ }
+
+ enum {
+ PLANE_LEFT = 0,
+ PLANE_RIGHT = 1,
+ PLANE_BOTTOM = 2,
+ PLANE_TOP = 3,
+ PLANE_NUM = 4,
+ PLANE_MASK_NONE = 0xff // Disable this plane
+ };
+ enum {
+ PLANE_LEFT_MASK = (1<<PLANE_LEFT),
+ PLANE_RIGHT_MASK = (1<<PLANE_RIGHT),
+ PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM),
+ PLANE_TOP_MASK = (1<<PLANE_TOP),
+ PLANE_ALL_MASK = 0xf,
+ };
+
+ enum
+ { // Indexes to mAgentPlanes[] and mPlaneMask[]
+ AGENT_PLANE_LEFT = 0,
+ AGENT_PLANE_RIGHT = 1,
+ AGENT_PLANE_NEAR = 2,
+ AGENT_PLANE_BOTTOM = 3,
+ AGENT_PLANE_TOP = 4,
+ AGENT_PLANE_FAR = 5,
+ AGENT_PLANE_USER_CLIP = 6
+ };
+ enum
+ { // Sizes for mAgentPlanes[]. 7th entry is special case for user clip
+ AGENT_PLANE_NO_USER_CLIP_NUM = 6,
+ AGENT_PLANE_USER_CLIP_NUM = 7,
+ PLANE_MASK_NUM = 8 // 7 actually used, 8 is for alignment
+ };
+
+ enum
+ {
+ AGENT_FRUSTRUM_NUM = 8
+ };
+
+ enum {
+ HORIZ_PLANE_LEFT = 0,
+ HORIZ_PLANE_RIGHT = 1,
+ HORIZ_PLANE_NUM = 2
+ };
+ enum {
+ HORIZ_PLANE_LEFT_MASK = (1<<HORIZ_PLANE_LEFT),
+ HORIZ_PLANE_RIGHT_MASK = (1<<HORIZ_PLANE_RIGHT),
+ HORIZ_PLANE_ALL_MASK = 0x3
+ };
private:
- LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
- LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in a local region space, derived from mAgentPlanes
- LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);
- U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment
-
- F32 mView; // angle between top and bottom frustum planes in radians.
- F32 mAspect; // width/height
- S32 mViewHeightInPixels; // for ViewHeightInPixels() only
- F32 mNearPlane;
- F32 mFarPlane;
- F32 mFixedDistance; // Always return this distance, unless < 0
- LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
- F32 mFrustRadiusSquared;
-
- U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
-
- LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
+ LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in a local region space, derived from mAgentPlanes
+ LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);
+ U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment
+
+ F32 mView; // angle between top and bottom frustum planes in radians.
+ F32 mAspect; // width/height
+ S32 mViewHeightInPixels; // for ViewHeightInPixels() only
+ F32 mNearPlane;
+ F32 mFarPlane;
+ F32 mFixedDistance; // Always return this distance, unless < 0
+ LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
+ F32 mFrustRadiusSquared;
+
+ U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
+
+ LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
public:
- LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM]; //8 corners of 6-plane frustum
- F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane
- LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }
+ LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM]; //8 corners of 6-plane frustum
+ F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane
+ LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }
public:
- LLCamera();
- LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
- virtual ~LLCamera();
-
- bool isChanged(); //check if mAgentPlanes changed since last frame.
+ LLCamera();
+ LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
+ virtual ~LLCamera();
+
+ bool isChanged(); //check if mAgentPlanes changed since last frame.
LLPlane getUserClipPlane();
- void setUserClipPlane(LLPlane& plane);
- void disableUserClipPlane();
- virtual void setView(F32 vertical_fov_rads);
- void setViewHeightInPixels(S32 height);
- void setAspect(F32 new_aspect);
- void setNear(F32 new_near);
- void setFar(F32 new_far);
-
- F32 getView() const { return mView; } // vertical FOV in radians
- S32 getViewHeightInPixels() const { return mViewHeightInPixels; }
- F32 getAspect() const { return mAspect; } // width / height
- F32 getNear() const { return mNearPlane; } // meters
- F32 getFar() const { return mFarPlane; } // meters
-
- // The values returned by the min/max view getters depend upon the aspect ratio
- // at the time they are called and therefore should not be cached.
- F32 getMinView() const;
- F32 getMaxView() const;
-
- F32 getYaw() const
- {
- return atan2f(mXAxis[VY], mXAxis[VX]);
- }
- F32 getPitch() const
- {
- F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]);
- return atan2f(mXAxis[VZ], xylen);
- }
-
- const LLVector3& getWorldPlanePos() const { return mWorldPlanePos; }
-
- // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer.
- // Return number of bytes copied.
- size_t writeFrustumToBuffer(char *buffer) const;
-
- // Copy mView, mAspect, mNearPlane, and mFarPlane from buffer.
- // Return number of bytes copied.
- size_t readFrustumFromBuffer(const char *buffer);
- void calcAgentFrustumPlanes(LLVector3* frust);
- void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes.
- void ignoreAgentFrustumPlane(S32 idx);
-
- // Returns 1 if partly in, 2 if fully in.
- // NOTE: 'center' is in absolute frame.
- S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
- S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
- S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
- S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
- S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius);
- S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
- S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
-
- //does a quick 'n dirty sphere-sphere check
- S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);
-
- // Returns height of object in pixels (must be height because field of view
- // is based on window height).
- F32 heightInPixels(const LLVector3 &center, F32 radius ) const;
-
- // return the distance from pos to camera if visible (-distance if not visible)
- void setFixedDistance(F32 distance) { mFixedDistance = distance; }
-
- friend std::ostream& operator<<(std::ostream &s, const LLCamera &C);
+ void setUserClipPlane(LLPlane& plane);
+ void disableUserClipPlane();
+ virtual void setView(F32 vertical_fov_rads);
+ void setViewHeightInPixels(S32 height);
+ void setAspect(F32 new_aspect);
+ void setNear(F32 new_near);
+ void setFar(F32 new_far);
+
+ F32 getView() const { return mView; } // vertical FOV in radians
+ S32 getViewHeightInPixels() const { return mViewHeightInPixels; }
+ F32 getAspect() const { return mAspect; } // width / height
+ F32 getNear() const { return mNearPlane; } // meters
+ F32 getFar() const { return mFarPlane; } // meters
+
+ // The values returned by the min/max view getters depend upon the aspect ratio
+ // at the time they are called and therefore should not be cached.
+ F32 getMinView() const;
+ F32 getMaxView() const;
+
+ F32 getYaw() const
+ {
+ return atan2f(mXAxis[VY], mXAxis[VX]);
+ }
+ F32 getPitch() const
+ {
+ F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]);
+ return atan2f(mXAxis[VZ], xylen);
+ }
+
+ const LLVector3& getWorldPlanePos() const { return mWorldPlanePos; }
+
+ // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer.
+ // Return number of bytes copied.
+ size_t writeFrustumToBuffer(char *buffer) const;
+
+ // Copy mView, mAspect, mNearPlane, and mFarPlane from buffer.
+ // Return number of bytes copied.
+ size_t readFrustumFromBuffer(const char *buffer);
+ void calcAgentFrustumPlanes(LLVector3* frust);
+ void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes.
+ void ignoreAgentFrustumPlane(S32 idx);
+
+ // Returns 1 if partly in, 2 if fully in.
+ // NOTE: 'center' is in absolute frame.
+ S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
+ S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
+ S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
+ S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
+ S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius);
+ S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
+ S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
+
+ //does a quick 'n dirty sphere-sphere check
+ S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);
+
+ // Returns height of object in pixels (must be height because field of view
+ // is based on window height).
+ F32 heightInPixels(const LLVector3 &center, F32 radius ) const;
+
+ // return the distance from pos to camera if visible (-distance if not visible)
+ void setFixedDistance(F32 distance) { mFixedDistance = distance; }
+
+ friend std::ostream& operator<<(std::ostream &s, const LLCamera &C);
protected:
- void calculateFrustumPlanes();
- void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
- void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
+ void calculateFrustumPlanes();
+ void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
+ void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
} LL_ALIGN_POSTFIX(16);
diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h
index 348feba27e..12fc6d570a 100644
--- a/indra/llmath/llmatrix4a.h
+++ b/indra/llmath/llmatrix4a.h
@@ -1,31 +1,31 @@
-/**
+/**
* @file llmatrix4a.h
* @brief LLMatrix4a class header file - memory aligned and vectorized 4x4 matrix
*
* $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_LLMATRIX4A_H
-#define LL_LLMATRIX4A_H
+#ifndef LL_LLMATRIX4A_H
+#define LL_LLMATRIX4A_H
#include "llvector4a.h"
#include "m4math.h"
@@ -35,7 +35,7 @@ class LLMatrix4a
{
public:
LL_ALIGN_16(LLVector4a mMatrix[4]);
-
+
LLMatrix4a()
{
@@ -56,14 +56,24 @@ public:
return (F32*)&mMatrix;
}
- inline void clear()
+ inline LLMatrix4& asMatrix4()
{
- mMatrix[0].clear();
- mMatrix[1].clear();
- mMatrix[2].clear();
- mMatrix[3].clear();
+ return *(LLMatrix4*)this;
}
+ inline const LLMatrix4& asMatrix4() const
+ {
+ return *(LLMatrix4*)this;
+ }
+
+ inline void clear()
+ {
+ mMatrix[0].clear();
+ mMatrix[1].clear();
+ mMatrix[2].clear();
+ mMatrix[3].clear();
+ }
+
inline void setIdentity()
{
mMatrix[0].set(1.f, 0.f, 0.f, 0.f);
@@ -72,14 +82,14 @@ public:
mMatrix[3].set(0.f, 0.f, 0.f, 1.f);
}
- inline void loadu(const LLMatrix4& src)
- {
- mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]);
- mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);
- mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);
- mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]);
- }
-
+ inline void loadu(const LLMatrix4& src)
+ {
+ mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]);
+ mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);
+ mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);
+ mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]);
+ }
+
inline void loadu(const F32* src)
{
mMatrix[0] = _mm_loadu_ps(src);
@@ -88,90 +98,90 @@ public:
mMatrix[3] = _mm_loadu_ps(src+12);
}
- inline void loadu(const LLMatrix3& src)
- {
- mMatrix[0].load3(src.mMatrix[0]);
- mMatrix[1].load3(src.mMatrix[1]);
- mMatrix[2].load3(src.mMatrix[2]);
- mMatrix[3].set(0,0,0,1.f);
- }
-
- inline void add(const LLMatrix4a& rhs)
- {
- mMatrix[0].add(rhs.mMatrix[0]);
- mMatrix[1].add(rhs.mMatrix[1]);
- mMatrix[2].add(rhs.mMatrix[2]);
- mMatrix[3].add(rhs.mMatrix[3]);
- }
-
- inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)
- {
- mMatrix[0] = r0;
- mMatrix[1] = r1;
- mMatrix[2] = r2;
- }
-
- inline void setMul(const LLMatrix4a& m, const F32 s)
- {
- mMatrix[0].setMul(m.mMatrix[0], s);
- mMatrix[1].setMul(m.mMatrix[1], s);
- mMatrix[2].setMul(m.mMatrix[2], s);
- mMatrix[3].setMul(m.mMatrix[3], s);
- }
-
- inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w)
- {
- LLVector4a d0,d1,d2,d3;
- d0.setSub(b.mMatrix[0], a.mMatrix[0]);
- d1.setSub(b.mMatrix[1], a.mMatrix[1]);
- d2.setSub(b.mMatrix[2], a.mMatrix[2]);
- d3.setSub(b.mMatrix[3], a.mMatrix[3]);
-
- // this = a + d*w
-
- d0.mul(w);
- d1.mul(w);
- d2.mul(w);
- d3.mul(w);
-
- mMatrix[0].setAdd(a.mMatrix[0],d0);
- mMatrix[1].setAdd(a.mMatrix[1],d1);
- mMatrix[2].setAdd(a.mMatrix[2],d2);
- mMatrix[3].setAdd(a.mMatrix[3],d3);
- }
-
- inline void rotate(const LLVector4a& v, LLVector4a& res) const
- {
- LLVector4a y,z;
-
- res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
- y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
- z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
-
- res.mul(mMatrix[0]);
- y.mul(mMatrix[1]);
- z.mul(mMatrix[2]);
-
- res.add(y);
- res.add(z);
- }
-
- inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const
- {
- LLVector4a x,y,z;
-
- x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
- y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
- z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
-
- x.mul(mMatrix[0]);
- y.mul(mMatrix[1]);
- z.mul(mMatrix[2]);
-
- x.add(y);
- z.add(mMatrix[3]);
- res.setAdd(x,z);
- }
+ inline void loadu(const LLMatrix3& src)
+ {
+ mMatrix[0].load3(src.mMatrix[0]);
+ mMatrix[1].load3(src.mMatrix[1]);
+ mMatrix[2].load3(src.mMatrix[2]);
+ mMatrix[3].set(0,0,0,1.f);
+ }
+
+ inline void add(const LLMatrix4a& rhs)
+ {
+ mMatrix[0].add(rhs.mMatrix[0]);
+ mMatrix[1].add(rhs.mMatrix[1]);
+ mMatrix[2].add(rhs.mMatrix[2]);
+ mMatrix[3].add(rhs.mMatrix[3]);
+ }
+
+ inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)
+ {
+ mMatrix[0] = r0;
+ mMatrix[1] = r1;
+ mMatrix[2] = r2;
+ }
+
+ inline void setMul(const LLMatrix4a& m, const F32 s)
+ {
+ mMatrix[0].setMul(m.mMatrix[0], s);
+ mMatrix[1].setMul(m.mMatrix[1], s);
+ mMatrix[2].setMul(m.mMatrix[2], s);
+ mMatrix[3].setMul(m.mMatrix[3], s);
+ }
+
+ inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w)
+ {
+ LLVector4a d0,d1,d2,d3;
+ d0.setSub(b.mMatrix[0], a.mMatrix[0]);
+ d1.setSub(b.mMatrix[1], a.mMatrix[1]);
+ d2.setSub(b.mMatrix[2], a.mMatrix[2]);
+ d3.setSub(b.mMatrix[3], a.mMatrix[3]);
+
+ // this = a + d*w
+
+ d0.mul(w);
+ d1.mul(w);
+ d2.mul(w);
+ d3.mul(w);
+
+ mMatrix[0].setAdd(a.mMatrix[0],d0);
+ mMatrix[1].setAdd(a.mMatrix[1],d1);
+ mMatrix[2].setAdd(a.mMatrix[2],d2);
+ mMatrix[3].setAdd(a.mMatrix[3],d3);
+ }
+
+ inline void rotate(const LLVector4a& v, LLVector4a& res) const
+ {
+ LLVector4a y,z;
+
+ res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
+ y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
+ z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
+
+ res.mul(mMatrix[0]);
+ y.mul(mMatrix[1]);
+ z.mul(mMatrix[2]);
+
+ res.add(y);
+ res.add(z);
+ }
+
+ inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const
+ {
+ LLVector4a x,y,z;
+
+ x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
+ y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
+ z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
+
+ x.mul(mMatrix[0]);
+ y.mul(mMatrix[1]);
+ z.mul(mMatrix[2]);
+
+ x.add(y);
+ z.add(mMatrix[3]);
+ res.setAdd(x,z);
+ }
inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) const
{
@@ -182,7 +192,7 @@ public:
res.set(x,y,z,w);
}
- inline void affineTransform(const LLVector4a& v, LLVector4a& res) const
+ inline void affineTransform(const LLVector4a& v, LLVector4a& res) const
{
affineTransformSSE(v,res);
}
@@ -226,7 +236,7 @@ inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)
{
s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]";
return s;
-}
+}
void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents);
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 9375a5dfca..4384c732b2 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1,24 +1,24 @@
-/**
+/**
* @file llvolume.cpp
*
* $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$
*/
@@ -45,16 +45,15 @@
#include "llmatrix3a.h"
#include "lloctree.h"
#include "llvolume.h"
-#include "llvolumeoctree.h"
#include "llstl.h"
#include "llsdserialize.h"
#include "llvector4a.h"
#include "llmatrix4a.h"
#include "llmeshoptimizer.h"
#include "lltimer.h"
+#include "llvolumeoctree.h"
-#include "mikktspace/mikktspace.h"
-#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file
+#include "mikktspace/mikktspace.hh"
#include "meshoptimizer/meshoptimizer.h"
@@ -66,7 +65,7 @@ const F32 MIN_CUT_DELTA = 0.02f;
const F32 HOLLOW_MIN = 0.f;
const F32 HOLLOW_MAX = 0.95f;
-const F32 HOLLOW_MAX_SQUARE = 0.7f;
+const F32 HOLLOW_MAX_SQUARE = 0.7f;
const F32 TWIST_MIN = -1.f;
const F32 TWIST_MAX = 1.f;
@@ -89,8 +88,8 @@ const F32 REV_MAX = 4.f;
const F32 TAPER_MIN = -1.f;
const F32 TAPER_MAX = 1.f;
-const F32 SKEW_MIN = -0.95f;
-const F32 SKEW_MAX = 0.95f;
+const F32 SKEW_MIN = -0.95f;
+const F32 SKEW_MAX = 0.95f;
const F32 SCULPT_MIN_AREA = 0.002f;
const S32 SCULPT_MIN_AREA_DETAIL = 1;
@@ -98,356 +97,285 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
BOOL gDebugGL = FALSE; // See settings.xml "RenderDebugGL"
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
-{
- LLVector3 test = (pt2-pt1)%(pt3-pt2);
-
- //answer
- if(test * norm < 0)
- {
- return FALSE;
- }
- else
- {
- return TRUE;
- }
-}
+{
+ LLVector3 test = (pt2-pt1)%(pt3-pt2);
+
+ //answer
+ if(test * norm < 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size)
{
- return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV);
+ return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV);
}
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size)
{
- F32 fAWdU[3];
- F32 dir[3];
- F32 diff[3];
-
- for (U32 i = 0; i < 3; i++)
- {
- dir[i] = 0.5f * (end[i] - start[i]);
- diff[i] = (0.5f * (end[i] + start[i])) - center[i];
- fAWdU[i] = fabsf(dir[i]);
- if(fabsf(diff[i])>size[i] + fAWdU[i]) return false;
- }
+ F32 fAWdU[3];
+ F32 dir[3];
+ F32 diff[3];
- float f;
- f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false;
- f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false;
- f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false;
+ for (U32 i = 0; i < 3; i++)
+ {
+ dir[i] = 0.5f * (end[i] - start[i]);
+ diff[i] = (0.5f * (end[i] + start[i])) - center[i];
+ fAWdU[i] = fabsf(dir[i]);
+ if(fabsf(diff[i])>size[i] + fAWdU[i]) return false;
+ }
- return true;
+ float f;
+ f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false;
+ f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false;
+ f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false;
+
+ return true;
}
// Finds tangent vec based on three vertices with texture coordinates.
// Fills in dummy values if the triangle has degenerate texture coordinates.
void calc_tangent_from_triangle(
- LLVector4a& normal,
- LLVector4a& tangent_out,
- const LLVector4a& v1,
- const LLVector2& w1,
- const LLVector4a& v2,
- const LLVector2& w2,
- const LLVector4a& v3,
- const LLVector2& w3)
-{
- const F32* v1ptr = v1.getF32ptr();
- const F32* v2ptr = v2.getF32ptr();
- const F32* v3ptr = v3.getF32ptr();
-
- float x1 = v2ptr[0] - v1ptr[0];
- float x2 = v3ptr[0] - v1ptr[0];
- float y1 = v2ptr[1] - v1ptr[1];
- float y2 = v3ptr[1] - v1ptr[1];
- float z1 = v2ptr[2] - v1ptr[2];
- float z2 = v3ptr[2] - v1ptr[2];
-
- float s1 = w2.mV[0] - w1.mV[0];
- float s2 = w3.mV[0] - w1.mV[0];
- float t1 = w2.mV[1] - w1.mV[1];
- float t2 = w3.mV[1] - w1.mV[1];
-
- F32 rd = s1*t2-s2*t1;
-
- float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
- : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
-
- llassert(llfinite(r));
- llassert(!llisnan(r));
-
- LLVector4a sdir(
- (t2 * x1 - t1 * x2) * r,
- (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r);
-
- LLVector4a tdir(
- (s1 * x2 - s2 * x1) * r,
- (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r);
-
- LLVector4a n = normal;
- LLVector4a t = sdir;
-
- LLVector4a ncrosst;
- ncrosst.setCross3(n,t);
-
- // Gram-Schmidt orthogonalize
- n.mul(n.dot3(t).getF32());
-
- LLVector4a tsubn;
- tsubn.setSub(t,n);
-
- if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
- {
- tsubn.normalize3fast_checked();
-
- // Calculate handedness
- F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
-
- tsubn.getF32ptr()[3] = handedness;
-
- tangent_out = tsubn;
- }
- else
- {
- // degenerate, make up a value
- //
- tangent_out.set(0,0,1,1);
- }
-
-}
-
-
-// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
-// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b,
-// and returns the intersection point along dir in intersection_t.
-
-// Moller-Trumbore algorithm
-BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t)
+ LLVector4a& normal,
+ LLVector4a& tangent_out,
+ const LLVector4a& v1,
+ const LLVector2& w1,
+ const LLVector4a& v2,
+ const LLVector2& w2,
+ const LLVector4a& v3,
+ const LLVector2& w3)
{
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
- /* find vectors for two edges sharing vert0 */
- LLVector4a edge1;
- edge1.setSub(vert1, vert0);
-
- LLVector4a edge2;
- edge2.setSub(vert2, vert0);
-
- /* begin calculating determinant - also used to calculate U parameter */
- LLVector4a pvec;
- pvec.setCross3(dir, edge2);
-
- /* if determinant is near zero, ray lies in plane of triangle */
- LLVector4a det;
- det.setAllDot3(edge1, pvec);
-
- if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7)
- {
- /* calculate distance from vert0 to ray origin */
- LLVector4a tvec;
- tvec.setSub(orig, vert0);
+ float x1 = v2ptr[0] - v1ptr[0];
+ float x2 = v3ptr[0] - v1ptr[0];
+ float y1 = v2ptr[1] - v1ptr[1];
+ float y2 = v3ptr[1] - v1ptr[1];
+ float z1 = v2ptr[2] - v1ptr[2];
+ float z2 = v3ptr[2] - v1ptr[2];
- /* calculate U parameter and test bounds */
- LLVector4a u;
- u.setAllDot3(tvec,pvec);
+ float s1 = w2.mV[0] - w1.mV[0];
+ float s2 = w3.mV[0] - w1.mV[0];
+ float t1 = w2.mV[1] - w1.mV[1];
+ float t2 = w3.mV[1] - w1.mV[1];
- if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) &&
- (u.lessEqual(det).getGatheredBits() & 0x7))
- {
- /* prepare to test V parameter */
- LLVector4a qvec;
- qvec.setCross3(tvec, edge1);
+ F32 rd = s1*t2-s2*t1;
- /* calculate V parameter and test bounds */
- LLVector4a v;
- v.setAllDot3(dir, qvec);
+ float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
+ : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
- //if (!(v < 0.f || u + v > det))
+ LLVector4a sdir(
+ (t2 * x1 - t1 * x2) * r,
+ (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
- LLVector4a sum_uv;
- sum_uv.setAdd(u, v);
+ LLVector4a tdir(
+ (s1 * x2 - s2 * x1) * r,
+ (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
- S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7;
- S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7;
+ LLVector4a n = normal;
+ LLVector4a t = sdir;
- if (v_gequal && sum_lequal)
- {
- /* calculate t, scale parameters, ray intersects triangle */
- LLVector4a t;
- t.setAllDot3(edge2,qvec);
-
- t.div(det);
- u.div(det);
- v.div(det);
-
- intersection_a = u[0];
- intersection_b = v[0];
- intersection_t = t[0];
- return TRUE;
- }
- }
- }
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
- return FALSE;
-}
+ // Gram-Schmidt orthogonalize
+ n.mul(n.dot3(t).getF32());
-BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t)
-{
- F32 u, v, t;
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
- /* find vectors for two edges sharing vert0 */
- LLVector4a edge1;
- edge1.setSub(vert1, vert0);
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast_checked();
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
- LLVector4a edge2;
- edge2.setSub(vert2, vert0);
+ tsubn.getF32ptr()[3] = handedness;
- /* begin calculating determinant - also used to calculate U parameter */
- LLVector4a pvec;
- pvec.setCross3(dir, edge2);
+ tangent_out = tsubn;
+ }
+ else
+ {
+ // degenerate, make up a value
+ //
+ tangent_out.set(0,0,1,1);
+ }
- /* if determinant is near zero, ray lies in plane of triangle */
- F32 det = edge1.dot3(pvec).getF32();
-
-
- if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)
- {
- return FALSE;
- }
-
- F32 inv_det = 1.f / det;
-
- /* calculate distance from vert0 to ray origin */
- LLVector4a tvec;
- tvec.setSub(orig, vert0);
-
- /* calculate U parameter and test bounds */
- u = (tvec.dot3(pvec).getF32()) * inv_det;
- if (u < 0.f || u > 1.f)
- {
- return FALSE;
- }
-
- /* prepare to test V parameter */
- tvec.sub(edge1);
-
- /* calculate V parameter and test bounds */
- v = (dir.dot3(tvec).getF32()) * inv_det;
-
- if (v < 0.f || u + v > 1.f)
- {
- return FALSE;
- }
+}
- /* calculate t, ray intersects triangle */
- t = (edge2.dot3(tvec).getF32()) * inv_det;
- intersection_a = u;
- intersection_b = v;
- intersection_t = t;
+// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
+// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b,
+// and returns the intersection point along dir in intersection_t.
+// Moller-Trumbore algorithm
+BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
+ F32& intersection_a, F32& intersection_b, F32& intersection_t)
+{
+
+ /* find vectors for two edges sharing vert0 */
+ LLVector4a edge1;
+ edge1.setSub(vert1, vert0);
+
+ LLVector4a edge2;
+ edge2.setSub(vert2, vert0);
+
+ /* begin calculating determinant - also used to calculate U parameter */
+ LLVector4a pvec;
+ pvec.setCross3(dir, edge2);
+
+ /* if determinant is near zero, ray lies in plane of triangle */
+ LLVector4a det;
+ det.setAllDot3(edge1, pvec);
+
+ if (det.greaterEqual(LLVector4a::getEpsilon()).getGatheredBits() & 0x7)
+ {
+ /* calculate distance from vert0 to ray origin */
+ LLVector4a tvec;
+ tvec.setSub(orig, vert0);
+
+ /* calculate U parameter and test bounds */
+ LLVector4a u;
+ u.setAllDot3(tvec,pvec);
+
+ if ((u.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7) &&
+ (u.lessEqual(det).getGatheredBits() & 0x7))
+ {
+ /* prepare to test V parameter */
+ LLVector4a qvec;
+ qvec.setCross3(tvec, edge1);
+
+ /* calculate V parameter and test bounds */
+ LLVector4a v;
+ v.setAllDot3(dir, qvec);
+
+
+ //if (!(v < 0.f || u + v > det))
+
+ LLVector4a sum_uv;
+ sum_uv.setAdd(u, v);
+
+ S32 v_gequal = v.greaterEqual(LLVector4a::getZero()).getGatheredBits() & 0x7;
+ S32 sum_lequal = sum_uv.lessEqual(det).getGatheredBits() & 0x7;
+
+ if (v_gequal && sum_lequal)
+ {
+ /* calculate t, scale parameters, ray intersects triangle */
+ LLVector4a t;
+ t.setAllDot3(edge2,qvec);
+
+ t.div(det);
+ u.div(det);
+ v.div(det);
+
+ intersection_a = u[0];
+ intersection_b = v[0];
+ intersection_t = t[0];
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
- return TRUE;
-}
+BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
+ F32& intersection_a, F32& intersection_b, F32& intersection_t)
+{
+ F32 u, v, t;
+
+ /* find vectors for two edges sharing vert0 */
+ LLVector4a edge1;
+ edge1.setSub(vert1, vert0);
+
+
+ LLVector4a edge2;
+ edge2.setSub(vert2, vert0);
+
+ /* begin calculating determinant - also used to calculate U parameter */
+ LLVector4a pvec;
+ pvec.setCross3(dir, edge2);
+
+ /* if determinant is near zero, ray lies in plane of triangle */
+ F32 det = edge1.dot3(pvec).getF32();
+
+
+ if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO)
+ {
+ return FALSE;
+ }
+
+ F32 inv_det = 1.f / det;
+
+ /* calculate distance from vert0 to ray origin */
+ LLVector4a tvec;
+ tvec.setSub(orig, vert0);
+
+ /* calculate U parameter and test bounds */
+ u = (tvec.dot3(pvec).getF32()) * inv_det;
+ if (u < 0.f || u > 1.f)
+ {
+ return FALSE;
+ }
+
+ /* prepare to test V parameter */
+ tvec.sub(edge1);
+
+ /* calculate V parameter and test bounds */
+ v = (dir.dot3(tvec).getF32()) * inv_det;
+
+ if (v < 0.f || u + v > 1.f)
+ {
+ return FALSE;
+ }
+
+ /* calculate t, ray intersects triangle */
+ t = (edge2.dot3(tvec).getF32()) * inv_det;
+
+ intersection_a = u;
+ intersection_b = v;
+ intersection_t = t;
+
+
+ return TRUE;
+}
//helper for non-aligned vectors
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided)
-{
- LLVector4a vert0a, vert1a, vert2a, origa, dira;
- vert0a.load3(vert0.mV);
- vert1a.load3(vert1.mV);
- vert2a.load3(vert2.mV);
- origa.load3(orig.mV);
- dira.load3(dir.mV);
-
- if (two_sided)
- {
- return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira,
- intersection_a, intersection_b, intersection_t);
- }
- else
- {
- return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira,
- intersection_a, intersection_b, intersection_t);
- }
+ F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided)
+{
+ LLVector4a vert0a, vert1a, vert2a, origa, dira;
+ vert0a.load3(vert0.mV);
+ vert1a.load3(vert1.mV);
+ vert2a.load3(vert2.mV);
+ origa.load3(orig.mV);
+ dira.load3(dir.mV);
+
+ if (two_sided)
+ {
+ return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira,
+ intersection_a, intersection_b, intersection_t);
+ }
+ else
+ {
+ return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira,
+ intersection_a, intersection_b, intersection_t);
+ }
}
-class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
-{
-public:
- const LLVolumeFace* mFace;
-
- LLVolumeOctreeRebound(const LLVolumeFace* face)
- {
- mFace = face;
- }
-
- virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
- { //this is a depth first traversal, so it's safe to assum all children have complete
- //bounding data
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
-
- LLVector4a& min = node->mExtents[0];
- LLVector4a& max = node->mExtents[1];
-
- if (!branch->isEmpty())
- { //node has data, find AABB that binds data set
- const LLVolumeTriangle* tri = *(branch->getDataBegin());
-
- //initialize min/max to first available vertex
- min = *(tri->mV[0]);
- max = *(tri->mV[0]);
-
- for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
- { //for each triangle in node
-
- //stretch by triangles in node
- tri = *iter;
-
- min.setMin(min, *tri->mV[0]);
- min.setMin(min, *tri->mV[1]);
- min.setMin(min, *tri->mV[2]);
-
- max.setMax(max, *tri->mV[0]);
- max.setMax(max, *tri->mV[1]);
- max.setMax(max, *tri->mV[2]);
- }
- }
- else if (branch->getChildCount() > 0)
- { //no data, but child nodes exist
- LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
-
- //initialize min/max to extents of first child
- min = child->mExtents[0];
- max = child->mExtents[1];
- }
- else
- {
- llassert(!branch->isLeaf()); // Empty leaf
- }
-
- for (S32 i = 0; i < branch->getChildCount(); ++i)
- { //stretch by child extents
- LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0);
- min.setMin(min, child->mExtents[0]);
- max.setMax(max, child->mExtents[1]);
- }
-
- node->mBounds[0].setAdd(min, max);
- node->mBounds[0].mul(0.5f);
-
- node->mBounds[1].setSub(max,min);
- node->mBounds[1].mul(0.5f);
- }
-};
-
//-------------------------------------------------------------------
// statics
//-------------------------------------------------------------------
@@ -457,91 +385,91 @@ public:
LLProfile::Face* LLProfile::addCap(S16 faceID)
{
- Face *face = vector_append(mFaces, 1);
-
- face->mIndex = 0;
- face->mCount = mTotal;
- face->mScaleU= 1.0f;
- face->mCap = TRUE;
- face->mFaceID = faceID;
- return face;
+ Face *face = vector_append(mFaces, 1);
+
+ face->mIndex = 0;
+ face->mCount = mTotal;
+ face->mScaleU= 1.0f;
+ face->mCap = TRUE;
+ face->mFaceID = faceID;
+ return face;
}
LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat)
{
- Face *face = vector_append(mFaces, 1);
+ Face *face = vector_append(mFaces, 1);
+
+ face->mIndex = i;
+ face->mCount = count;
+ face->mScaleU= scaleU;
- face->mIndex = i;
- face->mCount = count;
- face->mScaleU= scaleU;
-
- face->mFlat = flat;
- face->mCap = FALSE;
- face->mFaceID = faceID;
- return face;
+ face->mFlat = flat;
+ face->mCap = FALSE;
+ face->mFaceID = faceID;
+ return face;
}
//static
S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
{ // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points
- S32 np = 0;
-
- // Generate an n-sided "circular" path.
- // 0 is (1,0), and we go counter-clockwise along a circular path from there.
- F32 t, t_step, t_first, t_fraction;
-
- F32 begin = params.getBegin();
- F32 end = params.getEnd();
-
- t_step = 1.0f / sides;
-
- t_first = floor(begin * sides) / (F32)sides;
-
- // pt1 is the first point on the fractional face.
- // Starting t and ang values for the first face
- t = t_first;
-
- // Increment to the next point.
- // pt2 is the end point on the fractional face
- t += t_step;
-
- t_fraction = (begin - t_first)*sides;
-
- // Only use if it's not almost exactly on an edge.
- if (t_fraction < 0.9999f)
- {
- np++;
- }
-
- // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
- while (t < end)
- {
- // Iterate through all the integer steps of t.
- np++;
-
- t += t_step;
- }
-
- t_fraction = (end - (t - t_step))*sides;
-
- // Find the fraction that we need to add to the end point.
- t_fraction = (end - (t - t_step))*sides;
- if (t_fraction > 0.0001f)
- {
- np++;
- }
-
- // If we're sliced, the profile is open.
- if ((end - begin)*ang_scale < 0.99f)
- {
- if (params.getHollow() <= 0)
- {
- // put center point if not hollow.
- np++;
- }
- }
-
- return np;
+ S32 np = 0;
+
+ // Generate an n-sided "circular" path.
+ // 0 is (1,0), and we go counter-clockwise along a circular path from there.
+ F32 t, t_step, t_first, t_fraction;
+
+ F32 begin = params.getBegin();
+ F32 end = params.getEnd();
+
+ t_step = 1.0f / sides;
+
+ t_first = floor(begin * sides) / (F32)sides;
+
+ // pt1 is the first point on the fractional face.
+ // Starting t and ang values for the first face
+ t = t_first;
+
+ // Increment to the next point.
+ // pt2 is the end point on the fractional face
+ t += t_step;
+
+ t_fraction = (begin - t_first)*sides;
+
+ // Only use if it's not almost exactly on an edge.
+ if (t_fraction < 0.9999f)
+ {
+ np++;
+ }
+
+ // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
+ while (t < end)
+ {
+ // Iterate through all the integer steps of t.
+ np++;
+
+ t += t_step;
+ }
+
+ t_fraction = (end - (t - t_step))*sides;
+
+ // Find the fraction that we need to add to the end point.
+ t_fraction = (end - (t - t_step))*sides;
+ if (t_fraction > 0.0001f)
+ {
+ np++;
+ }
+
+ // If we're sliced, the profile is open.
+ if ((end - begin)*ang_scale < 0.99f)
+ {
+ if (params.getHollow() <= 0)
+ {
+ // put center point if not hollow.
+ np++;
+ }
+ }
+
+ return np;
}
// What is the bevel parameter used for? - DJS 04/05/02
@@ -549,129 +477,129 @@ S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 of
// filleted and chamfered corners
void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
{
- // Generate an n-sided "circular" path.
- // 0 is (1,0), and we go counter-clockwise along a circular path from there.
- static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
- F32 scale = 0.5f;
- F32 t, t_step, t_first, t_fraction, ang, ang_step;
- LLVector4a pt1,pt2;
-
- F32 begin = params.getBegin();
- F32 end = params.getEnd();
-
- t_step = 1.0f / sides;
- ang_step = 2.0f*F_PI*t_step*ang_scale;
-
- // Scale to have size "match" scale. Compensates to get object to generally fill bounding box.
-
- S32 total_sides = ll_round(sides / ang_scale); // Total number of sides all around
-
- if (total_sides < 8)
- {
- scale = tableScale[total_sides];
- }
-
- t_first = floor(begin * sides) / (F32)sides;
-
- // pt1 is the first point on the fractional face.
- // Starting t and ang values for the first face
- t = t_first;
- ang = 2.0f*F_PI*(t*ang_scale + offset);
- pt1.set(cos(ang)*scale,sin(ang)*scale, t);
-
- // Increment to the next point.
- // pt2 is the end point on the fractional face
- t += t_step;
- ang += ang_step;
- pt2.set(cos(ang)*scale,sin(ang)*scale,t);
-
- t_fraction = (begin - t_first)*sides;
-
- // Only use if it's not almost exactly on an edge.
- if (t_fraction < 0.9999f)
- {
- LLVector4a new_pt;
- new_pt.setLerp(pt1, pt2, t_fraction);
- mProfile.push_back(new_pt);
- }
-
- // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
- while (t < end)
- {
- // Iterate through all the integer steps of t.
- pt1.set(cos(ang)*scale,sin(ang)*scale,t);
-
- if (mProfile.size() > 0) {
- LLVector4a p = mProfile[mProfile.size()-1];
- for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
- //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1));
- LLVector4a new_pt;
- new_pt.setSub(pt1, p);
- new_pt.mul(1.0f/(float)(split+1) * (float)(i+1));
- new_pt.add(p);
- mProfile.push_back(new_pt);
- }
- }
- mProfile.push_back(pt1);
-
- t += t_step;
- ang += ang_step;
- }
-
- t_fraction = (end - (t - t_step))*sides;
-
- // pt1 is the first point on the fractional face
- // pt2 is the end point on the fractional face
- pt2.set(cos(ang)*scale,sin(ang)*scale,t);
-
- // Find the fraction that we need to add to the end point.
- t_fraction = (end - (t - t_step))*sides;
- if (t_fraction > 0.0001f)
- {
- LLVector4a new_pt;
- new_pt.setLerp(pt1, pt2, t_fraction);
-
- if (mProfile.size() > 0) {
- LLVector4a p = mProfile[mProfile.size()-1];
- for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
- //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1));
-
- LLVector4a pt1;
- pt1.setSub(new_pt, p);
- pt1.mul(1.0f/(float)(split+1) * (float)(i+1));
- pt1.add(p);
- mProfile.push_back(pt1);
- }
- }
- mProfile.push_back(new_pt);
- }
-
- // If we're sliced, the profile is open.
- if ((end - begin)*ang_scale < 0.99f)
- {
- if ((end - begin)*ang_scale > 0.5f)
- {
- mConcave = TRUE;
- }
- else
- {
- mConcave = FALSE;
- }
- mOpen = TRUE;
- if (params.getHollow() <= 0)
- {
- // put center point if not hollow.
- mProfile.push_back(LLVector4a(0,0,0));
- }
- }
- else
- {
- // The profile isn't open.
- mOpen = FALSE;
- mConcave = FALSE;
- }
-
- mTotal = mProfile.size();
+ // Generate an n-sided "circular" path.
+ // 0 is (1,0), and we go counter-clockwise along a circular path from there.
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+ F32 scale = 0.5f;
+ F32 t, t_step, t_first, t_fraction, ang, ang_step;
+ LLVector4a pt1,pt2;
+
+ F32 begin = params.getBegin();
+ F32 end = params.getEnd();
+
+ t_step = 1.0f / sides;
+ ang_step = 2.0f*F_PI*t_step*ang_scale;
+
+ // Scale to have size "match" scale. Compensates to get object to generally fill bounding box.
+
+ S32 total_sides = ll_round(sides / ang_scale); // Total number of sides all around
+
+ if (total_sides < 8)
+ {
+ scale = tableScale[total_sides];
+ }
+
+ t_first = floor(begin * sides) / (F32)sides;
+
+ // pt1 is the first point on the fractional face.
+ // Starting t and ang values for the first face
+ t = t_first;
+ ang = 2.0f*F_PI*(t*ang_scale + offset);
+ pt1.set(cos(ang)*scale,sin(ang)*scale, t);
+
+ // Increment to the next point.
+ // pt2 is the end point on the fractional face
+ t += t_step;
+ ang += ang_step;
+ pt2.set(cos(ang)*scale,sin(ang)*scale,t);
+
+ t_fraction = (begin - t_first)*sides;
+
+ // Only use if it's not almost exactly on an edge.
+ if (t_fraction < 0.9999f)
+ {
+ LLVector4a new_pt;
+ new_pt.setLerp(pt1, pt2, t_fraction);
+ mProfile.push_back(new_pt);
+ }
+
+ // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02
+ while (t < end)
+ {
+ // Iterate through all the integer steps of t.
+ pt1.set(cos(ang)*scale,sin(ang)*scale,t);
+
+ if (mProfile.size() > 0) {
+ LLVector4a p = mProfile[mProfile.size()-1];
+ for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
+ //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1));
+ LLVector4a new_pt;
+ new_pt.setSub(pt1, p);
+ new_pt.mul(1.0f/(float)(split+1) * (float)(i+1));
+ new_pt.add(p);
+ mProfile.push_back(new_pt);
+ }
+ }
+ mProfile.push_back(pt1);
+
+ t += t_step;
+ ang += ang_step;
+ }
+
+ t_fraction = (end - (t - t_step))*sides;
+
+ // pt1 is the first point on the fractional face
+ // pt2 is the end point on the fractional face
+ pt2.set(cos(ang)*scale,sin(ang)*scale,t);
+
+ // Find the fraction that we need to add to the end point.
+ t_fraction = (end - (t - t_step))*sides;
+ if (t_fraction > 0.0001f)
+ {
+ LLVector4a new_pt;
+ new_pt.setLerp(pt1, pt2, t_fraction);
+
+ if (mProfile.size() > 0) {
+ LLVector4a p = mProfile[mProfile.size()-1];
+ for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
+ //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1));
+
+ LLVector4a pt1;
+ pt1.setSub(new_pt, p);
+ pt1.mul(1.0f/(float)(split+1) * (float)(i+1));
+ pt1.add(p);
+ mProfile.push_back(pt1);
+ }
+ }
+ mProfile.push_back(new_pt);
+ }
+
+ // If we're sliced, the profile is open.
+ if ((end - begin)*ang_scale < 0.99f)
+ {
+ if ((end - begin)*ang_scale > 0.5f)
+ {
+ mConcave = TRUE;
+ }
+ else
+ {
+ mConcave = FALSE;
+ }
+ mOpen = TRUE;
+ if (params.getHollow() <= 0)
+ {
+ // put center point if not hollow.
+ mProfile.push_back(LLVector4a(0,0,0));
+ }
+ }
+ else
+ {
+ // The profile isn't open.
+ mOpen = FALSE;
+ mConcave = FALSE;
+ }
+
+ mTotal = mProfile.size();
}
// Hollow is percent of the original bounding box, not of this particular
@@ -679,603 +607,603 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
// a swept square.
LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split)
{
- // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them.
+ // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them.
- // Total add has number of vertices on outside.
- mTotalOut = mTotal;
+ // Total add has number of vertices on outside.
+ mTotalOut = mTotal;
- // Why is the "bevel" parameter -1? DJS 04/05/02
- genNGon(params, llfloor(sides),offset,-1, ang_scale, split);
+ // Why is the "bevel" parameter -1? DJS 04/05/02
+ genNGon(params, llfloor(sides),offset,-1, ang_scale, split);
- Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
+ Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- static thread_local LLAlignedArray<LLVector4a,64> pt;
- pt.resize(mTotal) ;
+ static thread_local LLAlignedArray<LLVector4a,64> pt;
+ pt.resize(mTotal) ;
- for (S32 i=mTotalOut;i<mTotal;i++)
- {
- pt[i] = mProfile[i];
- pt[i].mul(box_hollow);
- }
+ for (S32 i=mTotalOut;i<mTotal;i++)
+ {
+ pt[i] = mProfile[i];
+ pt[i].mul(box_hollow);
+ }
- S32 j=mTotal-1;
- for (S32 i=mTotalOut;i<mTotal;i++)
- {
- mProfile[i] = pt[j--];
- }
+ S32 j=mTotal-1;
+ for (S32 i=mTotalOut;i<mTotal;i++)
+ {
+ mProfile[i] = pt[j--];
+ }
- for (S32 i=0;i<(S32)mFaces.size();i++)
- {
- if (mFaces[i].mCap)
- {
- mFaces[i].mCount *= 2;
- }
- }
+ for (S32 i=0;i<(S32)mFaces.size();i++)
+ {
+ if (mFaces[i].mCap)
+ {
+ mFaces[i].mCount *= 2;
+ }
+ }
- return face;
+ return face;
}
//static
S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
- BOOL is_sculpted, S32 sculpt_size)
+ BOOL is_sculpted, S32 sculpt_size)
{ // this is basically LLProfile::generate stripped down to only operations that influence the number of points
- if (detail < MIN_LOD)
- {
- detail = MIN_LOD;
- }
-
- // Generate the face data
- F32 hollow = params.getHollow();
-
- S32 np = 0;
-
- switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
- {
- case LL_PCODE_PROFILE_SQUARE:
- {
- np = getNumNGonPoints(params, 4,-0.375, 0, 1, split);
-
- if (hollow)
- {
- np *= 2;
- }
- }
- break;
- case LL_PCODE_PROFILE_ISOTRI:
- case LL_PCODE_PROFILE_RIGHTTRI:
- case LL_PCODE_PROFILE_EQUALTRI:
- {
- np = getNumNGonPoints(params, 3,0, 0, 1, split);
-
- if (hollow)
- {
- np *= 2;
- }
- }
- break;
- case LL_PCODE_PROFILE_CIRCLE:
- {
- // If this has a square hollow, we should adjust the
- // number of faces a bit so that the geometry lines up.
- U8 hole_type=0;
- F32 circle_detail = MIN_DETAIL_FACES * detail;
- if (hollow)
- {
- hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
- if (hole_type == LL_PCODE_HOLE_SQUARE)
- {
- // Snap to the next multiple of four sides,
- // so that corners line up.
- circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
- }
- }
-
- S32 sides = (S32)circle_detail;
-
- if (is_sculpted)
- sides = sculpt_size;
-
- np = getNumNGonPoints(params, sides);
-
- if (hollow)
- {
- np *= 2;
- }
- }
- break;
- case LL_PCODE_PROFILE_CIRCLE_HALF:
- {
- // If this has a square hollow, we should adjust the
- // number of faces a bit so that the geometry lines up.
- U8 hole_type=0;
- // Number of faces is cut in half because it's only a half-circle.
- F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
- if (hollow)
- {
- hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
- if (hole_type == LL_PCODE_HOLE_SQUARE)
- {
- // Snap to the next multiple of four sides (div 2),
- // so that corners line up.
- circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
- }
- }
- np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
-
- if (hollow)
- {
- np *= 2;
- }
-
- // Special case for openness of sphere
- if ((params.getEnd() - params.getBegin()) < 1.f)
- {
- }
- else if (!hollow)
- {
- np++;
- }
- }
- break;
- default:
- break;
- };
-
-
- return np;
+ if (detail < MIN_LOD)
+ {
+ detail = MIN_LOD;
+ }
+
+ // Generate the face data
+ F32 hollow = params.getHollow();
+
+ S32 np = 0;
+
+ switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
+ {
+ case LL_PCODE_PROFILE_SQUARE:
+ {
+ np = getNumNGonPoints(params, 4,-0.375, 0, 1, split);
+
+ if (hollow)
+ {
+ np *= 2;
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_ISOTRI:
+ case LL_PCODE_PROFILE_RIGHTTRI:
+ case LL_PCODE_PROFILE_EQUALTRI:
+ {
+ np = getNumNGonPoints(params, 3,0, 0, 1, split);
+
+ if (hollow)
+ {
+ np *= 2;
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_CIRCLE:
+ {
+ // If this has a square hollow, we should adjust the
+ // number of faces a bit so that the geometry lines up.
+ U8 hole_type=0;
+ F32 circle_detail = MIN_DETAIL_FACES * detail;
+ if (hollow)
+ {
+ hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
+ if (hole_type == LL_PCODE_HOLE_SQUARE)
+ {
+ // Snap to the next multiple of four sides,
+ // so that corners line up.
+ circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
+ }
+ }
+
+ S32 sides = (S32)circle_detail;
+
+ if (is_sculpted)
+ sides = sculpt_size;
+
+ np = getNumNGonPoints(params, sides);
+
+ if (hollow)
+ {
+ np *= 2;
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_CIRCLE_HALF:
+ {
+ // If this has a square hollow, we should adjust the
+ // number of faces a bit so that the geometry lines up.
+ U8 hole_type=0;
+ // Number of faces is cut in half because it's only a half-circle.
+ F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
+ if (hollow)
+ {
+ hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
+ if (hole_type == LL_PCODE_HOLE_SQUARE)
+ {
+ // Snap to the next multiple of four sides (div 2),
+ // so that corners line up.
+ circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
+ }
+ }
+ np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
+
+ if (hollow)
+ {
+ np *= 2;
+ }
+
+ // Special case for openness of sphere
+ if ((params.getEnd() - params.getBegin()) < 1.f)
+ {
+ }
+ else if (!hollow)
+ {
+ np++;
+ }
+ }
+ break;
+ default:
+ break;
+ };
+
+
+ return np;
}
BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
- BOOL is_sculpted, S32 sculpt_size)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- if ((!mDirty) && (!is_sculpted))
- {
- return FALSE;
- }
- mDirty = FALSE;
-
- if (detail < MIN_LOD)
- {
- LL_INFOS() << "Generating profile with LOD < MIN_LOD. CLAMPING" << LL_ENDL;
- detail = MIN_LOD;
- }
-
- mProfile.resize(0);
- mFaces.resize(0);
-
- // Generate the face data
- S32 i;
- F32 begin = params.getBegin();
- F32 end = params.getEnd();
- F32 hollow = params.getHollow();
-
- // Quick validation to eliminate some server crashes.
- if (begin > end - 0.01f)
- {
- LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL;
- return FALSE;
- }
-
- S32 face_num = 0;
-
- switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
- {
- case LL_PCODE_PROFILE_SQUARE:
- {
- genNGon(params, 4,-0.375, 0, 1, split);
- if (path_open)
- {
- addCap (LL_FACE_PATH_BEGIN);
- }
-
- for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++)
- {
- addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);
- }
-
- LLVector4a scale(1,1,4,1);
-
- for (i = 0; i <(S32) mProfile.size(); i++)
- {
- // Scale by 4 to generate proper tex coords.
- mProfile[i].mul(scale);
- llassert(mProfile[i].isFinite3());
- }
-
- if (hollow)
- {
- switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
- {
- case LL_PCODE_HOLE_TRIANGLE:
- // This offset is not correct, but we can't change it now... DK 11/17/04
- addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split);
- break;
- case LL_PCODE_HOLE_CIRCLE:
- // TODO: Compute actual detail levels for cubes
- addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f);
- break;
- case LL_PCODE_HOLE_SAME:
- case LL_PCODE_HOLE_SQUARE:
- default:
- addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split);
- break;
- }
- }
-
- if (path_open) {
- mFaces[0].mCount = mTotal;
- }
- }
- break;
- case LL_PCODE_PROFILE_ISOTRI:
- case LL_PCODE_PROFILE_RIGHTTRI:
- case LL_PCODE_PROFILE_EQUALTRI:
- {
- genNGon(params, 3,0, 0, 1, split);
- LLVector4a scale(1,1,3,1);
- for (i = 0; i <(S32) mProfile.size(); i++)
- {
- // Scale by 3 to generate proper tex coords.
- mProfile[i].mul(scale);
- llassert(mProfile[i].isFinite3());
- }
-
- if (path_open)
- {
- addCap(LL_FACE_PATH_BEGIN);
- }
-
- for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++)
- {
- addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);
- }
- if (hollow)
- {
- // Swept triangles need smaller hollowness values,
- // because the triangle doesn't fill the bounding box.
- F32 triangle_hollow = hollow / 2.f;
-
- switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
- {
- case LL_PCODE_HOLE_CIRCLE:
- // TODO: Actually generate level of detail for triangles
- addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f);
- break;
- case LL_PCODE_HOLE_SQUARE:
- addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split);
- break;
- case LL_PCODE_HOLE_SAME:
- case LL_PCODE_HOLE_TRIANGLE:
- default:
- addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split);
- break;
- }
- }
- }
- break;
- case LL_PCODE_PROFILE_CIRCLE:
- {
- // If this has a square hollow, we should adjust the
- // number of faces a bit so that the geometry lines up.
- U8 hole_type=0;
- F32 circle_detail = MIN_DETAIL_FACES * detail;
- if (hollow)
- {
- hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
- if (hole_type == LL_PCODE_HOLE_SQUARE)
- {
- // Snap to the next multiple of four sides,
- // so that corners line up.
- circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
- }
- }
-
- S32 sides = (S32)circle_detail;
-
- if (is_sculpted)
- sides = sculpt_size;
-
- genNGon(params, sides);
-
- if (path_open)
- {
- addCap (LL_FACE_PATH_BEGIN);
- }
-
- if (mOpen && !hollow)
- {
- addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE);
- }
- else
- {
- addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE);
- }
-
- if (hollow)
- {
- switch (hole_type)
- {
- case LL_PCODE_HOLE_SQUARE:
- addHole(params, TRUE, 4, 0, hollow, 1.f, split);
- break;
- case LL_PCODE_HOLE_TRIANGLE:
- addHole(params, TRUE, 3, 0, hollow, 1.f, split);
- break;
- case LL_PCODE_HOLE_CIRCLE:
- case LL_PCODE_HOLE_SAME:
- default:
- addHole(params, FALSE, circle_detail, 0, hollow, 1.f);
- break;
- }
- }
- }
- break;
- case LL_PCODE_PROFILE_CIRCLE_HALF:
- {
- // If this has a square hollow, we should adjust the
- // number of faces a bit so that the geometry lines up.
- U8 hole_type=0;
- // Number of faces is cut in half because it's only a half-circle.
- F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
- if (hollow)
- {
- hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
- if (hole_type == LL_PCODE_HOLE_SQUARE)
- {
- // Snap to the next multiple of four sides (div 2),
- // so that corners line up.
- circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
- }
- }
- genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
- if (path_open)
- {
- addCap(LL_FACE_PATH_BEGIN);
- }
- if (mOpen && !params.getHollow())
- {
- addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE);
- }
- else
- {
- addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE);
- }
-
- if (hollow)
- {
- switch (hole_type)
- {
- case LL_PCODE_HOLE_SQUARE:
- addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split);
- break;
- case LL_PCODE_HOLE_TRIANGLE:
- addHole(params, TRUE, 3, 0.5f, hollow, 0.5f, split);
- break;
- case LL_PCODE_HOLE_CIRCLE:
- case LL_PCODE_HOLE_SAME:
- default:
- addHole(params, FALSE, circle_detail, 0.5f, hollow, 0.5f);
- break;
- }
- }
-
- // Special case for openness of sphere
- if ((params.getEnd() - params.getBegin()) < 1.f)
- {
- mOpen = TRUE;
- }
- else if (!hollow)
- {
- mOpen = FALSE;
- mProfile.push_back(mProfile[0]);
- mTotal++;
- }
- }
- break;
- default:
- LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL;
- break;
- };
-
- if (path_open)
- {
- addCap(LL_FACE_PATH_END); // bottom
- }
-
- if ( mOpen) // interior edge caps
- {
- addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE);
-
- if (hollow)
- {
- addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE);
- }
- else
- {
- addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE);
- }
- }
-
- return TRUE;
+ BOOL is_sculpted, S32 sculpt_size)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ if ((!mDirty) && (!is_sculpted))
+ {
+ return FALSE;
+ }
+ mDirty = FALSE;
+
+ if (detail < MIN_LOD)
+ {
+ LL_INFOS() << "Generating profile with LOD < MIN_LOD. CLAMPING" << LL_ENDL;
+ detail = MIN_LOD;
+ }
+
+ mProfile.resize(0);
+ mFaces.resize(0);
+
+ // Generate the face data
+ S32 i;
+ F32 begin = params.getBegin();
+ F32 end = params.getEnd();
+ F32 hollow = params.getHollow();
+
+ // Quick validation to eliminate some server crashes.
+ if (begin > end - 0.01f)
+ {
+ LL_WARNS() << "LLProfile::generate() assertion failed (begin >= end)" << LL_ENDL;
+ return FALSE;
+ }
+
+ S32 face_num = 0;
+
+ switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
+ {
+ case LL_PCODE_PROFILE_SQUARE:
+ {
+ genNGon(params, 4,-0.375, 0, 1, split);
+ if (path_open)
+ {
+ addCap (LL_FACE_PATH_BEGIN);
+ }
+
+ for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++)
+ {
+ addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);
+ }
+
+ LLVector4a scale(1,1,4,1);
+
+ for (i = 0; i <(S32) mProfile.size(); i++)
+ {
+ // Scale by 4 to generate proper tex coords.
+ mProfile[i].mul(scale);
+ llassert(mProfile[i].isFinite3());
+ }
+
+ if (hollow)
+ {
+ switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
+ {
+ case LL_PCODE_HOLE_TRIANGLE:
+ // This offset is not correct, but we can't change it now... DK 11/17/04
+ addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split);
+ break;
+ case LL_PCODE_HOLE_CIRCLE:
+ // TODO: Compute actual detail levels for cubes
+ addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f);
+ break;
+ case LL_PCODE_HOLE_SAME:
+ case LL_PCODE_HOLE_SQUARE:
+ default:
+ addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split);
+ break;
+ }
+ }
+
+ if (path_open) {
+ mFaces[0].mCount = mTotal;
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_ISOTRI:
+ case LL_PCODE_PROFILE_RIGHTTRI:
+ case LL_PCODE_PROFILE_EQUALTRI:
+ {
+ genNGon(params, 3,0, 0, 1, split);
+ LLVector4a scale(1,1,3,1);
+ for (i = 0; i <(S32) mProfile.size(); i++)
+ {
+ // Scale by 3 to generate proper tex coords.
+ mProfile[i].mul(scale);
+ llassert(mProfile[i].isFinite3());
+ }
+
+ if (path_open)
+ {
+ addCap(LL_FACE_PATH_BEGIN);
+ }
+
+ for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++)
+ {
+ addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);
+ }
+ if (hollow)
+ {
+ // Swept triangles need smaller hollowness values,
+ // because the triangle doesn't fill the bounding box.
+ F32 triangle_hollow = hollow / 2.f;
+
+ switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
+ {
+ case LL_PCODE_HOLE_CIRCLE:
+ // TODO: Actually generate level of detail for triangles
+ addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f);
+ break;
+ case LL_PCODE_HOLE_SQUARE:
+ addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split);
+ break;
+ case LL_PCODE_HOLE_SAME:
+ case LL_PCODE_HOLE_TRIANGLE:
+ default:
+ addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split);
+ break;
+ }
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_CIRCLE:
+ {
+ // If this has a square hollow, we should adjust the
+ // number of faces a bit so that the geometry lines up.
+ U8 hole_type=0;
+ F32 circle_detail = MIN_DETAIL_FACES * detail;
+ if (hollow)
+ {
+ hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
+ if (hole_type == LL_PCODE_HOLE_SQUARE)
+ {
+ // Snap to the next multiple of four sides,
+ // so that corners line up.
+ circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
+ }
+ }
+
+ S32 sides = (S32)circle_detail;
+
+ if (is_sculpted)
+ sides = sculpt_size;
+
+ genNGon(params, sides);
+
+ if (path_open)
+ {
+ addCap (LL_FACE_PATH_BEGIN);
+ }
+
+ if (mOpen && !hollow)
+ {
+ addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE);
+ }
+ else
+ {
+ addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE);
+ }
+
+ if (hollow)
+ {
+ switch (hole_type)
+ {
+ case LL_PCODE_HOLE_SQUARE:
+ addHole(params, TRUE, 4, 0, hollow, 1.f, split);
+ break;
+ case LL_PCODE_HOLE_TRIANGLE:
+ addHole(params, TRUE, 3, 0, hollow, 1.f, split);
+ break;
+ case LL_PCODE_HOLE_CIRCLE:
+ case LL_PCODE_HOLE_SAME:
+ default:
+ addHole(params, FALSE, circle_detail, 0, hollow, 1.f);
+ break;
+ }
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_CIRCLE_HALF:
+ {
+ // If this has a square hollow, we should adjust the
+ // number of faces a bit so that the geometry lines up.
+ U8 hole_type=0;
+ // Number of faces is cut in half because it's only a half-circle.
+ F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
+ if (hollow)
+ {
+ hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
+ if (hole_type == LL_PCODE_HOLE_SQUARE)
+ {
+ // Snap to the next multiple of four sides (div 2),
+ // so that corners line up.
+ circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
+ }
+ }
+ genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
+ if (path_open)
+ {
+ addCap(LL_FACE_PATH_BEGIN);
+ }
+ if (mOpen && !params.getHollow())
+ {
+ addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE);
+ }
+ else
+ {
+ addFace(0,mTotal,0,LL_FACE_OUTER_SIDE_0, FALSE);
+ }
+
+ if (hollow)
+ {
+ switch (hole_type)
+ {
+ case LL_PCODE_HOLE_SQUARE:
+ addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split);
+ break;
+ case LL_PCODE_HOLE_TRIANGLE:
+ addHole(params, TRUE, 3, 0.5f, hollow, 0.5f, split);
+ break;
+ case LL_PCODE_HOLE_CIRCLE:
+ case LL_PCODE_HOLE_SAME:
+ default:
+ addHole(params, FALSE, circle_detail, 0.5f, hollow, 0.5f);
+ break;
+ }
+ }
+
+ // Special case for openness of sphere
+ if ((params.getEnd() - params.getBegin()) < 1.f)
+ {
+ mOpen = TRUE;
+ }
+ else if (!hollow)
+ {
+ mOpen = FALSE;
+ mProfile.push_back(mProfile[0]);
+ mTotal++;
+ }
+ }
+ break;
+ default:
+ LL_ERRS() << "Unknown profile: getCurveType()=" << params.getCurveType() << LL_ENDL;
+ break;
+ };
+
+ if (path_open)
+ {
+ addCap(LL_FACE_PATH_END); // bottom
+ }
+
+ if ( mOpen) // interior edge caps
+ {
+ addFace(mTotal-1, 2,0.5,LL_FACE_PROFILE_BEGIN, TRUE);
+
+ if (hollow)
+ {
+ addFace(mTotalOut-1, 2,0.5,LL_FACE_PROFILE_END, TRUE);
+ }
+ else
+ {
+ addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE);
+ }
+ }
+
+ return TRUE;
}
BOOL LLProfileParams::importFile(LLFILE *fp)
{
- const S32 BUFSIZE = 16384;
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- // *NOTE: changing the size or type of these buffers will require
- // changing the sscanf below.
- char keyword[256]; /* Flawfinder: ignore */
- char valuestr[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
- valuestr[0] = 0;
- F32 tempF32;
- U32 tempU32;
-
- while (!feof(fp))
- {
- if (fgets(buffer, BUFSIZE, fp) == NULL)
- {
- buffer[0] = '\0';
- }
-
- sscanf( /* Flawfinder: ignore */
- buffer,
- " %255s %255s",
- keyword, valuestr);
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("curve", keyword))
- {
- sscanf(valuestr,"%d",&tempU32);
- setCurveType((U8) tempU32);
- }
- else if (!strcmp("begin",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setBegin(tempF32);
- }
- else if (!strcmp("end",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setEnd(tempF32);
- }
- else if (!strcmp("hollow",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setHollow(tempF32);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL;
- }
- }
-
- return TRUE;
+ const S32 BUFSIZE = 16384;
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ // *NOTE: changing the size or type of these buffers will require
+ // changing the sscanf below.
+ char keyword[256]; /* Flawfinder: ignore */
+ char valuestr[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+ valuestr[0] = 0;
+ F32 tempF32;
+ U32 tempU32;
+
+ while (!feof(fp))
+ {
+ if (fgets(buffer, BUFSIZE, fp) == NULL)
+ {
+ buffer[0] = '\0';
+ }
+
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %255s %255s",
+ keyword, valuestr);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("curve", keyword))
+ {
+ sscanf(valuestr,"%d",&tempU32);
+ setCurveType((U8) tempU32);
+ }
+ else if (!strcmp("begin",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setBegin(tempF32);
+ }
+ else if (!strcmp("end",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setEnd(tempF32);
+ }
+ else if (!strcmp("hollow",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setHollow(tempF32);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL;
+ }
+ }
+
+ return TRUE;
}
BOOL LLProfileParams::exportFile(LLFILE *fp) const
{
- fprintf(fp,"\t\tprofile 0\n");
- fprintf(fp,"\t\t{\n");
- fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType());
- fprintf(fp,"\t\t\tbegin\t%g\n", getBegin());
- fprintf(fp,"\t\t\tend\t%g\n", getEnd());
- fprintf(fp,"\t\t\thollow\t%g\n", getHollow());
- fprintf(fp, "\t\t}\n");
- return TRUE;
+ fprintf(fp,"\t\tprofile 0\n");
+ fprintf(fp,"\t\t{\n");
+ fprintf(fp,"\t\t\tcurve\t%d\n", getCurveType());
+ fprintf(fp,"\t\t\tbegin\t%g\n", getBegin());
+ fprintf(fp,"\t\t\tend\t%g\n", getEnd());
+ fprintf(fp,"\t\t\thollow\t%g\n", getHollow());
+ fprintf(fp, "\t\t}\n");
+ return TRUE;
}
BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
{
- const S32 BUFSIZE = 16384;
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- // *NOTE: changing the size or type of these buffers will require
- // changing the sscanf below.
- char keyword[256]; /* Flawfinder: ignore */
- char valuestr[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
- valuestr[0] = 0;
- F32 tempF32;
- U32 tempU32;
-
- while (input_stream.good())
- {
- input_stream.getline(buffer, BUFSIZE);
- sscanf( /* Flawfinder: ignore */
- buffer,
- " %255s %255s",
- keyword,
- valuestr);
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("curve", keyword))
- {
- sscanf(valuestr,"%d",&tempU32);
- setCurveType((U8) tempU32);
- }
- else if (!strcmp("begin",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setBegin(tempF32);
- }
- else if (!strcmp("end",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setEnd(tempF32);
- }
- else if (!strcmp("hollow",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setHollow(tempF32);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL;
- }
- }
-
- return TRUE;
+ const S32 BUFSIZE = 16384;
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ // *NOTE: changing the size or type of these buffers will require
+ // changing the sscanf below.
+ char keyword[256]; /* Flawfinder: ignore */
+ char valuestr[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+ valuestr[0] = 0;
+ F32 tempF32;
+ U32 tempU32;
+
+ while (input_stream.good())
+ {
+ input_stream.getline(buffer, BUFSIZE);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %255s %255s",
+ keyword,
+ valuestr);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("curve", keyword))
+ {
+ sscanf(valuestr,"%d",&tempU32);
+ setCurveType((U8) tempU32);
+ }
+ else if (!strcmp("begin",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setBegin(tempF32);
+ }
+ else if (!strcmp("end",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setEnd(tempF32);
+ }
+ else if (!strcmp("hollow",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setHollow(tempF32);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << keyword << " in profile import" << LL_ENDL;
+ }
+ }
+
+ return TRUE;
}
BOOL LLProfileParams::exportLegacyStream(std::ostream& output_stream) const
{
- output_stream <<"\t\tprofile 0\n";
- output_stream <<"\t\t{\n";
- output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n";
- output_stream <<"\t\t\tbegin\t" << getBegin() << "\n";
- output_stream <<"\t\t\tend\t" << getEnd() << "\n";
- output_stream <<"\t\t\thollow\t" << getHollow() << "\n";
- output_stream << "\t\t}\n";
- return TRUE;
+ output_stream <<"\t\tprofile 0\n";
+ output_stream <<"\t\t{\n";
+ output_stream <<"\t\t\tcurve\t" << (S32) getCurveType() << "\n";
+ output_stream <<"\t\t\tbegin\t" << getBegin() << "\n";
+ output_stream <<"\t\t\tend\t" << getEnd() << "\n";
+ output_stream <<"\t\t\thollow\t" << getHollow() << "\n";
+ output_stream << "\t\t}\n";
+ return TRUE;
}
LLSD LLProfileParams::asLLSD() const
{
- LLSD sd;
+ LLSD sd;
- sd["curve"] = getCurveType();
- sd["begin"] = getBegin();
- sd["end"] = getEnd();
- sd["hollow"] = getHollow();
- return sd;
+ sd["curve"] = getCurveType();
+ sd["begin"] = getBegin();
+ sd["end"] = getEnd();
+ sd["hollow"] = getHollow();
+ return sd;
}
bool LLProfileParams::fromLLSD(LLSD& sd)
{
- setCurveType(sd["curve"].asInteger());
- setBegin((F32)sd["begin"].asReal());
- setEnd((F32)sd["end"].asReal());
- setHollow((F32)sd["hollow"].asReal());
- return true;
+ setCurveType(sd["curve"].asInteger());
+ setBegin((F32)sd["begin"].asReal());
+ setEnd((F32)sd["end"].asReal());
+ setHollow((F32)sd["hollow"].asReal());
+ return true;
}
void LLProfileParams::copyParams(const LLProfileParams &params)
{
- setCurveType(params.getCurveType());
- setBegin(params.getBegin());
- setEnd(params.getEnd());
- setHollow(params.getHollow());
+ setCurveType(params.getCurveType());
+ setBegin(params.getBegin());
+ setEnd(params.getEnd());
+ setHollow(params.getHollow());
}
@@ -1285,760 +1213,760 @@ LLPath::~LLPath()
S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added
- S32 ret = 0;
+ S32 ret = 0;
- F32 step= 1.0f / sides;
- F32 t = params.getBegin();
- ret = 1;
+ F32 step= 1.0f / sides;
+ F32 t = params.getBegin();
+ ret = 1;
+
+ t+=step;
- t+=step;
+ // Snap to a quantized parameter, so that cut does not
+ // affect most sample points.
+ t = ((S32)(t * sides)) / (F32)sides;
- // Snap to a quantized parameter, so that cut does not
- // affect most sample points.
- t = ((S32)(t * sides)) / (F32)sides;
+ // Run through the non-cut dependent points.
+ while (t < params.getEnd())
+ {
+ ret++;
+ t+=step;
+ }
- // Run through the non-cut dependent points.
- while (t < params.getEnd())
- {
- ret++;
- t+=step;
- }
-
- ret++;
+ ret++;
- return ret;
+ return ret;
}
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
- static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
-
- F32 revolutions = params.getRevolutions();
- F32 skew = params.getSkew();
- F32 skew_mag = fabs(skew);
- F32 hole_x = params.getScaleX() * (1.0f - skew_mag);
- F32 hole_y = params.getScaleY();
-
- // Calculate taper begin/end for x,y (Negative means taper the beginning)
- F32 taper_x_begin = 1.0f;
- F32 taper_x_end = 1.0f - params.getTaperX();
- F32 taper_y_begin = 1.0f;
- F32 taper_y_end = 1.0f - params.getTaperY();
-
- if ( taper_x_end > 1.0f )
- {
- // Flip tapering.
- taper_x_begin = 2.0f - taper_x_end;
- taper_x_end = 1.0f;
- }
- if ( taper_y_end > 1.0f )
- {
- // Flip tapering.
- taper_y_begin = 2.0f - taper_y_end;
- taper_y_end = 1.0f;
- }
-
- // For spheres, the radius is usually zero.
- F32 radius_start = 0.5f;
- if (sides < 8)
- {
- radius_start = tableScale[sides];
- }
-
- // Scale the radius to take the hole size into account.
- radius_start *= 1.0f - hole_y;
-
- // Now check the radius offset to calculate the start,end radius. (Negative means
- // decrease the start radius instead).
- F32 radius_end = radius_start;
- F32 radius_offset = params.getRadiusOffset();
- if (radius_offset < 0.f)
- {
- radius_start *= 1.f + radius_offset;
- }
- else
- {
- radius_end *= 1.f - radius_offset;
- }
-
- // Is the path NOT a closed loop?
- mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) ||
- (skew_mag > 0.001f) ||
- (fabs(taper_x_end - taper_x_begin) > 0.001f) ||
- (fabs(taper_y_end - taper_y_begin) > 0.001f) ||
- (fabs(radius_end - radius_start) > 0.001f) );
-
- F32 ang, c, s;
- LLQuaternion twist, qang;
- PathPt *pt;
- LLVector3 path_axis (1.f, 0.f, 0.f);
- //LLVector3 twist_axis(0.f, 0.f, 1.f);
- F32 twist_begin = params.getTwistBegin() * twist_scale;
- F32 twist_end = params.getTwist() * twist_scale;
-
- // We run through this once before the main loop, to make sure
- // the path begins at the correct cut.
- F32 step= 1.0f / sides;
- F32 t = params.getBegin();
- pt = mPath.append(1);
- ang = 2.0f*F_PI*revolutions * t;
- s = sin(ang)*lerp(radius_start, radius_end, t);
- c = cos(ang)*lerp(radius_start, radius_end, t);
-
-
- pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
- + lerp(-skew ,skew, t) * 0.5f,
- c + lerp(0,params.getShear().mV[1],s),
- s);
- pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
- hole_y * lerp(taper_y_begin, taper_y_end, t),
- 0,1);
- pt->mTexT = t;
-
- // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
- twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
- // Rotate the point around the circle's center.
- qang.setQuat (ang,path_axis);
-
- LLMatrix3 rot(twist * qang);
-
- pt->mRot.loadu(rot);
-
- t+=step;
-
- // Snap to a quantized parameter, so that cut does not
- // affect most sample points.
- t = ((S32)(t * sides)) / (F32)sides;
-
- // Run through the non-cut dependent points.
- while (t < params.getEnd())
- {
- pt = mPath.append(1);
-
- ang = 2.0f*F_PI*revolutions * t;
- c = cos(ang)*lerp(radius_start, radius_end, t);
- s = sin(ang)*lerp(radius_start, radius_end, t);
-
- pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
- + lerp(-skew ,skew, t) * 0.5f,
- c + lerp(0,params.getShear().mV[1],s),
- s);
-
- pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
- hole_y * lerp(taper_y_begin, taper_y_end, t),
- 0,1);
- pt->mTexT = t;
-
- // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
- twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
- // Rotate the point around the circle's center.
- qang.setQuat (ang,path_axis);
- LLMatrix3 tmp(twist*qang);
- pt->mRot.loadu(tmp);
-
- t+=step;
- }
-
- // Make one final pass for the end cut.
- t = params.getEnd();
- pt = mPath.append(1);
- ang = 2.0f*F_PI*revolutions * t;
- c = cos(ang)*lerp(radius_start, radius_end, t);
- s = sin(ang)*lerp(radius_start, radius_end, t);
-
- pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
- + lerp(-skew ,skew, t) * 0.5f,
- c + lerp(0,params.getShear().mV[1],s),
- s);
- pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
- hole_y * lerp(taper_y_begin, taper_y_end, t),
- 0,1);
- pt->mTexT = t;
-
- // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
- twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
- // Rotate the point around the circle's center.
- qang.setQuat (ang,path_axis);
- LLMatrix3 tmp(twist*qang);
- pt->mRot.loadu(tmp);
-
- mTotal = mPath.size();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+
+ F32 revolutions = params.getRevolutions();
+ F32 skew = params.getSkew();
+ F32 skew_mag = fabs(skew);
+ F32 hole_x = params.getScaleX() * (1.0f - skew_mag);
+ F32 hole_y = params.getScaleY();
+
+ // Calculate taper begin/end for x,y (Negative means taper the beginning)
+ F32 taper_x_begin = 1.0f;
+ F32 taper_x_end = 1.0f - params.getTaperX();
+ F32 taper_y_begin = 1.0f;
+ F32 taper_y_end = 1.0f - params.getTaperY();
+
+ if ( taper_x_end > 1.0f )
+ {
+ // Flip tapering.
+ taper_x_begin = 2.0f - taper_x_end;
+ taper_x_end = 1.0f;
+ }
+ if ( taper_y_end > 1.0f )
+ {
+ // Flip tapering.
+ taper_y_begin = 2.0f - taper_y_end;
+ taper_y_end = 1.0f;
+ }
+
+ // For spheres, the radius is usually zero.
+ F32 radius_start = 0.5f;
+ if (sides < 8)
+ {
+ radius_start = tableScale[sides];
+ }
+
+ // Scale the radius to take the hole size into account.
+ radius_start *= 1.0f - hole_y;
+
+ // Now check the radius offset to calculate the start,end radius. (Negative means
+ // decrease the start radius instead).
+ F32 radius_end = radius_start;
+ F32 radius_offset = params.getRadiusOffset();
+ if (radius_offset < 0.f)
+ {
+ radius_start *= 1.f + radius_offset;
+ }
+ else
+ {
+ radius_end *= 1.f - radius_offset;
+ }
+
+ // Is the path NOT a closed loop?
+ mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) ||
+ (skew_mag > 0.001f) ||
+ (fabs(taper_x_end - taper_x_begin) > 0.001f) ||
+ (fabs(taper_y_end - taper_y_begin) > 0.001f) ||
+ (fabs(radius_end - radius_start) > 0.001f) );
+
+ F32 ang, c, s;
+ LLQuaternion twist, qang;
+ PathPt *pt;
+ LLVector3 path_axis (1.f, 0.f, 0.f);
+ //LLVector3 twist_axis(0.f, 0.f, 1.f);
+ F32 twist_begin = params.getTwistBegin() * twist_scale;
+ F32 twist_end = params.getTwist() * twist_scale;
+
+ // We run through this once before the main loop, to make sure
+ // the path begins at the correct cut.
+ F32 step= 1.0f / sides;
+ F32 t = params.getBegin();
+ pt = mPath.append(1);
+ ang = 2.0f*F_PI*revolutions * t;
+ s = sin(ang)*lerp(radius_start, radius_end, t);
+ c = cos(ang)*lerp(radius_start, radius_end, t);
+
+
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ + lerp(-skew ,skew, t) * 0.5f,
+ c + lerp(0,params.getShear().mV[1],s),
+ s);
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
+ pt->mTexT = t;
+
+ // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
+ twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
+ // Rotate the point around the circle's center.
+ qang.setQuat (ang,path_axis);
+
+ LLMatrix3 rot(twist * qang);
+
+ pt->mRot.loadu(rot);
+
+ t+=step;
+
+ // Snap to a quantized parameter, so that cut does not
+ // affect most sample points.
+ t = ((S32)(t * sides)) / (F32)sides;
+
+ // Run through the non-cut dependent points.
+ while (t < params.getEnd())
+ {
+ pt = mPath.append(1);
+
+ ang = 2.0f*F_PI*revolutions * t;
+ c = cos(ang)*lerp(radius_start, radius_end, t);
+ s = sin(ang)*lerp(radius_start, radius_end, t);
+
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ + lerp(-skew ,skew, t) * 0.5f,
+ c + lerp(0,params.getShear().mV[1],s),
+ s);
+
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
+ pt->mTexT = t;
+
+ // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
+ twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
+ // Rotate the point around the circle's center.
+ qang.setQuat (ang,path_axis);
+ LLMatrix3 tmp(twist*qang);
+ pt->mRot.loadu(tmp);
+
+ t+=step;
+ }
+
+ // Make one final pass for the end cut.
+ t = params.getEnd();
+ pt = mPath.append(1);
+ ang = 2.0f*F_PI*revolutions * t;
+ c = cos(ang)*lerp(radius_start, radius_end, t);
+ s = sin(ang)*lerp(radius_start, radius_end, t);
+
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ + lerp(-skew ,skew, t) * 0.5f,
+ c + lerp(0,params.getShear().mV[1],s),
+ s);
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
+ pt->mTexT = t;
+
+ // Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
+ twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
+ // Rotate the point around the circle's center.
+ qang.setQuat (ang,path_axis);
+ LLMatrix3 tmp(twist*qang);
+ pt->mRot.loadu(tmp);
+
+ mTotal = mPath.size();
}
const LLVector2 LLPathParams::getBeginScale() const
{
- LLVector2 begin_scale(1.f, 1.f);
- if (getScaleX() > 1)
- {
- begin_scale.mV[0] = 2-getScaleX();
- }
- if (getScaleY() > 1)
- {
- begin_scale.mV[1] = 2-getScaleY();
- }
- return begin_scale;
+ LLVector2 begin_scale(1.f, 1.f);
+ if (getScaleX() > 1)
+ {
+ begin_scale.mV[0] = 2-getScaleX();
+ }
+ if (getScaleY() > 1)
+ {
+ begin_scale.mV[1] = 2-getScaleY();
+ }
+ return begin_scale;
}
const LLVector2 LLPathParams::getEndScale() const
{
- LLVector2 end_scale(1.f, 1.f);
- if (getScaleX() < 1)
- {
- end_scale.mV[0] = getScaleX();
- }
- if (getScaleY() < 1)
- {
- end_scale.mV[1] = getScaleY();
- }
- return end_scale;
+ LLVector2 end_scale(1.f, 1.f);
+ if (getScaleX() < 1)
+ {
+ end_scale.mV[0] = getScaleX();
+ }
+ if (getScaleY() < 1)
+ {
+ end_scale.mV[1] = getScaleY();
+ }
+ return end_scale;
}
S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points
- if (detail < MIN_LOD)
- {
- detail = MIN_LOD;
- }
+ if (detail < MIN_LOD)
+ {
+ detail = MIN_LOD;
+ }
- S32 np = 2; // hardcode for line
+ S32 np = 2; // hardcode for line
- // Is this 0xf0 mask really necessary? DK 03/02/05
+ // Is this 0xf0 mask really necessary? DK 03/02/05
- switch (params.getCurveType() & 0xf0)
- {
- default:
- case LL_PCODE_PATH_LINE:
- {
- // Take the begin/end twist into account for detail.
- np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
- }
- break;
+ switch (params.getCurveType() & 0xf0)
+ {
+ default:
+ case LL_PCODE_PATH_LINE:
+ {
+ // Take the begin/end twist into account for detail.
+ np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
+ }
+ break;
- case LL_PCODE_PATH_CIRCLE:
- {
- // Increase the detail as the revolutions and twist increase.
- F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
+ case LL_PCODE_PATH_CIRCLE:
+ {
+ // Increase the detail as the revolutions and twist increase.
+ F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
- S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
+ S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
- np = sides;
- }
- break;
+ np = sides;
+ }
+ break;
- case LL_PCODE_PATH_CIRCLE2:
- {
- //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
- np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail));
- }
- break;
+ case LL_PCODE_PATH_CIRCLE2:
+ {
+ //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
+ np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail));
+ }
+ break;
- case LL_PCODE_PATH_TEST:
+ case LL_PCODE_PATH_TEST:
- np = 5;
- break;
- };
+ np = 5;
+ break;
+ };
- return np;
+ return np;
}
BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
- BOOL is_sculpted, S32 sculpt_size)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- if ((!mDirty) && (!is_sculpted))
- {
- return FALSE;
- }
-
- if (detail < MIN_LOD)
- {
- LL_INFOS() << "Generating path with LOD < MIN! Clamping to 1" << LL_ENDL;
- detail = MIN_LOD;
- }
-
- mDirty = FALSE;
- S32 np = 2; // hardcode for line
-
- mPath.resize(0);
- mOpen = TRUE;
-
- // Is this 0xf0 mask really necessary? DK 03/02/05
- switch (params.getCurveType() & 0xf0)
- {
- default:
- case LL_PCODE_PATH_LINE:
- {
- // Take the begin/end twist into account for detail.
- np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
- if (np < split+2)
- {
- np = split+2;
- }
-
- mStep = 1.0f / (np-1);
-
- mPath.resize(np);
-
- LLVector2 start_scale = params.getBeginScale();
- LLVector2 end_scale = params.getEndScale();
-
- for (S32 i=0;i<np;i++)
- {
- F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep);
- mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t),
- lerp(0,params.getShear().mV[1],t),
- t - 0.5f);
- LLQuaternion quat;
- quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
- LLMatrix3 tmp(quat);
- mPath[i].mRot.loadu(tmp);
- mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t),
- lerp(start_scale.mV[1],end_scale.mV[1],t),
- 0,1);
- mPath[i].mTexT = t;
- }
- }
- break;
-
- case LL_PCODE_PATH_CIRCLE:
- {
- // Increase the detail as the revolutions and twist increase.
- F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
-
- S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
-
- if (is_sculpted)
- sides = llmax(sculpt_size, 1);
-
- if (0 < sides)
- genNGon(params, sides);
- }
- break;
-
- case LL_PCODE_PATH_CIRCLE2:
- {
- if (params.getEnd() - params.getBegin() >= 0.99f &&
- params.getScaleX() >= .99f)
- {
- mOpen = FALSE;
- }
-
- //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
- genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
-
- F32 toggle = 0.5f;
- for (S32 i=0;i<(S32)mPath.size();i++)
- {
- mPath[i].mPos.getF32ptr()[0] = toggle;
- if (toggle == 0.5f)
- toggle = -0.5f;
- else
- toggle = 0.5f;
- }
- }
-
- break;
-
- case LL_PCODE_PATH_TEST:
-
- np = 5;
- mStep = 1.0f / (np-1);
-
- mPath.resize(np);
-
- for (S32 i=0;i<np;i++)
- {
- F32 t = (F32)i * mStep;
- mPath[i].mPos.set(0,
- lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
- lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t));
- mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t),
- lerp(1,params.getScale().mV[1],t), 0,1);
- mPath[i].mTexT = t;
- LLQuaternion quat;
- quat.setQuat(F_PI * params.getTwist() * t,1,0,0);
- LLMatrix3 tmp(quat);
- mPath[i].mRot.loadu(tmp);
- }
-
- break;
- };
-
- if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE;
-
- //if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) {
- // mOpen = TRUE;
- //}
-
- return TRUE;
+ BOOL is_sculpted, S32 sculpt_size)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ if ((!mDirty) && (!is_sculpted))
+ {
+ return FALSE;
+ }
+
+ if (detail < MIN_LOD)
+ {
+ LL_INFOS() << "Generating path with LOD < MIN! Clamping to 1" << LL_ENDL;
+ detail = MIN_LOD;
+ }
+
+ mDirty = FALSE;
+ S32 np = 2; // hardcode for line
+
+ mPath.resize(0);
+ mOpen = TRUE;
+
+ // Is this 0xf0 mask really necessary? DK 03/02/05
+ switch (params.getCurveType() & 0xf0)
+ {
+ default:
+ case LL_PCODE_PATH_LINE:
+ {
+ // Take the begin/end twist into account for detail.
+ np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
+ if (np < split+2)
+ {
+ np = split+2;
+ }
+
+ mStep = 1.0f / (np-1);
+
+ mPath.resize(np);
+
+ LLVector2 start_scale = params.getBeginScale();
+ LLVector2 end_scale = params.getEndScale();
+
+ for (S32 i=0;i<np;i++)
+ {
+ F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep);
+ mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t),
+ lerp(0,params.getShear().mV[1],t),
+ t - 0.5f);
+ LLQuaternion quat;
+ quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
+ LLMatrix3 tmp(quat);
+ mPath[i].mRot.loadu(tmp);
+ mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t),
+ lerp(start_scale.mV[1],end_scale.mV[1],t),
+ 0,1);
+ mPath[i].mTexT = t;
+ }
+ }
+ break;
+
+ case LL_PCODE_PATH_CIRCLE:
+ {
+ // Increase the detail as the revolutions and twist increase.
+ F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
+
+ S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
+
+ if (is_sculpted)
+ sides = llmax(sculpt_size, 1);
+
+ if (0 < sides)
+ genNGon(params, sides);
+ }
+ break;
+
+ case LL_PCODE_PATH_CIRCLE2:
+ {
+ if (params.getEnd() - params.getBegin() >= 0.99f &&
+ params.getScaleX() >= .99f)
+ {
+ mOpen = FALSE;
+ }
+
+ //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
+ genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
+
+ F32 toggle = 0.5f;
+ for (S32 i=0;i<(S32)mPath.size();i++)
+ {
+ mPath[i].mPos.getF32ptr()[0] = toggle;
+ if (toggle == 0.5f)
+ toggle = -0.5f;
+ else
+ toggle = 0.5f;
+ }
+ }
+
+ break;
+
+ case LL_PCODE_PATH_TEST:
+
+ np = 5;
+ mStep = 1.0f / (np-1);
+
+ mPath.resize(np);
+
+ for (S32 i=0;i<np;i++)
+ {
+ F32 t = (F32)i * mStep;
+ mPath[i].mPos.set(0,
+ lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
+ lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t));
+ mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t),
+ lerp(1,params.getScale().mV[1],t), 0,1);
+ mPath[i].mTexT = t;
+ LLQuaternion quat;
+ quat.setQuat(F_PI * params.getTwist() * t,1,0,0);
+ LLMatrix3 tmp(quat);
+ mPath[i].mRot.loadu(tmp);
+ }
+
+ break;
+ };
+
+ if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE;
+
+ //if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) {
+ // mOpen = TRUE;
+ //}
+
+ return TRUE;
}
BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split,
- BOOL is_sculpted, S32 sculpt_size)
+ BOOL is_sculpted, S32 sculpt_size)
{
- mOpen = TRUE; // Draw end caps
- if (getPathLength() == 0)
- {
- // Path hasn't been generated yet.
- // Some algorithms later assume at least TWO path points.
- resizePath(2);
- LLQuaternion quat;
- quat.setQuat(0,0,0);
- LLMatrix3 tmp(quat);
-
- for (U32 i = 0; i < 2; i++)
- {
- mPath[i].mPos.set(0, 0, 0);
- mPath[i].mRot.loadu(tmp);
- mPath[i].mScale.set(1, 1, 0, 1);
- mPath[i].mTexT = 0;
- }
- }
+ mOpen = TRUE; // Draw end caps
+ if (getPathLength() == 0)
+ {
+ // Path hasn't been generated yet.
+ // Some algorithms later assume at least TWO path points.
+ resizePath(2);
+ LLQuaternion quat;
+ quat.setQuat(0,0,0);
+ LLMatrix3 tmp(quat);
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mPath[i].mPos.set(0, 0, 0);
+ mPath[i].mRot.loadu(tmp);
+ mPath[i].mScale.set(1, 1, 0, 1);
+ mPath[i].mTexT = 0;
+ }
+ }
- return TRUE;
+ return TRUE;
}
BOOL LLPathParams::importFile(LLFILE *fp)
{
- const S32 BUFSIZE = 16384;
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- // *NOTE: changing the size or type of these buffers will require
- // changing the sscanf below.
- char keyword[256]; /* Flawfinder: ignore */
- char valuestr[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
- valuestr[0] = 0;
-
- F32 tempF32;
- F32 x, y;
- U32 tempU32;
-
- while (!feof(fp))
- {
- if (fgets(buffer, BUFSIZE, fp) == NULL)
- {
- buffer[0] = '\0';
- }
-
- sscanf( /* Flawfinder: ignore */
- buffer,
- " %255s %255s",
- keyword, valuestr);
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("curve", keyword))
- {
- sscanf(valuestr,"%d",&tempU32);
- setCurveType((U8) tempU32);
- }
- else if (!strcmp("begin",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setBegin(tempF32);
- }
- else if (!strcmp("end",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setEnd(tempF32);
- }
- else if (!strcmp("scale",keyword))
- {
- // Legacy for one dimensional scale per path
- sscanf(valuestr,"%g",&tempF32);
- setScale(tempF32, tempF32);
- }
- else if (!strcmp("scale_x", keyword))
- {
- sscanf(valuestr, "%g", &x);
- setScaleX(x);
- }
- else if (!strcmp("scale_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setScaleY(y);
- }
- else if (!strcmp("shear_x", keyword))
- {
- sscanf(valuestr, "%g", &x);
- setShearX(x);
- }
- else if (!strcmp("shear_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setShearY(y);
- }
- else if (!strcmp("twist",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setTwist(tempF32);
- }
- else if (!strcmp("twist_begin", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTwistBegin(y);
- }
- else if (!strcmp("radius_offset", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setRadiusOffset(y);
- }
- else if (!strcmp("taper_x", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTaperX(y);
- }
- else if (!strcmp("taper_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTaperY(y);
- }
- else if (!strcmp("revolutions", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setRevolutions(y);
- }
- else if (!strcmp("skew", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setSkew(y);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL;
- }
- }
- return TRUE;
+ const S32 BUFSIZE = 16384;
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ // *NOTE: changing the size or type of these buffers will require
+ // changing the sscanf below.
+ char keyword[256]; /* Flawfinder: ignore */
+ char valuestr[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+ valuestr[0] = 0;
+
+ F32 tempF32;
+ F32 x, y;
+ U32 tempU32;
+
+ while (!feof(fp))
+ {
+ if (fgets(buffer, BUFSIZE, fp) == NULL)
+ {
+ buffer[0] = '\0';
+ }
+
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %255s %255s",
+ keyword, valuestr);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("curve", keyword))
+ {
+ sscanf(valuestr,"%d",&tempU32);
+ setCurveType((U8) tempU32);
+ }
+ else if (!strcmp("begin",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setBegin(tempF32);
+ }
+ else if (!strcmp("end",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setEnd(tempF32);
+ }
+ else if (!strcmp("scale",keyword))
+ {
+ // Legacy for one dimensional scale per path
+ sscanf(valuestr,"%g",&tempF32);
+ setScale(tempF32, tempF32);
+ }
+ else if (!strcmp("scale_x", keyword))
+ {
+ sscanf(valuestr, "%g", &x);
+ setScaleX(x);
+ }
+ else if (!strcmp("scale_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setScaleY(y);
+ }
+ else if (!strcmp("shear_x", keyword))
+ {
+ sscanf(valuestr, "%g", &x);
+ setShearX(x);
+ }
+ else if (!strcmp("shear_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setShearY(y);
+ }
+ else if (!strcmp("twist",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setTwist(tempF32);
+ }
+ else if (!strcmp("twist_begin", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTwistBegin(y);
+ }
+ else if (!strcmp("radius_offset", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setRadiusOffset(y);
+ }
+ else if (!strcmp("taper_x", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTaperX(y);
+ }
+ else if (!strcmp("taper_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTaperY(y);
+ }
+ else if (!strcmp("revolutions", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setRevolutions(y);
+ }
+ else if (!strcmp("skew", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setSkew(y);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL;
+ }
+ }
+ return TRUE;
}
BOOL LLPathParams::exportFile(LLFILE *fp) const
{
- fprintf(fp, "\t\tpath 0\n");
- fprintf(fp, "\t\t{\n");
- fprintf(fp, "\t\t\tcurve\t%d\n", getCurveType());
- fprintf(fp, "\t\t\tbegin\t%g\n", getBegin());
- fprintf(fp, "\t\t\tend\t%g\n", getEnd());
- fprintf(fp, "\t\t\tscale_x\t%g\n", getScaleX() );
- fprintf(fp, "\t\t\tscale_y\t%g\n", getScaleY() );
- fprintf(fp, "\t\t\tshear_x\t%g\n", getShearX() );
- fprintf(fp, "\t\t\tshear_y\t%g\n", getShearY() );
- fprintf(fp,"\t\t\ttwist\t%g\n", getTwist());
-
- fprintf(fp,"\t\t\ttwist_begin\t%g\n", getTwistBegin());
- fprintf(fp,"\t\t\tradius_offset\t%g\n", getRadiusOffset());
- fprintf(fp,"\t\t\ttaper_x\t%g\n", getTaperX());
- fprintf(fp,"\t\t\ttaper_y\t%g\n", getTaperY());
- fprintf(fp,"\t\t\trevolutions\t%g\n", getRevolutions());
- fprintf(fp,"\t\t\tskew\t%g\n", getSkew());
-
- fprintf(fp, "\t\t}\n");
- return TRUE;
+ fprintf(fp, "\t\tpath 0\n");
+ fprintf(fp, "\t\t{\n");
+ fprintf(fp, "\t\t\tcurve\t%d\n", getCurveType());
+ fprintf(fp, "\t\t\tbegin\t%g\n", getBegin());
+ fprintf(fp, "\t\t\tend\t%g\n", getEnd());
+ fprintf(fp, "\t\t\tscale_x\t%g\n", getScaleX() );
+ fprintf(fp, "\t\t\tscale_y\t%g\n", getScaleY() );
+ fprintf(fp, "\t\t\tshear_x\t%g\n", getShearX() );
+ fprintf(fp, "\t\t\tshear_y\t%g\n", getShearY() );
+ fprintf(fp,"\t\t\ttwist\t%g\n", getTwist());
+
+ fprintf(fp,"\t\t\ttwist_begin\t%g\n", getTwistBegin());
+ fprintf(fp,"\t\t\tradius_offset\t%g\n", getRadiusOffset());
+ fprintf(fp,"\t\t\ttaper_x\t%g\n", getTaperX());
+ fprintf(fp,"\t\t\ttaper_y\t%g\n", getTaperY());
+ fprintf(fp,"\t\t\trevolutions\t%g\n", getRevolutions());
+ fprintf(fp,"\t\t\tskew\t%g\n", getSkew());
+
+ fprintf(fp, "\t\t}\n");
+ return TRUE;
}
BOOL LLPathParams::importLegacyStream(std::istream& input_stream)
{
- const S32 BUFSIZE = 16384;
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- // *NOTE: changing the size or type of these buffers will require
- // changing the sscanf below.
- char keyword[256]; /* Flawfinder: ignore */
- char valuestr[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
- valuestr[0] = 0;
-
- F32 tempF32;
- F32 x, y;
- U32 tempU32;
-
- while (input_stream.good())
- {
- input_stream.getline(buffer, BUFSIZE);
- sscanf( /* Flawfinder: ignore */
- buffer,
- " %255s %255s",
- keyword, valuestr);
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("curve", keyword))
- {
- sscanf(valuestr,"%d",&tempU32);
- setCurveType((U8) tempU32);
- }
- else if (!strcmp("begin",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setBegin(tempF32);
- }
- else if (!strcmp("end",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setEnd(tempF32);
- }
- else if (!strcmp("scale",keyword))
- {
- // Legacy for one dimensional scale per path
- sscanf(valuestr,"%g",&tempF32);
- setScale(tempF32, tempF32);
- }
- else if (!strcmp("scale_x", keyword))
- {
- sscanf(valuestr, "%g", &x);
- setScaleX(x);
- }
- else if (!strcmp("scale_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setScaleY(y);
- }
- else if (!strcmp("shear_x", keyword))
- {
- sscanf(valuestr, "%g", &x);
- setShearX(x);
- }
- else if (!strcmp("shear_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setShearY(y);
- }
- else if (!strcmp("twist",keyword))
- {
- sscanf(valuestr,"%g",&tempF32);
- setTwist(tempF32);
- }
- else if (!strcmp("twist_begin", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTwistBegin(y);
- }
- else if (!strcmp("radius_offset", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setRadiusOffset(y);
- }
- else if (!strcmp("taper_x", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTaperX(y);
- }
- else if (!strcmp("taper_y", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setTaperY(y);
- }
- else if (!strcmp("revolutions", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setRevolutions(y);
- }
- else if (!strcmp("skew", keyword))
- {
- sscanf(valuestr, "%g", &y);
- setSkew(y);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL;
- }
- }
- return TRUE;
+ const S32 BUFSIZE = 16384;
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ // *NOTE: changing the size or type of these buffers will require
+ // changing the sscanf below.
+ char keyword[256]; /* Flawfinder: ignore */
+ char valuestr[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+ valuestr[0] = 0;
+
+ F32 tempF32;
+ F32 x, y;
+ U32 tempU32;
+
+ while (input_stream.good())
+ {
+ input_stream.getline(buffer, BUFSIZE);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %255s %255s",
+ keyword, valuestr);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("curve", keyword))
+ {
+ sscanf(valuestr,"%d",&tempU32);
+ setCurveType((U8) tempU32);
+ }
+ else if (!strcmp("begin",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setBegin(tempF32);
+ }
+ else if (!strcmp("end",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setEnd(tempF32);
+ }
+ else if (!strcmp("scale",keyword))
+ {
+ // Legacy for one dimensional scale per path
+ sscanf(valuestr,"%g",&tempF32);
+ setScale(tempF32, tempF32);
+ }
+ else if (!strcmp("scale_x", keyword))
+ {
+ sscanf(valuestr, "%g", &x);
+ setScaleX(x);
+ }
+ else if (!strcmp("scale_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setScaleY(y);
+ }
+ else if (!strcmp("shear_x", keyword))
+ {
+ sscanf(valuestr, "%g", &x);
+ setShearX(x);
+ }
+ else if (!strcmp("shear_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setShearY(y);
+ }
+ else if (!strcmp("twist",keyword))
+ {
+ sscanf(valuestr,"%g",&tempF32);
+ setTwist(tempF32);
+ }
+ else if (!strcmp("twist_begin", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTwistBegin(y);
+ }
+ else if (!strcmp("radius_offset", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setRadiusOffset(y);
+ }
+ else if (!strcmp("taper_x", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTaperX(y);
+ }
+ else if (!strcmp("taper_y", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setTaperY(y);
+ }
+ else if (!strcmp("revolutions", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setRevolutions(y);
+ }
+ else if (!strcmp("skew", keyword))
+ {
+ sscanf(valuestr, "%g", &y);
+ setSkew(y);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << " in path import" << LL_ENDL;
+ }
+ }
+ return TRUE;
}
BOOL LLPathParams::exportLegacyStream(std::ostream& output_stream) const
{
- output_stream << "\t\tpath 0\n";
- output_stream << "\t\t{\n";
- output_stream << "\t\t\tcurve\t" << (S32) getCurveType() << "\n";
- output_stream << "\t\t\tbegin\t" << getBegin() << "\n";
- output_stream << "\t\t\tend\t" << getEnd() << "\n";
- output_stream << "\t\t\tscale_x\t" << getScaleX() << "\n";
- output_stream << "\t\t\tscale_y\t" << getScaleY() << "\n";
- output_stream << "\t\t\tshear_x\t" << getShearX() << "\n";
- output_stream << "\t\t\tshear_y\t" << getShearY() << "\n";
- output_stream <<"\t\t\ttwist\t" << getTwist() << "\n";
-
- output_stream <<"\t\t\ttwist_begin\t" << getTwistBegin() << "\n";
- output_stream <<"\t\t\tradius_offset\t" << getRadiusOffset() << "\n";
- output_stream <<"\t\t\ttaper_x\t" << getTaperX() << "\n";
- output_stream <<"\t\t\ttaper_y\t" << getTaperY() << "\n";
- output_stream <<"\t\t\trevolutions\t" << getRevolutions() << "\n";
- output_stream <<"\t\t\tskew\t" << getSkew() << "\n";
-
- output_stream << "\t\t}\n";
- return TRUE;
+ output_stream << "\t\tpath 0\n";
+ output_stream << "\t\t{\n";
+ output_stream << "\t\t\tcurve\t" << (S32) getCurveType() << "\n";
+ output_stream << "\t\t\tbegin\t" << getBegin() << "\n";
+ output_stream << "\t\t\tend\t" << getEnd() << "\n";
+ output_stream << "\t\t\tscale_x\t" << getScaleX() << "\n";
+ output_stream << "\t\t\tscale_y\t" << getScaleY() << "\n";
+ output_stream << "\t\t\tshear_x\t" << getShearX() << "\n";
+ output_stream << "\t\t\tshear_y\t" << getShearY() << "\n";
+ output_stream <<"\t\t\ttwist\t" << getTwist() << "\n";
+
+ output_stream <<"\t\t\ttwist_begin\t" << getTwistBegin() << "\n";
+ output_stream <<"\t\t\tradius_offset\t" << getRadiusOffset() << "\n";
+ output_stream <<"\t\t\ttaper_x\t" << getTaperX() << "\n";
+ output_stream <<"\t\t\ttaper_y\t" << getTaperY() << "\n";
+ output_stream <<"\t\t\trevolutions\t" << getRevolutions() << "\n";
+ output_stream <<"\t\t\tskew\t" << getSkew() << "\n";
+
+ output_stream << "\t\t}\n";
+ return TRUE;
}
LLSD LLPathParams::asLLSD() const
{
- LLSD sd = LLSD();
- sd["curve"] = getCurveType();
- sd["begin"] = getBegin();
- sd["end"] = getEnd();
- sd["scale_x"] = getScaleX();
- sd["scale_y"] = getScaleY();
- sd["shear_x"] = getShearX();
- sd["shear_y"] = getShearY();
- sd["twist"] = getTwist();
- sd["twist_begin"] = getTwistBegin();
- sd["radius_offset"] = getRadiusOffset();
- sd["taper_x"] = getTaperX();
- sd["taper_y"] = getTaperY();
- sd["revolutions"] = getRevolutions();
- sd["skew"] = getSkew();
-
- return sd;
+ LLSD sd = LLSD();
+ sd["curve"] = getCurveType();
+ sd["begin"] = getBegin();
+ sd["end"] = getEnd();
+ sd["scale_x"] = getScaleX();
+ sd["scale_y"] = getScaleY();
+ sd["shear_x"] = getShearX();
+ sd["shear_y"] = getShearY();
+ sd["twist"] = getTwist();
+ sd["twist_begin"] = getTwistBegin();
+ sd["radius_offset"] = getRadiusOffset();
+ sd["taper_x"] = getTaperX();
+ sd["taper_y"] = getTaperY();
+ sd["revolutions"] = getRevolutions();
+ sd["skew"] = getSkew();
+
+ return sd;
}
bool LLPathParams::fromLLSD(LLSD& sd)
{
- setCurveType(sd["curve"].asInteger());
- setBegin((F32)sd["begin"].asReal());
- setEnd((F32)sd["end"].asReal());
- setScaleX((F32)sd["scale_x"].asReal());
- setScaleY((F32)sd["scale_y"].asReal());
- setShearX((F32)sd["shear_x"].asReal());
- setShearY((F32)sd["shear_y"].asReal());
- setTwist((F32)sd["twist"].asReal());
- setTwistBegin((F32)sd["twist_begin"].asReal());
- setRadiusOffset((F32)sd["radius_offset"].asReal());
- setTaperX((F32)sd["taper_x"].asReal());
- setTaperY((F32)sd["taper_y"].asReal());
- setRevolutions((F32)sd["revolutions"].asReal());
- setSkew((F32)sd["skew"].asReal());
- return true;
+ setCurveType(sd["curve"].asInteger());
+ setBegin((F32)sd["begin"].asReal());
+ setEnd((F32)sd["end"].asReal());
+ setScaleX((F32)sd["scale_x"].asReal());
+ setScaleY((F32)sd["scale_y"].asReal());
+ setShearX((F32)sd["shear_x"].asReal());
+ setShearY((F32)sd["shear_y"].asReal());
+ setTwist((F32)sd["twist"].asReal());
+ setTwistBegin((F32)sd["twist_begin"].asReal());
+ setRadiusOffset((F32)sd["radius_offset"].asReal());
+ setTaperX((F32)sd["taper_x"].asReal());
+ setTaperY((F32)sd["taper_y"].asReal());
+ setRevolutions((F32)sd["revolutions"].asReal());
+ setSkew((F32)sd["skew"].asReal());
+ return true;
}
void LLPathParams::copyParams(const LLPathParams &params)
{
- setCurveType(params.getCurveType());
- setBegin(params.getBegin());
- setEnd(params.getEnd());
- setScale(params.getScaleX(), params.getScaleY() );
- setShear(params.getShearX(), params.getShearY() );
- setTwist(params.getTwist());
- setTwistBegin(params.getTwistBegin());
- setRadiusOffset(params.getRadiusOffset());
- setTaper( params.getTaperX(), params.getTaperY() );
- setRevolutions(params.getRevolutions());
- setSkew(params.getSkew());
+ setCurveType(params.getCurveType());
+ setBegin(params.getBegin());
+ setEnd(params.getEnd());
+ setScale(params.getScaleX(), params.getScaleY() );
+ setShear(params.getShearX(), params.getShearY() );
+ setTwist(params.getTwist());
+ setTwistBegin(params.getTwistBegin());
+ setRadiusOffset(params.getRadiusOffset());
+ setTaper( params.getTaperX(), params.getTaperY() );
+ setRevolutions(params.getRevolutions());
+ setSkew(params.getSkew());
}
LLProfile::~LLProfile()
@@ -2049,53 +1977,53 @@ LLProfile::~LLProfile()
S32 LLVolume::sNumMeshPoints = 0;
LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face, const BOOL is_unique)
- : mParams(params)
-{
- mUnique = is_unique;
- mFaceMask = 0x0;
- mDetail = detail;
- mSculptLevel = -2;
- mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
- mIsMeshAssetLoaded = false;
+ : mParams(params)
+{
+ mUnique = is_unique;
+ mFaceMask = 0x0;
+ mDetail = detail;
+ mSculptLevel = -2;
+ mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
+ mIsMeshAssetLoaded = false;
mIsMeshAssetUnavaliable = false;
- mLODScaleBias.setVec(1,1,1);
- mHullPoints = NULL;
- mHullIndices = NULL;
- mNumHullPoints = 0;
- mNumHullIndices = 0;
-
- // set defaults
- if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
- {
- mPathp = new LLDynamicPath();
- }
- else
- {
- mPathp = new LLPath();
- }
- mProfilep = new LLProfile();
-
- mGenerateSingleFace = generate_single_face;
-
- generate();
-
- if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
- {
- createVolumeFaces();
- }
+ mLODScaleBias.setVec(1,1,1);
+ mHullPoints = NULL;
+ mHullIndices = NULL;
+ mNumHullPoints = 0;
+ mNumHullIndices = 0;
+
+ // set defaults
+ if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
+ {
+ mPathp = new LLDynamicPath();
+ }
+ else
+ {
+ mPathp = new LLPath();
+ }
+ mProfilep = new LLProfile();
+
+ mGenerateSingleFace = generate_single_face;
+
+ generate();
+
+ if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
+ {
+ createVolumeFaces();
+ }
}
void LLVolume::resizePath(S32 length)
{
- mPathp->resizePath(length);
- mVolumeFaces.clear();
- setDirty();
+ mPathp->resizePath(length);
+ mVolumeFaces.clear();
+ setDirty();
}
void LLVolume::regen()
{
- generate();
- createVolumeFaces();
+ generate();
+ createVolumeFaces();
}
void LLVolume::genTangents(S32 face)
@@ -2107,103 +2035,103 @@ void LLVolume::genTangents(S32 face)
LLVolume::~LLVolume()
{
- sNumMeshPoints -= mMesh.size();
- delete mPathp;
+ sNumMeshPoints -= mMesh.size();
+ delete mPathp;
- delete mProfilep;
+ delete mProfilep;
- mPathp = NULL;
- mProfilep = NULL;
- mVolumeFaces.clear();
+ mPathp = NULL;
+ mProfilep = NULL;
+ mVolumeFaces.clear();
- ll_aligned_free_16(mHullPoints);
- mHullPoints = NULL;
- ll_aligned_free_16(mHullIndices);
- mHullIndices = NULL;
+ ll_aligned_free_16(mHullPoints);
+ mHullPoints = NULL;
+ ll_aligned_free_16(mHullIndices);
+ mHullIndices = NULL;
}
BOOL LLVolume::generate()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- LL_CHECK_MEMORY
- llassert_always(mProfilep);
-
- //Added 10.03.05 Dave Parks
- // Split is a parameter to LLProfile::generate that tesselates edges on the profile
- // to prevent lighting and texture interpolation errors on triangles that are
- // stretched due to twisting or scaling on the path.
- S32 split = (S32) ((mDetail)*0.66f);
-
- if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE &&
- (mParams.getPathParams().getScale().mV[0] != 1.0f ||
- mParams.getPathParams().getScale().mV[1] != 1.0f) &&
- (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE ||
- mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI ||
- mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI ||
- mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI))
- {
- split = 0;
- }
-
- mLODScaleBias.setVec(0.5f, 0.5f, 0.5f);
-
- F32 profile_detail = mDetail;
- F32 path_detail = mDetail;
-
- if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
- {
- U8 path_type = mParams.getPathParams().getCurveType();
- U8 profile_type = mParams.getProfileParams().getCurveType();
- if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
- {
- //cylinders don't care about Z-Axis
- mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
- }
- else if (path_type == LL_PCODE_PATH_CIRCLE)
- {
- mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
- }
- }
-
- BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
- BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
-
- if (regenPath || regenProf )
- {
- S32 sizeS = mPathp->mPath.size();
- S32 sizeT = mProfilep->mProfile.size();
-
- sNumMeshPoints -= mMesh.size();
- mMesh.resize(sizeT * sizeS);
- sNumMeshPoints += mMesh.size();
-
- //generate vertex positions
-
- // Run along the path.
- LLVector4a* dst = mMesh.mArray;
-
- for (S32 s = 0; s < sizeS; ++s)
- {
- F32* scale = mPathp->mPath[s].mScale.getF32ptr();
-
- F32 sc [] =
- { scale[0], 0, 0, 0,
- 0, scale[1], 0, 0,
- 0, 0, scale[2], 0,
- 0, 0, 0, 1 };
-
- LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix);
- LLMatrix4 scale_mat(sc);
-
- scale_mat *= rot;
-
- LLMatrix4a rot_mat;
- rot_mat.loadu(scale_mat);
-
- LLVector4a* profile = mProfilep->mProfile.mArray;
- LLVector4a* end_profile = profile+sizeT;
- LLVector4a offset = mPathp->mPath[s].mPos;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ LL_CHECK_MEMORY
+ llassert_always(mProfilep);
+
+ //Added 10.03.05 Dave Parks
+ // Split is a parameter to LLProfile::generate that tesselates edges on the profile
+ // to prevent lighting and texture interpolation errors on triangles that are
+ // stretched due to twisting or scaling on the path.
+ S32 split = (S32) ((mDetail)*0.66f);
+
+ if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE &&
+ (mParams.getPathParams().getScale().mV[0] != 1.0f ||
+ mParams.getPathParams().getScale().mV[1] != 1.0f) &&
+ (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE ||
+ mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI ||
+ mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI ||
+ mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI))
+ {
+ split = 0;
+ }
+
+ mLODScaleBias.setVec(0.5f, 0.5f, 0.5f);
+
+ F32 profile_detail = mDetail;
+ F32 path_detail = mDetail;
+
+ if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
+ {
+ U8 path_type = mParams.getPathParams().getCurveType();
+ U8 profile_type = mParams.getProfileParams().getCurveType();
+ if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
+ {
+ //cylinders don't care about Z-Axis
+ mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
+ }
+ else if (path_type == LL_PCODE_PATH_CIRCLE)
+ {
+ mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
+ }
+ }
+
+ BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
+ BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
+
+ if (regenPath || regenProf )
+ {
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
+
+ sNumMeshPoints -= mMesh.size();
+ mMesh.resize(sizeT * sizeS);
+ sNumMeshPoints += mMesh.size();
+
+ //generate vertex positions
+
+ // Run along the path.
+ LLVector4a* dst = mMesh.mArray;
+
+ for (S32 s = 0; s < sizeS; ++s)
+ {
+ F32* scale = mPathp->mPath[s].mScale.getF32ptr();
+
+ F32 sc [] =
+ { scale[0], 0, 0, 0,
+ 0, scale[1], 0, 0,
+ 0, 0, scale[2], 0,
+ 0, 0, 0, 1 };
+
+ LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix);
+ LLMatrix4 scale_mat(sc);
+
+ scale_mat *= rot;
+
+ LLMatrix4a rot_mat;
+ rot_mat.loadu(scale_mat);
+
+ LLVector4a* profile = mProfilep->mProfile.mArray;
+ LLVector4a* end_profile = profile+sizeT;
+ LLVector4a offset = mPathp->mPath[s].mPos;
// hack to work around MAINT-5660 for debug until we can suss out
// what is wrong with the path generated that inserts NaNs...
@@ -2212,241 +2140,241 @@ BOOL LLVolume::generate()
offset.clear();
}
- LLVector4a tmp;
+ LLVector4a tmp;
- // Run along the profile.
- while (profile < end_profile)
- {
- rot_mat.rotate(*profile++, tmp);
- dst->setAdd(tmp,offset);
- ++dst;
- }
- }
+ // Run along the profile.
+ while (profile < end_profile)
+ {
+ rot_mat.rotate(*profile++, tmp);
+ dst->setAdd(tmp,offset);
+ ++dst;
+ }
+ }
- for (std::vector<LLProfile::Face>::iterator iter = mProfilep->mFaces.begin();
- iter != mProfilep->mFaces.end(); ++iter)
- {
- LLFaceID id = iter->mFaceID;
- mFaceMask |= id;
- }
- LL_CHECK_MEMORY
- return TRUE;
- }
+ for (std::vector<LLProfile::Face>::iterator iter = mProfilep->mFaces.begin();
+ iter != mProfilep->mFaces.end(); ++iter)
+ {
+ LLFaceID id = iter->mFaceID;
+ mFaceMask |= id;
+ }
+ LL_CHECK_MEMORY
+ return TRUE;
+ }
- LL_CHECK_MEMORY
- return FALSE;
+ LL_CHECK_MEMORY
+ return FALSE;
}
void LLVolumeFace::VertexData::init()
{
- if (!mData)
- {
- mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2);
- }
+ if (!mData)
+ {
+ mData = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*2);
+ }
}
LLVolumeFace::VertexData::VertexData()
{
- mData = NULL;
- init();
+ mData = NULL;
+ init();
}
-
+
LLVolumeFace::VertexData::VertexData(const VertexData& rhs)
{
- mData = NULL;
- *this = rhs;
+ mData = NULL;
+ *this = rhs;
}
const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolumeFace::VertexData& rhs)
{
- if (this != &rhs)
- {
- init();
- LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a));
- mTexCoord = rhs.mTexCoord;
- }
- return *this;
+ if (this != &rhs)
+ {
+ init();
+ LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 2*sizeof(LLVector4a));
+ mTexCoord = rhs.mTexCoord;
+ }
+ return *this;
}
LLVolumeFace::VertexData::~VertexData()
{
- ll_aligned_free_16(mData);
- mData = NULL;
+ ll_aligned_free_16(mData);
+ mData = NULL;
}
LLVector4a& LLVolumeFace::VertexData::getPosition()
{
- return mData[POSITION];
+ return mData[POSITION];
}
LLVector4a& LLVolumeFace::VertexData::getNormal()
{
- return mData[NORMAL];
+ return mData[NORMAL];
}
const LLVector4a& LLVolumeFace::VertexData::getPosition() const
{
- return mData[POSITION];
+ return mData[POSITION];
}
const LLVector4a& LLVolumeFace::VertexData::getNormal() const
{
- return mData[NORMAL];
+ return mData[NORMAL];
}
void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos)
{
- mData[POSITION] = pos;
+ mData[POSITION] = pos;
}
void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm)
{
- mData[NORMAL] = norm;
+ mData[NORMAL] = norm;
}
bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const
{
- const F32* lp = this->getPosition().getF32ptr();
- const F32* rp = rhs.getPosition().getF32ptr();
+ const F32* lp = this->getPosition().getF32ptr();
+ const F32* rp = rhs.getPosition().getF32ptr();
- if (lp[0] != rp[0])
- {
- return lp[0] < rp[0];
- }
+ if (lp[0] != rp[0])
+ {
+ return lp[0] < rp[0];
+ }
- if (rp[1] != lp[1])
- {
- return lp[1] < rp[1];
- }
+ if (rp[1] != lp[1])
+ {
+ return lp[1] < rp[1];
+ }
- if (rp[2] != lp[2])
- {
- return lp[2] < rp[2];
- }
+ if (rp[2] != lp[2])
+ {
+ return lp[2] < rp[2];
+ }
- lp = getNormal().getF32ptr();
- rp = rhs.getNormal().getF32ptr();
+ lp = getNormal().getF32ptr();
+ rp = rhs.getNormal().getF32ptr();
- if (lp[0] != rp[0])
- {
- return lp[0] < rp[0];
- }
+ if (lp[0] != rp[0])
+ {
+ return lp[0] < rp[0];
+ }
- if (rp[1] != lp[1])
- {
- return lp[1] < rp[1];
- }
+ if (rp[1] != lp[1])
+ {
+ return lp[1] < rp[1];
+ }
- if (rp[2] != lp[2])
- {
- return lp[2] < rp[2];
- }
+ if (rp[2] != lp[2])
+ {
+ return lp[2] < rp[2];
+ }
- if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0])
- {
- return mTexCoord.mV[0] < rhs.mTexCoord.mV[0];
- }
+ if (mTexCoord.mV[0] != rhs.mTexCoord.mV[0])
+ {
+ return mTexCoord.mV[0] < rhs.mTexCoord.mV[0];
+ }
- return mTexCoord.mV[1] < rhs.mTexCoord.mV[1];
+ return mTexCoord.mV[1] < rhs.mTexCoord.mV[1];
}
bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)const
{
- return mData[POSITION].equals3(rhs.getPosition()) &&
- mData[NORMAL].equals3(rhs.getNormal()) &&
- mTexCoord == rhs.mTexCoord;
+ return mData[POSITION].equals3(rhs.getPosition()) &&
+ mData[NORMAL].equals3(rhs.getNormal()) &&
+ mTexCoord == rhs.mTexCoord;
}
bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const
{
- bool retval = false;
+ bool retval = false;
- const F32 epsilon = 0.00001f;
+ const F32 epsilon = 0.00001f;
- if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&
- fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon &&
- fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon)
- {
- if (angle_cutoff > 1.f)
- {
- retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon));
- }
- else
- {
- F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32();
- retval = cur_angle > angle_cutoff;
- }
- }
+ if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&
+ fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon &&
+ fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon)
+ {
+ if (angle_cutoff > 1.f)
+ {
+ retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon));
+ }
+ else
+ {
+ F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]).getF32();
+ retval = cur_angle > angle_cutoff;
+ }
+ }
- return retval;
+ return retval;
}
bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- //input stream is now pointing at a zlib compressed block of LLSD
- //decompress block
- LLSD mdl;
- U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size);
- if (uzip_result != LLUZipHelper::ZR_OK)
- {
- LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
- return false;
- }
- return unpackVolumeFacesInternal(mdl);
+ //input stream is now pointing at a zlib compressed block of LLSD
+ //decompress block
+ LLSD mdl;
+ U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size);
+ if (uzip_result != LLUZipHelper::ZR_OK)
+ {
+ LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
+ return false;
+ }
+ return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
{
- //input data is now pointing at a zlib compressed block of LLSD
- //decompress block
- LLSD mdl;
- U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
- if (uzip_result != LLUZipHelper::ZR_OK)
- {
- LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
- return false;
- }
- return unpackVolumeFacesInternal(mdl);
+ //input data is now pointing at a zlib compressed block of LLSD
+ //decompress block
+ LLSD mdl;
+ U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
+ if (uzip_result != LLUZipHelper::ZR_OK)
+ {
+ LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
+ return false;
+ }
+ return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
{
- {
- U32 face_count = mdl.size();
-
- if (face_count == 0)
- { //no faces unpacked, treat as failed decode
- LL_WARNS() << "found no faces!" << LL_ENDL;
- return false;
- }
-
- mVolumeFaces.resize(face_count);
-
- for (size_t i = 0; i < face_count; ++i)
- {
- LLVolumeFace& face = mVolumeFaces[i];
-
- if (mdl[i].has("NoGeometry"))
- { //face has no geometry, continue
- face.resizeIndices(3);
- face.resizeVertices(1);
- face.mPositions->clear();
- face.mNormals->clear();
- face.mTexCoords->setZero();
- memset(face.mIndices, 0, sizeof(U16)*3);
- continue;
- }
-
- LLSD::Binary pos = mdl[i]["Position"];
- LLSD::Binary norm = mdl[i]["Normal"];
+ {
+ U32 face_count = mdl.size();
+
+ if (face_count == 0)
+ { //no faces unpacked, treat as failed decode
+ LL_WARNS() << "found no faces!" << LL_ENDL;
+ return false;
+ }
+
+ mVolumeFaces.resize(face_count);
+
+ for (size_t i = 0; i < face_count; ++i)
+ {
+ LLVolumeFace& face = mVolumeFaces[i];
+
+ if (mdl[i].has("NoGeometry"))
+ { //face has no geometry, continue
+ face.resizeIndices(3);
+ face.resizeVertices(1);
+ face.mPositions->clear();
+ face.mNormals->clear();
+ face.mTexCoords->setZero();
+ memset(face.mIndices, 0, sizeof(U16)*3);
+ continue;
+ }
+
+ LLSD::Binary pos = mdl[i]["Position"];
+ LLSD::Binary norm = mdl[i]["Normal"];
LLSD::Binary tangent = mdl[i]["Tangent"];
- LLSD::Binary tc = mdl[i]["TexCoord0"];
- LLSD::Binary idx = mdl[i]["TriangleList"];
+ LLSD::Binary tc = mdl[i]["TexCoord0"];
+ LLSD::Binary idx = mdl[i]["TriangleList"];
- //copy out indices
+ //copy out indices
S32 num_indices = idx.size() / 2;
const S32 indices_to_discard = num_indices % 3;
if (indices_to_discard > 0)
@@ -2462,22 +2390,22 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL;
continue;
}
-
- if (idx.empty() || face.mNumIndices < 3)
- { //why is there an empty index list?
- LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL;
- continue;
- }
-
- U16* indices = (U16*) &(idx[0]);
+
+ if (idx.empty() || face.mNumIndices < 3)
+ { //why is there an empty index list?
+ LL_WARNS() << "Empty face present! Face index: " << i << " Total: " << face_count << LL_ENDL;
+ continue;
+ }
+
+ U16* indices = (U16*) &(idx[0]);
for (U32 j = 0; j < num_indices; ++j)
- {
- face.mIndices[j] = indices[j];
- }
+ {
+ face.mIndices[j] = indices[j];
+ }
- //copy out vertices
- U32 num_verts = pos.size()/(3*2);
- face.resizeVertices(num_verts);
+ //copy out vertices
+ U32 num_verts = pos.size()/(3*2);
+ face.resizeVertices(num_verts);
if (num_verts > 0 && !face.mPositions)
{
@@ -2486,19 +2414,19 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
continue;
}
- LLVector3 minp;
- LLVector3 maxp;
- LLVector2 min_tc;
- LLVector2 max_tc;
-
- minp.setValue(mdl[i]["PositionDomain"]["Min"]);
- maxp.setValue(mdl[i]["PositionDomain"]["Max"]);
- LLVector4a min_pos, max_pos;
- min_pos.load3(minp.mV);
- max_pos.load3(maxp.mV);
+ LLVector3 minp;
+ LLVector3 maxp;
+ LLVector2 min_tc;
+ LLVector2 max_tc;
+
+ minp.setValue(mdl[i]["PositionDomain"]["Min"]);
+ maxp.setValue(mdl[i]["PositionDomain"]["Max"]);
+ LLVector4a min_pos, max_pos;
+ min_pos.load3(minp.mV);
+ max_pos.load3(maxp.mV);
- min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]);
- max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]);
+ min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]);
+ max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]);
//unpack normalized scale/translation
if (mdl[i].has("NormalizedScale"))
@@ -2509,56 +2437,56 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
{
face.mNormalizedScale.set(1, 1, 1);
}
-
- LLVector4a pos_range;
- pos_range.setSub(max_pos, min_pos);
- LLVector2 tc_range2 = max_tc - min_tc;
-
- LLVector4a tc_range;
- tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);
- LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]);
-
- LLVector4a* pos_out = face.mPositions;
- LLVector4a* norm_out = face.mNormals;
- LLVector4a* tc_out = (LLVector4a*) face.mTexCoords;
-
- {
- U16* v = (U16*) &(pos[0]);
- for (U32 j = 0; j < num_verts; ++j)
- {
- pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]);
- pos_out->div(65535.f);
- pos_out->mul(pos_range);
- pos_out->add(min_pos);
- pos_out++;
- v += 3;
- }
-
- }
-
- {
- if (!norm.empty())
- {
- U16* n = (U16*) &(norm[0]);
- for (U32 j = 0; j < num_verts; ++j)
- {
- norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]);
- norm_out->div(65535.f);
- norm_out->mul(2.f);
- norm_out->sub(1.f);
- norm_out++;
- n += 3;
- }
- }
- else
- {
- for (U32 j = 0; j < num_verts; ++j)
- {
- norm_out->clear();
- norm_out++; // or just norm_out[j].clear();
- }
- }
- }
+
+ LLVector4a pos_range;
+ pos_range.setSub(max_pos, min_pos);
+ LLVector2 tc_range2 = max_tc - min_tc;
+
+ LLVector4a tc_range;
+ tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);
+ LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]);
+
+ LLVector4a* pos_out = face.mPositions;
+ LLVector4a* norm_out = face.mNormals;
+ LLVector4a* tc_out = (LLVector4a*) face.mTexCoords;
+
+ {
+ U16* v = (U16*) &(pos[0]);
+ for (U32 j = 0; j < num_verts; ++j)
+ {
+ pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]);
+ pos_out->div(65535.f);
+ pos_out->mul(pos_range);
+ pos_out->add(min_pos);
+ pos_out++;
+ v += 3;
+ }
+
+ }
+
+ {
+ if (!norm.empty())
+ {
+ U16* n = (U16*) &(norm[0]);
+ for (U32 j = 0; j < num_verts; ++j)
+ {
+ norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]);
+ norm_out->div(65535.f);
+ norm_out->mul(2.f);
+ norm_out->sub(1.f);
+ norm_out++;
+ n += 3;
+ }
+ }
+ else
+ {
+ for (U32 j = 0; j < num_verts; ++j)
+ {
+ norm_out->clear();
+ norm_out++; // or just norm_out[j].clear();
+ }
+ }
+ }
#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
{
@@ -2567,9 +2495,9 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
face.allocateTangents(face.mNumVertices);
U16* t = (U16*)&(tangent[0]);
- // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to
+ // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to
// maintain compliance with the GLTF spec
- LLVector4a* t_out = face.mTangents;
+ LLVector4a* t_out = face.mTangents;
for (U32 j = 0; j < num_verts; ++j)
{
@@ -2588,43 +2516,43 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
}
#endif
- {
- if (!tc.empty())
- {
- U16* t = (U16*) &(tc[0]);
- for (U32 j = 0; j < num_verts; j+=2)
- {
- if (j < num_verts-1)
- {
- tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]);
- }
- else
- {
- tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f);
- }
-
- t += 4;
-
- tc_out->div(65535.f);
- tc_out->mul(tc_range);
- tc_out->add(min_tc4);
-
- tc_out++;
- }
- }
- else
- {
- for (U32 j = 0; j < num_verts; j += 2)
- {
- tc_out->clear();
- tc_out++;
- }
- }
- }
-
- if (mdl[i].has("Weights"))
- {
- face.allocateWeights(num_verts);
+ {
+ if (!tc.empty())
+ {
+ U16* t = (U16*) &(tc[0]);
+ for (U32 j = 0; j < num_verts; j+=2)
+ {
+ if (j < num_verts-1)
+ {
+ tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]);
+ }
+ else
+ {
+ tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f);
+ }
+
+ t += 4;
+
+ tc_out->div(65535.f);
+ tc_out->mul(tc_range);
+ tc_out->add(min_tc4);
+
+ tc_out++;
+ }
+ }
+ else
+ {
+ for (U32 j = 0; j < num_verts; j += 2)
+ {
+ tc_out->clear();
+ tc_out++;
+ }
+ }
+ }
+
+ if (mdl[i].has("Weights"))
+ {
+ face.allocateWeights(num_verts);
if (!face.mWeights && num_verts)
{
LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL;
@@ -2633,40 +2561,40 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
continue;
}
- LLSD::Binary weights = mdl[i]["Weights"];
+ LLSD::Binary weights = mdl[i]["Weights"];
- U32 idx = 0;
+ U32 idx = 0;
- U32 cur_vertex = 0;
- while (idx < weights.size() && cur_vertex < num_verts)
- {
- const U8 END_INFLUENCES = 0xFF;
- U8 joint = weights[idx++];
+ U32 cur_vertex = 0;
+ while (idx < weights.size() && cur_vertex < num_verts)
+ {
+ const U8 END_INFLUENCES = 0xFF;
+ U8 joint = weights[idx++];
- U32 cur_influence = 0;
- LLVector4 wght(0,0,0,0);
+ U32 cur_influence = 0;
+ LLVector4 wght(0,0,0,0);
U32 joints[4] = {0,0,0,0};
- LLVector4 joints_with_weights(0,0,0,0);
-
- while (joint != END_INFLUENCES && idx < weights.size())
- {
- U16 influence = weights[idx++];
- influence |= ((U16) weights[idx++] << 8);
-
- F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f);
- wght.mV[cur_influence] = w;
- joints[cur_influence] = joint;
- cur_influence++;
-
- if (cur_influence >= 4)
- {
- joint = END_INFLUENCES;
- }
- else
- {
- joint = weights[idx++];
- }
- }
+ LLVector4 joints_with_weights(0,0,0,0);
+
+ while (joint != END_INFLUENCES && idx < weights.size())
+ {
+ U16 influence = weights[idx++];
+ influence |= ((U16) weights[idx++] << 8);
+
+ F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f);
+ wght.mV[cur_influence] = w;
+ joints[cur_influence] = joint;
+ cur_influence++;
+
+ if (cur_influence >= 4)
+ {
+ joint = END_INFLUENCES;
+ }
+ else
+ {
+ joint = weights[idx++];
+ }
+ }
F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW];
if (wsum <= 0.f)
{
@@ -2680,139 +2608,139 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
// A failure here would indicate a floating point precision error in the math.
llassert((k >= cur_influence) || (f_combined - S32(f_combined) > 0.0f));
}
- face.mWeights[cur_vertex].loadua(joints_with_weights.mV);
-
- cur_vertex++;
- }
-
- if (cur_vertex != num_verts || idx != weights.size())
- {
- LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL;
- }
-
- }
-
- // modifier flags?
- bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR);
- bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT);
-
-
- // translate to actions:
- bool do_reflect_x = false;
- bool do_reverse_triangles = false;
- bool do_invert_normals = false;
-
- if (do_mirror)
- {
- do_reflect_x = true;
- do_reverse_triangles = !do_reverse_triangles;
- }
-
- if (do_invert)
- {
- do_invert_normals = true;
- do_reverse_triangles = !do_reverse_triangles;
- }
-
- // now do the work
-
- if (do_reflect_x)
- {
- LLVector4a* p = (LLVector4a*) face.mPositions;
- LLVector4a* n = (LLVector4a*) face.mNormals;
-
- for (S32 i = 0; i < face.mNumVertices; i++)
- {
- p[i].mul(-1.0f);
- n[i].mul(-1.0f);
- }
- }
-
- if (do_invert_normals)
- {
- LLVector4a* n = (LLVector4a*) face.mNormals;
-
- for (S32 i = 0; i < face.mNumVertices; i++)
- {
- n[i].mul(-1.0f);
- }
- }
-
- if (do_reverse_triangles)
- {
- for (U32 j = 0; j < face.mNumIndices; j += 3)
- {
- // swap the 2nd and 3rd index
- S32 swap = face.mIndices[j+1];
- face.mIndices[j+1] = face.mIndices[j+2];
- face.mIndices[j+2] = swap;
- }
- }
-
- //calculate bounding box
- // VFExtents change
- LLVector4a& min = face.mExtents[0];
- LLVector4a& max = face.mExtents[1];
-
- if (face.mNumVertices < 3)
- { //empty face, use a dummy 1cm (at 1m scale) bounding box
- min.splat(-0.005f);
- max.splat(0.005f);
- }
- else
- {
- min = max = face.mPositions[0];
-
- for (S32 i = 1; i < face.mNumVertices; ++i)
- {
- min.setMin(min, face.mPositions[i]);
- max.setMax(max, face.mPositions[i]);
- }
-
- if (face.mTexCoords)
- {
- LLVector2& min_tc = face.mTexCoordExtents[0];
- LLVector2& max_tc = face.mTexCoordExtents[1];
-
- min_tc = face.mTexCoords[0];
- max_tc = face.mTexCoords[0];
-
- for (U32 j = 1; j < face.mNumVertices; ++j)
- {
- update_min_max(min_tc, max_tc, face.mTexCoords[j]);
- }
- }
- else
- {
- face.mTexCoordExtents[0].set(0,0);
- face.mTexCoordExtents[1].set(1,1);
- }
- }
- }
- }
-
- if (!cacheOptimize(true))
- {
- // Out of memory?
- LL_WARNS() << "Failed to optimize!" << LL_ENDL;
- mVolumeFaces.clear();
- return false;
- }
-
- mSculptLevel = 0; // success!
-
- return true;
+ face.mWeights[cur_vertex].loadua(joints_with_weights.mV);
+
+ cur_vertex++;
+ }
+
+ if (cur_vertex != num_verts || idx != weights.size())
+ {
+ LL_WARNS() << "Vertex weight count does not match vertex count!" << LL_ENDL;
+ }
+
+ }
+
+ // modifier flags?
+ bool do_mirror = (mParams.getSculptType() & LL_SCULPT_FLAG_MIRROR);
+ bool do_invert = (mParams.getSculptType() &LL_SCULPT_FLAG_INVERT);
+
+
+ // translate to actions:
+ bool do_reflect_x = false;
+ bool do_reverse_triangles = false;
+ bool do_invert_normals = false;
+
+ if (do_mirror)
+ {
+ do_reflect_x = true;
+ do_reverse_triangles = !do_reverse_triangles;
+ }
+
+ if (do_invert)
+ {
+ do_invert_normals = true;
+ do_reverse_triangles = !do_reverse_triangles;
+ }
+
+ // now do the work
+
+ if (do_reflect_x)
+ {
+ LLVector4a* p = (LLVector4a*) face.mPositions;
+ LLVector4a* n = (LLVector4a*) face.mNormals;
+
+ for (S32 i = 0; i < face.mNumVertices; i++)
+ {
+ p[i].mul(-1.0f);
+ n[i].mul(-1.0f);
+ }
+ }
+
+ if (do_invert_normals)
+ {
+ LLVector4a* n = (LLVector4a*) face.mNormals;
+
+ for (S32 i = 0; i < face.mNumVertices; i++)
+ {
+ n[i].mul(-1.0f);
+ }
+ }
+
+ if (do_reverse_triangles)
+ {
+ for (U32 j = 0; j < face.mNumIndices; j += 3)
+ {
+ // swap the 2nd and 3rd index
+ S32 swap = face.mIndices[j+1];
+ face.mIndices[j+1] = face.mIndices[j+2];
+ face.mIndices[j+2] = swap;
+ }
+ }
+
+ //calculate bounding box
+ // VFExtents change
+ LLVector4a& min = face.mExtents[0];
+ LLVector4a& max = face.mExtents[1];
+
+ if (face.mNumVertices < 3)
+ { //empty face, use a dummy 1cm (at 1m scale) bounding box
+ min.splat(-0.005f);
+ max.splat(0.005f);
+ }
+ else
+ {
+ min = max = face.mPositions[0];
+
+ for (S32 i = 1; i < face.mNumVertices; ++i)
+ {
+ min.setMin(min, face.mPositions[i]);
+ max.setMax(max, face.mPositions[i]);
+ }
+
+ if (face.mTexCoords)
+ {
+ LLVector2& min_tc = face.mTexCoordExtents[0];
+ LLVector2& max_tc = face.mTexCoordExtents[1];
+
+ min_tc = face.mTexCoords[0];
+ max_tc = face.mTexCoords[0];
+
+ for (U32 j = 1; j < face.mNumVertices; ++j)
+ {
+ update_min_max(min_tc, max_tc, face.mTexCoords[j]);
+ }
+ }
+ else
+ {
+ face.mTexCoordExtents[0].set(0,0);
+ face.mTexCoordExtents[1].set(1,1);
+ }
+ }
+ }
+ }
+
+ if (!cacheOptimize(true))
+ {
+ // Out of memory?
+ LL_WARNS() << "Failed to optimize!" << LL_ENDL;
+ mVolumeFaces.clear();
+ return false;
+ }
+
+ mSculptLevel = 0; // success!
+
+ return true;
}
bool LLVolume::isMeshAssetLoaded()
{
- return mIsMeshAssetLoaded;
+ return mIsMeshAssetLoaded;
}
void LLVolume::setMeshAssetLoaded(bool loaded)
{
- mIsMeshAssetLoaded = loaded;
+ mIsMeshAssetLoaded = loaded;
if (loaded)
{
mIsMeshAssetUnavaliable = false;
@@ -2833,375 +2761,375 @@ bool LLVolume::isMeshAssetUnavaliable()
return mIsMeshAssetUnavaliable;
}
-void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const
+void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const
{
- faces = mVolumeFaces;
+ faces = mVolumeFaces;
}
void LLVolume::copyFacesFrom(const std::vector<LLVolumeFace> &faces)
{
- mVolumeFaces = faces;
- mSculptLevel = 0;
+ mVolumeFaces = faces;
+ mSculptLevel = 0;
}
void LLVolume::copyVolumeFaces(const LLVolume* volume)
{
- mVolumeFaces = volume->mVolumeFaces;
- mSculptLevel = 0;
+ mVolumeFaces = volume->mVolumeFaces;
+ mSculptLevel = 0;
}
bool LLVolume::cacheOptimize(bool gen_tangents)
{
- for (S32 i = 0; i < mVolumeFaces.size(); ++i)
- {
- if (!mVolumeFaces[i].cacheOptimize(gen_tangents))
- {
- return false;
- }
- }
- return true;
+ for (S32 i = 0; i < mVolumeFaces.size(); ++i)
+ {
+ if (!mVolumeFaces[i].cacheOptimize(gen_tangents))
+ {
+ return false;
+ }
+ }
+ return true;
}
-S32 LLVolume::getNumFaces() const
+S32 LLVolume::getNumFaces() const
{
- return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size();
+ return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size();
}
void LLVolume::createVolumeFaces()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- if (mGenerateSingleFace)
- {
- // do nothing
- }
- else
- {
- S32 num_faces = getNumFaces();
- BOOL partial_build = TRUE;
- if (num_faces != mVolumeFaces.size())
- {
- partial_build = FALSE;
- mVolumeFaces.resize(num_faces);
- }
- // Initialize volume faces with parameter data
- for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++)
- {
- LLVolumeFace& vf = mVolumeFaces[i];
- LLProfile::Face& face = mProfilep->mFaces[i];
- vf.mBeginS = face.mIndex;
- vf.mNumS = face.mCount;
- if (vf.mNumS < 0)
- {
- LL_ERRS() << "Volume face corruption detected." << LL_ENDL;
- }
-
- vf.mBeginT = 0;
- vf.mNumT= getPath().mPath.size();
- vf.mID = i;
-
- // Set the type mask bits correctly
- if (mParams.getProfileParams().getHollow() > 0)
- {
- vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK;
- }
- if (mProfilep->isOpen())
- {
- vf.mTypeMask |= LLVolumeFace::OPEN_MASK;
- }
- if (face.mCap)
- {
- vf.mTypeMask |= LLVolumeFace::CAP_MASK;
- if (face.mFaceID == LL_FACE_PATH_BEGIN)
- {
- vf.mTypeMask |= LLVolumeFace::TOP_MASK;
- }
- else
- {
- llassert(face.mFaceID == LL_FACE_PATH_END);
- vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK;
- }
- }
- else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
- {
- vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK;
- }
- else
- {
- vf.mTypeMask |= LLVolumeFace::SIDE_MASK;
- if (face.mFlat)
- {
- vf.mTypeMask |= LLVolumeFace::FLAT_MASK;
- }
- if (face.mFaceID & LL_FACE_INNER_SIDE)
- {
- vf.mTypeMask |= LLVolumeFace::INNER_MASK;
- if (face.mFlat && vf.mNumS > 2)
- { //flat inner faces have to copy vert normals
- vf.mNumS = vf.mNumS*2;
- if (vf.mNumS < 0)
- {
- LL_ERRS() << "Volume face corruption detected." << LL_ENDL;
- }
- }
- }
- else
- {
- vf.mTypeMask |= LLVolumeFace::OUTER_MASK;
- }
- }
- }
-
- for (face_list_t::iterator iter = mVolumeFaces.begin();
- iter != mVolumeFaces.end(); ++iter)
- {
- (*iter).create(this, partial_build);
- }
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ if (mGenerateSingleFace)
+ {
+ // do nothing
+ }
+ else
+ {
+ S32 num_faces = getNumFaces();
+ BOOL partial_build = TRUE;
+ if (num_faces != mVolumeFaces.size())
+ {
+ partial_build = FALSE;
+ mVolumeFaces.resize(num_faces);
+ }
+ // Initialize volume faces with parameter data
+ for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++)
+ {
+ LLVolumeFace& vf = mVolumeFaces[i];
+ LLProfile::Face& face = mProfilep->mFaces[i];
+ vf.mBeginS = face.mIndex;
+ vf.mNumS = face.mCount;
+ if (vf.mNumS < 0)
+ {
+ LL_ERRS() << "Volume face corruption detected." << LL_ENDL;
+ }
+
+ vf.mBeginT = 0;
+ vf.mNumT= getPath().mPath.size();
+ vf.mID = i;
+
+ // Set the type mask bits correctly
+ if (mParams.getProfileParams().getHollow() > 0)
+ {
+ vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK;
+ }
+ if (mProfilep->isOpen())
+ {
+ vf.mTypeMask |= LLVolumeFace::OPEN_MASK;
+ }
+ if (face.mCap)
+ {
+ vf.mTypeMask |= LLVolumeFace::CAP_MASK;
+ if (face.mFaceID == LL_FACE_PATH_BEGIN)
+ {
+ vf.mTypeMask |= LLVolumeFace::TOP_MASK;
+ }
+ else
+ {
+ llassert(face.mFaceID == LL_FACE_PATH_END);
+ vf.mTypeMask |= LLVolumeFace::BOTTOM_MASK;
+ }
+ }
+ else if (face.mFaceID & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
+ {
+ vf.mTypeMask |= LLVolumeFace::FLAT_MASK | LLVolumeFace::END_MASK;
+ }
+ else
+ {
+ vf.mTypeMask |= LLVolumeFace::SIDE_MASK;
+ if (face.mFlat)
+ {
+ vf.mTypeMask |= LLVolumeFace::FLAT_MASK;
+ }
+ if (face.mFaceID & LL_FACE_INNER_SIDE)
+ {
+ vf.mTypeMask |= LLVolumeFace::INNER_MASK;
+ if (face.mFlat && vf.mNumS > 2)
+ { //flat inner faces have to copy vert normals
+ vf.mNumS = vf.mNumS*2;
+ if (vf.mNumS < 0)
+ {
+ LL_ERRS() << "Volume face corruption detected." << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ vf.mTypeMask |= LLVolumeFace::OUTER_MASK;
+ }
+ }
+ }
+
+ for (face_list_t::iterator iter = mVolumeFaces.begin();
+ iter != mVolumeFaces.end(); ++iter)
+ {
+ (*iter).create(this, partial_build);
+ }
+ }
}
inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b)
{
- // maps RGB values to vector values [0..255] -> [-0.5..0.5]
- LLVector4a value;
- LLVector4a sub(0.5f, 0.5f, 0.5f);
+ // maps RGB values to vector values [0..255] -> [-0.5..0.5]
+ LLVector4a value;
+ LLVector4a sub(0.5f, 0.5f, 0.5f);
- value.set(r,g,b);
- value.mul(1.f/255.f);
- value.sub(sub);
+ value.set(r,g,b);
+ value.mul(1.f/255.f);
+ value.sub(sub);
- return value;
+ return value;
}
inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components)
{
- U32 index = (x + y * sculpt_width) * sculpt_components;
- return index;
+ U32 index = (x + y * sculpt_width) * sculpt_components;
+ return index;
}
inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components)
{
- U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width);
- U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height);
+ U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width);
+ U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height);
- return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);
+ return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);
}
inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data)
{
- LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]);
+ LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]);
- return v;
+ return v;
}
inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
{
- U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components);
+ U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components);
- return sculpt_index_to_vector(index, sculpt_data);
+ return sculpt_index_to_vector(index, sculpt_data);
}
inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
{
- U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);
+ U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);
- return sculpt_index_to_vector(index, sculpt_data);
+ return sculpt_index_to_vector(index, sculpt_data);
}
F32 LLVolume::sculptGetSurfaceArea()
{
- // test to see if image has enough variation to create non-degenerate geometry
+ // test to see if image has enough variation to create non-degenerate geometry
- F32 area = 0;
+ F32 area = 0;
- S32 sizeS = mPathp->mPath.size();
- S32 sizeT = mProfilep->mProfile.size();
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
+
+ for (S32 s = 0; s < sizeS-1; s++)
+ {
+ for (S32 t = 0; t < sizeT-1; t++)
+ {
+ // get four corners of quad
+ LLVector4a& p1 = mMesh[(s )*sizeT + (t )];
+ LLVector4a& p2 = mMesh[(s+1)*sizeT + (t )];
+ LLVector4a& p3 = mMesh[(s )*sizeT + (t+1)];
+ LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)];
- for (S32 s = 0; s < sizeS-1; s++)
- {
- for (S32 t = 0; t < sizeT-1; t++)
- {
- // get four corners of quad
- LLVector4a& p1 = mMesh[(s )*sizeT + (t )];
- LLVector4a& p2 = mMesh[(s+1)*sizeT + (t )];
- LLVector4a& p3 = mMesh[(s )*sizeT + (t+1)];
- LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)];
-
- // compute the area of the quad by taking the length of the cross product of the two triangles
- LLVector4a v0,v1,v2,v3;
- v0.setSub(p1,p2);
- v1.setSub(p1,p3);
- v2.setSub(p4,p2);
- v3.setSub(p4,p3);
-
- LLVector4a cross1, cross2;
- cross1.setCross3(v0,v1);
- cross2.setCross3(v2,v3);
-
- //LLVector3 cross1 = (p1 - p2) % (p1 - p3);
- //LLVector3 cross2 = (p4 - p2) % (p4 - p3);
-
- area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f;
- }
- }
+ // compute the area of the quad by taking the length of the cross product of the two triangles
+ LLVector4a v0,v1,v2,v3;
+ v0.setSub(p1,p2);
+ v1.setSub(p1,p3);
+ v2.setSub(p4,p2);
+ v3.setSub(p4,p3);
+
+ LLVector4a cross1, cross2;
+ cross1.setCross3(v0,v1);
+ cross2.setCross3(v2,v3);
+
+ //LLVector3 cross1 = (p1 - p2) % (p1 - p3);
+ //LLVector3 cross2 = (p4 - p2) % (p4 - p3);
+
+ area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f;
+ }
+ }
- return area;
+ return area;
}
// create empty placeholder shape
void LLVolume::sculptGenerateEmptyPlaceholder()
{
- S32 sizeS = mPathp->mPath.size();
- S32 sizeT = mProfilep->mProfile.size();
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
- S32 line = 0;
+ S32 line = 0;
- for (S32 s = 0; s < sizeS; s++)
- {
- for (S32 t = 0; t < sizeT; t++)
- {
- S32 i = t + line;
- LLVector4a& pt = mMesh[i];
+ for (S32 s = 0; s < sizeS; s++)
+ {
+ for (S32 t = 0; t < sizeT; t++)
+ {
+ S32 i = t + line;
+ LLVector4a& pt = mMesh[i];
+
+ F32* p = pt.getF32ptr();
- F32* p = pt.getF32ptr();
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
- p[0] = 0;
- p[1] = 0;
- p[2] = 0;
-
- llassert(pt.isFinite3());
- }
- line += sizeT;
- }
+ llassert(pt.isFinite3());
+ }
+ line += sizeT;
+ }
}
// create sphere placeholder shape
void LLVolume::sculptGenerateSpherePlaceholder()
{
- S32 sizeS = mPathp->mPath.size();
- S32 sizeT = mProfilep->mProfile.size();
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
- S32 line = 0;
+ S32 line = 0;
- for (S32 s = 0; s < sizeS; s++)
- {
- for (S32 t = 0; t < sizeT; t++)
- {
- S32 i = t + line;
- LLVector4a& pt = mMesh[i];
+ for (S32 s = 0; s < sizeS; s++)
+ {
+ for (S32 t = 0; t < sizeT; t++)
+ {
+ S32 i = t + line;
+ LLVector4a& pt = mMesh[i];
- F32 u = (F32)s / (sizeS - 1);
- F32 v = (F32)t / (sizeT - 1);
+ F32 u = (F32)s / (sizeS - 1);
+ F32 v = (F32)t / (sizeT - 1);
- const F32 RADIUS = (F32) 0.3;
+ const F32 RADIUS = (F32) 0.3;
- F32* p = pt.getF32ptr();
+ F32* p = pt.getF32ptr();
- p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
- p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
- p[2] = (F32)(cos(F_PI * v) * RADIUS);
+ p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
+ p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
+ p[2] = (F32)(cos(F_PI * v) * RADIUS);
- llassert(pt.isFinite3());
- }
- line += sizeT;
- }
+ llassert(pt.isFinite3());
+ }
+ line += sizeT;
+ }
}
// create the vertices from the map
void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type)
{
- U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
- BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
- BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
- BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR
-
- S32 sizeS = mPathp->mPath.size();
- S32 sizeT = mProfilep->mProfile.size();
-
- S32 line = 0;
- for (S32 s = 0; s < sizeS; s++)
- {
- // Run along the profile.
- for (S32 t = 0; t < sizeT; t++)
- {
- S32 i = t + line;
- LLVector4a& pt = mMesh[i];
-
- S32 reversed_t = t;
-
- if (reverse_horizontal)
- {
- reversed_t = sizeT - t - 1;
- }
-
- U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width);
- U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height);
-
-
- if (y == 0) // top row stitching
- {
- // pinch?
- if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
- {
- x = sculpt_width / 2;
- }
- }
-
- if (y == sculpt_height) // bottom row stitching
- {
- // wrap?
- if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
- {
- y = 0;
- }
- else
- {
- y = sculpt_height - 1;
- }
-
- // pinch?
- if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
- {
- x = sculpt_width / 2;
- }
- }
-
- if (x == sculpt_width) // side stitching
- {
- // wrap?
- if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
- (sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
- (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
- {
- x = 0;
- }
-
- else
- {
- x = sculpt_width - 1;
- }
- }
-
- pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data);
-
- if (sculpt_mirror)
- {
- LLVector4a scale(-1.f,1,1,1);
- pt.mul(scale);
- }
-
- llassert(pt.isFinite3());
- }
-
- line += sizeT;
- }
+ U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
+ BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
+ BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
+ BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR
+
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
+
+ S32 line = 0;
+ for (S32 s = 0; s < sizeS; s++)
+ {
+ // Run along the profile.
+ for (S32 t = 0; t < sizeT; t++)
+ {
+ S32 i = t + line;
+ LLVector4a& pt = mMesh[i];
+
+ S32 reversed_t = t;
+
+ if (reverse_horizontal)
+ {
+ reversed_t = sizeT - t - 1;
+ }
+
+ U32 x = (U32) ((F32)reversed_t/(sizeT-1) * (F32) sculpt_width);
+ U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height);
+
+
+ if (y == 0) // top row stitching
+ {
+ // pinch?
+ if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
+ {
+ x = sculpt_width / 2;
+ }
+ }
+
+ if (y == sculpt_height) // bottom row stitching
+ {
+ // wrap?
+ if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
+ {
+ y = 0;
+ }
+ else
+ {
+ y = sculpt_height - 1;
+ }
+
+ // pinch?
+ if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
+ {
+ x = sculpt_width / 2;
+ }
+ }
+
+ if (x == sculpt_width) // side stitching
+ {
+ // wrap?
+ if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
+ (sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
+ (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
+ {
+ x = 0;
+ }
+
+ else
+ {
+ x = sculpt_width - 1;
+ }
+ }
+
+ pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data);
+
+ if (sculpt_mirror)
+ {
+ LLVector4a scale(-1.f,1,1,1);
+ pt.mul(scale);
+ }
+
+ llassert(pt.isFinite3());
+ }
+
+ line += sizeT;
+ }
}
@@ -3213,24 +3141,24 @@ const S32 SCULPT_REZ_4 = 32;
S32 sculpt_sides(F32 detail)
{
- // detail is usually one of: 1, 1.5, 2.5, 4.0.
-
- if (detail <= 1.0)
- {
- return SCULPT_REZ_1;
- }
- if (detail <= 2.0)
- {
- return SCULPT_REZ_2;
- }
- if (detail <= 3.0)
- {
- return SCULPT_REZ_3;
- }
- else
- {
- return SCULPT_REZ_4;
- }
+ // detail is usually one of: 1, 1.5, 2.5, 4.0.
+
+ if (detail <= 1.0)
+ {
+ return SCULPT_REZ_1;
+ }
+ if (detail <= 2.0)
+ {
+ return SCULPT_REZ_2;
+ }
+ if (detail <= 3.0)
+ {
+ return SCULPT_REZ_3;
+ }
+ else
+ {
+ return SCULPT_REZ_4;
+ }
}
@@ -3238,120 +3166,120 @@ S32 sculpt_sides(F32 detail)
// determine the number of vertices in both s and t direction for this sculpt
void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t)
{
- // this code has the following properties:
- // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map
- // while still using all available verts
- // 2) the mesh cannot have more verts than is allowed by LOD
- // 3) the mesh cannot have more verts than is allowed by the map
-
- S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0);
- S32 max_vertices_map = width * height / 4;
-
- S32 vertices;
- if (max_vertices_map > 0)
- vertices = llmin(max_vertices_lod, max_vertices_map);
- else
- vertices = max_vertices_lod;
-
-
- F32 ratio;
- if ((width == 0) || (height == 0))
- ratio = 1.f;
- else
- ratio = (F32) width / (F32) height;
-
-
- s = (S32)(F32) sqrt(((F32)vertices / ratio));
-
- s = llmax(s, 4); // no degenerate sizes, please
- t = vertices / s;
-
- t = llmax(t, 4); // no degenerate sizes, please
- s = vertices / t;
+ // this code has the following properties:
+ // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map
+ // while still using all available verts
+ // 2) the mesh cannot have more verts than is allowed by LOD
+ // 3) the mesh cannot have more verts than is allowed by the map
+
+ S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0);
+ S32 max_vertices_map = width * height / 4;
+
+ S32 vertices;
+ if (max_vertices_map > 0)
+ vertices = llmin(max_vertices_lod, max_vertices_map);
+ else
+ vertices = max_vertices_lod;
+
+
+ F32 ratio;
+ if ((width == 0) || (height == 0))
+ ratio = 1.f;
+ else
+ ratio = (F32) width / (F32) height;
+
+
+ s = (S32)(F32) sqrt(((F32)vertices / ratio));
+
+ s = llmax(s, 4); // no degenerate sizes, please
+ t = vertices / s;
+
+ t = llmax(t, 4); // no degenerate sizes, please
+ s = vertices / t;
}
// sculpt replaces generate() for sculpted surfaces
void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)
{
- U8 sculpt_type = mParams.getSculptType();
-
- BOOL data_is_empty = FALSE;
-
- if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL)
- {
- sculpt_level = -1;
- data_is_empty = TRUE;
- }
+ U8 sculpt_type = mParams.getSculptType();
- S32 requested_sizeS = 0;
- S32 requested_sizeT = 0;
+ BOOL data_is_empty = FALSE;
- sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT);
+ if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL)
+ {
+ sculpt_level = -1;
+ data_is_empty = TRUE;
+ }
- mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS);
- mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT);
+ S32 requested_sizeS = 0;
+ S32 requested_sizeT = 0;
- S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got
- S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got
+ sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT);
- // weird crash bug - DEV-11158 - trying to collect more data:
- if ((sizeS == 0) || (sizeT == 0))
- {
- LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL;
- }
+ mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS);
+ mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT);
- sNumMeshPoints -= mMesh.size();
- mMesh.resize(sizeS * sizeT);
- sNumMeshPoints += mMesh.size();
+ S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got
+ S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got
- //generate vertex positions
- if (!data_is_empty)
- {
- sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type);
+ // weird crash bug - DEV-11158 - trying to collect more data:
+ if ((sizeS == 0) || (sizeT == 0))
+ {
+ LL_WARNS() << "sculpt bad mesh size " << sizeS << " " << sizeT << LL_ENDL;
+ }
+
+ sNumMeshPoints -= mMesh.size();
+ mMesh.resize(sizeS * sizeT);
+ sNumMeshPoints += mMesh.size();
- // don't test lowest LOD to support legacy content DEV-33670
- if (mDetail > SCULPT_MIN_AREA_DETAIL)
- {
- F32 area = sculptGetSurfaceArea();
+ //generate vertex positions
+ if (!data_is_empty)
+ {
+ sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type);
- mSurfaceArea = area;
+ // don't test lowest LOD to support legacy content DEV-33670
+ if (mDetail > SCULPT_MIN_AREA_DETAIL)
+ {
+ F32 area = sculptGetSurfaceArea();
- const F32 SCULPT_MAX_AREA = 384.f;
+ mSurfaceArea = area;
- if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
- {
- data_is_empty = TRUE;
- visible_placeholder = true;
- }
- }
- }
+ const F32 SCULPT_MAX_AREA = 384.f;
- if (data_is_empty)
- {
- if (visible_placeholder)
- {
- // Object should be visible since there will be nothing else to display
- sculptGenerateSpherePlaceholder();
- }
- else
- {
- sculptGenerateEmptyPlaceholder();
- }
- }
+ if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
+ {
+ data_is_empty = TRUE;
+ visible_placeholder = true;
+ }
+ }
+ }
+ if (data_is_empty)
+ {
+ if (visible_placeholder)
+ {
+ // Object should be visible since there will be nothing else to display
+ sculptGenerateSpherePlaceholder();
+ }
+ else
+ {
+ sculptGenerateEmptyPlaceholder();
+ }
+ }
- for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++)
- {
- mFaceMask |= mProfilep->mFaces[i].mFaceID;
- }
+
+ for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++)
+ {
+ mFaceMask |= mProfilep->mFaces[i].mFaceID;
+ }
- mSculptLevel = sculpt_level;
+ mSculptLevel = sculpt_level;
- // Delete any existing faces so that they get regenerated
- mVolumeFaces.clear();
-
- createVolumeFaces();
+ // Delete any existing faces so that they get regenerated
+ mVolumeFaces.clear();
+
+ createVolumeFaces();
}
@@ -3359,12 +3287,12 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
BOOL LLVolume::isCap(S32 face)
{
- return mProfilep->mFaces[face].mCap;
+ return mProfilep->mFaces[face].mCap;
}
BOOL LLVolume::isFlat(S32 face)
{
- return mProfilep->mFaces[face].mFlat;
+ return mProfilep->mFaces[face].mFlat;
}
@@ -3375,457 +3303,457 @@ bool LLVolumeParams::isSculpt() const
bool LLVolumeParams::isMeshSculpt() const
{
- return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;
+ return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;
}
bool LLVolumeParams::operator==(const LLVolumeParams &params) const
{
- return ( (getPathParams() == params.getPathParams()) &&
- (getProfileParams() == params.getProfileParams()) &&
- (mSculptID == params.mSculptID) &&
- (mSculptType == params.mSculptType) );
+ return ( (getPathParams() == params.getPathParams()) &&
+ (getProfileParams() == params.getProfileParams()) &&
+ (mSculptID == params.mSculptID) &&
+ (mSculptType == params.mSculptType) );
}
bool LLVolumeParams::operator!=(const LLVolumeParams &params) const
{
- return ( (getPathParams() != params.getPathParams()) ||
- (getProfileParams() != params.getProfileParams()) ||
- (mSculptID != params.mSculptID) ||
- (mSculptType != params.mSculptType) );
+ return ( (getPathParams() != params.getPathParams()) ||
+ (getProfileParams() != params.getProfileParams()) ||
+ (mSculptID != params.mSculptID) ||
+ (mSculptType != params.mSculptType) );
}
bool LLVolumeParams::operator<(const LLVolumeParams &params) const
{
- if( getPathParams() != params.getPathParams() )
- {
- return getPathParams() < params.getPathParams();
- }
+ if( getPathParams() != params.getPathParams() )
+ {
+ return getPathParams() < params.getPathParams();
+ }
+
+ if (getProfileParams() != params.getProfileParams())
+ {
+ return getProfileParams() < params.getProfileParams();
+ }
+
+ if (mSculptID != params.mSculptID)
+ {
+ return mSculptID < params.mSculptID;
+ }
- if (getProfileParams() != params.getProfileParams())
- {
- return getProfileParams() < params.getProfileParams();
- }
-
- if (mSculptID != params.mSculptID)
- {
- return mSculptID < params.mSculptID;
- }
-
- return mSculptType < params.mSculptType;
+ return mSculptType < params.mSculptType;
}
void LLVolumeParams::copyParams(const LLVolumeParams &params)
{
- mProfileParams.copyParams(params.mProfileParams);
- mPathParams.copyParams(params.mPathParams);
- mSculptID = params.getSculptID();
- mSculptType = params.getSculptType();
+ mProfileParams.copyParams(params.mProfileParams);
+ mPathParams.copyParams(params.mPathParams);
+ mSculptID = params.getSculptID();
+ mSculptType = params.getSculptType();
}
// Less restricitve approx 0 for volumes
const F32 APPROXIMATELY_ZERO = 0.001f;
bool approx_zero( F32 f, F32 tolerance = APPROXIMATELY_ZERO)
{
- return (f >= -tolerance) && (f <= tolerance);
+ return (f >= -tolerance) && (f <= tolerance);
}
// return true if in range (or nearly so)
static bool limit_range(F32& v, F32 min, F32 max, F32 tolerance = APPROXIMATELY_ZERO)
{
- F32 min_delta = v - min;
- if (min_delta < 0.f)
- {
- v = min;
- if (!approx_zero(min_delta, tolerance))
- return false;
- }
- F32 max_delta = max - v;
- if (max_delta < 0.f)
- {
- v = max;
- if (!approx_zero(max_delta, tolerance))
- return false;
- }
- return true;
+ F32 min_delta = v - min;
+ if (min_delta < 0.f)
+ {
+ v = min;
+ if (!approx_zero(min_delta, tolerance))
+ return false;
+ }
+ F32 max_delta = max - v;
+ if (max_delta < 0.f)
+ {
+ v = max;
+ if (!approx_zero(max_delta, tolerance))
+ return false;
+ }
+ return true;
}
bool LLVolumeParams::setBeginAndEndS(const F32 b, const F32 e)
{
- bool valid = true;
+ bool valid = true;
- // First, clamp to valid ranges.
- F32 begin = b;
- valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA);
+ // First, clamp to valid ranges.
+ F32 begin = b;
+ valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA);
- F32 end = e;
- if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error
- valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
+ F32 end = e;
+ if (end >= .0149f && end < MIN_CUT_DELTA) end = MIN_CUT_DELTA; // eliminate warning for common rounding error
+ valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
- valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
+ valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
- // Now set them.
- mProfileParams.setBegin(begin);
- mProfileParams.setEnd(end);
+ // Now set them.
+ mProfileParams.setBegin(begin);
+ mProfileParams.setEnd(end);
- return valid;
+ return valid;
}
bool LLVolumeParams::setBeginAndEndT(const F32 b, const F32 e)
{
- bool valid = true;
+ bool valid = true;
- // First, clamp to valid ranges.
- F32 begin = b;
- valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA);
+ // First, clamp to valid ranges.
+ F32 begin = b;
+ valid &= limit_range(begin, 0.f, 1.f - MIN_CUT_DELTA);
- F32 end = e;
- valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
+ F32 end = e;
+ valid &= limit_range(end, MIN_CUT_DELTA, 1.f);
- valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
+ valid &= limit_range(begin, 0.f, end - MIN_CUT_DELTA, .01f);
- // Now set them.
- mPathParams.setBegin(begin);
- mPathParams.setEnd(end);
+ // Now set them.
+ mPathParams.setBegin(begin);
+ mPathParams.setEnd(end);
- return valid;
-}
+ return valid;
+}
bool LLVolumeParams::setHollow(const F32 h)
{
- // Validate the hollow based on path and profile.
- U8 profile = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
- U8 hole_type = mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK;
-
- F32 max_hollow = HOLLOW_MAX;
-
- // Only square holes have trouble.
- if (LL_PCODE_HOLE_SQUARE == hole_type)
- {
- switch(profile)
- {
- case LL_PCODE_PROFILE_CIRCLE:
- case LL_PCODE_PROFILE_CIRCLE_HALF:
- case LL_PCODE_PROFILE_EQUALTRI:
- max_hollow = HOLLOW_MAX_SQUARE;
- }
- }
-
- F32 hollow = h;
- bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow);
- mProfileParams.setHollow(hollow);
-
- return valid;
-}
+ // Validate the hollow based on path and profile.
+ U8 profile = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
+ U8 hole_type = mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK;
+
+ F32 max_hollow = HOLLOW_MAX;
+
+ // Only square holes have trouble.
+ if (LL_PCODE_HOLE_SQUARE == hole_type)
+ {
+ switch(profile)
+ {
+ case LL_PCODE_PROFILE_CIRCLE:
+ case LL_PCODE_PROFILE_CIRCLE_HALF:
+ case LL_PCODE_PROFILE_EQUALTRI:
+ max_hollow = HOLLOW_MAX_SQUARE;
+ }
+ }
+
+ F32 hollow = h;
+ bool valid = limit_range(hollow, HOLLOW_MIN, max_hollow);
+ mProfileParams.setHollow(hollow);
+
+ return valid;
+}
bool LLVolumeParams::setTwistBegin(const F32 b)
{
- F32 twist_begin = b;
- bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX);
- mPathParams.setTwistBegin(twist_begin);
- return valid;
+ F32 twist_begin = b;
+ bool valid = limit_range(twist_begin, TWIST_MIN, TWIST_MAX);
+ mPathParams.setTwistBegin(twist_begin);
+ return valid;
}
bool LLVolumeParams::setTwistEnd(const F32 e)
-{
- F32 twist_end = e;
- bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX);
- mPathParams.setTwistEnd(twist_end);
- return valid;
+{
+ F32 twist_end = e;
+ bool valid = limit_range(twist_end, TWIST_MIN, TWIST_MAX);
+ mPathParams.setTwistEnd(twist_end);
+ return valid;
}
bool LLVolumeParams::setRatio(const F32 x, const F32 y)
{
- F32 min_x = RATIO_MIN;
- F32 max_x = RATIO_MAX;
- F32 min_y = RATIO_MIN;
- F32 max_y = RATIO_MAX;
- // If this is a circular path (and not a sphere) then 'ratio' is actually hole size.
- U8 path_type = mPathParams.getCurveType();
- U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
- if ( LL_PCODE_PATH_CIRCLE == path_type &&
- LL_PCODE_PROFILE_CIRCLE_HALF != profile_type)
- {
- // Holes are more restricted...
- min_x = HOLE_X_MIN;
- max_x = HOLE_X_MAX;
- min_y = HOLE_Y_MIN;
- max_y = HOLE_Y_MAX;
- }
-
- F32 ratio_x = x;
- bool valid = limit_range(ratio_x, min_x, max_x);
- F32 ratio_y = y;
- valid &= limit_range(ratio_y, min_y, max_y);
-
- mPathParams.setScale(ratio_x, ratio_y);
-
- return valid;
+ F32 min_x = RATIO_MIN;
+ F32 max_x = RATIO_MAX;
+ F32 min_y = RATIO_MIN;
+ F32 max_y = RATIO_MAX;
+ // If this is a circular path (and not a sphere) then 'ratio' is actually hole size.
+ U8 path_type = mPathParams.getCurveType();
+ U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
+ if ( LL_PCODE_PATH_CIRCLE == path_type &&
+ LL_PCODE_PROFILE_CIRCLE_HALF != profile_type)
+ {
+ // Holes are more restricted...
+ min_x = HOLE_X_MIN;
+ max_x = HOLE_X_MAX;
+ min_y = HOLE_Y_MIN;
+ max_y = HOLE_Y_MAX;
+ }
+
+ F32 ratio_x = x;
+ bool valid = limit_range(ratio_x, min_x, max_x);
+ F32 ratio_y = y;
+ valid &= limit_range(ratio_y, min_y, max_y);
+
+ mPathParams.setScale(ratio_x, ratio_y);
+
+ return valid;
}
bool LLVolumeParams::setShear(const F32 x, const F32 y)
{
- F32 shear_x = x;
- bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX);
- F32 shear_y = y;
- valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX);
- mPathParams.setShear(shear_x, shear_y);
- return valid;
+ F32 shear_x = x;
+ bool valid = limit_range(shear_x, SHEAR_MIN, SHEAR_MAX);
+ F32 shear_y = y;
+ valid &= limit_range(shear_y, SHEAR_MIN, SHEAR_MAX);
+ mPathParams.setShear(shear_x, shear_y);
+ return valid;
}
bool LLVolumeParams::setTaperX(const F32 v)
{
- F32 taper = v;
- bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX);
- mPathParams.setTaperX(taper);
- return valid;
+ F32 taper = v;
+ bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX);
+ mPathParams.setTaperX(taper);
+ return valid;
}
bool LLVolumeParams::setTaperY(const F32 v)
{
- F32 taper = v;
- bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX);
- mPathParams.setTaperY(taper);
- return valid;
+ F32 taper = v;
+ bool valid = limit_range(taper, TAPER_MIN, TAPER_MAX);
+ mPathParams.setTaperY(taper);
+ return valid;
}
bool LLVolumeParams::setRevolutions(const F32 r)
{
- F32 revolutions = r;
- bool valid = limit_range(revolutions, REV_MIN, REV_MAX);
- mPathParams.setRevolutions(revolutions);
- return valid;
+ F32 revolutions = r;
+ bool valid = limit_range(revolutions, REV_MIN, REV_MAX);
+ mPathParams.setRevolutions(revolutions);
+ return valid;
}
bool LLVolumeParams::setRadiusOffset(const F32 offset)
{
- bool valid = true;
-
- // If this is a sphere, just set it to 0 and get out.
- U8 path_type = mPathParams.getCurveType();
- U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
- if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ||
- LL_PCODE_PATH_CIRCLE != path_type )
- {
- mPathParams.setRadiusOffset(0.f);
- return true;
- }
-
- // Limit radius offset, based on taper and hole size y.
- F32 radius_offset = offset;
- F32 taper_y = getTaperY();
- F32 radius_mag = fabs(radius_offset);
- F32 hole_y_mag = fabs(getRatioY());
- F32 taper_y_mag = fabs(taper_y);
- // Check to see if the taper effects us.
- if ( (radius_offset > 0.f && taper_y < 0.f) ||
- (radius_offset < 0.f && taper_y > 0.f) )
- {
- // The taper does not help increase the radius offset range.
- taper_y_mag = 0.f;
- }
- F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
-
- // Enforce the maximum magnitude.
- F32 delta = max_radius_mag - radius_mag;
- if (delta < 0.f)
- {
- // Check radius offset sign.
- if (radius_offset < 0.f)
- {
- radius_offset = -max_radius_mag;
- }
- else
- {
- radius_offset = max_radius_mag;
- }
- valid = approx_zero(delta, .1f);
- }
-
- mPathParams.setRadiusOffset(radius_offset);
- return valid;
+ bool valid = true;
+
+ // If this is a sphere, just set it to 0 and get out.
+ U8 path_type = mPathParams.getCurveType();
+ U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
+ if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ||
+ LL_PCODE_PATH_CIRCLE != path_type )
+ {
+ mPathParams.setRadiusOffset(0.f);
+ return true;
+ }
+
+ // Limit radius offset, based on taper and hole size y.
+ F32 radius_offset = offset;
+ F32 taper_y = getTaperY();
+ F32 radius_mag = fabs(radius_offset);
+ F32 hole_y_mag = fabs(getRatioY());
+ F32 taper_y_mag = fabs(taper_y);
+ // Check to see if the taper effects us.
+ if ( (radius_offset > 0.f && taper_y < 0.f) ||
+ (radius_offset < 0.f && taper_y > 0.f) )
+ {
+ // The taper does not help increase the radius offset range.
+ taper_y_mag = 0.f;
+ }
+ F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
+
+ // Enforce the maximum magnitude.
+ F32 delta = max_radius_mag - radius_mag;
+ if (delta < 0.f)
+ {
+ // Check radius offset sign.
+ if (radius_offset < 0.f)
+ {
+ radius_offset = -max_radius_mag;
+ }
+ else
+ {
+ radius_offset = max_radius_mag;
+ }
+ valid = approx_zero(delta, .1f);
+ }
+
+ mPathParams.setRadiusOffset(radius_offset);
+ return valid;
}
bool LLVolumeParams::setSkew(const F32 skew_value)
{
- bool valid = true;
-
- // Check the skew value against the revolutions.
- F32 skew = llclamp(skew_value, SKEW_MIN, SKEW_MAX);
- F32 skew_mag = fabs(skew);
- F32 revolutions = getRevolutions();
- F32 scale_x = getRatioX();
- F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
- // Discontinuity; A revolution of 1 allows skews below 0.5.
- if ( fabs(revolutions - 1.0f) < 0.001)
- min_skew_mag = 0.0f;
-
- // Clip skew.
- F32 delta = skew_mag - min_skew_mag;
- if (delta < 0.f)
- {
- // Check skew sign.
- if (skew < 0.0f)
- {
- skew = -min_skew_mag;
- }
- else
- {
- skew = min_skew_mag;
- }
- valid = approx_zero(delta, .01f);
- }
-
- mPathParams.setSkew(skew);
- return valid;
+ bool valid = true;
+
+ // Check the skew value against the revolutions.
+ F32 skew = llclamp(skew_value, SKEW_MIN, SKEW_MAX);
+ F32 skew_mag = fabs(skew);
+ F32 revolutions = getRevolutions();
+ F32 scale_x = getRatioX();
+ F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
+ // Discontinuity; A revolution of 1 allows skews below 0.5.
+ if ( fabs(revolutions - 1.0f) < 0.001)
+ min_skew_mag = 0.0f;
+
+ // Clip skew.
+ F32 delta = skew_mag - min_skew_mag;
+ if (delta < 0.f)
+ {
+ // Check skew sign.
+ if (skew < 0.0f)
+ {
+ skew = -min_skew_mag;
+ }
+ else
+ {
+ skew = min_skew_mag;
+ }
+ valid = approx_zero(delta, .01f);
+ }
+
+ mPathParams.setSkew(skew);
+ return valid;
}
bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type)
{
- mSculptID = sculpt_id;
- mSculptType = sculpt_type;
- return true;
+ mSculptID = sculpt_id;
+ mSculptType = sculpt_type;
+ return true;
}
bool LLVolumeParams::setType(U8 profile, U8 path)
{
- bool result = true;
- // First, check profile and path for validity.
- U8 profile_type = profile & LL_PCODE_PROFILE_MASK;
- U8 hole_type = (profile & LL_PCODE_HOLE_MASK) >> 4;
- U8 path_type = path >> 4;
-
- if (profile_type > LL_PCODE_PROFILE_MAX)
- {
- // Bad profile. Make it square.
- profile = LL_PCODE_PROFILE_SQUARE;
- result = false;
- LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type
- << ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL;
- }
- else if (hole_type > LL_PCODE_HOLE_MAX)
- {
- // Bad hole. Make it the same.
- profile = profile_type;
- result = false;
- LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type
- << ") to be LL_PCODE_HOLE_SAME" << LL_ENDL;
- }
-
- if (path_type < LL_PCODE_PATH_MIN ||
- path_type > LL_PCODE_PATH_MAX)
- {
- // Bad path. Make it linear.
- result = false;
- LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path
- << ") to be LL_PCODE_PATH_LINE" << LL_ENDL;
- path = LL_PCODE_PATH_LINE;
- }
-
- mProfileParams.setCurveType(profile);
- mPathParams.setCurveType(path);
- return result;
-}
-
-// static
+ bool result = true;
+ // First, check profile and path for validity.
+ U8 profile_type = profile & LL_PCODE_PROFILE_MASK;
+ U8 hole_type = (profile & LL_PCODE_HOLE_MASK) >> 4;
+ U8 path_type = path >> 4;
+
+ if (profile_type > LL_PCODE_PROFILE_MAX)
+ {
+ // Bad profile. Make it square.
+ profile = LL_PCODE_PROFILE_SQUARE;
+ result = false;
+ LL_WARNS() << "LLVolumeParams::setType changing bad profile type (" << profile_type
+ << ") to be LL_PCODE_PROFILE_SQUARE" << LL_ENDL;
+ }
+ else if (hole_type > LL_PCODE_HOLE_MAX)
+ {
+ // Bad hole. Make it the same.
+ profile = profile_type;
+ result = false;
+ LL_WARNS() << "LLVolumeParams::setType changing bad hole type (" << hole_type
+ << ") to be LL_PCODE_HOLE_SAME" << LL_ENDL;
+ }
+
+ if (path_type < LL_PCODE_PATH_MIN ||
+ path_type > LL_PCODE_PATH_MAX)
+ {
+ // Bad path. Make it linear.
+ result = false;
+ LL_WARNS() << "LLVolumeParams::setType changing bad path (" << path
+ << ") to be LL_PCODE_PATH_LINE" << LL_ENDL;
+ path = LL_PCODE_PATH_LINE;
+ }
+
+ mProfileParams.setCurveType(profile);
+ mPathParams.setCurveType(path);
+ return result;
+}
+
+// static
bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
- U8 path_curve, F32 path_begin, F32 path_end,
- F32 scx, F32 scy, F32 shx, F32 shy,
- F32 twistend, F32 twistbegin, F32 radiusoffset,
- F32 tx, F32 ty, F32 revolutions, F32 skew)
-{
- LLVolumeParams test_params;
- if (!test_params.setType (prof_curve, path_curve))
- {
- return false;
- }
- if (!test_params.setBeginAndEndS (prof_begin, prof_end))
- {
- return false;
- }
- if (!test_params.setBeginAndEndT (path_begin, path_end))
- {
- return false;
- }
- if (!test_params.setHollow (hollow))
- {
- return false;
- }
- if (!test_params.setTwistBegin (twistbegin))
- {
- return false;
- }
- if (!test_params.setTwistEnd (twistend))
- {
- return false;
- }
- if (!test_params.setRatio (scx, scy))
- {
- return false;
- }
- if (!test_params.setShear (shx, shy))
- {
- return false;
- }
- if (!test_params.setTaper (tx, ty))
- {
- return false;
- }
- if (!test_params.setRevolutions (revolutions))
- {
- return false;
- }
- if (!test_params.setRadiusOffset (radiusoffset))
- {
- return false;
- }
- if (!test_params.setSkew (skew))
- {
- return false;
- }
- return true;
+ U8 path_curve, F32 path_begin, F32 path_end,
+ F32 scx, F32 scy, F32 shx, F32 shy,
+ F32 twistend, F32 twistbegin, F32 radiusoffset,
+ F32 tx, F32 ty, F32 revolutions, F32 skew)
+{
+ LLVolumeParams test_params;
+ if (!test_params.setType (prof_curve, path_curve))
+ {
+ return false;
+ }
+ if (!test_params.setBeginAndEndS (prof_begin, prof_end))
+ {
+ return false;
+ }
+ if (!test_params.setBeginAndEndT (path_begin, path_end))
+ {
+ return false;
+ }
+ if (!test_params.setHollow (hollow))
+ {
+ return false;
+ }
+ if (!test_params.setTwistBegin (twistbegin))
+ {
+ return false;
+ }
+ if (!test_params.setTwistEnd (twistend))
+ {
+ return false;
+ }
+ if (!test_params.setRatio (scx, scy))
+ {
+ return false;
+ }
+ if (!test_params.setShear (shx, shy))
+ {
+ return false;
+ }
+ if (!test_params.setTaper (tx, ty))
+ {
+ return false;
+ }
+ if (!test_params.setRevolutions (revolutions))
+ {
+ return false;
+ }
+ if (!test_params.setRadiusOffset (radiusoffset))
+ {
+ return false;
+ }
+ if (!test_params.setSkew (skew))
+ {
+ return false;
+ }
+ return true;
}
void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
-{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
- //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
+{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
+ //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};
- for (S32 i = 0; i < 4; i++)
- {
- S32 count = 0;
- S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]);
- S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]);
+ F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};
+ for (S32 i = 0; i < 4; i++)
+ {
+ S32 count = 0;
+ S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]);
+ S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]);
- count = (profile_points-1)*2*(path_points-1);
- count += profile_points*2;
+ count = (profile_points-1)*2*(path_points-1);
+ count += profile_points*2;
- counts[i] = count;
- }
+ counts[i] = count;
+ }
}
S32 LLVolume::getNumTriangles(S32* vcount) const
{
- U32 triangle_count = 0;
- U32 vertex_count = 0;
+ U32 triangle_count = 0;
+ U32 vertex_count = 0;
- for (S32 i = 0; i < getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = getVolumeFace(i);
- triangle_count += face.mNumIndices/3;
-
- vertex_count += face.mNumVertices;
- }
+ for (S32 i = 0; i < getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = getVolumeFace(i);
+ triangle_count += face.mNumIndices/3;
+ vertex_count += face.mNumVertices;
+ }
- if (vcount)
- {
- *vcount = vertex_count;
- }
- return triangle_count;
+ if (vcount)
+ {
+ *vcount = vertex_count;
+ }
+
+ return triangle_count;
}
@@ -3833,989 +3761,989 @@ S32 LLVolume::getNumTriangles(S32* vcount) const
// generateSilhouetteVertices()
//-----------------------------------------------------------------------------
void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
- std::vector<LLVector3> &normals,
- const LLVector3& obj_cam_vec_in,
- const LLMatrix4& mat_in,
- const LLMatrix3& norm_mat_in,
- S32 face_mask)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
-
- LLMatrix4a mat;
- mat.loadu(mat_in);
-
- LLMatrix4a norm_mat;
- norm_mat.loadu(norm_mat_in);
-
- LLVector4a obj_cam_vec;
- obj_cam_vec.load3(obj_cam_vec_in.mV);
-
- vertices.clear();
- normals.clear();
-
- if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
- {
- return;
- }
-
- S32 cur_index = 0;
- //for each face
- for (face_list_t::iterator iter = mVolumeFaces.begin();
- iter != mVolumeFaces.end(); ++iter)
- {
- LLVolumeFace& face = *iter;
-
- if (!(face_mask & (0x1 << cur_index++)) ||
- face.mNumIndices == 0 || face.mEdge.empty())
- {
- continue;
- }
-
- if (face.mTypeMask & (LLVolumeFace::CAP_MASK))
- {
- LLVector4a* v = (LLVector4a*)face.mPositions;
- LLVector4a* n = (LLVector4a*)face.mNormals;
-
- for (U32 j = 0; j < face.mNumIndices / 3; j++)
- {
- for (S32 k = 0; k < 3; k++)
- {
- S32 index = face.mEdge[j * 3 + k];
-
- if (index == -1)
- {
- // silhouette edge, currently only cubes, so no other conditions
-
- S32 v1 = face.mIndices[j * 3 + k];
- S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)];
-
- LLVector4a t;
- mat.affineTransform(v[v1], t);
- vertices.push_back(LLVector3(t[0], t[1], t[2]));
-
- norm_mat.rotate(n[v1], t);
-
- t.normalize3fast();
- normals.push_back(LLVector3(t[0], t[1], t[2]));
-
- mat.affineTransform(v[v2], t);
- vertices.push_back(LLVector3(t[0], t[1], t[2]));
-
- norm_mat.rotate(n[v2], t);
- t.normalize3fast();
- normals.push_back(LLVector3(t[0], t[1], t[2]));
- }
- }
- }
-
- }
- else
- {
-
- //==============================================
- //DEBUG draw edge map instead of silhouette edge
- //==============================================
+ std::vector<LLVector3> &normals,
+ const LLVector3& obj_cam_vec_in,
+ const LLMatrix4& mat_in,
+ const LLMatrix3& norm_mat_in,
+ S32 face_mask)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ LLMatrix4a mat;
+ mat.loadu(mat_in);
+
+ LLMatrix4a norm_mat;
+ norm_mat.loadu(norm_mat_in);
+
+ LLVector4a obj_cam_vec;
+ obj_cam_vec.load3(obj_cam_vec_in.mV);
+
+ vertices.clear();
+ normals.clear();
+
+ if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ {
+ return;
+ }
+
+ S32 cur_index = 0;
+ //for each face
+ for (face_list_t::iterator iter = mVolumeFaces.begin();
+ iter != mVolumeFaces.end(); ++iter)
+ {
+ LLVolumeFace& face = *iter;
+
+ if (!(face_mask & (0x1 << cur_index++)) ||
+ face.mNumIndices == 0 || face.mEdge.empty())
+ {
+ continue;
+ }
+
+ if (face.mTypeMask & (LLVolumeFace::CAP_MASK))
+ {
+ LLVector4a* v = (LLVector4a*)face.mPositions;
+ LLVector4a* n = (LLVector4a*)face.mNormals;
+
+ for (U32 j = 0; j < face.mNumIndices / 3; j++)
+ {
+ for (S32 k = 0; k < 3; k++)
+ {
+ S32 index = face.mEdge[j * 3 + k];
+
+ if (index == -1)
+ {
+ // silhouette edge, currently only cubes, so no other conditions
+
+ S32 v1 = face.mIndices[j * 3 + k];
+ S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)];
+
+ LLVector4a t;
+ mat.affineTransform(v[v1], t);
+ vertices.push_back(LLVector3(t[0], t[1], t[2]));
+
+ norm_mat.rotate(n[v1], t);
+
+ t.normalize3fast();
+ normals.push_back(LLVector3(t[0], t[1], t[2]));
+
+ mat.affineTransform(v[v2], t);
+ vertices.push_back(LLVector3(t[0], t[1], t[2]));
+
+ norm_mat.rotate(n[v2], t);
+ t.normalize3fast();
+ normals.push_back(LLVector3(t[0], t[1], t[2]));
+ }
+ }
+ }
+
+ }
+ else
+ {
+
+ //==============================================
+ //DEBUG draw edge map instead of silhouette edge
+ //==============================================
#if DEBUG_SILHOUETTE_EDGE_MAP
- //for each triangle
+ //for each triangle
U32 tri_count = face.mNumIndices / 3;
for (U32 j = 0; j < tri_count; j++) {
- //get vertices
- S32 v1 = face.mIndices[j*3+0];
- S32 v2 = face.mIndices[j*3+1];
- S32 v3 = face.mIndices[j*3+2];
-
- //get current face center
- LLVector3 cCenter = (face.mVertices[v1].getPosition() +
- face.mVertices[v2].getPosition() +
- face.mVertices[v3].getPosition()) / 3.0f;
-
- //for each edge
- for (S32 k = 0; k < 3; k++) {
+ //get vertices
+ S32 v1 = face.mIndices[j*3+0];
+ S32 v2 = face.mIndices[j*3+1];
+ S32 v3 = face.mIndices[j*3+2];
+
+ //get current face center
+ LLVector3 cCenter = (face.mVertices[v1].getPosition() +
+ face.mVertices[v2].getPosition() +
+ face.mVertices[v3].getPosition()) / 3.0f;
+
+ //for each edge
+ for (S32 k = 0; k < 3; k++) {
S32 nIndex = face.mEdge[j*3+k];
- if (nIndex <= -1) {
- continue;
- }
+ if (nIndex <= -1) {
+ continue;
+ }
if (nIndex >= (S32)tri_count) {
- continue;
- }
- //get neighbor vertices
- v1 = face.mIndices[nIndex*3+0];
- v2 = face.mIndices[nIndex*3+1];
- v3 = face.mIndices[nIndex*3+2];
-
- //get neighbor face center
- LLVector3 nCenter = (face.mVertices[v1].getPosition() +
- face.mVertices[v2].getPosition() +
- face.mVertices[v3].getPosition()) / 3.0f;
-
- //draw line
- vertices.push_back(cCenter);
- vertices.push_back(nCenter);
- normals.push_back(LLVector3(1,1,1));
- normals.push_back(LLVector3(1,1,1));
- segments.push_back(vertices.size());
- }
- }
-
- continue;
-
- //==============================================
- //DEBUG
- //==============================================
-
- //==============================================
- //DEBUG draw normals instead of silhouette edge
- //==============================================
+ continue;
+ }
+ //get neighbor vertices
+ v1 = face.mIndices[nIndex*3+0];
+ v2 = face.mIndices[nIndex*3+1];
+ v3 = face.mIndices[nIndex*3+2];
+
+ //get neighbor face center
+ LLVector3 nCenter = (face.mVertices[v1].getPosition() +
+ face.mVertices[v2].getPosition() +
+ face.mVertices[v3].getPosition()) / 3.0f;
+
+ //draw line
+ vertices.push_back(cCenter);
+ vertices.push_back(nCenter);
+ normals.push_back(LLVector3(1,1,1));
+ normals.push_back(LLVector3(1,1,1));
+ segments.push_back(vertices.size());
+ }
+ }
+
+ continue;
+
+ //==============================================
+ //DEBUG
+ //==============================================
+
+ //==============================================
+ //DEBUG draw normals instead of silhouette edge
+ //==============================================
#elif DEBUG_SILHOUETTE_NORMALS
- //for each vertex
- for (U32 j = 0; j < face.mNumVertices; j++) {
- vertices.push_back(face.mVertices[j].getPosition());
- vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f);
- normals.push_back(LLVector3(0,0,1));
- normals.push_back(LLVector3(0,0,1));
- segments.push_back(vertices.size());
+ //for each vertex
+ for (U32 j = 0; j < face.mNumVertices; j++) {
+ vertices.push_back(face.mVertices[j].getPosition());
+ vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f);
+ normals.push_back(LLVector3(0,0,1));
+ normals.push_back(LLVector3(0,0,1));
+ segments.push_back(vertices.size());
#if DEBUG_SILHOUETTE_BINORMALS
- vertices.push_back(face.mVertices[j].getPosition());
- vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);
- normals.push_back(LLVector3(0,0,1));
- normals.push_back(LLVector3(0,0,1));
- segments.push_back(vertices.size());
+ vertices.push_back(face.mVertices[j].getPosition());
+ vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);
+ normals.push_back(LLVector3(0,0,1));
+ normals.push_back(LLVector3(0,0,1));
+ segments.push_back(vertices.size());
#endif
- }
-
- continue;
+ }
+
+ continue;
#else
- //==============================================
- //DEBUG
- //==============================================
-
- static const U8 AWAY = 0x01,
- TOWARDS = 0x02;
-
- //for each triangle
- std::vector<U8> fFacing;
- vector_append(fFacing, face.mNumIndices/3);
-
- LLVector4a* v = (LLVector4a*) face.mPositions;
- LLVector4a* n = (LLVector4a*) face.mNormals;
-
- for (U32 j = 0; j < face.mNumIndices/3; j++)
- {
- //approximate normal
- S32 v1 = face.mIndices[j*3+0];
- S32 v2 = face.mIndices[j*3+1];
- S32 v3 = face.mIndices[j*3+2];
-
- LLVector4a c1,c2;
- c1.setSub(v[v1], v[v2]);
- c2.setSub(v[v2], v[v3]);
-
- LLVector4a norm;
-
- norm.setCross3(c1, c2);
-
- if (norm.dot3(norm) < 0.00000001f)
- {
- fFacing[j] = AWAY | TOWARDS;
- }
- else
- {
- //get view vector
- LLVector4a view;
- view.setSub(obj_cam_vec, v[v1]);
- bool away = view.dot3(norm) > 0.0f;
- if (away)
- {
- fFacing[j] = AWAY;
- }
- else
- {
- fFacing[j] = TOWARDS;
- }
- }
- }
-
- //for each triangle
- for (U32 j = 0; j < face.mNumIndices/3; j++)
- {
- if (fFacing[j] == (AWAY | TOWARDS))
- { //this is a degenerate triangle
- //take neighbor facing (degenerate faces get facing of one of their neighbors)
- // *FIX IF NEEDED: this does not deal with neighboring degenerate faces
- for (S32 k = 0; k < 3; k++)
- {
- S32 index = face.mEdge[j*3+k];
- if (index != -1)
- {
- fFacing[j] = fFacing[index];
- break;
- }
- }
- continue; //skip degenerate face
- }
-
- //for each edge
- for (S32 k = 0; k < 3; k++) {
- S32 index = face.mEdge[j*3+k];
- if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) {
- //our neighbor is degenerate, make him face our direction
- fFacing[face.mEdge[j*3+k]] = fFacing[j];
- continue;
- }
-
- if (index == -1 || //edge has no neighbor, MUST be a silhouette edge
- (fFacing[index] & fFacing[j]) == 0) { //we found a silhouette edge
-
- S32 v1 = face.mIndices[j*3+k];
- S32 v2 = face.mIndices[j*3+((k+1)%3)];
-
- LLVector4a t;
- mat.affineTransform(v[v1], t);
- vertices.push_back(LLVector3(t[0], t[1], t[2]));
-
- norm_mat.rotate(n[v1], t);
-
- t.normalize3fast();
- normals.push_back(LLVector3(t[0], t[1], t[2]));
-
- mat.affineTransform(v[v2], t);
- vertices.push_back(LLVector3(t[0], t[1], t[2]));
-
- norm_mat.rotate(n[v2], t);
- t.normalize3fast();
- normals.push_back(LLVector3(t[0], t[1], t[2]));
- }
- }
- }
+ //==============================================
+ //DEBUG
+ //==============================================
+
+ static const U8 AWAY = 0x01,
+ TOWARDS = 0x02;
+
+ //for each triangle
+ std::vector<U8> fFacing;
+ vector_append(fFacing, face.mNumIndices/3);
+
+ LLVector4a* v = (LLVector4a*) face.mPositions;
+ LLVector4a* n = (LLVector4a*) face.mNormals;
+
+ for (U32 j = 0; j < face.mNumIndices/3; j++)
+ {
+ //approximate normal
+ S32 v1 = face.mIndices[j*3+0];
+ S32 v2 = face.mIndices[j*3+1];
+ S32 v3 = face.mIndices[j*3+2];
+
+ LLVector4a c1,c2;
+ c1.setSub(v[v1], v[v2]);
+ c2.setSub(v[v2], v[v3]);
+
+ LLVector4a norm;
+
+ norm.setCross3(c1, c2);
+
+ if (norm.dot3(norm) < 0.00000001f)
+ {
+ fFacing[j] = AWAY | TOWARDS;
+ }
+ else
+ {
+ //get view vector
+ LLVector4a view;
+ view.setSub(obj_cam_vec, v[v1]);
+ bool away = view.dot3(norm) > 0.0f;
+ if (away)
+ {
+ fFacing[j] = AWAY;
+ }
+ else
+ {
+ fFacing[j] = TOWARDS;
+ }
+ }
+ }
+
+ //for each triangle
+ for (U32 j = 0; j < face.mNumIndices/3; j++)
+ {
+ if (fFacing[j] == (AWAY | TOWARDS))
+ { //this is a degenerate triangle
+ //take neighbor facing (degenerate faces get facing of one of their neighbors)
+ // *FIX IF NEEDED: this does not deal with neighboring degenerate faces
+ for (S32 k = 0; k < 3; k++)
+ {
+ S32 index = face.mEdge[j*3+k];
+ if (index != -1)
+ {
+ fFacing[j] = fFacing[index];
+ break;
+ }
+ }
+ continue; //skip degenerate face
+ }
+
+ //for each edge
+ for (S32 k = 0; k < 3; k++) {
+ S32 index = face.mEdge[j*3+k];
+ if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) {
+ //our neighbor is degenerate, make him face our direction
+ fFacing[face.mEdge[j*3+k]] = fFacing[j];
+ continue;
+ }
+
+ if (index == -1 || //edge has no neighbor, MUST be a silhouette edge
+ (fFacing[index] & fFacing[j]) == 0) { //we found a silhouette edge
+
+ S32 v1 = face.mIndices[j*3+k];
+ S32 v2 = face.mIndices[j*3+((k+1)%3)];
+
+ LLVector4a t;
+ mat.affineTransform(v[v1], t);
+ vertices.push_back(LLVector3(t[0], t[1], t[2]));
+
+ norm_mat.rotate(n[v1], t);
+
+ t.normalize3fast();
+ normals.push_back(LLVector3(t[0], t[1], t[2]));
+
+ mat.affineTransform(v[v2], t);
+ vertices.push_back(LLVector3(t[0], t[1], t[2]));
+
+ norm_mat.rotate(n[v2], t);
+ t.normalize3fast();
+ normals.push_back(LLVector3(t[0], t[1], t[2]));
+ }
+ }
+ }
#endif
- }
- }
-}
-
-S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face,
- LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
-{
- S32 hit_face = -1;
-
- S32 start_face;
- S32 end_face;
-
- if (face == -1) // ALL_SIDES
- {
- start_face = 0;
- end_face = getNumVolumeFaces() - 1;
- }
- else
- {
- start_face = face;
- end_face = face;
- }
-
- LLVector4a dir;
- dir.setSub(end, start);
-
- F32 closest_t = 2.f; // must be larger than 1
-
- end_face = llmin(end_face, getNumVolumeFaces()-1);
-
- for (S32 i = start_face; i <= end_face; i++)
- {
- LLVolumeFace &face = mVolumeFaces[i];
-
- LLVector4a box_center;
- box_center.setAdd(face.mExtents[0], face.mExtents[1]);
- box_center.mul(0.5f);
-
- LLVector4a box_size;
- box_size.setSub(face.mExtents[1], face.mExtents[0]);
+ }
+ }
+}
+
+S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
+{
+ S32 hit_face = -1;
+
+ S32 start_face;
+ S32 end_face;
+
+ if (face == -1) // ALL_SIDES
+ {
+ start_face = 0;
+ end_face = getNumVolumeFaces() - 1;
+ }
+ else
+ {
+ start_face = face;
+ end_face = face;
+ }
+
+ LLVector4a dir;
+ dir.setSub(end, start);
+
+ F32 closest_t = 2.f; // must be larger than 1
+
+ end_face = llmin(end_face, getNumVolumeFaces()-1);
+
+ for (S32 i = start_face; i <= end_face; i++)
+ {
+ LLVolumeFace &face = mVolumeFaces[i];
+
+ LLVector4a box_center;
+ box_center.setAdd(face.mExtents[0], face.mExtents[1]);
+ box_center.mul(0.5f);
+
+ LLVector4a box_size;
+ box_size.setSub(face.mExtents[1], face.mExtents[0]);
if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))
- {
- if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
- {
+ {
+ if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
+ {
genTangents(i);
- }
-
- if (isUnique())
- { //don't bother with an octree for flexi volumes
- U32 tri_count = face.mNumIndices/3;
-
- for (U32 j = 0; j < tri_count; ++j)
- {
- U16 idx0 = face.mIndices[j*3+0];
- U16 idx1 = face.mIndices[j*3+1];
- U16 idx2 = face.mIndices[j*3+2];
-
- const LLVector4a& v0 = face.mPositions[idx0];
- const LLVector4a& v1 = face.mPositions[idx1];
- const LLVector4a& v2 = face.mPositions[idx2];
-
- F32 a,b,t;
-
- if (LLTriangleRayIntersect(v0, v1, v2,
- start, dir, a, b, t))
- {
- if ((t >= 0.f) && // if hit is after start
- (t <= 1.f) && // and before end
- (t < closest_t)) // and this hit is closer
- {
- closest_t = t;
- hit_face = i;
-
- if (intersection != NULL)
- {
- LLVector4a intersect = dir;
- intersect.mul(closest_t);
- intersect.add(start);
- *intersection = intersect;
- }
-
-
- if (tex_coord != NULL)
- {
- LLVector2* tc = (LLVector2*) face.mTexCoords;
- *tex_coord = ((1.f - a - b) * tc[idx0] +
- a * tc[idx1] +
- b * tc[idx2]);
-
- }
-
- if (normal!= NULL)
- {
- LLVector4a* norm = face.mNormals;
-
- LLVector4a n1,n2,n3;
- n1 = norm[idx0];
- n1.mul(1.f-a-b);
-
- n2 = norm[idx1];
- n2.mul(a);
-
- n3 = norm[idx2];
- n3.mul(b);
-
- n1.add(n2);
- n1.add(n3);
-
- *normal = n1;
- }
-
- if (tangent_out != NULL)
- {
- LLVector4a* tangents = face.mTangents;
-
- LLVector4a t1,t2,t3;
- t1 = tangents[idx0];
- t1.mul(1.f-a-b);
-
- t2 = tangents[idx1];
- t2.mul(a);
-
- t3 = tangents[idx2];
- t3.mul(b);
-
- t1.add(t2);
- t1.add(t3);
-
- *tangent_out = t1;
- }
- }
- }
- }
- }
- else
- {
+ }
+
+ if (isUnique())
+ { //don't bother with an octree for flexi volumes
+ U32 tri_count = face.mNumIndices/3;
+
+ for (U32 j = 0; j < tri_count; ++j)
+ {
+ U16 idx0 = face.mIndices[j*3+0];
+ U16 idx1 = face.mIndices[j*3+1];
+ U16 idx2 = face.mIndices[j*3+2];
+
+ const LLVector4a& v0 = face.mPositions[idx0];
+ const LLVector4a& v1 = face.mPositions[idx1];
+ const LLVector4a& v2 = face.mPositions[idx2];
+
+ F32 a,b,t;
+
+ if (LLTriangleRayIntersect(v0, v1, v2,
+ start, dir, a, b, t))
+ {
+ if ((t >= 0.f) && // if hit is after start
+ (t <= 1.f) && // and before end
+ (t < closest_t)) // and this hit is closer
+ {
+ closest_t = t;
+ hit_face = i;
+
+ if (intersection != NULL)
+ {
+ LLVector4a intersect = dir;
+ intersect.mul(closest_t);
+ intersect.add(start);
+ *intersection = intersect;
+ }
+
+
+ if (tex_coord != NULL)
+ {
+ LLVector2* tc = (LLVector2*) face.mTexCoords;
+ *tex_coord = ((1.f - a - b) * tc[idx0] +
+ a * tc[idx1] +
+ b * tc[idx2]);
+
+ }
+
+ if (normal!= NULL)
+ {
+ LLVector4a* norm = face.mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *normal = n1;
+ }
+
+ if (tangent_out != NULL)
+ {
+ LLVector4a* tangents = face.mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *tangent_out = t1;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
if (!face.getOctree())
- {
- face.createOctree();
- }
-
- LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
+ {
+ face.createOctree();
+ }
+
+ LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
intersect.traverse(face.getOctree());
- if (intersect.mHitFace)
- {
- hit_face = i;
- }
- }
- }
- }
-
-
- return hit_face;
+ if (intersect.mHitFace)
+ {
+ hit_face = i;
+ }
+ }
+ }
+ }
+
+
+ return hit_face;
}
class LLVertexIndexPair
{
public:
- LLVertexIndexPair(const LLVector3 &vertex, const S32 index);
+ LLVertexIndexPair(const LLVector3 &vertex, const S32 index);
- LLVector3 mVertex;
- S32 mIndex;
+ LLVector3 mVertex;
+ S32 mIndex;
};
LLVertexIndexPair::LLVertexIndexPair(const LLVector3 &vertex, const S32 index)
{
- mVertex = vertex;
- mIndex = index;
+ mVertex = vertex;
+ mIndex = index;
}
const F32 VERTEX_SLOP = 0.00001f;
struct lessVertex
{
- bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b)
- {
- const F32 slop = VERTEX_SLOP;
-
- if (a->mVertex.mV[0] + slop < b->mVertex.mV[0])
- {
- return TRUE;
- }
- else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0])
- {
- return FALSE;
- }
-
- if (a->mVertex.mV[1] + slop < b->mVertex.mV[1])
- {
- return TRUE;
- }
- else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1])
- {
- return FALSE;
- }
-
- if (a->mVertex.mV[2] + slop < b->mVertex.mV[2])
- {
- return TRUE;
- }
- else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2])
- {
- return FALSE;
- }
-
- return FALSE;
- }
+ bool operator()(const LLVertexIndexPair *a, const LLVertexIndexPair *b)
+ {
+ const F32 slop = VERTEX_SLOP;
+
+ if (a->mVertex.mV[0] + slop < b->mVertex.mV[0])
+ {
+ return TRUE;
+ }
+ else if (a->mVertex.mV[0] - slop > b->mVertex.mV[0])
+ {
+ return FALSE;
+ }
+
+ if (a->mVertex.mV[1] + slop < b->mVertex.mV[1])
+ {
+ return TRUE;
+ }
+ else if (a->mVertex.mV[1] - slop > b->mVertex.mV[1])
+ {
+ return FALSE;
+ }
+
+ if (a->mVertex.mV[2] + slop < b->mVertex.mV[2])
+ {
+ return TRUE;
+ }
+ else if (a->mVertex.mV[2] - slop > b->mVertex.mV[2])
+ {
+ return FALSE;
+ }
+
+ return FALSE;
+ }
};
struct lessTriangle
{
- bool operator()(const S32 *a, const S32 *b)
- {
- if (*a < *b)
- {
- return TRUE;
- }
- else if (*a > *b)
- {
- return FALSE;
- }
-
- if (*(a+1) < *(b+1))
- {
- return TRUE;
- }
- else if (*(a+1) > *(b+1))
- {
- return FALSE;
- }
-
- if (*(a+2) < *(b+2))
- {
- return TRUE;
- }
- else if (*(a+2) > *(b+2))
- {
- return FALSE;
- }
-
- return FALSE;
- }
+ bool operator()(const S32 *a, const S32 *b)
+ {
+ if (*a < *b)
+ {
+ return TRUE;
+ }
+ else if (*a > *b)
+ {
+ return FALSE;
+ }
+
+ if (*(a+1) < *(b+1))
+ {
+ return TRUE;
+ }
+ else if (*(a+1) > *(b+1))
+ {
+ return FALSE;
+ }
+
+ if (*(a+2) < *(b+2))
+ {
+ return TRUE;
+ }
+ else if (*(a+2) > *(b+2))
+ {
+ return FALSE;
+ }
+
+ return FALSE;
+ }
};
BOOL equalTriangle(const S32 *a, const S32 *b)
{
- if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2)))
- {
- return TRUE;
- }
- return FALSE;
+ if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2)))
+ {
+ return TRUE;
+ }
+ return FALSE;
}
BOOL LLVolumeParams::importFile(LLFILE *fp)
{
- //LL_INFOS() << "importing volume" << LL_ENDL;
- const S32 BUFSIZE = 16384;
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- // *NOTE: changing the size or type of this buffer will require
- // changing the sscanf below.
- char keyword[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
-
- while (!feof(fp))
- {
- if (fgets(buffer, BUFSIZE, fp) == NULL)
- {
- buffer[0] = '\0';
- }
-
- sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("profile", keyword))
- {
- mProfileParams.importFile(fp);
- }
- else if (!strcmp("path",keyword))
- {
- mPathParams.importFile(fp);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL;
- }
- }
-
- return TRUE;
+ //LL_INFOS() << "importing volume" << LL_ENDL;
+ const S32 BUFSIZE = 16384;
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ // *NOTE: changing the size or type of this buffer will require
+ // changing the sscanf below.
+ char keyword[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+
+ while (!feof(fp))
+ {
+ if (fgets(buffer, BUFSIZE, fp) == NULL)
+ {
+ buffer[0] = '\0';
+ }
+
+ sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("profile", keyword))
+ {
+ mProfileParams.importFile(fp);
+ }
+ else if (!strcmp("path",keyword))
+ {
+ mPathParams.importFile(fp);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL;
+ }
+ }
+
+ return TRUE;
}
BOOL LLVolumeParams::exportFile(LLFILE *fp) const
{
- fprintf(fp,"\tshape 0\n");
- fprintf(fp,"\t{\n");
- mPathParams.exportFile(fp);
- mProfileParams.exportFile(fp);
- fprintf(fp, "\t}\n");
- return TRUE;
+ fprintf(fp,"\tshape 0\n");
+ fprintf(fp,"\t{\n");
+ mPathParams.exportFile(fp);
+ mProfileParams.exportFile(fp);
+ fprintf(fp, "\t}\n");
+ return TRUE;
}
BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
{
- //LL_INFOS() << "importing volume" << LL_ENDL;
- const S32 BUFSIZE = 16384;
- // *NOTE: changing the size or type of this buffer will require
- // changing the sscanf below.
- char buffer[BUFSIZE]; /* Flawfinder: ignore */
- char keyword[256]; /* Flawfinder: ignore */
- keyword[0] = 0;
-
- while (input_stream.good())
- {
- input_stream.getline(buffer, BUFSIZE);
- sscanf(buffer, " %255s", keyword);
- if (!strcmp("{", keyword))
- {
- continue;
- }
- if (!strcmp("}",keyword))
- {
- break;
- }
- else if (!strcmp("profile", keyword))
- {
- mProfileParams.importLegacyStream(input_stream);
- }
- else if (!strcmp("path",keyword))
- {
- mPathParams.importLegacyStream(input_stream);
- }
- else
- {
- LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL;
- }
- }
-
- return TRUE;
+ //LL_INFOS() << "importing volume" << LL_ENDL;
+ const S32 BUFSIZE = 16384;
+ // *NOTE: changing the size or type of this buffer will require
+ // changing the sscanf below.
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ char keyword[256]; /* Flawfinder: ignore */
+ keyword[0] = 0;
+
+ while (input_stream.good())
+ {
+ input_stream.getline(buffer, BUFSIZE);
+ sscanf(buffer, " %255s", keyword);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("profile", keyword))
+ {
+ mProfileParams.importLegacyStream(input_stream);
+ }
+ else if (!strcmp("path",keyword))
+ {
+ mPathParams.importLegacyStream(input_stream);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword " << keyword << " in volume import" << LL_ENDL;
+ }
+ }
+
+ return TRUE;
}
BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const
{
- output_stream <<"\tshape 0\n";
- output_stream <<"\t{\n";
- mPathParams.exportLegacyStream(output_stream);
- mProfileParams.exportLegacyStream(output_stream);
- output_stream << "\t}\n";
- return TRUE;
+ output_stream <<"\tshape 0\n";
+ output_stream <<"\t{\n";
+ mPathParams.exportLegacyStream(output_stream);
+ mProfileParams.exportLegacyStream(output_stream);
+ output_stream << "\t}\n";
+ return TRUE;
}
LLSD LLVolumeParams::sculptAsLLSD() const
{
- LLSD sd = LLSD();
- sd["id"] = getSculptID();
- sd["type"] = getSculptType();
+ LLSD sd = LLSD();
+ sd["id"] = getSculptID();
+ sd["type"] = getSculptType();
- return sd;
+ return sd;
}
bool LLVolumeParams::sculptFromLLSD(LLSD& sd)
{
- setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger());
- return true;
+ setSculptID(sd["id"].asUUID(), (U8)sd["type"].asInteger());
+ return true;
}
LLSD LLVolumeParams::asLLSD() const
{
- LLSD sd = LLSD();
- sd["path"] = mPathParams;
- sd["profile"] = mProfileParams;
- sd["sculpt"] = sculptAsLLSD();
-
- return sd;
+ LLSD sd = LLSD();
+ sd["path"] = mPathParams;
+ sd["profile"] = mProfileParams;
+ sd["sculpt"] = sculptAsLLSD();
+
+ return sd;
}
bool LLVolumeParams::fromLLSD(LLSD& sd)
{
- mPathParams.fromLLSD(sd["path"]);
- mProfileParams.fromLLSD(sd["profile"]);
- sculptFromLLSD(sd["sculpt"]);
-
- return true;
+ mPathParams.fromLLSD(sd["path"]);
+ mProfileParams.fromLLSD(sd["profile"]);
+ sculptFromLLSD(sd["sculpt"]);
+
+ return true;
}
void LLVolumeParams::reduceS(F32 begin, F32 end)
{
- begin = llclampf(begin);
- end = llclampf(end);
- if (begin > end)
- {
- F32 temp = begin;
- begin = end;
- end = temp;
- }
- F32 a = mProfileParams.getBegin();
- F32 b = mProfileParams.getEnd();
- mProfileParams.setBegin(a + begin * (b - a));
- mProfileParams.setEnd(a + end * (b - a));
+ begin = llclampf(begin);
+ end = llclampf(end);
+ if (begin > end)
+ {
+ F32 temp = begin;
+ begin = end;
+ end = temp;
+ }
+ F32 a = mProfileParams.getBegin();
+ F32 b = mProfileParams.getEnd();
+ mProfileParams.setBegin(a + begin * (b - a));
+ mProfileParams.setEnd(a + end * (b - a));
}
void LLVolumeParams::reduceT(F32 begin, F32 end)
{
- begin = llclampf(begin);
- end = llclampf(end);
- if (begin > end)
- {
- F32 temp = begin;
- begin = end;
- end = temp;
- }
- F32 a = mPathParams.getBegin();
- F32 b = mPathParams.getEnd();
- mPathParams.setBegin(a + begin * (b - a));
- mPathParams.setEnd(a + end * (b - a));
+ begin = llclampf(begin);
+ end = llclampf(end);
+ if (begin > end)
+ {
+ F32 temp = begin;
+ begin = end;
+ end = temp;
+ }
+ F32 a = mPathParams.getBegin();
+ F32 b = mPathParams.getEnd();
+ mPathParams.setBegin(a + begin * (b - a));
+ mPathParams.setEnd(a + end * (b - a));
}
-const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity
-const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity
+const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity
+const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity
-// returns TRUE if the shape can be approximated with a convex shape
+// returns TRUE if the shape can be approximated with a convex shape
// for collison purposes
BOOL LLVolumeParams::isConvex() const
{
- if (!getSculptID().isNull())
- {
- // can't determine, be safe and say no:
- return FALSE;
- }
-
- F32 path_length = mPathParams.getEnd() - mPathParams.getBegin();
- F32 hollow = mProfileParams.getHollow();
-
- U8 path_type = mPathParams.getCurveType();
- if ( path_length > MIN_CONCAVE_PATH_WEDGE
- && ( mPathParams.getTwist() != mPathParams.getTwistBegin()
- || (hollow > 0.f
- && LL_PCODE_PATH_LINE != path_type) ) )
- {
- // twist along a "not too short" path is concave
- return FALSE;
- }
-
- F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin();
- BOOL same_hole = hollow == 0.f
- || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME;
-
- F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE;
- U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
- if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
- {
- // it is a sphere and spheres get twice the minimum profile wedge
- min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE;
- }
-
- BOOL convex_profile = ( ( profile_length == 1.f
- || profile_length <= 0.5f )
- && hollow == 0.f ) // trivially convex
- || ( profile_length <= min_profile_wedge
- && same_hole ); // effectvely convex (even when hollow)
-
- if (!convex_profile)
- {
- // profile is concave
- return FALSE;
- }
-
- if ( LL_PCODE_PATH_LINE == path_type )
- {
- // straight paths with convex profile
- return TRUE;
- }
-
- BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f);
- if (concave_path)
- {
- return FALSE;
- }
-
- // we're left with spheres, toroids and tubes
- if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
- {
- // at this stage all spheres must be convex
- return TRUE;
- }
-
- // it's a toroid or tube
- if ( path_length <= MIN_CONCAVE_PATH_WEDGE )
- {
- // effectively convex
- return TRUE;
- }
-
- return FALSE;
+ if (!getSculptID().isNull())
+ {
+ // can't determine, be safe and say no:
+ return FALSE;
+ }
+
+ F32 path_length = mPathParams.getEnd() - mPathParams.getBegin();
+ F32 hollow = mProfileParams.getHollow();
+
+ U8 path_type = mPathParams.getCurveType();
+ if ( path_length > MIN_CONCAVE_PATH_WEDGE
+ && ( mPathParams.getTwist() != mPathParams.getTwistBegin()
+ || (hollow > 0.f
+ && LL_PCODE_PATH_LINE != path_type) ) )
+ {
+ // twist along a "not too short" path is concave
+ return FALSE;
+ }
+
+ F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin();
+ BOOL same_hole = hollow == 0.f
+ || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME;
+
+ F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE;
+ U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
+ if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
+ {
+ // it is a sphere and spheres get twice the minimum profile wedge
+ min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE;
+ }
+
+ BOOL convex_profile = ( ( profile_length == 1.f
+ || profile_length <= 0.5f )
+ && hollow == 0.f ) // trivially convex
+ || ( profile_length <= min_profile_wedge
+ && same_hole ); // effectvely convex (even when hollow)
+
+ if (!convex_profile)
+ {
+ // profile is concave
+ return FALSE;
+ }
+
+ if ( LL_PCODE_PATH_LINE == path_type )
+ {
+ // straight paths with convex profile
+ return TRUE;
+ }
+
+ BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f);
+ if (concave_path)
+ {
+ return FALSE;
+ }
+
+ // we're left with spheres, toroids and tubes
+ if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
+ {
+ // at this stage all spheres must be convex
+ return TRUE;
+ }
+
+ // it's a toroid or tube
+ if ( path_length <= MIN_CONCAVE_PATH_WEDGE )
+ {
+ // effectively convex
+ return TRUE;
+ }
+
+ return FALSE;
}
// debug
void LLVolumeParams::setCube()
{
- mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE);
- mProfileParams.setBegin(0.f);
- mProfileParams.setEnd(1.f);
- mProfileParams.setHollow(0.f);
+ mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE);
+ mProfileParams.setBegin(0.f);
+ mProfileParams.setEnd(1.f);
+ mProfileParams.setHollow(0.f);
- mPathParams.setBegin(0.f);
- mPathParams.setEnd(1.f);
- mPathParams.setScale(1.f, 1.f);
- mPathParams.setShear(0.f, 0.f);
- mPathParams.setCurveType(LL_PCODE_PATH_LINE);
- mPathParams.setTwistBegin(0.f);
- mPathParams.setTwistEnd(0.f);
- mPathParams.setRadiusOffset(0.f);
- mPathParams.setTaper(0.f, 0.f);
- mPathParams.setRevolutions(0.f);
- mPathParams.setSkew(0.f);
+ mPathParams.setBegin(0.f);
+ mPathParams.setEnd(1.f);
+ mPathParams.setScale(1.f, 1.f);
+ mPathParams.setShear(0.f, 0.f);
+ mPathParams.setCurveType(LL_PCODE_PATH_LINE);
+ mPathParams.setTwistBegin(0.f);
+ mPathParams.setTwistEnd(0.f);
+ mPathParams.setRadiusOffset(0.f);
+ mPathParams.setTaper(0.f, 0.f);
+ mPathParams.setRevolutions(0.f);
+ mPathParams.setSkew(0.f);
}
LLFaceID LLVolume::generateFaceMask()
{
- LLFaceID new_mask = 0x0000;
-
- switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK)
- {
- case LL_PCODE_PROFILE_CIRCLE:
- case LL_PCODE_PROFILE_CIRCLE_HALF:
- new_mask |= LL_FACE_OUTER_SIDE_0;
- break;
- case LL_PCODE_PROFILE_SQUARE:
- {
- for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++)
- {
- new_mask |= LL_FACE_OUTER_SIDE_0 << side;
- }
- }
- break;
- case LL_PCODE_PROFILE_ISOTRI:
- case LL_PCODE_PROFILE_EQUALTRI:
- case LL_PCODE_PROFILE_RIGHTTRI:
- {
- for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++)
- {
- new_mask |= LL_FACE_OUTER_SIDE_0 << side;
- }
- }
- break;
- default:
- LL_ERRS() << "Unknown profile!" << LL_ENDL;
- break;
- }
-
- // handle hollow objects
- if (mParams.getProfileParams().getHollow() > 0)
- {
- new_mask |= LL_FACE_INNER_SIDE;
- }
-
- // handle open profile curves
- if (mProfilep->isOpen())
- {
- new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END;
- }
-
- // handle open path curves
- if (mPathp->isOpen())
- {
- new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END;
- }
-
- return new_mask;
+ LLFaceID new_mask = 0x0000;
+
+ switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK)
+ {
+ case LL_PCODE_PROFILE_CIRCLE:
+ case LL_PCODE_PROFILE_CIRCLE_HALF:
+ new_mask |= LL_FACE_OUTER_SIDE_0;
+ break;
+ case LL_PCODE_PROFILE_SQUARE:
+ {
+ for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++)
+ {
+ new_mask |= LL_FACE_OUTER_SIDE_0 << side;
+ }
+ }
+ break;
+ case LL_PCODE_PROFILE_ISOTRI:
+ case LL_PCODE_PROFILE_EQUALTRI:
+ case LL_PCODE_PROFILE_RIGHTTRI:
+ {
+ for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++)
+ {
+ new_mask |= LL_FACE_OUTER_SIDE_0 << side;
+ }
+ }
+ break;
+ default:
+ LL_ERRS() << "Unknown profile!" << LL_ENDL;
+ break;
+ }
+
+ // handle hollow objects
+ if (mParams.getProfileParams().getHollow() > 0)
+ {
+ new_mask |= LL_FACE_INNER_SIDE;
+ }
+
+ // handle open profile curves
+ if (mProfilep->isOpen())
+ {
+ new_mask |= LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END;
+ }
+
+ // handle open path curves
+ if (mPathp->isOpen())
+ {
+ new_mask |= LL_FACE_PATH_BEGIN | LL_FACE_PATH_END;
+ }
+
+ return new_mask;
}
BOOL LLVolume::isFaceMaskValid(LLFaceID face_mask)
{
- LLFaceID test_mask = 0;
- for(S32 i = 0; i < getNumFaces(); i++)
- {
- test_mask |= mProfilep->mFaces[i].mFaceID;
- }
+ LLFaceID test_mask = 0;
+ for(S32 i = 0; i < getNumFaces(); i++)
+ {
+ test_mask |= mProfilep->mFaces[i].mFaceID;
+ }
- return test_mask == face_mask;
+ return test_mask == face_mask;
}
BOOL LLVolume::isConvex() const
{
- // mParams.isConvex() may return FALSE even though the final
- // geometry is actually convex due to LOD approximations.
- // TODO -- provide LLPath and LLProfile with isConvex() methods
- // that correctly determine convexity. -- Leviathan
- return mParams.isConvex();
+ // mParams.isConvex() may return FALSE even though the final
+ // geometry is actually convex due to LOD approximations.
+ // TODO -- provide LLPath and LLProfile with isConvex() methods
+ // that correctly determine convexity. -- Leviathan
+ return mParams.isConvex();
}
std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params)
{
- s << "{type=" << (U32) profile_params.mCurveType;
- s << ", begin=" << profile_params.mBegin;
- s << ", end=" << profile_params.mEnd;
- s << ", hollow=" << profile_params.mHollow;
- s << "}";
- return s;
+ s << "{type=" << (U32) profile_params.mCurveType;
+ s << ", begin=" << profile_params.mBegin;
+ s << ", end=" << profile_params.mEnd;
+ s << ", hollow=" << profile_params.mHollow;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params)
{
- s << "{type=" << (U32) path_params.mCurveType;
- s << ", begin=" << path_params.mBegin;
- s << ", end=" << path_params.mEnd;
- s << ", twist=" << path_params.mTwistEnd;
- s << ", scale=" << path_params.mScale;
- s << ", shear=" << path_params.mShear;
- s << ", twist_begin=" << path_params.mTwistBegin;
- s << ", radius_offset=" << path_params.mRadiusOffset;
- s << ", taper=" << path_params.mTaper;
- s << ", revolutions=" << path_params.mRevolutions;
- s << ", skew=" << path_params.mSkew;
- s << "}";
- return s;
+ s << "{type=" << (U32) path_params.mCurveType;
+ s << ", begin=" << path_params.mBegin;
+ s << ", end=" << path_params.mEnd;
+ s << ", twist=" << path_params.mTwistEnd;
+ s << ", scale=" << path_params.mScale;
+ s << ", shear=" << path_params.mShear;
+ s << ", twist_begin=" << path_params.mTwistBegin;
+ s << ", radius_offset=" << path_params.mRadiusOffset;
+ s << ", taper=" << path_params.mTaper;
+ s << ", revolutions=" << path_params.mRevolutions;
+ s << ", skew=" << path_params.mSkew;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params)
{
- s << "{profileparams = " << volume_params.mProfileParams;
- s << ", pathparams = " << volume_params.mPathParams;
- s << "}";
- return s;
+ s << "{profileparams = " << volume_params.mProfileParams;
+ s << ", pathparams = " << volume_params.mPathParams;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLProfile &profile)
{
- s << " {open=" << (U32) profile.mOpen;
- s << ", dirty=" << profile.mDirty;
- s << ", totalout=" << profile.mTotalOut;
- s << ", total=" << profile.mTotal;
- s << "}";
- return s;
+ s << " {open=" << (U32) profile.mOpen;
+ s << ", dirty=" << profile.mDirty;
+ s << ", totalout=" << profile.mTotalOut;
+ s << ", total=" << profile.mTotal;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLPath &path)
{
- s << "{open=" << (U32) path.mOpen;
- s << ", dirty=" << path.mDirty;
- s << ", step=" << path.mStep;
- s << ", total=" << path.mTotal;
- s << "}";
- return s;
+ s << "{open=" << (U32) path.mOpen;
+ s << ", dirty=" << path.mDirty;
+ s << ", step=" << path.mStep;
+ s << ", total=" << path.mTotal;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLVolume &volume)
{
- s << "{params = " << volume.getParams();
- s << ", path = " << *volume.mPathp;
- s << ", profile = " << *volume.mProfilep;
- s << "}";
- return s;
+ s << "{params = " << volume.getParams();
+ s << ", path = " << *volume.mPathp;
+ s << ", profile = " << *volume.mProfilep;
+ s << "}";
+ return s;
}
std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)
{
- s << "{params = " << volumep->getParams();
- s << ", path = " << *(volumep->mPathp);
- s << ", profile = " << *(volumep->mProfilep);
- s << "}";
- return s;
-}
-
-LLVolumeFace::LLVolumeFace() :
- mID(0),
- mTypeMask(0),
- mBeginS(0),
- mBeginT(0),
- mNumS(0),
- mNumT(0),
- mNumVertices(0),
- mNumAllocatedVertices(0),
- mNumIndices(0),
- mPositions(NULL),
- mNormals(NULL),
- mTangents(NULL),
- mTexCoords(NULL),
- mIndices(NULL),
- mWeights(NULL),
+ s << "{params = " << volumep->getParams();
+ s << ", path = " << *(volumep->mPathp);
+ s << ", profile = " << *(volumep->mProfilep);
+ s << "}";
+ return s;
+}
+
+LLVolumeFace::LLVolumeFace() :
+ mID(0),
+ mTypeMask(0),
+ mBeginS(0),
+ mBeginT(0),
+ mNumS(0),
+ mNumT(0),
+ mNumVertices(0),
+ mNumAllocatedVertices(0),
+ mNumIndices(0),
+ mPositions(NULL),
+ mNormals(NULL),
+ mTangents(NULL),
+ mTexCoords(NULL),
+ mIndices(NULL),
+ mWeights(NULL),
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
mJustWeights(NULL),
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
- mOctree(NULL),
+ mOctree(NULL),
mOctreeTriangles(NULL),
- mOptimized(FALSE)
+ mOptimized(FALSE)
{
- mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
- mExtents[0].splat(-0.5f);
- mExtents[1].splat(0.5f);
- mCenter = mExtents+2;
+ mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
+ mExtents[0].splat(-0.5f);
+ mExtents[1].splat(0.5f);
+ mCenter = mExtents+2;
}
LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
-: mID(0),
- mTypeMask(0),
- mBeginS(0),
- mBeginT(0),
- mNumS(0),
- mNumT(0),
- mNumVertices(0),
- mNumAllocatedVertices(0),
- mNumIndices(0),
- mPositions(NULL),
- mNormals(NULL),
- mTangents(NULL),
- mTexCoords(NULL),
- mIndices(NULL),
- mWeights(NULL),
+: mID(0),
+ mTypeMask(0),
+ mBeginS(0),
+ mBeginT(0),
+ mNumS(0),
+ mNumT(0),
+ mNumVertices(0),
+ mNumAllocatedVertices(0),
+ mNumIndices(0),
+ mPositions(NULL),
+ mNormals(NULL),
+ mTangents(NULL),
+ mTexCoords(NULL),
+ mIndices(NULL),
+ mWeights(NULL),
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
mJustWeights(NULL),
mJointIndices(NULL),
@@ -4824,78 +4752,78 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mOctree(NULL),
mOctreeTriangles(NULL)
{
- mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
- mCenter = mExtents+2;
- *this = src;
+ mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
+ mCenter = mExtents+2;
+ *this = src;
}
LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
{
- if (&src == this)
- { //self assignment, do nothing
- return *this;
- }
-
- mID = src.mID;
- mTypeMask = src.mTypeMask;
- mBeginS = src.mBeginS;
- mBeginT = src.mBeginT;
- mNumS = src.mNumS;
- mNumT = src.mNumT;
-
- mExtents[0] = src.mExtents[0];
- mExtents[1] = src.mExtents[1];
- *mCenter = *src.mCenter;
-
- mNumVertices = 0;
- mNumIndices = 0;
-
- freeData();
-
- resizeVertices(src.mNumVertices);
- resizeIndices(src.mNumIndices);
-
- if (mNumVertices)
- {
- S32 vert_size = mNumVertices*sizeof(LLVector4a);
- S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF;
-
- LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);
-
- if (src.mNormals)
- {
- LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
- }
-
- if(src.mTexCoords)
- {
- LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size);
- }
-
- if (src.mTangents)
- {
- allocateTangents(src.mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);
- }
- else
- {
- ll_aligned_free_16(mTangents);
- mTangents = NULL;
- }
-
- if (src.mWeights)
- {
+ if (&src == this)
+ { //self assignment, do nothing
+ return *this;
+ }
+
+ mID = src.mID;
+ mTypeMask = src.mTypeMask;
+ mBeginS = src.mBeginS;
+ mBeginT = src.mBeginT;
+ mNumS = src.mNumS;
+ mNumT = src.mNumT;
+
+ mExtents[0] = src.mExtents[0];
+ mExtents[1] = src.mExtents[1];
+ *mCenter = *src.mCenter;
+
+ mNumVertices = 0;
+ mNumIndices = 0;
+
+ freeData();
+
+ resizeVertices(src.mNumVertices);
+ resizeIndices(src.mNumIndices);
+
+ if (mNumVertices)
+ {
+ S32 vert_size = mNumVertices*sizeof(LLVector4a);
+ S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF;
+
+ LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);
+
+ if (src.mNormals)
+ {
+ LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
+ }
+
+ if(src.mTexCoords)
+ {
+ LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size);
+ }
+
+ if (src.mTangents)
+ {
+ allocateTangents(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);
+ }
+ else
+ {
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
+ }
+
+ if (src.mWeights)
+ {
llassert(!mWeights); // don't orphan an old alloc here accidentally
- allocateWeights(src.mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
+ allocateWeights(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
mWeightsScrubbed = src.mWeightsScrubbed;
- }
- else
- {
- ll_aligned_free_16(mWeights);
- mWeights = NULL;
+ }
+ else
+ {
+ ll_aligned_free_16(mWeights);
+ mWeights = NULL;
mWeightsScrubbed = FALSE;
- }
+ }
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
if (src.mJointIndices)
@@ -4908,60 +4836,60 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
{
ll_aligned_free_16(mJointIndices);
mJointIndices = NULL;
- }
+ }
#endif
- }
-
- if (mNumIndices)
- {
- S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF;
-
- LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);
- }
- else
+ }
+
+ if (mNumIndices)
+ {
+ S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF;
+
+ LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);
+ }
+ else
{
ll_aligned_free_16(mIndices);
mIndices = NULL;
}
- mOptimized = src.mOptimized;
+ mOptimized = src.mOptimized;
mNormalizedScale = src.mNormalizedScale;
- //delete
- return *this;
+ //delete
+ return *this;
}
LLVolumeFace::~LLVolumeFace()
{
- ll_aligned_free_16(mExtents);
- mExtents = NULL;
- mCenter = NULL;
+ ll_aligned_free_16(mExtents);
+ mExtents = NULL;
+ mCenter = NULL;
- freeData();
+ freeData();
}
void LLVolumeFace::freeData()
{
- ll_aligned_free<64>(mPositions);
- mPositions = NULL;
+ ll_aligned_free<64>(mPositions);
+ mPositions = NULL;
- //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately
- mNormals = NULL;
- mTexCoords = NULL;
+ //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately
+ mNormals = NULL;
+ mTexCoords = NULL;
- ll_aligned_free_16(mIndices);
- mIndices = NULL;
- ll_aligned_free_16(mTangents);
- mTangents = NULL;
- ll_aligned_free_16(mWeights);
- mWeights = NULL;
+ ll_aligned_free_16(mIndices);
+ mIndices = NULL;
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
+ ll_aligned_free_16(mWeights);
+ mWeights = NULL;
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
ll_aligned_free_16(mJointIndices);
- mJointIndices = NULL;
+ mJointIndices = NULL;
ll_aligned_free_16(mJustWeights);
- mJustWeights = NULL;
+ mJustWeights = NULL;
#endif
destroyOctree();
@@ -4969,73 +4897,73 @@ void LLVolumeFace::freeData()
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- //tree for this face is no longer valid
+ //tree for this face is no longer valid
destroyOctree();
- LL_CHECK_MEMORY
- BOOL ret = FALSE ;
- if (mTypeMask & CAP_MASK)
- {
- ret = createCap(volume, partial_build);
- LL_CHECK_MEMORY
- }
- else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
- {
- ret = createSide(volume, partial_build);
- LL_CHECK_MEMORY
- }
- else
- {
- LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL;
- }
-
- return ret ;
+ LL_CHECK_MEMORY
+ BOOL ret = FALSE ;
+ if (mTypeMask & CAP_MASK)
+ {
+ ret = createCap(volume, partial_build);
+ LL_CHECK_MEMORY
+ }
+ else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
+ {
+ ret = createSide(volume, partial_build);
+ LL_CHECK_MEMORY
+ }
+ else
+ {
+ LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL;
+ }
+
+ return ret ;
}
void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv)
{
- cv.setPosition(mPositions[index]);
- if (mNormals)
- {
- cv.setNormal(mNormals[index]);
- }
- else
- {
- cv.getNormal().clear();
- }
-
- if (mTexCoords)
- {
- cv.mTexCoord = mTexCoords[index];
- }
- else
- {
- cv.mTexCoord.clear();
- }
+ cv.setPosition(mPositions[index]);
+ if (mNormals)
+ {
+ cv.setNormal(mNormals[index]);
+ }
+ else
+ {
+ cv.getNormal().clear();
+ }
+
+ if (mTexCoords)
+ {
+ cv.mTexCoord = mTexCoords[index];
+ }
+ else
+ {
+ cv.mTexCoord.clear();
+ }
}
bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const
{
- return getPosition().equals3(rhs.getPosition()) &&
- mTexCoord == rhs.mTexCoord &&
- getNormal().equals3(rhs.getNormal());
+ return getPosition().equals3(rhs.getPosition()) &&
+ mTexCoord == rhs.mTexCoord &&
+ getNormal().equals3(rhs.getNormal());
}
bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a, const LLVector3& b) const
{
- if (a.mV[0] != b.mV[0])
- {
- return a.mV[0] < b.mV[0];
- }
-
- if (a.mV[1] != b.mV[1])
- {
- return a.mV[1] < b.mV[1];
- }
-
- return a.mV[2] < b.mV[2];
+ if (a.mV[0] != b.mV[0])
+ {
+ return a.mV[0] < b.mV[0];
+ }
+
+ if (a.mV[1] != b.mV[1])
+ {
+ return a.mV[1] < b.mV[1];
+ }
+
+ return a.mV[2] < b.mV[2];
}
void LLVolumeFace::remap()
@@ -5084,18 +5012,18 @@ void LLVolumeFace::remap()
void LLVolumeFace::optimize(F32 angle_cutoff)
{
- LLVolumeFace new_face;
+ LLVolumeFace new_face;
- //map of points to vector of vertices at that point
- std::map<U64, std::vector<VertexMapData> > point_map;
+ //map of points to vector of vertices at that point
+ std::map<U64, std::vector<VertexMapData> > point_map;
- LLVector4a range;
- range.setSub(mExtents[1],mExtents[0]);
+ LLVector4a range;
+ range.setSub(mExtents[1],mExtents[0]);
- //remove redundant vertices
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- U16 index = mIndices[i];
+ //remove redundant vertices
+ for (U32 i = 0; i < mNumIndices; ++i)
+ {
+ U16 index = mIndices[i];
if (index >= mNumVertices)
{
@@ -5108,81 +5036,81 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
- LLVolumeFace::VertexData cv;
- getVertexData(index, cv);
-
- BOOL found = FALSE;
-
- LLVector4a pos;
- pos.setSub(mPositions[index], mExtents[0]);
- pos.div(range);
-
- U64 pos64 = 0;
-
- pos64 = (U16) (pos[0]*65535);
- pos64 = pos64 | (((U64) (pos[1]*65535)) << 16);
- pos64 = pos64 | (((U64) (pos[2]*65535)) << 32);
-
- std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64);
-
- if (point_iter != point_map.end())
- { //duplicate point might exist
- for (U32 j = 0; j < point_iter->second.size(); ++j)
- {
- LLVolumeFace::VertexData& tv = (point_iter->second)[j];
- if (tv.compareNormal(cv, angle_cutoff))
- {
- found = TRUE;
- new_face.pushIndex((point_iter->second)[j].mIndex);
- break;
- }
- }
- }
-
- if (!found)
- {
- new_face.pushVertex(cv);
- U16 index = (U16) new_face.mNumVertices-1;
- new_face.pushIndex(index);
-
- VertexMapData d;
- d.setPosition(cv.getPosition());
- d.mTexCoord = cv.mTexCoord;
- d.setNormal(cv.getNormal());
- d.mIndex = index;
- if (point_iter != point_map.end())
- {
- point_iter->second.push_back(d);
- }
- else
- {
- point_map[pos64].push_back(d);
- }
- }
- }
-
-
- if (angle_cutoff > 1.f && !mNormals)
- {
- // Now alloc'd with positions
- //ll_aligned_free_16(new_face.mNormals);
- new_face.mNormals = NULL;
- }
-
- if (!mTexCoords)
- {
- // Now alloc'd with positions
- //ll_aligned_free_16(new_face.mTexCoords);
- new_face.mTexCoords = NULL;
- }
-
- // Only swap data if we've actually optimized the mesh
- //
- if (new_face.mNumVertices <= mNumVertices)
- {
+ LLVolumeFace::VertexData cv;
+ getVertexData(index, cv);
+
+ BOOL found = FALSE;
+
+ LLVector4a pos;
+ pos.setSub(mPositions[index], mExtents[0]);
+ pos.div(range);
+
+ U64 pos64 = 0;
+
+ pos64 = (U16) (pos[0]*65535);
+ pos64 = pos64 | (((U64) (pos[1]*65535)) << 16);
+ pos64 = pos64 | (((U64) (pos[2]*65535)) << 32);
+
+ std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64);
+
+ if (point_iter != point_map.end())
+ { //duplicate point might exist
+ for (U32 j = 0; j < point_iter->second.size(); ++j)
+ {
+ LLVolumeFace::VertexData& tv = (point_iter->second)[j];
+ if (tv.compareNormal(cv, angle_cutoff))
+ {
+ found = TRUE;
+ new_face.pushIndex((point_iter->second)[j].mIndex);
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ new_face.pushVertex(cv);
+ U16 index = (U16) new_face.mNumVertices-1;
+ new_face.pushIndex(index);
+
+ VertexMapData d;
+ d.setPosition(cv.getPosition());
+ d.mTexCoord = cv.mTexCoord;
+ d.setNormal(cv.getNormal());
+ d.mIndex = index;
+ if (point_iter != point_map.end())
+ {
+ point_iter->second.push_back(d);
+ }
+ else
+ {
+ point_map[pos64].push_back(d);
+ }
+ }
+ }
+
+
+ if (angle_cutoff > 1.f && !mNormals)
+ {
+ // Now alloc'd with positions
+ //ll_aligned_free_16(new_face.mNormals);
+ new_face.mNormals = NULL;
+ }
+
+ if (!mTexCoords)
+ {
+ // Now alloc'd with positions
+ //ll_aligned_free_16(new_face.mTexCoords);
+ new_face.mTexCoords = NULL;
+ }
+
+ // Only swap data if we've actually optimized the mesh
+ //
+ if (new_face.mNumVertices <= mNumVertices)
+ {
llassert(new_face.mNumIndices == mNumIndices);
- swapData(new_face);
- }
+ swapData(new_face);
+ }
}
@@ -5191,52 +5119,52 @@ class LLVCacheTriangleData;
class LLVCacheVertexData
{
public:
- S32 mIdx;
- S32 mCacheTag;
- F64 mScore;
- U32 mActiveTriangles;
- std::vector<LLVCacheTriangleData*> mTriangles;
-
- LLVCacheVertexData()
- {
- mCacheTag = -1;
- mScore = 0.0;
- mActiveTriangles = 0;
- mIdx = -1;
- }
+ S32 mIdx;
+ S32 mCacheTag;
+ F64 mScore;
+ U32 mActiveTriangles;
+ std::vector<LLVCacheTriangleData*> mTriangles;
+
+ LLVCacheVertexData()
+ {
+ mCacheTag = -1;
+ mScore = 0.0;
+ mActiveTriangles = 0;
+ mIdx = -1;
+ }
};
class LLVCacheTriangleData
{
public:
- bool mActive;
- F64 mScore;
- LLVCacheVertexData* mVertex[3];
-
- LLVCacheTriangleData()
- {
- mActive = true;
- mScore = 0.0;
- mVertex[0] = mVertex[1] = mVertex[2] = NULL;
- }
-
- void complete()
- {
- mActive = false;
- for (S32 i = 0; i < 3; ++i)
- {
- if (mVertex[i])
- {
- llassert(mVertex[i]->mActiveTriangles > 0);
- mVertex[i]->mActiveTriangles--;
- }
- }
- }
-
- bool operator<(const LLVCacheTriangleData& rhs) const
- { //highest score first
- return rhs.mScore < mScore;
- }
+ bool mActive;
+ F64 mScore;
+ LLVCacheVertexData* mVertex[3];
+
+ LLVCacheTriangleData()
+ {
+ mActive = true;
+ mScore = 0.0;
+ mVertex[0] = mVertex[1] = mVertex[2] = NULL;
+ }
+
+ void complete()
+ {
+ mActive = false;
+ for (S32 i = 0; i < 3; ++i)
+ {
+ if (mVertex[i])
+ {
+ llassert(mVertex[i]->mActiveTriangles > 0);
+ mVertex[i]->mActiveTriangles--;
+ }
+ }
+ }
+
+ bool operator<(const LLVCacheTriangleData& rhs) const
+ { //highest score first
+ return rhs.mScore < mScore;
+ }
};
const F64 FindVertexScore_CacheDecayPower = 1.5;
@@ -5248,205 +5176,205 @@ const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3);
F64 find_vertex_score(LLVCacheVertexData& data)
{
- F64 score = -1.0;
+ F64 score = -1.0;
- score = 0.0;
+ score = 0.0;
- S32 cache_idx = data.mCacheTag;
+ S32 cache_idx = data.mCacheTag;
- if (cache_idx < 0)
- {
- //not in cache
- }
- else
- {
- if (cache_idx < 3)
- { //vertex was in the last triangle
- score = FindVertexScore_LastTriScore;
- }
- else
- { //more points for being higher in the cache
- score = 1.0-((cache_idx-3)*FindVertexScore_Scaler);
- score = pow(score, FindVertexScore_CacheDecayPower);
- }
- }
+ if (cache_idx < 0)
+ {
+ //not in cache
+ }
+ else
+ {
+ if (cache_idx < 3)
+ { //vertex was in the last triangle
+ score = FindVertexScore_LastTriScore;
+ }
+ else
+ { //more points for being higher in the cache
+ score = 1.0-((cache_idx-3)*FindVertexScore_Scaler);
+ score = pow(score, FindVertexScore_CacheDecayPower);
+ }
+ }
- //bonus points for having low valence
- F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
- score += FindVertexScore_ValenceBoostScale * valence_boost;
+ //bonus points for having low valence
+ F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
+ score += FindVertexScore_ValenceBoostScale * valence_boost;
- return score;
+ return score;
}
class LLVCacheFIFO
{
public:
- LLVCacheVertexData* mCache[MaxSizeVertexCache];
- U32 mMisses;
-
- LLVCacheFIFO()
- {
- mMisses = 0;
- for (U32 i = 0; i < MaxSizeVertexCache; ++i)
- {
- mCache[i] = NULL;
- }
- }
-
- void addVertex(LLVCacheVertexData* data)
- {
- if (data->mCacheTag == -1)
- {
- mMisses++;
-
- S32 end = MaxSizeVertexCache-1;
-
- if (mCache[end])
- {
- mCache[end]->mCacheTag = -1;
- }
-
- for (S32 i = end; i > 0; --i)
- {
- mCache[i] = mCache[i-1];
- if (mCache[i])
- {
- mCache[i]->mCacheTag = i;
- }
- }
-
- mCache[0] = data;
- data->mCacheTag = 0;
- }
- }
+ LLVCacheVertexData* mCache[MaxSizeVertexCache];
+ U32 mMisses;
+
+ LLVCacheFIFO()
+ {
+ mMisses = 0;
+ for (U32 i = 0; i < MaxSizeVertexCache; ++i)
+ {
+ mCache[i] = NULL;
+ }
+ }
+
+ void addVertex(LLVCacheVertexData* data)
+ {
+ if (data->mCacheTag == -1)
+ {
+ mMisses++;
+
+ S32 end = MaxSizeVertexCache-1;
+
+ if (mCache[end])
+ {
+ mCache[end]->mCacheTag = -1;
+ }
+
+ for (S32 i = end; i > 0; --i)
+ {
+ mCache[i] = mCache[i-1];
+ if (mCache[i])
+ {
+ mCache[i]->mCacheTag = i;
+ }
+ }
+
+ mCache[0] = data;
+ data->mCacheTag = 0;
+ }
+ }
};
class LLVCacheLRU
{
public:
- LLVCacheVertexData* mCache[MaxSizeVertexCache+3];
-
- LLVCacheTriangleData* mBestTriangle;
-
- U32 mMisses;
-
- LLVCacheLRU()
- {
- for (U32 i = 0; i < MaxSizeVertexCache+3; ++i)
- {
- mCache[i] = NULL;
- }
-
- mBestTriangle = NULL;
- mMisses = 0;
- }
-
- void addVertex(LLVCacheVertexData* data)
- {
- S32 end = MaxSizeVertexCache+2;
- if (data->mCacheTag != -1)
- { //just moving a vertex to the front of the cache
- end = data->mCacheTag;
- }
- else
- {
- mMisses++;
- if (mCache[end])
- { //adding a new vertex, vertex at end of cache falls off
- mCache[end]->mCacheTag = -1;
- }
- }
-
- for (S32 i = end; i > 0; --i)
- { //adjust cache pointers and tags
- mCache[i] = mCache[i-1];
-
- if (mCache[i])
- {
- mCache[i]->mCacheTag = i;
- }
- }
-
- mCache[0] = data;
- mCache[0]->mCacheTag = 0;
- }
-
- void addTriangle(LLVCacheTriangleData* data)
- {
- addVertex(data->mVertex[0]);
- addVertex(data->mVertex[1]);
- addVertex(data->mVertex[2]);
- }
-
- void updateScores()
- {
- LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache;
- LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3;
-
- while(data_iter != end_data)
- {
- LLVCacheVertexData* data = *data_iter++;
- //trailing 3 vertices aren't actually in the cache for scoring purposes
- if (data)
- {
- data->mCacheTag = -1;
- }
- }
-
- data_iter = mCache;
- end_data = mCache+MaxSizeVertexCache;
-
- while (data_iter != end_data)
- { //update scores of vertices in cache
- LLVCacheVertexData* data = *data_iter++;
- if (data)
- {
- data->mScore = find_vertex_score(*data);
- }
- }
-
- mBestTriangle = NULL;
- //update triangle scores
- data_iter = mCache;
- end_data = mCache+MaxSizeVertexCache+3;
-
- while (data_iter != end_data)
- {
- LLVCacheVertexData* data = *data_iter++;
- if (data)
- {
- for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter)
- {
- LLVCacheTriangleData* tri = *iter;
- if (tri->mActive)
- {
- tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0;
- tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0;
- tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0;
-
- if (!mBestTriangle || mBestTriangle->mScore < tri->mScore)
- {
- mBestTriangle = tri;
- }
- }
- }
- }
- }
-
- //knock trailing 3 vertices off the cache
- data_iter = mCache+MaxSizeVertexCache;
- end_data = mCache+MaxSizeVertexCache+3;
- while (data_iter != end_data)
- {
- LLVCacheVertexData* data = *data_iter;
- if (data)
- {
- llassert(data->mCacheTag == -1);
- *data_iter = NULL;
- }
- ++data_iter;
- }
- }
+ LLVCacheVertexData* mCache[MaxSizeVertexCache+3];
+
+ LLVCacheTriangleData* mBestTriangle;
+
+ U32 mMisses;
+
+ LLVCacheLRU()
+ {
+ for (U32 i = 0; i < MaxSizeVertexCache+3; ++i)
+ {
+ mCache[i] = NULL;
+ }
+
+ mBestTriangle = NULL;
+ mMisses = 0;
+ }
+
+ void addVertex(LLVCacheVertexData* data)
+ {
+ S32 end = MaxSizeVertexCache+2;
+ if (data->mCacheTag != -1)
+ { //just moving a vertex to the front of the cache
+ end = data->mCacheTag;
+ }
+ else
+ {
+ mMisses++;
+ if (mCache[end])
+ { //adding a new vertex, vertex at end of cache falls off
+ mCache[end]->mCacheTag = -1;
+ }
+ }
+
+ for (S32 i = end; i > 0; --i)
+ { //adjust cache pointers and tags
+ mCache[i] = mCache[i-1];
+
+ if (mCache[i])
+ {
+ mCache[i]->mCacheTag = i;
+ }
+ }
+
+ mCache[0] = data;
+ mCache[0]->mCacheTag = 0;
+ }
+
+ void addTriangle(LLVCacheTriangleData* data)
+ {
+ addVertex(data->mVertex[0]);
+ addVertex(data->mVertex[1]);
+ addVertex(data->mVertex[2]);
+ }
+
+ void updateScores()
+ {
+ LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache;
+ LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3;
+
+ while(data_iter != end_data)
+ {
+ LLVCacheVertexData* data = *data_iter++;
+ //trailing 3 vertices aren't actually in the cache for scoring purposes
+ if (data)
+ {
+ data->mCacheTag = -1;
+ }
+ }
+
+ data_iter = mCache;
+ end_data = mCache+MaxSizeVertexCache;
+
+ while (data_iter != end_data)
+ { //update scores of vertices in cache
+ LLVCacheVertexData* data = *data_iter++;
+ if (data)
+ {
+ data->mScore = find_vertex_score(*data);
+ }
+ }
+
+ mBestTriangle = NULL;
+ //update triangle scores
+ data_iter = mCache;
+ end_data = mCache+MaxSizeVertexCache+3;
+
+ while (data_iter != end_data)
+ {
+ LLVCacheVertexData* data = *data_iter++;
+ if (data)
+ {
+ for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter)
+ {
+ LLVCacheTriangleData* tri = *iter;
+ if (tri->mActive)
+ {
+ tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0;
+ tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0;
+ tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0;
+
+ if (!mBestTriangle || mBestTriangle->mScore < tri->mScore)
+ {
+ mBestTriangle = tri;
+ }
+ }
+ }
+ }
+ }
+
+ //knock trailing 3 vertices off the cache
+ data_iter = mCache+MaxSizeVertexCache;
+ end_data = mCache+MaxSizeVertexCache+3;
+ while (data_iter != end_data)
+ {
+ LLVCacheVertexData* data = *data_iter;
+ if (data)
+ {
+ llassert(data->mCacheTag == -1);
+ *data_iter = NULL;
+ }
+ ++data_iter;
+ }
+ }
};
// data structures for tangent generation
@@ -5477,7 +5405,7 @@ struct MikktData
LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]);
-
+
for (int i = 0; i < face->mNumIndices; ++i)
{
@@ -5507,75 +5435,55 @@ struct MikktData
}
}
}
-};
+ uint32_t GetNumFaces()
+ {
+ return uint32_t(face->mNumIndices / 3);
+ }
+
+ uint32_t GetNumVerticesOfFace(const uint32_t face_num)
+ {
+ return 3;
+ }
+
+ mikk::float3 GetPosition(const uint32_t face_num, const uint32_t vert_num)
+ {
+ F32* v = p[face_num * 3 + vert_num].mV;
+ return mikk::float3(v);
+ }
+
+ mikk::float3 GetTexCoord(const uint32_t face_num, const uint32_t vert_num)
+ {
+ F32* uv = tc[face_num * 3 + vert_num].mV;
+ return mikk::float3(uv[0], uv[1], 1.0f);
+ }
+
+ mikk::float3 GetNormal(const uint32_t face_num, const uint32_t vert_num)
+ {
+ F32* normal = n[face_num * 3 + vert_num].mV;
+ return mikk::float3(normal);
+ }
+
+ void SetTangentSpace(const uint32_t face_num, const uint32_t vert_num, mikk::float3 T, bool orientation)
+ {
+ S32 i = face_num * 3 + vert_num;
+ t[i].set(T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
+ }
+};
bool LLVolumeFace::cacheOptimize(bool gen_tangents)
-{ //optimize for vertex cache according to Forsyth method:
+{ //optimize for vertex cache according to Forsyth method:
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- llassert(!mOptimized);
- mOptimized = TRUE;
+ llassert(!mOptimized);
+ mOptimized = TRUE;
if (gen_tangents && mNormals && mTexCoords)
{ // generate mikkt space tangents before cache optimizing since the index buffer may change
// a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
// and is executed on a background thread
- SMikkTSpaceInterface ms;
-
- ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
- {
- MikktData* data = (MikktData*)pContext->m_pUserData;
- LLVolumeFace* face = data->face;
- return face->mNumIndices / 3;
- };
-
- ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)
- {
- return 3;
- };
-
- ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
- {
- MikktData* data = (MikktData*)pContext->m_pUserData;
- F32* v = data->p[iFace * 3 + iVert].mV;
- fvPosOut[0] = v[0];
- fvPosOut[1] = v[1];
- fvPosOut[2] = v[2];
- };
-
- ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
- {
- MikktData* data = (MikktData*)pContext->m_pUserData;
- F32* n = data->n[iFace * 3 + iVert].mV;
- fvNormOut[0] = n[0];
- fvNormOut[1] = n[1];
- fvNormOut[2] = n[2];
- };
-
- ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
- {
- MikktData* data = (MikktData*)pContext->m_pUserData;
- F32* tc = data->tc[iFace * 3 + iVert].mV;
- fvTexcOut[0] = tc[0];
- fvTexcOut[1] = tc[1];
- };
-
- ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
- {
- MikktData* data = (MikktData*)pContext->m_pUserData;
- S32 i = iFace * 3 + iVert;
-
- data->t[i].set(fvTangent);
- data->t[i].mV[3] = fSign;
- };
-
- ms.m_setTSpace = nullptr;
-
MikktData data(this);
-
- SMikkTSpaceContext ctx = { &ms, &data };
-
- genTangSpaceDefault(&ctx);
+ mikk::Mikktspace ctx(data);
+ ctx.genTangSpace();
//re-weld
meshopt_Stream mos[] =
@@ -5596,9 +5504,6 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
if (vert_count < 65535 && vert_count != 0)
{
- std::vector<U32> indices;
- indices.resize(mNumIndices);
-
//copy results back into volume
resizeVertices(vert_count);
@@ -5670,98 +5575,97 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
resizeIndices(mNumIndices);
meshopt_optimizeVertexCache<U16>(mIndices, src_indices, mNumIndices, mNumVertices);
-
+
ll_aligned_free_16(src_indices);
- return true;
+ return true;
}
void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
if (getOctree())
- {
- return;
- }
+ {
+ return;
+ }
llassert(mNumIndices % 3 == 0);
- mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);
- new LLVolumeOctreeListener(mOctree);
+ mOctree = new LLVolumeOctree(center, size);
const U32 num_triangles = mNumIndices / 3;
// Initialize all the triangles we need
mOctreeTriangles = new LLVolumeTriangle[num_triangles];
for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
- { //for each triangle
+ { //for each triangle
const U32 index = triangle_index * 3;
LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
-
- const LLVector4a& v0 = mPositions[mIndices[index]];
- const LLVector4a& v1 = mPositions[mIndices[index + 1]];
- const LLVector4a& v2 = mPositions[mIndices[index + 2]];
-
- //store pointers to vertex data
- tri->mV[0] = &v0;
- tri->mV[1] = &v1;
- tri->mV[2] = &v2;
-
- //store indices
- tri->mIndex[0] = mIndices[index];
- tri->mIndex[1] = mIndices[index + 1];
- tri->mIndex[2] = mIndices[index + 2];
-
- //get minimum point
- LLVector4a min = v0;
- min.setMin(min, v1);
- min.setMin(min, v2);
-
- //get maximum point
- LLVector4a max = v0;
- max.setMax(max, v1);
- max.setMax(max, v2);
-
- //compute center
- LLVector4a center;
- center.setAdd(min, max);
- center.mul(0.5f);
-
- tri->mPositionGroup = center;
-
- //compute "radius"
- LLVector4a size;
- size.setSub(max,min);
-
- tri->mRadius = size.getLength3().getF32() * scaler;
-
- //insert
- mOctree->insert(tri);
- }
-
- //remove unneeded octree layers
- while (!mOctree->balance()) { }
-
- //calculate AABB for each node
- LLVolumeOctreeRebound rebound(this);
- rebound.traverse(mOctree);
-
- if (gDebugGL)
- {
- LLVolumeOctreeValidate validate;
- validate.traverse(mOctree);
- }
+
+ const LLVector4a& v0 = mPositions[mIndices[index]];
+ const LLVector4a& v1 = mPositions[mIndices[index + 1]];
+ const LLVector4a& v2 = mPositions[mIndices[index + 2]];
+
+ //store pointers to vertex data
+ tri->mV[0] = &v0;
+ tri->mV[1] = &v1;
+ tri->mV[2] = &v2;
+
+ //store indices
+ tri->mIndex[0] = mIndices[index];
+ tri->mIndex[1] = mIndices[index + 1];
+ tri->mIndex[2] = mIndices[index + 2];
+
+ //get minimum point
+ LLVector4a min = v0;
+ min.setMin(min, v1);
+ min.setMin(min, v2);
+
+ //get maximum point
+ LLVector4a max = v0;
+ max.setMax(max, v1);
+ max.setMax(max, v2);
+
+ //compute center
+ LLVector4a center;
+ center.setAdd(min, max);
+ center.mul(0.5f);
+
+ tri->mPositionGroup = center;
+
+ //compute "radius"
+ LLVector4a size;
+ size.setSub(max,min);
+
+ tri->mRadius = size.getLength3().getF32() * scaler;
+
+ //insert
+ mOctree->insert(tri);
+ }
+
+ //remove unneeded octree layers
+ while (!mOctree->balance()) { }
+
+ //calculate AABB for each node
+ LLVolumeOctreeRebound rebound;
+ rebound.traverse(mOctree);
+
+ if (gDebugGL)
+ {
+ LLVolumeOctreeValidate validate;
+ validate.traverse(mOctree);
+ }
}
void LLVolumeFace::destroyOctree()
{
delete mOctree;
- mOctree = NULL;
+ mOctree = nullptr;
delete[] mOctreeTriangles;
- mOctreeTriangles = NULL;
+ mOctreeTriangles = nullptr;
}
-const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
+const LLVolumeOctree* LLVolumeFace::getOctree() const
{
return mOctree;
}
@@ -5769,145 +5673,145 @@ const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree
void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
- llswap(rhs.mPositions, mPositions);
- llswap(rhs.mNormals, mNormals);
- llswap(rhs.mTangents, mTangents);
- llswap(rhs.mTexCoords, mTexCoords);
- llswap(rhs.mIndices,mIndices);
- llswap(rhs.mNumVertices, mNumVertices);
- llswap(rhs.mNumIndices, mNumIndices);
+ llswap(rhs.mPositions, mPositions);
+ llswap(rhs.mNormals, mNormals);
+ llswap(rhs.mTangents, mTangents);
+ llswap(rhs.mTexCoords, mTexCoords);
+ llswap(rhs.mIndices,mIndices);
+ llswap(rhs.mNumVertices, mNumVertices);
+ llswap(rhs.mNumIndices, mNumIndices);
}
-void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
- LLVolumeFace::VertexData& v1,
- LLVolumeFace::VertexData& v2,
- LLVolumeFace::VertexData& vout,
- F32 coef01,
- F32 coef02)
+void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
+ LLVolumeFace::VertexData& v1,
+ LLVolumeFace::VertexData& v2,
+ LLVolumeFace::VertexData& vout,
+ F32 coef01,
+ F32 coef02)
{
- LLVector4a lhs;
- lhs.setSub(v1.getPosition(), v0.getPosition());
- lhs.mul(coef01);
- LLVector4a rhs;
- rhs.setSub(v2.getPosition(), v0.getPosition());
- rhs.mul(coef02);
-
- rhs.add(lhs);
- rhs.add(v0.getPosition());
+ LLVector4a lhs;
+ lhs.setSub(v1.getPosition(), v0.getPosition());
+ lhs.mul(coef01);
+ LLVector4a rhs;
+ rhs.setSub(v2.getPosition(), v0.getPosition());
+ rhs.mul(coef02);
- vout.setPosition(rhs);
+ rhs.add(lhs);
+ rhs.add(v0.getPosition());
- vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02);
- vout.setNormal(v0.getNormal());
+ vout.setPosition(rhs);
+
+ vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02);
+ vout.setNormal(v0.getNormal());
}
BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
- LL_CHECK_MEMORY
-
- const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
- const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
- S32 max_s = volume->getProfile().getTotal();
- S32 max_t = volume->getPath().mPath.size();
-
- // S32 i;
- S32 grid_size = (profile.size()-1)/4;
- // VFExtents change
- LLVector4a& min = mExtents[0];
- LLVector4a& max = mExtents[1];
-
- S32 offset = 0;
- if (mTypeMask & TOP_MASK)
- {
- offset = (max_t-1) * max_s;
- }
- else
- {
- offset = mBeginS;
- }
-
- {
- VertexData corners[4];
- VertexData baseVert;
- for(S32 t = 0; t < 4; t++)
- {
- corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr());
- corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f;
- corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1];
- }
-
- {
- LLVector4a lhs;
- lhs.setSub(corners[1].getPosition(), corners[0].getPosition());
- LLVector4a rhs;
- rhs.setSub(corners[2].getPosition(), corners[1].getPosition());
- baseVert.getNormal().setCross3(lhs, rhs);
- baseVert.getNormal().normalize3fast();
- }
-
- if(!(mTypeMask & TOP_MASK))
- {
- baseVert.getNormal().mul(-1.0f);
- }
- else
- {
- //Swap the UVs on the U(X) axis for top face
- LLVector2 swap;
- swap = corners[0].mTexCoord;
- corners[0].mTexCoord=corners[3].mTexCoord;
- corners[3].mTexCoord=swap;
- swap = corners[1].mTexCoord;
- corners[1].mTexCoord=corners[2].mTexCoord;
- corners[2].mTexCoord=swap;
- }
-
- S32 size = (grid_size+1)*(grid_size+1);
- resizeVertices(size);
-
- LLVector4a* pos = (LLVector4a*) mPositions;
- LLVector4a* norm = (LLVector4a*) mNormals;
- LLVector2* tc = (LLVector2*) mTexCoords;
-
- for(int gx = 0;gx<grid_size+1;gx++)
- {
- for(int gy = 0;gy<grid_size+1;gy++)
- {
- VertexData newVert;
- LerpPlanarVertex(
- corners[0],
- corners[1],
- corners[3],
- newVert,
- (F32)gx/(F32)grid_size,
- (F32)gy/(F32)grid_size);
-
- *pos++ = newVert.getPosition();
- *norm++ = baseVert.getNormal();
- *tc++ = newVert.mTexCoord;
-
- if (gx == 0 && gy == 0)
- {
- min = newVert.getPosition();
- max = min;
- }
- else
- {
- min.setMin(min, newVert.getPosition());
- max.setMax(max, newVert.getPosition());
- }
- }
- }
-
- mCenter->setAdd(min, max);
- mCenter->mul(0.5f);
- }
-
- if (!partial_build)
- {
- resizeIndices(grid_size*grid_size*6);
- if (!volume->isMeshAssetLoaded())
- {
+ LL_CHECK_MEMORY
+
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
+ S32 max_s = volume->getProfile().getTotal();
+ S32 max_t = volume->getPath().mPath.size();
+
+ // S32 i;
+ S32 grid_size = (profile.size()-1)/4;
+ // VFExtents change
+ LLVector4a& min = mExtents[0];
+ LLVector4a& max = mExtents[1];
+
+ S32 offset = 0;
+ if (mTypeMask & TOP_MASK)
+ {
+ offset = (max_t-1) * max_s;
+ }
+ else
+ {
+ offset = mBeginS;
+ }
+
+ {
+ VertexData corners[4];
+ VertexData baseVert;
+ for(S32 t = 0; t < 4; t++)
+ {
+ corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr());
+ corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f;
+ corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1];
+ }
+
+ {
+ LLVector4a lhs;
+ lhs.setSub(corners[1].getPosition(), corners[0].getPosition());
+ LLVector4a rhs;
+ rhs.setSub(corners[2].getPosition(), corners[1].getPosition());
+ baseVert.getNormal().setCross3(lhs, rhs);
+ baseVert.getNormal().normalize3fast();
+ }
+
+ if(!(mTypeMask & TOP_MASK))
+ {
+ baseVert.getNormal().mul(-1.0f);
+ }
+ else
+ {
+ //Swap the UVs on the U(X) axis for top face
+ LLVector2 swap;
+ swap = corners[0].mTexCoord;
+ corners[0].mTexCoord=corners[3].mTexCoord;
+ corners[3].mTexCoord=swap;
+ swap = corners[1].mTexCoord;
+ corners[1].mTexCoord=corners[2].mTexCoord;
+ corners[2].mTexCoord=swap;
+ }
+
+ S32 size = (grid_size+1)*(grid_size+1);
+ resizeVertices(size);
+
+ LLVector4a* pos = (LLVector4a*) mPositions;
+ LLVector4a* norm = (LLVector4a*) mNormals;
+ LLVector2* tc = (LLVector2*) mTexCoords;
+
+ for(int gx = 0;gx<grid_size+1;gx++)
+ {
+ for(int gy = 0;gy<grid_size+1;gy++)
+ {
+ VertexData newVert;
+ LerpPlanarVertex(
+ corners[0],
+ corners[1],
+ corners[3],
+ newVert,
+ (F32)gx/(F32)grid_size,
+ (F32)gy/(F32)grid_size);
+
+ *pos++ = newVert.getPosition();
+ *norm++ = baseVert.getNormal();
+ *tc++ = newVert.mTexCoord;
+
+ if (gx == 0 && gy == 0)
+ {
+ min = newVert.getPosition();
+ max = min;
+ }
+ else
+ {
+ min.setMin(min, newVert.getPosition());
+ max.setMax(max, newVert.getPosition());
+ }
+ }
+ }
+
+ mCenter->setAdd(min, max);
+ mCenter->mul(0.5f);
+ }
+
+ if (!partial_build)
+ {
+ resizeIndices(grid_size*grid_size*6);
+ if (!volume->isMeshAssetLoaded())
+ {
S32 size = grid_size * grid_size * 6;
try
{
@@ -5918,567 +5822,564 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL;
return false;
}
- }
-
- U16* out = mIndices;
-
- S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
-
- int cur_edge = 0;
-
- for(S32 gx = 0;gx<grid_size;gx++)
- {
-
- for(S32 gy = 0;gy<grid_size;gy++)
- {
- if (mTypeMask & TOP_MASK)
- {
- for(S32 i=5;i>=0;i--)
- {
- *out++ = ((gy*(grid_size+1))+gx+idxs[i]);
- }
-
- S32 edge_value = grid_size * 2 * gy + gx * 2;
-
- if (gx > 0)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1; // Mark face to higlight it
- }
-
- if (gy < grid_size - 1)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- mEdge[cur_edge++] = edge_value;
-
- if (gx < grid_size - 1)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- if (gy > 0)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- for(S32 i=0;i<6;i++)
- {
- *out++ = ((gy*(grid_size+1))+gx+idxs[i]);
- }
-
- S32 edge_value = grid_size * 2 * gy + gx * 2;
-
- if (gy > 0)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- if (gx < grid_size - 1)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- mEdge[cur_edge++] = edge_value;
-
- if (gy < grid_size - 1)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- if (gx > 0)
- {
- mEdge[cur_edge++] = edge_value;
- }
- else
- {
- mEdge[cur_edge++] = -1;
- }
-
- mEdge[cur_edge++] = edge_value;
- }
- }
- }
- }
-
- LL_CHECK_MEMORY
- return TRUE;
+ }
+
+ U16* out = mIndices;
+
+ S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
+
+ int cur_edge = 0;
+
+ for(S32 gx = 0;gx<grid_size;gx++)
+ {
+
+ for(S32 gy = 0;gy<grid_size;gy++)
+ {
+ if (mTypeMask & TOP_MASK)
+ {
+ for(S32 i=5;i>=0;i--)
+ {
+ *out++ = ((gy*(grid_size+1))+gx+idxs[i]);
+ }
+
+ S32 edge_value = grid_size * 2 * gy + gx * 2;
+
+ if (gx > 0)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1; // Mark face to higlight it
+ }
+
+ if (gy < grid_size - 1)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ mEdge[cur_edge++] = edge_value;
+
+ if (gx < grid_size - 1)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ if (gy > 0)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ for(S32 i=0;i<6;i++)
+ {
+ *out++ = ((gy*(grid_size+1))+gx+idxs[i]);
+ }
+
+ S32 edge_value = grid_size * 2 * gy + gx * 2;
+
+ if (gy > 0)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ if (gx < grid_size - 1)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ mEdge[cur_edge++] = edge_value;
+
+ if (gy < grid_size - 1)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ if (gx > 0)
+ {
+ mEdge[cur_edge++] = edge_value;
+ }
+ else
+ {
+ mEdge[cur_edge++] = -1;
+ }
+
+ mEdge[cur_edge++] = edge_value;
+ }
+ }
+ }
+ }
+
+ LL_CHECK_MEMORY
+ return TRUE;
}
BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
{
- if (!(mTypeMask & HOLLOW_MASK) &&
- !(mTypeMask & OPEN_MASK) &&
- ((volume->getParams().getPathParams().getBegin()==0.0f)&&
- (volume->getParams().getPathParams().getEnd()==1.0f))&&
- (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE &&
- volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE)
- ){
- return createUnCutCubeCap(volume, partial_build);
- }
-
- S32 num_vertices = 0, num_indices = 0;
-
- const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
- const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
-
- // All types of caps have the same number of vertices and indices
- num_vertices = profile.size();
- num_indices = (profile.size() - 2)*3;
-
- if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
- {
- resizeVertices(num_vertices+1);
-
- //if (!partial_build)
- {
- resizeIndices(num_indices+3);
- }
- }
- else
- {
- resizeVertices(num_vertices);
- //if (!partial_build)
- {
- resizeIndices(num_indices);
- }
- }
-
- LL_CHECK_MEMORY;
-
- S32 max_s = volume->getProfile().getTotal();
- S32 max_t = volume->getPath().mPath.size();
-
- mCenter->clear();
-
- S32 offset = 0;
- if (mTypeMask & TOP_MASK)
- {
- offset = (max_t-1) * max_s;
- }
- else
- {
- offset = mBeginS;
- }
-
- // Figure out the normal, assume all caps are flat faces.
- // Cross product to get normals.
-
- LLVector2 cuv;
- LLVector2 min_uv, max_uv;
- // VFExtents change
- LLVector4a& min = mExtents[0];
- LLVector4a& max = mExtents[1];
-
- LLVector2* tc = (LLVector2*) mTexCoords;
- LLVector4a* pos = (LLVector4a*) mPositions;
- LLVector4a* norm = (LLVector4a*) mNormals;
-
- // Copy the vertices into the array
-
- const LLVector4a* src = mesh.mArray+offset;
- const LLVector4a* end = src+num_vertices;
-
- min = *src;
- max = min;
-
-
- const LLVector4a* p = profile.mArray;
-
- if (mTypeMask & TOP_MASK)
- {
- min_uv.set((*p)[0]+0.5f,
- (*p)[1]+0.5f);
-
- max_uv = min_uv;
-
- while(src < end)
- {
- tc->mV[0] = (*p)[0]+0.5f;
- tc->mV[1] = (*p)[1]+0.5f;
-
- llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds
- update_min_max(min,max,*src);
- update_min_max(min_uv, max_uv, *tc);
-
- *pos = *src;
-
- llassert(pos->isFinite3());
-
- ++p;
- ++tc;
- ++src;
- ++pos;
- }
- }
- else
- {
-
- min_uv.set((*p)[0]+0.5f,
- 0.5f - (*p)[1]);
- max_uv = min_uv;
-
- while(src < end)
- {
- // Mirror for underside.
- tc->mV[0] = (*p)[0]+0.5f;
- tc->mV[1] = 0.5f - (*p)[1];
-
- llassert(src->isFinite3());
- update_min_max(min,max,*src);
- update_min_max(min_uv, max_uv, *tc);
-
- *pos = *src;
-
- llassert(pos->isFinite3());
-
- ++p;
- ++tc;
- ++src;
- ++pos;
- }
- }
-
- LL_CHECK_MEMORY
-
- mCenter->setAdd(min, max);
- mCenter->mul(0.5f);
-
- cuv = (min_uv + max_uv)*0.5f;
-
-
- VertexData vd;
- vd.setPosition(*mCenter);
- vd.mTexCoord = cuv;
-
- if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
- {
- *pos++ = *mCenter;
- *tc++ = cuv;
- num_vertices++;
- }
-
- LL_CHECK_MEMORY
-
- //if (partial_build)
- //{
- // return TRUE;
- //}
-
- if (mTypeMask & HOLLOW_MASK)
- {
- if (mTypeMask & TOP_MASK)
- {
- // HOLLOW TOP
- // Does it matter if it's open or closed? - djs
-
- S32 pt1 = 0, pt2 = num_vertices - 1;
- S32 i = 0;
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- const LLVector4a& p1 = profile[pt1];
- const LLVector4a& p2 = profile[pt2];
- const LLVector4a& pa = profile[pt1+1];
- const LLVector4a& pb = profile[pt2-1];
-
- const F32* p1V = p1.getF32ptr();
- const F32* p2V = p2.getF32ptr();
- const F32* paV = pa.getF32ptr();
- const F32* pbV = pb.getF32ptr();
-
- //p1.mV[VZ] = 0.f;
- //p2.mV[VZ] = 0.f;
- //pa.mV[VZ] = 0.f;
- //pb.mV[VZ] = 0.f;
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
- (paV[0]*p2V[1] - p2V[0]*paV[1]) +
- (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
-
- area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
- (pbV[0]*paV[1] - paV[0]*pbV[1]) +
- (paV[0]*p1V[1] - p1V[0]*paV[1]);
-
- area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
- (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
- (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
-
- area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
- (paV[0]*pbV[1] - pbV[0]*paV[1]) +
- (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector4a d1;
- d1.setSub(p1, pa);
-
- LLVector4a d2;
- d2.setSub(p2, pb);
-
- if (d1.dot3(d1) < d2.dot3(d2))
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- if (use_tri1a2)
- {
- mIndices[i++] = pt1;
- mIndices[i++] = pt1 + 1;
- mIndices[i++] = pt2;
- pt1++;
- }
- else
- {
- mIndices[i++] = pt1;
- mIndices[i++] = pt2 - 1;
- mIndices[i++] = pt2;
- pt2--;
- }
- }
- }
- else
- {
- // HOLLOW BOTTOM
- // Does it matter if it's open or closed? - djs
-
- llassert(mTypeMask & BOTTOM_MASK);
- S32 pt1 = 0, pt2 = num_vertices - 1;
-
- S32 i = 0;
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- const LLVector4a& p1 = profile[pt1];
- const LLVector4a& p2 = profile[pt2];
- const LLVector4a& pa = profile[pt1+1];
- const LLVector4a& pb = profile[pt2-1];
-
- const F32* p1V = p1.getF32ptr();
- const F32* p2V = p2.getF32ptr();
- const F32* paV = pa.getF32ptr();
- const F32* pbV = pb.getF32ptr();
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
- (paV[0]*p2V[1] - p2V[0]*paV[1]) +
- (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
-
- area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
- (pbV[0]*paV[1] - paV[0]*pbV[1]) +
- (paV[0]*p1V[1] - p1V[0]*paV[1]);
-
- area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
- (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
- (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
-
- area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
- (paV[0]*pbV[1] - pbV[0]*paV[1]) +
- (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector4a d1;
- d1.setSub(p1,pa);
- LLVector4a d2;
- d2.setSub(p2,pb);
-
- if (d1.dot3(d1) < d2.dot3(d2))
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- // Flipped backfacing from top
- if (use_tri1a2)
- {
- mIndices[i++] = pt1;
- mIndices[i++] = pt2;
- mIndices[i++] = pt1 + 1;
- pt1++;
- }
- else
- {
- mIndices[i++] = pt1;
- mIndices[i++] = pt2;
- mIndices[i++] = pt2 - 1;
- pt2--;
- }
- }
- }
- }
- else
- {
- // Not hollow, generate the triangle fan.
- U16 v1 = 2;
- U16 v2 = 1;
-
- if (mTypeMask & TOP_MASK)
- {
- v1 = 1;
- v2 = 2;
- }
-
- for (S32 i = 0; i < (num_vertices - 2); i++)
- {
- mIndices[3*i] = num_vertices - 1;
- mIndices[3*i+v1] = i;
- mIndices[3*i+v2] = i + 1;
- }
-
-
- }
-
- LLVector4a d0,d1;
- LL_CHECK_MEMORY
-
-
- d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
- d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
-
- LLVector4a normal;
- normal.setCross3(d0,d1);
-
- if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
- {
- normal.normalize3fast();
- }
- else
- { //degenerate, make up a value
- if(normal.getF32ptr()[2] >= 0)
- normal.set(0.f,0.f,1.f);
- else
- normal.set(0.f,0.f,-1.f);
- }
-
- llassert(llfinite(normal.getF32ptr()[0]));
- llassert(llfinite(normal.getF32ptr()[1]));
- llassert(llfinite(normal.getF32ptr()[2]));
-
- llassert(!llisnan(normal.getF32ptr()[0]));
- llassert(!llisnan(normal.getF32ptr()[1]));
- llassert(!llisnan(normal.getF32ptr()[2]));
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- norm[i].load4a(normal.getF32ptr());
- }
-
- return TRUE;
+ if (!(mTypeMask & HOLLOW_MASK) &&
+ !(mTypeMask & OPEN_MASK) &&
+ ((volume->getParams().getPathParams().getBegin()==0.0f)&&
+ (volume->getParams().getPathParams().getEnd()==1.0f))&&
+ (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE &&
+ volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE)
+ ){
+ return createUnCutCubeCap(volume, partial_build);
+ }
+
+ S32 num_vertices = 0, num_indices = 0;
+
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
+
+ // All types of caps have the same number of vertices and indices
+ num_vertices = profile.size();
+ num_indices = (profile.size() - 2)*3;
+
+ if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
+ {
+ resizeVertices(num_vertices+1);
+
+ //if (!partial_build)
+ {
+ resizeIndices(num_indices+3);
+ }
+ }
+ else
+ {
+ resizeVertices(num_vertices);
+ //if (!partial_build)
+ {
+ resizeIndices(num_indices);
+ }
+ }
+
+ LL_CHECK_MEMORY;
+
+ S32 max_s = volume->getProfile().getTotal();
+ S32 max_t = volume->getPath().mPath.size();
+
+ mCenter->clear();
+
+ S32 offset = 0;
+ if (mTypeMask & TOP_MASK)
+ {
+ offset = (max_t-1) * max_s;
+ }
+ else
+ {
+ offset = mBeginS;
+ }
+
+ // Figure out the normal, assume all caps are flat faces.
+ // Cross product to get normals.
+
+ LLVector2 cuv;
+ LLVector2 min_uv, max_uv;
+ // VFExtents change
+ LLVector4a& min = mExtents[0];
+ LLVector4a& max = mExtents[1];
+
+ LLVector2* tc = (LLVector2*) mTexCoords;
+ LLVector4a* pos = (LLVector4a*) mPositions;
+ LLVector4a* norm = (LLVector4a*) mNormals;
+
+ // Copy the vertices into the array
+
+ const LLVector4a* src = mesh.mArray+offset;
+ const LLVector4a* end = src+num_vertices;
+
+ min = *src;
+ max = min;
+
+
+ const LLVector4a* p = profile.mArray;
+
+ if (mTypeMask & TOP_MASK)
+ {
+ min_uv.set((*p)[0]+0.5f,
+ (*p)[1]+0.5f);
+
+ max_uv = min_uv;
+
+ while(src < end)
+ {
+ tc->mV[0] = (*p)[0]+0.5f;
+ tc->mV[1] = (*p)[1]+0.5f;
+
+ llassert(src->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds
+ update_min_max(min,max,*src);
+ update_min_max(min_uv, max_uv, *tc);
+
+ *pos = *src;
+
+ llassert(pos->isFinite3());
+
+ ++p;
+ ++tc;
+ ++src;
+ ++pos;
+ }
+ }
+ else
+ {
+
+ min_uv.set((*p)[0]+0.5f,
+ 0.5f - (*p)[1]);
+ max_uv = min_uv;
+
+ while(src < end)
+ {
+ // Mirror for underside.
+ tc->mV[0] = (*p)[0]+0.5f;
+ tc->mV[1] = 0.5f - (*p)[1];
+
+ llassert(src->isFinite3());
+ update_min_max(min,max,*src);
+ update_min_max(min_uv, max_uv, *tc);
+
+ *pos = *src;
+
+ llassert(pos->isFinite3());
+
+ ++p;
+ ++tc;
+ ++src;
+ ++pos;
+ }
+ }
+
+ LL_CHECK_MEMORY
+
+ mCenter->setAdd(min, max);
+ mCenter->mul(0.5f);
+
+ cuv = (min_uv + max_uv)*0.5f;
+
+
+ VertexData vd;
+ vd.setPosition(*mCenter);
+ vd.mTexCoord = cuv;
+
+ if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
+ {
+ *pos++ = *mCenter;
+ *tc++ = cuv;
+ num_vertices++;
+ }
+
+ LL_CHECK_MEMORY
+
+ //if (partial_build)
+ //{
+ // return TRUE;
+ //}
+
+ if (mTypeMask & HOLLOW_MASK)
+ {
+ if (mTypeMask & TOP_MASK)
+ {
+ // HOLLOW TOP
+ // Does it matter if it's open or closed? - djs
+
+ S32 pt1 = 0, pt2 = num_vertices - 1;
+ S32 i = 0;
+ while (pt2 - pt1 > 1)
+ {
+ // Use the profile points instead of the mesh, since you want
+ // the un-transformed profile distances.
+ const LLVector4a& p1 = profile[pt1];
+ const LLVector4a& p2 = profile[pt2];
+ const LLVector4a& pa = profile[pt1+1];
+ const LLVector4a& pb = profile[pt2-1];
+
+ const F32* p1V = p1.getF32ptr();
+ const F32* p2V = p2.getF32ptr();
+ const F32* paV = pa.getF32ptr();
+ const F32* pbV = pb.getF32ptr();
+
+ //p1.mV[VZ] = 0.f;
+ //p2.mV[VZ] = 0.f;
+ //pa.mV[VZ] = 0.f;
+ //pb.mV[VZ] = 0.f;
+
+ // Use area of triangle to determine backfacing
+ F32 area_1a2, area_1ba, area_21b, area_2ab;
+ area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
+ (paV[0]*p2V[1] - p2V[0]*paV[1]) +
+ (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
+
+ area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*paV[1] - paV[0]*pbV[1]) +
+ (paV[0]*p1V[1] - p1V[0]*paV[1]);
+
+ area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
+ (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
+
+ area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
+ (paV[0]*pbV[1] - pbV[0]*paV[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
+
+ BOOL use_tri1a2 = TRUE;
+ BOOL tri_1a2 = TRUE;
+ BOOL tri_21b = TRUE;
+
+ if (area_1a2 < 0)
+ {
+ tri_1a2 = FALSE;
+ }
+ if (area_2ab < 0)
+ {
+ // Can't use, because it contains point b
+ tri_1a2 = FALSE;
+ }
+ if (area_21b < 0)
+ {
+ tri_21b = FALSE;
+ }
+ if (area_1ba < 0)
+ {
+ // Can't use, because it contains point b
+ tri_21b = FALSE;
+ }
+
+ if (!tri_1a2)
+ {
+ use_tri1a2 = FALSE;
+ }
+ else if (!tri_21b)
+ {
+ use_tri1a2 = TRUE;
+ }
+ else
+ {
+ LLVector4a d1;
+ d1.setSub(p1, pa);
+
+ LLVector4a d2;
+ d2.setSub(p2, pb);
+
+ if (d1.dot3(d1) < d2.dot3(d2))
+ {
+ use_tri1a2 = TRUE;
+ }
+ else
+ {
+ use_tri1a2 = FALSE;
+ }
+ }
+
+ if (use_tri1a2)
+ {
+ mIndices[i++] = pt1;
+ mIndices[i++] = pt1 + 1;
+ mIndices[i++] = pt2;
+ pt1++;
+ }
+ else
+ {
+ mIndices[i++] = pt1;
+ mIndices[i++] = pt2 - 1;
+ mIndices[i++] = pt2;
+ pt2--;
+ }
+ }
+ }
+ else
+ {
+ // HOLLOW BOTTOM
+ // Does it matter if it's open or closed? - djs
+
+ llassert(mTypeMask & BOTTOM_MASK);
+ S32 pt1 = 0, pt2 = num_vertices - 1;
+
+ S32 i = 0;
+ while (pt2 - pt1 > 1)
+ {
+ // Use the profile points instead of the mesh, since you want
+ // the un-transformed profile distances.
+ const LLVector4a& p1 = profile[pt1];
+ const LLVector4a& p2 = profile[pt2];
+ const LLVector4a& pa = profile[pt1+1];
+ const LLVector4a& pb = profile[pt2-1];
+
+ const F32* p1V = p1.getF32ptr();
+ const F32* p2V = p2.getF32ptr();
+ const F32* paV = pa.getF32ptr();
+ const F32* pbV = pb.getF32ptr();
+
+ // Use area of triangle to determine backfacing
+ F32 area_1a2, area_1ba, area_21b, area_2ab;
+ area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
+ (paV[0]*p2V[1] - p2V[0]*paV[1]) +
+ (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
+
+ area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*paV[1] - paV[0]*pbV[1]) +
+ (paV[0]*p1V[1] - p1V[0]*paV[1]);
+
+ area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
+ (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
+
+ area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
+ (paV[0]*pbV[1] - pbV[0]*paV[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
+
+ BOOL use_tri1a2 = TRUE;
+ BOOL tri_1a2 = TRUE;
+ BOOL tri_21b = TRUE;
+
+ if (area_1a2 < 0)
+ {
+ tri_1a2 = FALSE;
+ }
+ if (area_2ab < 0)
+ {
+ // Can't use, because it contains point b
+ tri_1a2 = FALSE;
+ }
+ if (area_21b < 0)
+ {
+ tri_21b = FALSE;
+ }
+ if (area_1ba < 0)
+ {
+ // Can't use, because it contains point b
+ tri_21b = FALSE;
+ }
+
+ if (!tri_1a2)
+ {
+ use_tri1a2 = FALSE;
+ }
+ else if (!tri_21b)
+ {
+ use_tri1a2 = TRUE;
+ }
+ else
+ {
+ LLVector4a d1;
+ d1.setSub(p1,pa);
+ LLVector4a d2;
+ d2.setSub(p2,pb);
+
+ if (d1.dot3(d1) < d2.dot3(d2))
+ {
+ use_tri1a2 = TRUE;
+ }
+ else
+ {
+ use_tri1a2 = FALSE;
+ }
+ }
+
+ // Flipped backfacing from top
+ if (use_tri1a2)
+ {
+ mIndices[i++] = pt1;
+ mIndices[i++] = pt2;
+ mIndices[i++] = pt1 + 1;
+ pt1++;
+ }
+ else
+ {
+ mIndices[i++] = pt1;
+ mIndices[i++] = pt2;
+ mIndices[i++] = pt2 - 1;
+ pt2--;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Not hollow, generate the triangle fan.
+ U16 v1 = 2;
+ U16 v2 = 1;
+
+ if (mTypeMask & TOP_MASK)
+ {
+ v1 = 1;
+ v2 = 2;
+ }
+
+ for (S32 i = 0; i < (num_vertices - 2); i++)
+ {
+ mIndices[3*i] = num_vertices - 1;
+ mIndices[3*i+v1] = i;
+ mIndices[3*i+v2] = i + 1;
+ }
+
+
+ }
+
+ LLVector4a d0,d1;
+ LL_CHECK_MEMORY
+
+
+ d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
+ d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
+
+ LLVector4a normal;
+ normal.setCross3(d0,d1);
+
+ if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ normal.normalize3fast();
+ }
+ else
+ { //degenerate, make up a value
+ if(normal.getF32ptr()[2] >= 0)
+ normal.set(0.f,0.f,1.f);
+ else
+ normal.set(0.f,0.f,-1.f);
+ }
+
+ llassert(llfinite(normal.getF32ptr()[0]));
+ llassert(llfinite(normal.getF32ptr()[1]));
+ llassert(llfinite(normal.getF32ptr()[2]));
+
+ llassert(!llisnan(normal.getF32ptr()[0]));
+ llassert(!llisnan(normal.getF32ptr()[1]));
+ llassert(!llisnan(normal.getF32ptr()[2]));
+
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ norm[i].load4a(normal.getF32ptr());
+ }
+
+ return TRUE;
}
-void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
- const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
-
void LLVolumeFace::createTangents()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -6486,7 +6387,7 @@ void LLVolumeFace::createTangents()
if (!mTangents)
{
allocateTangents(mNumVertices);
-
+
//generate tangents
LLVector4a* ptr = (LLVector4a*)mTangents;
@@ -6496,7 +6397,7 @@ void LLVolumeFace::createTangents()
(*ptr++).clear();
}
- CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents);
+ LLCalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents);
//normalize normals
for (U32 i = 0; i < mNumVertices; i++)
@@ -6510,29 +6411,29 @@ void LLVolumeFace::createTangents()
void LLVolumeFace::resizeVertices(S32 num_verts)
{
- ll_aligned_free<64>(mPositions);
- //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
- ll_aligned_free_16(mTangents);
+ ll_aligned_free<64>(mPositions);
+ //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
+ ll_aligned_free_16(mTangents);
- mTangents = NULL;
+ mTangents = NULL;
- if (num_verts)
- {
- //pad texture coordinate block end to allow for QWORD reads
- S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
+ if (num_verts)
+ {
+ //pad texture coordinate block end to allow for QWORD reads
+ S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
- mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size);
- mNormals = mPositions+num_verts;
- mTexCoords = (LLVector2*) (mNormals+num_verts);
+ mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size);
+ mNormals = mPositions+num_verts;
+ mTexCoords = (LLVector2*) (mNormals+num_verts);
- ll_assert_aligned(mPositions, 64);
- }
- else
- {
- mPositions = NULL;
- mNormals = NULL;
- mTexCoords = NULL;
- }
+ ll_assert_aligned(mPositions, 64);
+ }
+ else
+ {
+ mPositions = NULL;
+ mNormals = NULL;
+ mTexCoords = NULL;
+ }
if (mPositions)
@@ -6553,70 +6454,70 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)
{
- pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord);
+ pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord);
}
void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc)
{
- S32 new_verts = mNumVertices+1;
+ S32 new_verts = mNumVertices+1;
- if (new_verts > mNumAllocatedVertices)
- {
- // double buffer size on expansion
- new_verts *= 2;
+ if (new_verts > mNumAllocatedVertices)
+ {
+ // double buffer size on expansion
+ new_verts *= 2;
- S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF;
- S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF;
+ S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF;
+ S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF;
- S32 old_vsize = mNumVertices*16;
+ S32 old_vsize = mNumVertices*16;
+
+ S32 new_size = new_verts*16*2+new_tc_size;
- S32 new_size = new_verts*16*2+new_tc_size;
+ LLVector4a* old_buf = mPositions;
- LLVector4a* old_buf = mPositions;
+ mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size);
+ mNormals = mPositions+new_verts;
+ mTexCoords = (LLVector2*) (mNormals+new_verts);
- mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size);
- mNormals = mPositions+new_verts;
- mTexCoords = (LLVector2*) (mNormals+new_verts);
+ if (old_buf != NULL)
+ {
+ // copy old positions into new buffer
+ LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize);
- if (old_buf != NULL)
- {
- // copy old positions into new buffer
- LLVector4a::memcpyNonAliased16((F32*)mPositions, (F32*)old_buf, old_vsize);
+ // normals
+ LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize);
- // normals
- LLVector4a::memcpyNonAliased16((F32*)mNormals, (F32*)(old_buf + mNumVertices), old_vsize);
+ // tex coords
+ LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size);
+ }
- // tex coords
- LLVector4a::memcpyNonAliased16((F32*)mTexCoords, (F32*)(old_buf + mNumVertices * 2), old_tc_size);
- }
-
- // just clear tangents
- ll_aligned_free_16(mTangents);
- mTangents = NULL;
- ll_aligned_free<64>(old_buf);
+ // just clear tangents
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
+ ll_aligned_free<64>(old_buf);
- mNumAllocatedVertices = new_verts;
+ mNumAllocatedVertices = new_verts;
- }
+ }
- mPositions[mNumVertices] = pos;
- mNormals[mNumVertices] = norm;
- mTexCoords[mNumVertices] = tc;
+ mPositions[mNumVertices] = pos;
+ mNormals[mNumVertices] = norm;
+ mTexCoords[mNumVertices] = tc;
- mNumVertices++;
+ mNumVertices++;
}
void LLVolumeFace::allocateTangents(S32 num_verts)
{
- ll_aligned_free_16(mTangents);
- mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+ ll_aligned_free_16(mTangents);
+ mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
void LLVolumeFace::allocateWeights(S32 num_verts)
{
- ll_aligned_free_16(mWeights);
- mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
-
+ ll_aligned_free_16(mWeights);
+ mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+
}
void LLVolumeFace::allocateJointIndices(S32 num_verts)
@@ -6625,27 +6526,27 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)
ll_aligned_free_16(mJointIndices);
ll_aligned_free_16(mJustWeights);
- mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts);
- mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);
+ mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts);
+ mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);
#endif
}
void LLVolumeFace::resizeIndices(S32 num_indices)
{
- ll_aligned_free_16(mIndices);
+ ll_aligned_free_16(mIndices);
llassert(num_indices % 3 == 0);
-
- if (num_indices)
- {
- //pad index block end to allow for QWORD reads
- S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF;
-
- mIndices = (U16*) ll_aligned_malloc_16(size);
- }
- else
- {
- mIndices = NULL;
- }
+
+ if (num_indices)
+ {
+ //pad index block end to allow for QWORD reads
+ S32 size = ((num_indices*sizeof(U16)) + 0xF) & ~0xF;
+
+ mIndices = (U16*) ll_aligned_malloc_16(size);
+ }
+ else
+ {
+ mIndices = NULL;
+ }
if (mIndices)
{
@@ -6660,73 +6561,73 @@ void LLVolumeFace::resizeIndices(S32 num_indices)
void LLVolumeFace::pushIndex(const U16& idx)
{
- S32 new_count = mNumIndices + 1;
- S32 new_size = ((new_count*2)+0xF) & ~0xF;
-
- S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
- if (new_size != old_size)
- {
- mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size);
- ll_assert_aligned(mIndices,16);
- }
+ S32 new_count = mNumIndices + 1;
+ S32 new_size = ((new_count*2)+0xF) & ~0xF;
- mIndices[mNumIndices++] = idx;
+ S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
+ if (new_size != old_size)
+ {
+ mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size);
+ ll_assert_aligned(mIndices,16);
+ }
+
+ mIndices[mNumIndices++] = idx;
}
void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx)
{
- resizeVertices(v.size());
- resizeIndices(idx.size());
+ resizeVertices(v.size());
+ resizeIndices(idx.size());
- for (U32 i = 0; i < v.size(); ++i)
- {
- mPositions[i] = v[i].getPosition();
- mNormals[i] = v[i].getNormal();
- mTexCoords[i] = v[i].mTexCoord;
- }
+ for (U32 i = 0; i < v.size(); ++i)
+ {
+ mPositions[i] = v[i].getPosition();
+ mNormals[i] = v[i].getNormal();
+ mTexCoords[i] = v[i].mTexCoord;
+ }
- for (U32 i = 0; i < idx.size(); ++i)
- {
- mIndices[i] = idx[i];
- }
+ for (U32 i = 0; i < idx.size(); ++i)
+ {
+ mIndices[i] = idx[i];
+ }
}
BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- LL_CHECK_MEMORY
- BOOL flat = mTypeMask & FLAT_MASK;
+ LL_CHECK_MEMORY
+ BOOL flat = mTypeMask & FLAT_MASK;
- U8 sculpt_type = volume->getParams().getSculptType();
- U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
- BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
- BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
- BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR
+ U8 sculpt_type = volume->getParams().getSculptType();
+ U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
+ BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
+ BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
+ BOOL sculpt_reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR
+
+ S32 num_vertices, num_indices;
- S32 num_vertices, num_indices;
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
+ const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath;
- const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
- const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
- const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath;
+ S32 max_s = volume->getProfile().getTotal();
- S32 max_s = volume->getProfile().getTotal();
+ S32 s, t, i;
+ F32 ss, tt;
- S32 s, t, i;
- F32 ss, tt;
+ num_vertices = mNumS*mNumT;
+ num_indices = (mNumS-1)*(mNumT-1)*6;
- num_vertices = mNumS*mNumT;
- num_indices = (mNumS-1)*(mNumT-1)*6;
+ partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build;
- partial_build = (num_vertices > mNumVertices || num_indices > mNumIndices) ? FALSE : partial_build;
-
- if (!partial_build)
- {
- resizeVertices(num_vertices);
- resizeIndices(num_indices);
+ if (!partial_build)
+ {
+ resizeVertices(num_vertices);
+ resizeIndices(num_indices);
- if (!volume->isMeshAssetLoaded())
- {
+ if (!volume->isMeshAssetLoaded())
+ {
try
{
mEdge.resize(num_indices);
@@ -6736,237 +6637,237 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL;
return false;
}
- }
- }
-
- LL_CHECK_MEMORY
-
- LLVector4a* pos = (LLVector4a*) mPositions;
- LLVector2* tc = (LLVector2*) mTexCoords;
- F32 begin_stex = floorf(profile[mBeginS][2]);
- S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;
-
- S32 cur_vertex = 0;
- S32 end_t = mBeginT+mNumT;
- bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2;
-
- // Copy the vertices into the array
- for (t = mBeginT; t < end_t; t++)
- {
- tt = path_data[t].mTexT;
- for (s = 0; s < num_s; s++)
- {
- if (mTypeMask & END_MASK)
- {
- if (s)
- {
- ss = 1.f;
- }
- else
- {
- ss = 0.f;
- }
- }
- else
- {
- // Get s value for tex-coord.
+ }
+ }
+
+ LL_CHECK_MEMORY
+
+ LLVector4a* pos = (LLVector4a*) mPositions;
+ LLVector2* tc = (LLVector2*) mTexCoords;
+ F32 begin_stex = floorf(profile[mBeginS][2]);
+ S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;
+
+ S32 cur_vertex = 0;
+ S32 end_t = mBeginT+mNumT;
+ bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2;
+
+ // Copy the vertices into the array
+ for (t = mBeginT; t < end_t; t++)
+ {
+ tt = path_data[t].mTexT;
+ for (s = 0; s < num_s; s++)
+ {
+ if (mTypeMask & END_MASK)
+ {
+ if (s)
+ {
+ ss = 1.f;
+ }
+ else
+ {
+ ss = 0.f;
+ }
+ }
+ else
+ {
+ // Get s value for tex-coord.
S32 index = mBeginS + s;
if (index >= profile.size())
{
// edge?
ss = flat ? 1.f - begin_stex : 1.f;
}
- else if (!flat)
- {
- ss = profile[index][2];
- }
- else
- {
- ss = profile[index][2] - begin_stex;
- }
- }
-
- if (sculpt_reverse_horizontal)
- {
- ss = 1.f - ss;
- }
-
- // Check to see if this triangle wraps around the array.
- if (mBeginS + s >= max_s)
- {
- // We're wrapping
- i = mBeginS + s + max_s*(t-1);
- }
- else
- {
- i = mBeginS + s + max_s*t;
- }
-
- mesh[i].store4a((F32*)(pos+cur_vertex));
- tc[cur_vertex].set(ss,tt);
-
- cur_vertex++;
-
- if (test && s > 0)
- {
- mesh[i].store4a((F32*)(pos+cur_vertex));
- tc[cur_vertex].set(ss,tt);
- cur_vertex++;
- }
- }
-
- if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2)
- {
- if (mTypeMask & OPEN_MASK)
- {
- s = num_s-1;
- }
- else
- {
- s = 0;
- }
-
- i = mBeginS + s + max_s*t;
- ss = profile[mBeginS + s][2] - begin_stex;
-
- mesh[i].store4a((F32*)(pos+cur_vertex));
- tc[cur_vertex].set(ss,tt);
-
- cur_vertex++;
- }
- }
- LL_CHECK_MEMORY
-
- mCenter->clear();
-
- LLVector4a* cur_pos = pos;
- LLVector4a* end_pos = pos + mNumVertices;
-
- //get bounding box for this side
- LLVector4a face_min;
- LLVector4a face_max;
-
- face_min = face_max = *cur_pos++;
-
- while (cur_pos < end_pos)
- {
- update_min_max(face_min, face_max, *cur_pos++);
- }
- // VFExtents change
- mExtents[0] = face_min;
- mExtents[1] = face_max;
-
- U32 tc_count = mNumVertices;
- if (tc_count%2 == 1)
- { //odd number of texture coordinates, duplicate last entry to padded end of array
- tc_count++;
- mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1];
- }
-
- LLVector4a* cur_tc = (LLVector4a*) mTexCoords;
- LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count);
-
- LLVector4a tc_min;
- LLVector4a tc_max;
-
- tc_min = tc_max = *cur_tc++;
-
- while (cur_tc < end_tc)
- {
- update_min_max(tc_min, tc_max, *cur_tc++);
- }
-
- F32* minp = tc_min.getF32ptr();
- F32* maxp = tc_max.getF32ptr();
-
- mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]);
- mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]);
- mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]);
- mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]);
-
- mCenter->setAdd(face_min, face_max);
- mCenter->mul(0.5f);
-
- S32 cur_index = 0;
- S32 cur_edge = 0;
- BOOL flat_face = mTypeMask & FLAT_MASK;
-
- if (!partial_build)
- {
- // Now we generate the indices.
- for (t = 0; t < (mNumT-1); t++)
- {
- for (s = 0; s < (mNumS-1); s++)
- {
- mIndices[cur_index++] = s + mNumS*t; //bottom left
- mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
- mIndices[cur_index++] = s + mNumS*(t+1); //top left
- mIndices[cur_index++] = s + mNumS*t; //bottom left
- mIndices[cur_index++] = s+1 + mNumS*t; //bottom right
- mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
-
- mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face
- if (t < mNumT-2) { //top right/top left neighbor face
- mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
- }
- else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
- mEdge[cur_edge++] = -1;
- }
- else { //wrap on T
- mEdge[cur_edge++] = s*2+1;
- }
- if (s > 0) { //top left/bottom left neighbor face
- mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1;
- }
- else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
- mEdge[cur_edge++] = -1;
- }
- else { //wrap on S
- mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1;
- }
-
- if (t > 0) { //bottom left/bottom right neighbor face
- mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2;
- }
- else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
- mEdge[cur_edge++] = -1;
- }
- else { //wrap on T
- mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2;
- }
- if (s < mNumS-2) { //bottom right/top right neighbor face
- mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2;
- }
- else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
- mEdge[cur_edge++] = -1;
- }
- else { //wrap on S
- mEdge[cur_edge++] = (mNumS-1)*2*t;
- }
- mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face
- }
- }
- }
-
- LL_CHECK_MEMORY
-
- //clear normals
- F32* dst = (F32*) mNormals;
- F32* end = (F32*) (mNormals+mNumVertices);
- LLVector4a zero = LLVector4a::getZero();
-
- while (dst < end)
- {
- zero.store4a(dst);
- dst += 4;
- }
-
- LL_CHECK_MEMORY
-
- //generate normals
- U32 count = mNumIndices/3;
-
- LLVector4a* norm = mNormals;
+ else if (!flat)
+ {
+ ss = profile[index][2];
+ }
+ else
+ {
+ ss = profile[index][2] - begin_stex;
+ }
+ }
+
+ if (sculpt_reverse_horizontal)
+ {
+ ss = 1.f - ss;
+ }
+
+ // Check to see if this triangle wraps around the array.
+ if (mBeginS + s >= max_s)
+ {
+ // We're wrapping
+ i = mBeginS + s + max_s*(t-1);
+ }
+ else
+ {
+ i = mBeginS + s + max_s*t;
+ }
+
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
+
+ cur_vertex++;
+
+ if (test && s > 0)
+ {
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
+ cur_vertex++;
+ }
+ }
+
+ if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2)
+ {
+ if (mTypeMask & OPEN_MASK)
+ {
+ s = num_s-1;
+ }
+ else
+ {
+ s = 0;
+ }
+
+ i = mBeginS + s + max_s*t;
+ ss = profile[mBeginS + s][2] - begin_stex;
+
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
+
+ cur_vertex++;
+ }
+ }
+ LL_CHECK_MEMORY
+
+ mCenter->clear();
+
+ LLVector4a* cur_pos = pos;
+ LLVector4a* end_pos = pos + mNumVertices;
+
+ //get bounding box for this side
+ LLVector4a face_min;
+ LLVector4a face_max;
+
+ face_min = face_max = *cur_pos++;
+
+ while (cur_pos < end_pos)
+ {
+ update_min_max(face_min, face_max, *cur_pos++);
+ }
+ // VFExtents change
+ mExtents[0] = face_min;
+ mExtents[1] = face_max;
+
+ U32 tc_count = mNumVertices;
+ if (tc_count%2 == 1)
+ { //odd number of texture coordinates, duplicate last entry to padded end of array
+ tc_count++;
+ mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1];
+ }
+
+ LLVector4a* cur_tc = (LLVector4a*) mTexCoords;
+ LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count);
+
+ LLVector4a tc_min;
+ LLVector4a tc_max;
+
+ tc_min = tc_max = *cur_tc++;
+
+ while (cur_tc < end_tc)
+ {
+ update_min_max(tc_min, tc_max, *cur_tc++);
+ }
+
+ F32* minp = tc_min.getF32ptr();
+ F32* maxp = tc_max.getF32ptr();
+
+ mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]);
+ mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]);
+ mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]);
+ mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]);
+
+ mCenter->setAdd(face_min, face_max);
+ mCenter->mul(0.5f);
+
+ S32 cur_index = 0;
+ S32 cur_edge = 0;
+ BOOL flat_face = mTypeMask & FLAT_MASK;
+
+ if (!partial_build)
+ {
+ // Now we generate the indices.
+ for (t = 0; t < (mNumT-1); t++)
+ {
+ for (s = 0; s < (mNumS-1); s++)
+ {
+ mIndices[cur_index++] = s + mNumS*t; //bottom left
+ mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
+ mIndices[cur_index++] = s + mNumS*(t+1); //top left
+ mIndices[cur_index++] = s + mNumS*t; //bottom left
+ mIndices[cur_index++] = s+1 + mNumS*t; //bottom right
+ mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
+
+ mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face
+ if (t < mNumT-2) { //top right/top left neighbor face
+ mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
+ }
+ else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
+ mEdge[cur_edge++] = -1;
+ }
+ else { //wrap on T
+ mEdge[cur_edge++] = s*2+1;
+ }
+ if (s > 0) { //top left/bottom left neighbor face
+ mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1;
+ }
+ else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
+ mEdge[cur_edge++] = -1;
+ }
+ else { //wrap on S
+ mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1;
+ }
+
+ if (t > 0) { //bottom left/bottom right neighbor face
+ mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2;
+ }
+ else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
+ mEdge[cur_edge++] = -1;
+ }
+ else { //wrap on T
+ mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2;
+ }
+ if (s < mNumS-2) { //bottom right/top right neighbor face
+ mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2;
+ }
+ else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
+ mEdge[cur_edge++] = -1;
+ }
+ else { //wrap on S
+ mEdge[cur_edge++] = (mNumS-1)*2*t;
+ }
+ mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face
+ }
+ }
+ }
+
+ LL_CHECK_MEMORY
+
+ //clear normals
+ F32* dst = (F32*) mNormals;
+ F32* end = (F32*) (mNormals+mNumVertices);
+ LLVector4a zero = LLVector4a::getZero();
+
+ while (dst < end)
+ {
+ zero.store4a(dst);
+ dst += 4;
+ }
+
+ LL_CHECK_MEMORY
+
+ //generate normals
+ U32 count = mNumIndices/3;
+
+ LLVector4a* norm = mNormals;
static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;
try
@@ -6978,242 +6879,242 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL;
return false;
}
- LLVector4a* output = triangle_normals.mArray;
- LLVector4a* end_output = output+count;
-
- U16* idx = mIndices;
-
- while (output < end_output)
- {
- LLVector4a b,v1,v2;
- b.load4a((F32*) (pos+idx[0]));
- v1.load4a((F32*) (pos+idx[1]));
- v2.load4a((F32*) (pos+idx[2]));
-
- //calculate triangle normal
- LLVector4a a;
-
- a.setSub(b, v1);
- b.sub(v2);
-
-
- LLQuad& vector1 = *((LLQuad*) &v1);
- LLQuad& vector2 = *((LLQuad*) &v2);
-
- LLQuad& amQ = *((LLQuad*) &a);
- LLQuad& bmQ = *((LLQuad*) &b);
-
- //v1.setCross3(t,v0);
- //setCross3(const LLVector4a& a, const LLVector4a& b)
- // Vectors are stored in memory in w, z, y, x order from high to low
- // Set vector1 = { a[W], a[X], a[Z], a[Y] }
- vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
- // Set vector2 = { b[W], b[Y], b[X], b[Z] }
- vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
- // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] }
- vector2 = _mm_mul_ps( vector1, vector2 );
- // vector3 = { a[W], a[Y], a[X], a[Z] }
- amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
- // vector4 = { b[W], b[X], b[Z], b[Y] }
- bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
- // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
- vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ ));
-
- llassert(v1.isFinite3());
-
- v1.store4a((F32*) output);
-
-
- output++;
- idx += 3;
- }
-
- idx = mIndices;
-
- LLVector4a* src = triangle_normals.mArray;
-
- for (U32 i = 0; i < count; i++) //for each triangle
- {
- LLVector4a c;
- c.load4a((F32*) (src++));
-
- LLVector4a* n0p = norm+idx[0];
- LLVector4a* n1p = norm+idx[1];
- LLVector4a* n2p = norm+idx[2];
-
- idx += 3;
-
- LLVector4a n0,n1,n2;
- n0.load4a((F32*) n0p);
- n1.load4a((F32*) n1p);
- n2.load4a((F32*) n2p);
-
- n0.add(c);
- n1.add(c);
- n2.add(c);
-
- llassert(c.isFinite3());
-
- //even out quad contributions
- switch (i%2+1)
- {
- case 0: n0.add(c); break;
- case 1: n1.add(c); break;
- case 2: n2.add(c); break;
- };
-
- n0.store4a((F32*) n0p);
- n1.store4a((F32*) n1p);
- n2.store4a((F32*) n2p);
- }
-
- LL_CHECK_MEMORY
-
- // adjust normals based on wrapping and stitching
-
- LLVector4a top;
- top.setSub(pos[0], pos[mNumS*(mNumT-2)]);
- BOOL s_bottom_converges = (top.dot3(top) < 0.000001f);
-
- top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]);
- BOOL s_top_converges = (top.dot3(top) < 0.000001f);
-
- if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes
- {
- if (volume->getPath().isOpen() == FALSE)
- { //wrap normals on T
- for (S32 i = 0; i < mNumS; i++)
- {
- LLVector4a n;
- n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]);
- norm[i] = n;
- norm[mNumS*(mNumT-1)+i] = n;
- }
- }
-
- if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges))
- { //wrap normals on S
- for (S32 i = 0; i < mNumT; i++)
- {
- LLVector4a n;
- n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]);
- norm[mNumS * i] = n;
- norm[mNumS * i+mNumS-1] = n;
- }
- }
-
- if (volume->getPathType() == LL_PCODE_PATH_CIRCLE &&
- ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF))
- {
- if (s_bottom_converges)
- { //all lower S have same normal
- for (S32 i = 0; i < mNumT; i++)
- {
- norm[mNumS*i].set(1,0,0);
- }
- }
-
- if (s_top_converges)
- { //all upper S have same normal
- for (S32 i = 0; i < mNumT; i++)
- {
- norm[mNumS*i+mNumS-1].set(-1,0,0);
- }
- }
- }
- }
- else // logic for sculpt volumes
- {
- BOOL average_poles = FALSE;
- BOOL wrap_s = FALSE;
- BOOL wrap_t = FALSE;
-
- if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
- average_poles = TRUE;
-
- if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
- (sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
- (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
- wrap_s = TRUE;
-
- if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
- wrap_t = TRUE;
-
-
- if (average_poles)
- {
- // average normals for north pole
-
- LLVector4a average;
- average.clear();
-
- for (S32 i = 0; i < mNumS; i++)
- {
- average.add(norm[i]);
- }
-
- // set average
- for (S32 i = 0; i < mNumS; i++)
- {
- norm[i] = average;
- }
-
- // average normals for south pole
-
- average.clear();
-
- for (S32 i = 0; i < mNumS; i++)
- {
- average.add(norm[i + mNumS * (mNumT - 1)]);
- }
-
- // set average
- for (S32 i = 0; i < mNumS; i++)
- {
- norm[i + mNumS * (mNumT - 1)] = average;
- }
-
- }
-
-
- if (wrap_s)
- {
- for (S32 i = 0; i < mNumT; i++)
- {
- LLVector4a n;
- n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]);
- norm[mNumS * i] = n;
- norm[mNumS * i+mNumS-1] = n;
- }
- }
-
- if (wrap_t)
- {
- for (S32 i = 0; i < mNumS; i++)
- {
- LLVector4a n;
- n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]);
- norm[i] = n;
- norm[mNumS*(mNumT-1)+i] = n;
- }
- }
-
- }
-
- LL_CHECK_MEMORY
-
- return TRUE;
+ LLVector4a* output = triangle_normals.mArray;
+ LLVector4a* end_output = output+count;
+
+ U16* idx = mIndices;
+
+ while (output < end_output)
+ {
+ LLVector4a b,v1,v2;
+ b.load4a((F32*) (pos+idx[0]));
+ v1.load4a((F32*) (pos+idx[1]));
+ v2.load4a((F32*) (pos+idx[2]));
+
+ //calculate triangle normal
+ LLVector4a a;
+
+ a.setSub(b, v1);
+ b.sub(v2);
+
+
+ LLQuad& vector1 = *((LLQuad*) &v1);
+ LLQuad& vector2 = *((LLQuad*) &v2);
+
+ LLQuad& amQ = *((LLQuad*) &a);
+ LLQuad& bmQ = *((LLQuad*) &b);
+
+ //v1.setCross3(t,v0);
+ //setCross3(const LLVector4a& a, const LLVector4a& b)
+ // Vectors are stored in memory in w, z, y, x order from high to low
+ // Set vector1 = { a[W], a[X], a[Z], a[Y] }
+ vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
+ // Set vector2 = { b[W], b[Y], b[X], b[Z] }
+ vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
+ // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] }
+ vector2 = _mm_mul_ps( vector1, vector2 );
+ // vector3 = { a[W], a[Y], a[X], a[Z] }
+ amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
+ // vector4 = { b[W], b[X], b[Z], b[Y] }
+ bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
+ // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
+ vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ ));
+
+ llassert(v1.isFinite3());
+
+ v1.store4a((F32*) output);
+
+
+ output++;
+ idx += 3;
+ }
+
+ idx = mIndices;
+
+ LLVector4a* src = triangle_normals.mArray;
+
+ for (U32 i = 0; i < count; i++) //for each triangle
+ {
+ LLVector4a c;
+ c.load4a((F32*) (src++));
+
+ LLVector4a* n0p = norm+idx[0];
+ LLVector4a* n1p = norm+idx[1];
+ LLVector4a* n2p = norm+idx[2];
+
+ idx += 3;
+
+ LLVector4a n0,n1,n2;
+ n0.load4a((F32*) n0p);
+ n1.load4a((F32*) n1p);
+ n2.load4a((F32*) n2p);
+
+ n0.add(c);
+ n1.add(c);
+ n2.add(c);
+
+ llassert(c.isFinite3());
+
+ //even out quad contributions
+ switch (i%2+1)
+ {
+ case 0: n0.add(c); break;
+ case 1: n1.add(c); break;
+ case 2: n2.add(c); break;
+ };
+
+ n0.store4a((F32*) n0p);
+ n1.store4a((F32*) n1p);
+ n2.store4a((F32*) n2p);
+ }
+
+ LL_CHECK_MEMORY
+
+ // adjust normals based on wrapping and stitching
+
+ LLVector4a top;
+ top.setSub(pos[0], pos[mNumS*(mNumT-2)]);
+ BOOL s_bottom_converges = (top.dot3(top) < 0.000001f);
+
+ top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]);
+ BOOL s_top_converges = (top.dot3(top) < 0.000001f);
+
+ if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes
+ {
+ if (volume->getPath().isOpen() == FALSE)
+ { //wrap normals on T
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ LLVector4a n;
+ n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]);
+ norm[i] = n;
+ norm[mNumS*(mNumT-1)+i] = n;
+ }
+ }
+
+ if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges))
+ { //wrap normals on S
+ for (S32 i = 0; i < mNumT; i++)
+ {
+ LLVector4a n;
+ n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]);
+ norm[mNumS * i] = n;
+ norm[mNumS * i+mNumS-1] = n;
+ }
+ }
+
+ if (volume->getPathType() == LL_PCODE_PATH_CIRCLE &&
+ ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF))
+ {
+ if (s_bottom_converges)
+ { //all lower S have same normal
+ for (S32 i = 0; i < mNumT; i++)
+ {
+ norm[mNumS*i].set(1,0,0);
+ }
+ }
+
+ if (s_top_converges)
+ { //all upper S have same normal
+ for (S32 i = 0; i < mNumT; i++)
+ {
+ norm[mNumS*i+mNumS-1].set(-1,0,0);
+ }
+ }
+ }
+ }
+ else // logic for sculpt volumes
+ {
+ BOOL average_poles = FALSE;
+ BOOL wrap_s = FALSE;
+ BOOL wrap_t = FALSE;
+
+ if (sculpt_stitching == LL_SCULPT_TYPE_SPHERE)
+ average_poles = TRUE;
+
+ if ((sculpt_stitching == LL_SCULPT_TYPE_SPHERE) ||
+ (sculpt_stitching == LL_SCULPT_TYPE_TORUS) ||
+ (sculpt_stitching == LL_SCULPT_TYPE_CYLINDER))
+ wrap_s = TRUE;
+
+ if (sculpt_stitching == LL_SCULPT_TYPE_TORUS)
+ wrap_t = TRUE;
+
+
+ if (average_poles)
+ {
+ // average normals for north pole
+
+ LLVector4a average;
+ average.clear();
+
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ average.add(norm[i]);
+ }
+
+ // set average
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ norm[i] = average;
+ }
+
+ // average normals for south pole
+
+ average.clear();
+
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ average.add(norm[i + mNumS * (mNumT - 1)]);
+ }
+
+ // set average
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ norm[i + mNumS * (mNumT - 1)] = average;
+ }
+
+ }
+
+
+ if (wrap_s)
+ {
+ for (S32 i = 0; i < mNumT; i++)
+ {
+ LLVector4a n;
+ n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]);
+ norm[mNumS * i] = n;
+ norm[mNumS * i+mNumS-1] = n;
+ }
+ }
+
+ if (wrap_t)
+ {
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ LLVector4a n;
+ n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]);
+ norm[i] = n;
+ norm[mNumS*(mNumT-1)+i] = n;
+ }
+ }
+
+ }
+
+ LL_CHECK_MEMORY
+
+ return TRUE;
}
//adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
-void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
+void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
- LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
- // new(tan1) LLVector4a;
+ LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
+ // new(tan1) LLVector4a;
LLVector4a* tan2 = tan1 + vertexCount;
@@ -7228,86 +7129,86 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
U32 i1 = *index_array++;
U32 i2 = *index_array++;
U32 i3 = *index_array++;
-
+
const LLVector4a& v1 = vertex[i1];
const LLVector4a& v2 = vertex[i2];
const LLVector4a& v3 = vertex[i3];
-
+
const LLVector2& w1 = texcoord[i1];
const LLVector2& w2 = texcoord[i2];
const LLVector2& w3 = texcoord[i3];
-
- const F32* v1ptr = v1.getF32ptr();
- const F32* v2ptr = v2.getF32ptr();
- const F32* v3ptr = v3.getF32ptr();
-
+
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
+
float x1 = v2ptr[0] - v1ptr[0];
float x2 = v3ptr[0] - v1ptr[0];
float y1 = v2ptr[1] - v1ptr[1];
float y2 = v3ptr[1] - v1ptr[1];
float z1 = v2ptr[2] - v1ptr[2];
float z2 = v3ptr[2] - v1ptr[2];
-
+
float s1 = w2.mV[0] - w1.mV[0];
float s2 = w3.mV[0] - w1.mV[0];
float t1 = w2.mV[1] - w1.mV[1];
float t2 = w3.mV[1] - w1.mV[1];
-
- F32 rd = s1*t2-s2*t1;
-
- float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
- : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
-
- llassert(llfinite(r));
- llassert(!llisnan(r));
-
- LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r);
- LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r);
-
- tan1[i1].add(sdir);
- tan1[i2].add(sdir);
- tan1[i3].add(sdir);
-
- tan2[i1].add(tdir);
- tan2[i2].add(tdir);
- tan2[i3].add(tdir);
- }
-
+
+ F32 rd = s1*t2-s2*t1;
+
+ float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
+ : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
+
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
+
+ LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+
+ tan1[i1].add(sdir);
+ tan1[i2].add(sdir);
+ tan1[i3].add(sdir);
+
+ tan2[i1].add(tdir);
+ tan2[i2].add(tdir);
+ tan2[i3].add(tdir);
+ }
+
for (U32 a = 0; a < vertexCount; a++)
{
LLVector4a n = normal[a];
- const LLVector4a& t = tan1[a];
+ const LLVector4a& t = tan1[a];
- LLVector4a ncrosst;
- ncrosst.setCross3(n,t);
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
// Gram-Schmidt orthogonalize
n.mul(n.dot3(t).getF32());
- LLVector4a tsubn;
- tsubn.setSub(t,n);
-
- if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
- {
- tsubn.normalize3fast();
-
- // Calculate handedness
- F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f;
-
- tsubn.getF32ptr()[3] = handedness;
-
- tangent[a] = tsubn;
- }
- else
- { //degenerate, make up a value
- tangent[a].set(0,0,1,1);
- }
- }
-
- ll_aligned_free_16(tan1);
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
+
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast();
+
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f;
+
+ tsubn.getF32ptr()[3] = handedness;
+
+ tangent[a] = tsubn;
+ }
+ else
+ { //degenerate, make up a value
+ tangent[a].set(0,0,1,1);
+ }
+ }
+
+ ll_aligned_free_16(tan1);
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 917ad6030c..ccc0671315 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvolume.h
* @brief LLVolume base class.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -41,6 +41,7 @@ template <class T, typename T_PTR> class LLOctreeNode;
class LLVolumeFace;
class LLVolume;
class LLVolumeTriangle;
+class LLVolumeOctree;
#include "lluuid.h"
#include "v4color.h"
@@ -69,8 +70,8 @@ const S32 MAX_LOD = 3;
// These are defined here but are not enforced at this level,
// rather they are here for the convenience of code that uses
// the LLVolume class.
-const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
-const F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
+const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
+const F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
const F32 CUT_QUANTA = 0.00002f;
const F32 SCALE_QUANTA = 0.01f;
@@ -84,100 +85,100 @@ const S32 MAX_VOLUME_TRIANGLE_INDICES = 10000;
//============================================================================
// useful masks
-const LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // has a thickness
-const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle)
-const LLPCode LL_PCODE_PATCH_MASK = 0x20; // segmented segments (2 angles)
-const LLPCode LL_PCODE_HEMI_MASK = 0x10; // half-primitives get their own type per PR's dictum
-const LLPCode LL_PCODE_BASE_MASK = 0x0F;
-
- // primitive shapes
-const LLPCode LL_PCODE_CUBE = 1;
-const LLPCode LL_PCODE_PRISM = 2;
-const LLPCode LL_PCODE_TETRAHEDRON = 3;
-const LLPCode LL_PCODE_PYRAMID = 4;
-const LLPCode LL_PCODE_CYLINDER = 5;
-const LLPCode LL_PCODE_CONE = 6;
-const LLPCode LL_PCODE_SPHERE = 7;
-const LLPCode LL_PCODE_TORUS = 8;
-const LLPCode LL_PCODE_VOLUME = 9;
-
- // surfaces
-//const LLPCode LL_PCODE_SURFACE_TRIANGLE = 10;
-//const LLPCode LL_PCODE_SURFACE_SQUARE = 11;
-//const LLPCode LL_PCODE_SURFACE_DISC = 12;
-
-const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects)
-const LLPCode LL_PCODE_LEGACY = 15;
+const LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // has a thickness
+const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle)
+const LLPCode LL_PCODE_PATCH_MASK = 0x20; // segmented segments (2 angles)
+const LLPCode LL_PCODE_HEMI_MASK = 0x10; // half-primitives get their own type per PR's dictum
+const LLPCode LL_PCODE_BASE_MASK = 0x0F;
+
+ // primitive shapes
+const LLPCode LL_PCODE_CUBE = 1;
+const LLPCode LL_PCODE_PRISM = 2;
+const LLPCode LL_PCODE_TETRAHEDRON = 3;
+const LLPCode LL_PCODE_PYRAMID = 4;
+const LLPCode LL_PCODE_CYLINDER = 5;
+const LLPCode LL_PCODE_CONE = 6;
+const LLPCode LL_PCODE_SPHERE = 7;
+const LLPCode LL_PCODE_TORUS = 8;
+const LLPCode LL_PCODE_VOLUME = 9;
+
+ // surfaces
+//const LLPCode LL_PCODE_SURFACE_TRIANGLE = 10;
+//const LLPCode LL_PCODE_SURFACE_SQUARE = 11;
+//const LLPCode LL_PCODE_SURFACE_DISC = 12;
+
+const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects)
+const LLPCode LL_PCODE_LEGACY = 15;
// Pcodes for legacy objects
-//const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR
-const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER
-//const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD
-//const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON
-const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS
-const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees
-//const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE
-const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS
-const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK
-//const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
-//const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY;
-//const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE
-//const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK
-const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
-const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE
-
- // hemis
-const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK;
-const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK;
-const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK;
-const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK;
+//const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR
+const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER
+//const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD
+//const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON
+const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS
+const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees
+//const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE
+const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS
+const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK
+//const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
+//const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY;
+//const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE
+//const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK
+const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
+const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE
+
+ // hemis
+const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK;
+const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK;
+const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK;
+const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK;
// Volumes consist of a profile at the base that is swept around
// a path to make a volume.
// The profile code
-const U8 LL_PCODE_PROFILE_MASK = 0x0f;
-const U8 LL_PCODE_PROFILE_MIN = 0x00;
-const U8 LL_PCODE_PROFILE_CIRCLE = 0x00;
-const U8 LL_PCODE_PROFILE_SQUARE = 0x01;
-const U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
-const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03;
-const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04;
-const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
-const U8 LL_PCODE_PROFILE_MAX = 0x05;
+const U8 LL_PCODE_PROFILE_MASK = 0x0f;
+const U8 LL_PCODE_PROFILE_MIN = 0x00;
+const U8 LL_PCODE_PROFILE_CIRCLE = 0x00;
+const U8 LL_PCODE_PROFILE_SQUARE = 0x01;
+const U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
+const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03;
+const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04;
+const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
+const U8 LL_PCODE_PROFILE_MAX = 0x05;
// Stored in the profile byte
-const U8 LL_PCODE_HOLE_MASK = 0xf0;
-const U8 LL_PCODE_HOLE_MIN = 0x00;
-const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile
-const U8 LL_PCODE_HOLE_CIRCLE = 0x10;
-const U8 LL_PCODE_HOLE_SQUARE = 0x20;
-const U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
-const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max
+const U8 LL_PCODE_HOLE_MASK = 0xf0;
+const U8 LL_PCODE_HOLE_MIN = 0x00;
+const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile
+const U8 LL_PCODE_HOLE_CIRCLE = 0x10;
+const U8 LL_PCODE_HOLE_SQUARE = 0x20;
+const U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
+const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max
const U8 LL_PCODE_PATH_IGNORE = 0x00;
-const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max
+const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max
const U8 LL_PCODE_PATH_LINE = 0x10;
const U8 LL_PCODE_PATH_CIRCLE = 0x20;
const U8 LL_PCODE_PATH_CIRCLE2 = 0x30;
const U8 LL_PCODE_PATH_TEST = 0x40;
const U8 LL_PCODE_PATH_FLEXIBLE = 0x80;
-const U8 LL_PCODE_PATH_MAX = 0x08;
+const U8 LL_PCODE_PATH_MAX = 0x08;
//============================================================================
// face identifiers
typedef U16 LLFaceID;
-const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
-const LLFaceID LL_FACE_PATH_END = 0x1 << 1;
-const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
-const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
-const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
-const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
-const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
-const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
-const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
+const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
+const LLFaceID LL_FACE_PATH_END = 0x1 << 1;
+const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
+const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
+const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
+const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
+const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
+const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
+const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
//============================================================================
@@ -190,7 +191,7 @@ const U8 LL_SCULPT_TYPE_PLANE = 3;
const U8 LL_SCULPT_TYPE_CYLINDER = 4;
const U8 LL_SCULPT_TYPE_MESH = 5;
const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE |
- LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH;
+ LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH;
// for value checks, assign new value after adding new types
const U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_MESH;
@@ -206,125 +207,125 @@ extern BOOL gDebugGL;
class LLProfileParams
{
public:
- LLProfileParams()
- : mCurveType(LL_PCODE_PROFILE_SQUARE),
- mBegin(0.f),
- mEnd(1.f),
- mHollow(0.f),
- mCRC(0)
- {
- }
-
- LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
- : mCurveType(curve),
- mBegin(begin),
- mEnd(end),
- mHollow(hollow),
- mCRC(0)
- {
- }
-
- LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
- {
- mCurveType = curve;
- F32 temp_f32 = begin * CUT_QUANTA;
- if (temp_f32 > 1.f)
- {
- temp_f32 = 1.f;
- }
- mBegin = temp_f32;
- temp_f32 = end * CUT_QUANTA;
- if (temp_f32 > 1.f)
- {
- temp_f32 = 1.f;
- }
- mEnd = 1.f - temp_f32;
- temp_f32 = hollow * HOLLOW_QUANTA;
- if (temp_f32 > 1.f)
- {
- temp_f32 = 1.f;
- }
- mHollow = temp_f32;
- mCRC = 0;
- }
-
- bool operator==(const LLProfileParams &params) const;
- bool operator!=(const LLProfileParams &params) const;
- bool operator<(const LLProfileParams &params) const;
-
- void copyParams(const LLProfileParams &params);
-
- BOOL importFile(LLFILE *fp);
- BOOL exportFile(LLFILE *fp) const;
-
- BOOL importLegacyStream(std::istream& input_stream);
- BOOL exportLegacyStream(std::ostream& output_stream) const;
-
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- const F32& getBegin () const { return mBegin; }
- const F32& getEnd () const { return mEnd; }
- const F32& getHollow() const { return mHollow; }
- const U8& getCurveType () const { return mCurveType; }
-
- void setCurveType(const U32 type) { mCurveType = type;}
- void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;}
- void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;}
- void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;}
-
- friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
+ LLProfileParams()
+ : mCurveType(LL_PCODE_PROFILE_SQUARE),
+ mBegin(0.f),
+ mEnd(1.f),
+ mHollow(0.f),
+ mCRC(0)
+ {
+ }
+
+ LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
+ : mCurveType(curve),
+ mBegin(begin),
+ mEnd(end),
+ mHollow(hollow),
+ mCRC(0)
+ {
+ }
+
+ LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
+ {
+ mCurveType = curve;
+ F32 temp_f32 = begin * CUT_QUANTA;
+ if (temp_f32 > 1.f)
+ {
+ temp_f32 = 1.f;
+ }
+ mBegin = temp_f32;
+ temp_f32 = end * CUT_QUANTA;
+ if (temp_f32 > 1.f)
+ {
+ temp_f32 = 1.f;
+ }
+ mEnd = 1.f - temp_f32;
+ temp_f32 = hollow * HOLLOW_QUANTA;
+ if (temp_f32 > 1.f)
+ {
+ temp_f32 = 1.f;
+ }
+ mHollow = temp_f32;
+ mCRC = 0;
+ }
+
+ bool operator==(const LLProfileParams &params) const;
+ bool operator!=(const LLProfileParams &params) const;
+ bool operator<(const LLProfileParams &params) const;
+
+ void copyParams(const LLProfileParams &params);
+
+ BOOL importFile(LLFILE *fp);
+ BOOL exportFile(LLFILE *fp) const;
+
+ BOOL importLegacyStream(std::istream& input_stream);
+ BOOL exportLegacyStream(std::ostream& output_stream) const;
+
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ const F32& getBegin () const { return mBegin; }
+ const F32& getEnd () const { return mEnd; }
+ const F32& getHollow() const { return mHollow; }
+ const U8& getCurveType () const { return mCurveType; }
+
+ void setCurveType(const U32 type) { mCurveType = type;}
+ void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;}
+ void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;}
+ void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;}
+
+ friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
protected:
- // Profile params
- U8 mCurveType;
- F32 mBegin;
- F32 mEnd;
- F32 mHollow;
+ // Profile params
+ U8 mCurveType;
+ F32 mBegin;
+ F32 mEnd;
+ F32 mHollow;
- U32 mCRC;
+ U32 mCRC;
};
inline bool LLProfileParams::operator==(const LLProfileParams &params) const
{
- return
- (getCurveType() == params.getCurveType()) &&
- (getBegin() == params.getBegin()) &&
- (getEnd() == params.getEnd()) &&
- (getHollow() == params.getHollow());
+ return
+ (getCurveType() == params.getCurveType()) &&
+ (getBegin() == params.getBegin()) &&
+ (getEnd() == params.getEnd()) &&
+ (getHollow() == params.getHollow());
}
inline bool LLProfileParams::operator!=(const LLProfileParams &params) const
{
- return
- (getCurveType() != params.getCurveType()) ||
- (getBegin() != params.getBegin()) ||
- (getEnd() != params.getEnd()) ||
- (getHollow() != params.getHollow());
+ return
+ (getCurveType() != params.getCurveType()) ||
+ (getBegin() != params.getBegin()) ||
+ (getEnd() != params.getEnd()) ||
+ (getHollow() != params.getHollow());
}
inline bool LLProfileParams::operator<(const LLProfileParams &params) const
{
- if (getCurveType() != params.getCurveType())
- {
- return getCurveType() < params.getCurveType();
- }
- else
- if (getBegin() != params.getBegin())
- {
- return getBegin() < params.getBegin();
- }
- else
- if (getEnd() != params.getEnd())
- {
- return getEnd() < params.getEnd();
- }
- else
- {
- return getHollow() < params.getHollow();
- }
+ if (getCurveType() != params.getCurveType())
+ {
+ return getCurveType() < params.getCurveType();
+ }
+ else
+ if (getBegin() != params.getBegin())
+ {
+ return getBegin() < params.getBegin();
+ }
+ else
+ if (getEnd() != params.getEnd())
+ {
+ return getEnd() < params.getEnd();
+ }
+ else
+ {
+ return getHollow() < params.getHollow();
+ }
}
#define U8_TO_F32(x) (F32)(*((S8 *)&x))
@@ -332,225 +333,225 @@ inline bool LLProfileParams::operator<(const LLProfileParams &params) const
class LLPathParams
{
public:
- LLPathParams()
- :
- mCurveType(LL_PCODE_PATH_LINE),
- mBegin(0.f),
- mEnd(1.f),
- mScale(1.f,1.f),
- mShear(0.f,0.f),
- mTwistBegin(0.f),
- mTwistEnd(0.f),
- mRadiusOffset(0.f),
- mTaper(0.f,0.f),
- mRevolutions(1.f),
- mSkew(0.f),
- mCRC(0)
- {
- }
-
- LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew)
- : mCurveType(curve),
- mBegin(begin),
- mEnd(end),
- mScale(scx,scy),
- mShear(shx,shy),
- mTwistBegin(twistbegin),
- mTwistEnd(twistend),
- mRadiusOffset(radiusoffset),
- mTaper(tx,ty),
- mRevolutions(revolutions),
- mSkew(skew),
- mCRC(0)
- {
- }
-
- LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
- {
- mCurveType = curve;
- mBegin = (F32)(begin * CUT_QUANTA);
- mEnd = (F32)(100.f - end) * CUT_QUANTA;
- if (mEnd > 1.f)
- mEnd = 1.f;
- mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
- mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA);
- mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
- mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
- mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
- mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA);
- mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f;
- mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
-
- mCRC = 0;
- }
-
- bool operator==(const LLPathParams &params) const;
- bool operator!=(const LLPathParams &params) const;
- bool operator<(const LLPathParams &params) const;
-
- void copyParams(const LLPathParams &params);
-
- BOOL importFile(LLFILE *fp);
- BOOL exportFile(LLFILE *fp) const;
-
- BOOL importLegacyStream(std::istream& input_stream);
- BOOL exportLegacyStream(std::ostream& output_stream) const;
-
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- const F32& getBegin() const { return mBegin; }
- const F32& getEnd() const { return mEnd; }
- const LLVector2 &getScale() const { return mScale; }
- const F32& getScaleX() const { return mScale.mV[0]; }
- const F32& getScaleY() const { return mScale.mV[1]; }
- const LLVector2 getBeginScale() const;
- const LLVector2 getEndScale() const;
- const LLVector2 &getShear() const { return mShear; }
- const F32& getShearX() const { return mShear.mV[0]; }
- const F32& getShearY() const { return mShear.mV[1]; }
- const U8& getCurveType () const { return mCurveType; }
-
- const F32& getTwistBegin() const { return mTwistBegin; }
- const F32& getTwistEnd() const { return mTwistEnd; }
- const F32& getTwist() const { return mTwistEnd; } // deprecated
- const F32& getRadiusOffset() const { return mRadiusOffset; }
- const LLVector2 &getTaper() const { return mTaper; }
- const F32& getTaperX() const { return mTaper.mV[0]; }
- const F32& getTaperY() const { return mTaper.mV[1]; }
- const F32& getRevolutions() const { return mRevolutions; }
- const F32& getSkew() const { return mSkew; }
-
- void setCurveType(const U8 type) { mCurveType = type; }
- void setBegin(const F32 begin) { mBegin = begin; }
- void setEnd(const F32 end) { mEnd = end; }
-
- void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); }
- void setScaleX(const F32 v) { mScale.mV[VX] = v; }
- void setScaleY(const F32 v) { mScale.mV[VY] = v; }
- void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); }
- void setShearX(const F32 v) { mShear.mV[VX] = v; }
- void setShearY(const F32 v) { mShear.mV[VY] = v; }
-
- void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; }
- void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; }
- void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated
- void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; }
- void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); }
- void setTaperX(const F32 v) { mTaper.mV[VX] = v; }
- void setTaperY(const F32 v) { mTaper.mV[VY] = v; }
- void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; }
- void setSkew(const F32 skew) { mSkew = skew; }
-
- friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);
+ LLPathParams()
+ :
+ mCurveType(LL_PCODE_PATH_LINE),
+ mBegin(0.f),
+ mEnd(1.f),
+ mScale(1.f,1.f),
+ mShear(0.f,0.f),
+ mTwistBegin(0.f),
+ mTwistEnd(0.f),
+ mRadiusOffset(0.f),
+ mTaper(0.f,0.f),
+ mRevolutions(1.f),
+ mSkew(0.f),
+ mCRC(0)
+ {
+ }
+
+ LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew)
+ : mCurveType(curve),
+ mBegin(begin),
+ mEnd(end),
+ mScale(scx,scy),
+ mShear(shx,shy),
+ mTwistBegin(twistbegin),
+ mTwistEnd(twistend),
+ mRadiusOffset(radiusoffset),
+ mTaper(tx,ty),
+ mRevolutions(revolutions),
+ mSkew(skew),
+ mCRC(0)
+ {
+ }
+
+ LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
+ {
+ mCurveType = curve;
+ mBegin = (F32)(begin * CUT_QUANTA);
+ mEnd = (F32)(100.f - end) * CUT_QUANTA;
+ if (mEnd > 1.f)
+ mEnd = 1.f;
+ mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
+ mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA);
+ mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
+ mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
+ mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
+ mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA);
+ mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f;
+ mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
+
+ mCRC = 0;
+ }
+
+ bool operator==(const LLPathParams &params) const;
+ bool operator!=(const LLPathParams &params) const;
+ bool operator<(const LLPathParams &params) const;
+
+ void copyParams(const LLPathParams &params);
+
+ BOOL importFile(LLFILE *fp);
+ BOOL exportFile(LLFILE *fp) const;
+
+ BOOL importLegacyStream(std::istream& input_stream);
+ BOOL exportLegacyStream(std::ostream& output_stream) const;
+
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ const F32& getBegin() const { return mBegin; }
+ const F32& getEnd() const { return mEnd; }
+ const LLVector2 &getScale() const { return mScale; }
+ const F32& getScaleX() const { return mScale.mV[0]; }
+ const F32& getScaleY() const { return mScale.mV[1]; }
+ const LLVector2 getBeginScale() const;
+ const LLVector2 getEndScale() const;
+ const LLVector2 &getShear() const { return mShear; }
+ const F32& getShearX() const { return mShear.mV[0]; }
+ const F32& getShearY() const { return mShear.mV[1]; }
+ const U8& getCurveType () const { return mCurveType; }
+
+ const F32& getTwistBegin() const { return mTwistBegin; }
+ const F32& getTwistEnd() const { return mTwistEnd; }
+ const F32& getTwist() const { return mTwistEnd; } // deprecated
+ const F32& getRadiusOffset() const { return mRadiusOffset; }
+ const LLVector2 &getTaper() const { return mTaper; }
+ const F32& getTaperX() const { return mTaper.mV[0]; }
+ const F32& getTaperY() const { return mTaper.mV[1]; }
+ const F32& getRevolutions() const { return mRevolutions; }
+ const F32& getSkew() const { return mSkew; }
+
+ void setCurveType(const U8 type) { mCurveType = type; }
+ void setBegin(const F32 begin) { mBegin = begin; }
+ void setEnd(const F32 end) { mEnd = end; }
+
+ void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); }
+ void setScaleX(const F32 v) { mScale.mV[VX] = v; }
+ void setScaleY(const F32 v) { mScale.mV[VY] = v; }
+ void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); }
+ void setShearX(const F32 v) { mShear.mV[VX] = v; }
+ void setShearY(const F32 v) { mShear.mV[VY] = v; }
+
+ void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; }
+ void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; }
+ void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated
+ void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; }
+ void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); }
+ void setTaperX(const F32 v) { mTaper.mV[VX] = v; }
+ void setTaperY(const F32 v) { mTaper.mV[VY] = v; }
+ void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; }
+ void setSkew(const F32 skew) { mSkew = skew; }
+
+ friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);
protected:
- // Path params
- U8 mCurveType;
- F32 mBegin;
- F32 mEnd;
- LLVector2 mScale;
- LLVector2 mShear;
-
- F32 mTwistBegin;
- F32 mTwistEnd;
- F32 mRadiusOffset;
- LLVector2 mTaper;
- F32 mRevolutions;
- F32 mSkew;
-
- U32 mCRC;
+ // Path params
+ U8 mCurveType;
+ F32 mBegin;
+ F32 mEnd;
+ LLVector2 mScale;
+ LLVector2 mShear;
+
+ F32 mTwistBegin;
+ F32 mTwistEnd;
+ F32 mRadiusOffset;
+ LLVector2 mTaper;
+ F32 mRevolutions;
+ F32 mSkew;
+
+ U32 mCRC;
};
inline bool LLPathParams::operator==(const LLPathParams &params) const
{
- return
- (getCurveType() == params.getCurveType()) &&
- (getScale() == params.getScale()) &&
- (getBegin() == params.getBegin()) &&
- (getEnd() == params.getEnd()) &&
- (getShear() == params.getShear()) &&
- (getTwist() == params.getTwist()) &&
- (getTwistBegin() == params.getTwistBegin()) &&
- (getRadiusOffset() == params.getRadiusOffset()) &&
- (getTaper() == params.getTaper()) &&
- (getRevolutions() == params.getRevolutions()) &&
- (getSkew() == params.getSkew());
+ return
+ (getCurveType() == params.getCurveType()) &&
+ (getScale() == params.getScale()) &&
+ (getBegin() == params.getBegin()) &&
+ (getEnd() == params.getEnd()) &&
+ (getShear() == params.getShear()) &&
+ (getTwist() == params.getTwist()) &&
+ (getTwistBegin() == params.getTwistBegin()) &&
+ (getRadiusOffset() == params.getRadiusOffset()) &&
+ (getTaper() == params.getTaper()) &&
+ (getRevolutions() == params.getRevolutions()) &&
+ (getSkew() == params.getSkew());
}
inline bool LLPathParams::operator!=(const LLPathParams &params) const
{
- return
- (getCurveType() != params.getCurveType()) ||
- (getScale() != params.getScale()) ||
- (getBegin() != params.getBegin()) ||
- (getEnd() != params.getEnd()) ||
- (getShear() != params.getShear()) ||
- (getTwist() != params.getTwist()) ||
- (getTwistBegin() !=params.getTwistBegin()) ||
- (getRadiusOffset() != params.getRadiusOffset()) ||
- (getTaper() != params.getTaper()) ||
- (getRevolutions() != params.getRevolutions()) ||
- (getSkew() != params.getSkew());
+ return
+ (getCurveType() != params.getCurveType()) ||
+ (getScale() != params.getScale()) ||
+ (getBegin() != params.getBegin()) ||
+ (getEnd() != params.getEnd()) ||
+ (getShear() != params.getShear()) ||
+ (getTwist() != params.getTwist()) ||
+ (getTwistBegin() !=params.getTwistBegin()) ||
+ (getRadiusOffset() != params.getRadiusOffset()) ||
+ (getTaper() != params.getTaper()) ||
+ (getRevolutions() != params.getRevolutions()) ||
+ (getSkew() != params.getSkew());
}
inline bool LLPathParams::operator<(const LLPathParams &params) const
{
- if( getCurveType() != params.getCurveType())
- {
- return getCurveType() < params.getCurveType();
- }
- else
- if( getScale() != params.getScale())
- {
- return getScale() < params.getScale();
- }
- else
- if( getBegin() != params.getBegin())
- {
- return getBegin() < params.getBegin();
- }
- else
- if( getEnd() != params.getEnd())
- {
- return getEnd() < params.getEnd();
- }
- else
- if( getShear() != params.getShear())
- {
- return getShear() < params.getShear();
- }
- else
- if( getTwist() != params.getTwist())
- {
- return getTwist() < params.getTwist();
- }
- else
- if( getTwistBegin() != params.getTwistBegin())
- {
- return getTwistBegin() < params.getTwistBegin();
- }
- else
- if( getRadiusOffset() != params.getRadiusOffset())
- {
- return getRadiusOffset() < params.getRadiusOffset();
- }
- else
- if( getTaper() != params.getTaper())
- {
- return getTaper() < params.getTaper();
- }
- else
- if( getRevolutions() != params.getRevolutions())
- {
- return getRevolutions() < params.getRevolutions();
- }
- else
- {
- return getSkew() < params.getSkew();
- }
+ if( getCurveType() != params.getCurveType())
+ {
+ return getCurveType() < params.getCurveType();
+ }
+ else
+ if( getScale() != params.getScale())
+ {
+ return getScale() < params.getScale();
+ }
+ else
+ if( getBegin() != params.getBegin())
+ {
+ return getBegin() < params.getBegin();
+ }
+ else
+ if( getEnd() != params.getEnd())
+ {
+ return getEnd() < params.getEnd();
+ }
+ else
+ if( getShear() != params.getShear())
+ {
+ return getShear() < params.getShear();
+ }
+ else
+ if( getTwist() != params.getTwist())
+ {
+ return getTwist() < params.getTwist();
+ }
+ else
+ if( getTwistBegin() != params.getTwistBegin())
+ {
+ return getTwistBegin() < params.getTwistBegin();
+ }
+ else
+ if( getRadiusOffset() != params.getRadiusOffset())
+ {
+ return getRadiusOffset() < params.getRadiusOffset();
+ }
+ else
+ if( getTaper() != params.getTaper())
+ {
+ return getTaper() < params.getTaper();
+ }
+ else
+ if( getRevolutions() != params.getRevolutions())
+ {
+ return getRevolutions() < params.getRevolutions();
+ }
+ else
+ {
+ return getSkew() < params.getSkew();
+ }
}
typedef LLVolumeParams* LLVolumeParamsPtr;
@@ -559,190 +560,190 @@ typedef const LLVolumeParams* const_LLVolumeParamsPtr;
class LLVolumeParams
{
public:
- LLVolumeParams()
- : mSculptType(LL_SCULPT_TYPE_NONE)
- {
- }
-
- LLVolumeParams(LLProfileParams &profile, LLPathParams &path,
- LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE)
- : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type)
- {
- }
-
- bool operator==(const LLVolumeParams &params) const;
- bool operator!=(const LLVolumeParams &params) const;
- bool operator<(const LLVolumeParams &params) const;
-
-
- void copyParams(const LLVolumeParams &params);
-
- const LLProfileParams &getProfileParams() const {return mProfileParams;}
- LLProfileParams &getProfileParams() {return mProfileParams;}
- const LLPathParams &getPathParams() const {return mPathParams;}
- LLPathParams &getPathParams() {return mPathParams;}
-
- BOOL importFile(LLFILE *fp);
- BOOL exportFile(LLFILE *fp) const;
-
- BOOL importLegacyStream(std::istream& input_stream);
- BOOL exportLegacyStream(std::ostream& output_stream) const;
-
- LLSD sculptAsLLSD() const;
- bool sculptFromLLSD(LLSD& sd);
-
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- bool setType(U8 profile, U8 path);
-
- //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1
- //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1
- //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin
- //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin
-
- bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
- bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
-
- bool setHollow(const F32 hollow); // range 0 to 1
- bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base
- bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement,
- bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base
- bool setShear(const F32 x, const F32 y); // 0 = no movement
-
- bool setTwistBegin(const F32 twist_begin); // range -1 to 1
- bool setTwistEnd(const F32 twist_end); // range -1 to 1
- bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated
- bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; }
- bool setTaperX(const F32 v); // -1 to 1
- bool setTaperY(const F32 v); // -1 to 1
- bool setRevolutions(const F32 revolutions); // 1 to 4
- bool setRadiusOffset(const F32 radius_offset);
- bool setSkew(const F32 skew);
- bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type);
-
- static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
- U8 path_curve, F32 path_begin, F32 path_end,
- F32 scx, F32 scy, F32 shx, F32 shy,
- F32 twistend, F32 twistbegin, F32 radiusoffset,
- F32 tx, F32 ty, F32 revolutions, F32 skew);
-
- const F32& getBeginS() const { return mProfileParams.getBegin(); }
- const F32& getBeginT() const { return mPathParams.getBegin(); }
- const F32& getEndS() const { return mProfileParams.getEnd(); }
- const F32& getEndT() const { return mPathParams.getEnd(); }
-
- const F32& getHollow() const { return mProfileParams.getHollow(); }
- const F32& getTwist() const { return mPathParams.getTwist(); }
- const F32& getRatio() const { return mPathParams.getScaleX(); }
- const F32& getRatioX() const { return mPathParams.getScaleX(); }
- const F32& getRatioY() const { return mPathParams.getScaleY(); }
- const F32& getShearX() const { return mPathParams.getShearX(); }
- const F32& getShearY() const { return mPathParams.getShearY(); }
-
- const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); }
- const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
- const F32& getTaper() const { return mPathParams.getTaperX(); }
- const F32& getTaperX() const { return mPathParams.getTaperX(); }
- const F32& getTaperY() const { return mPathParams.getTaperY(); }
- const F32& getRevolutions() const { return mPathParams.getRevolutions(); }
- const F32& getSkew() const { return mPathParams.getSkew(); }
- const LLUUID& getSculptID() const { return mSculptID; }
- const U8& getSculptType() const { return mSculptType; }
- bool isSculpt() const;
- bool isMeshSculpt() const;
- BOOL isConvex() const;
-
- // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
- // (begin, end) = (0, 1) will not change the volume
- // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
- void reduceS(F32 begin, F32 end);
- void reduceT(F32 begin, F32 end);
-
- struct compare
- {
- bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const
- {
- return (*first < *second);
- }
- };
-
- friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
-
- // debug helper functions
- void setCube();
+ LLVolumeParams()
+ : mSculptType(LL_SCULPT_TYPE_NONE)
+ {
+ }
+
+ LLVolumeParams(LLProfileParams &profile, LLPathParams &path,
+ LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE)
+ : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type)
+ {
+ }
+
+ bool operator==(const LLVolumeParams &params) const;
+ bool operator!=(const LLVolumeParams &params) const;
+ bool operator<(const LLVolumeParams &params) const;
+
+
+ void copyParams(const LLVolumeParams &params);
+
+ const LLProfileParams &getProfileParams() const {return mProfileParams;}
+ LLProfileParams &getProfileParams() {return mProfileParams;}
+ const LLPathParams &getPathParams() const {return mPathParams;}
+ LLPathParams &getPathParams() {return mPathParams;}
+
+ BOOL importFile(LLFILE *fp);
+ BOOL exportFile(LLFILE *fp) const;
+
+ BOOL importLegacyStream(std::istream& input_stream);
+ BOOL exportLegacyStream(std::ostream& output_stream) const;
+
+ LLSD sculptAsLLSD() const;
+ bool sculptFromLLSD(LLSD& sd);
+
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ bool setType(U8 profile, U8 path);
+
+ //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1
+ //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1
+ //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin
+ //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin
+
+ bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
+ bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
+
+ bool setHollow(const F32 hollow); // range 0 to 1
+ bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base
+ bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement,
+ bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base
+ bool setShear(const F32 x, const F32 y); // 0 = no movement
+
+ bool setTwistBegin(const F32 twist_begin); // range -1 to 1
+ bool setTwistEnd(const F32 twist_end); // range -1 to 1
+ bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated
+ bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; }
+ bool setTaperX(const F32 v); // -1 to 1
+ bool setTaperY(const F32 v); // -1 to 1
+ bool setRevolutions(const F32 revolutions); // 1 to 4
+ bool setRadiusOffset(const F32 radius_offset);
+ bool setSkew(const F32 skew);
+ bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type);
+
+ static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
+ U8 path_curve, F32 path_begin, F32 path_end,
+ F32 scx, F32 scy, F32 shx, F32 shy,
+ F32 twistend, F32 twistbegin, F32 radiusoffset,
+ F32 tx, F32 ty, F32 revolutions, F32 skew);
+
+ const F32& getBeginS() const { return mProfileParams.getBegin(); }
+ const F32& getBeginT() const { return mPathParams.getBegin(); }
+ const F32& getEndS() const { return mProfileParams.getEnd(); }
+ const F32& getEndT() const { return mPathParams.getEnd(); }
+
+ const F32& getHollow() const { return mProfileParams.getHollow(); }
+ const F32& getTwist() const { return mPathParams.getTwist(); }
+ const F32& getRatio() const { return mPathParams.getScaleX(); }
+ const F32& getRatioX() const { return mPathParams.getScaleX(); }
+ const F32& getRatioY() const { return mPathParams.getScaleY(); }
+ const F32& getShearX() const { return mPathParams.getShearX(); }
+ const F32& getShearY() const { return mPathParams.getShearY(); }
+
+ const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); }
+ const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
+ const F32& getTaper() const { return mPathParams.getTaperX(); }
+ const F32& getTaperX() const { return mPathParams.getTaperX(); }
+ const F32& getTaperY() const { return mPathParams.getTaperY(); }
+ const F32& getRevolutions() const { return mPathParams.getRevolutions(); }
+ const F32& getSkew() const { return mPathParams.getSkew(); }
+ const LLUUID& getSculptID() const { return mSculptID; }
+ const U8& getSculptType() const { return mSculptType; }
+ bool isSculpt() const;
+ bool isMeshSculpt() const;
+ BOOL isConvex() const;
+
+ // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
+ // (begin, end) = (0, 1) will not change the volume
+ // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
+ void reduceS(F32 begin, F32 end);
+ void reduceT(F32 begin, F32 end);
+
+ struct compare
+ {
+ bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const
+ {
+ return (*first < *second);
+ }
+ };
+
+ friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
+
+ // debug helper functions
+ void setCube();
protected:
- LLProfileParams mProfileParams;
- LLPathParams mPathParams;
- LLUUID mSculptID;
- U8 mSculptType;
+ LLProfileParams mProfileParams;
+ LLPathParams mPathParams;
+ LLUUID mSculptID;
+ U8 mSculptType;
};
class LLProfile
{
- friend class LLVolume;
+ friend class LLVolume;
public:
- LLProfile()
- : mOpen(FALSE),
- mConcave(FALSE),
- mDirty(TRUE),
- mTotalOut(0),
- mTotal(2)
- {
- }
-
- S32 getTotal() const { return mTotal; }
- S32 getTotalOut() const { return mTotalOut; } // Total number of outside points
- BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
- BOOL isOpen() const { return mOpen; }
- void setDirty() { mDirty = TRUE; }
-
- static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
- BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
- BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
- BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
- BOOL isConcave() const { return mConcave; }
+ LLProfile()
+ : mOpen(FALSE),
+ mConcave(FALSE),
+ mDirty(TRUE),
+ mTotalOut(0),
+ mTotal(2)
+ {
+ }
+
+ S32 getTotal() const { return mTotal; }
+ S32 getTotalOut() const { return mTotalOut; } // Total number of outside points
+ BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
+ BOOL isOpen() const { return mOpen; }
+ void setDirty() { mDirty = TRUE; }
+
+ static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
+ BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
+ BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
+ BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
+ BOOL isConcave() const { return mConcave; }
public:
- struct Face
- {
- S32 mIndex;
- S32 mCount;
- F32 mScaleU;
- BOOL mCap;
- BOOL mFlat;
- LLFaceID mFaceID;
- };
-
- LLAlignedArray<LLVector4a, 64> mProfile;
- //LLAlignedArray<LLVector4a, 64> mNormals;
- std::vector<Face> mFaces;
-
- //LLAlignedArray<LLVector4a, 64> mEdgeNormals;
- //LLAlignedArray<LLVector4a, 64> mEdgeCenters;
-
- friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
+ struct Face
+ {
+ S32 mIndex;
+ S32 mCount;
+ F32 mScaleU;
+ BOOL mCap;
+ BOOL mFlat;
+ LLFaceID mFaceID;
+ };
+
+ LLAlignedArray<LLVector4a, 64> mProfile;
+ //LLAlignedArray<LLVector4a, 64> mNormals;
+ std::vector<Face> mFaces;
+
+ //LLAlignedArray<LLVector4a, 64> mEdgeNormals;
+ //LLAlignedArray<LLVector4a, 64> mEdgeCenters;
+
+ friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
protected:
- ~LLProfile();
+ ~LLProfile();
- static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
- void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
+ static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
+ void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
- Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
- Face* addCap (S16 faceID);
- Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
+ Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
+ Face* addCap (S16 faceID);
+ Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
protected:
- BOOL mOpen;
- BOOL mConcave;
- BOOL mDirty;
+ BOOL mOpen;
+ BOOL mConcave;
+ BOOL mDirty;
- S32 mTotalOut;
- S32 mTotal;
+ S32 mTotalOut;
+ S32 mTotal;
};
//-------------------------------------------------------------------
@@ -752,220 +753,220 @@ protected:
class LLPath
{
public:
- class PathPt
- {
- public:
- LLMatrix4a mRot;
- LLVector4a mPos;
-
- LLVector4a mScale;
- F32 mTexT;
- F32 pad[3]; //for alignment
- PathPt()
- {
- mPos.clear();
- mTexT = 0;
- mScale.clear();
- mRot.setRows(LLVector4a(1,0,0,0),
- LLVector4a(0,1,0,0),
- LLVector4a(0,0,1,0));
-
- //distinguished data in the pad for debugging
- pad[0] = 3.14159f;
- pad[1] = -3.14159f;
- pad[2] = 0.585f;
- }
- };
+ class PathPt
+ {
+ public:
+ LLMatrix4a mRot;
+ LLVector4a mPos;
+
+ LLVector4a mScale;
+ F32 mTexT;
+ F32 pad[3]; //for alignment
+ PathPt()
+ {
+ mPos.clear();
+ mTexT = 0;
+ mScale.clear();
+ mRot.setRows(LLVector4a(1,0,0,0),
+ LLVector4a(0,1,0,0),
+ LLVector4a(0,0,1,0));
+
+ //distinguished data in the pad for debugging
+ pad[0] = 3.14159f;
+ pad[1] = -3.14159f;
+ pad[2] = 0.585f;
+ }
+ };
public:
- LLPath()
- : mOpen(FALSE),
- mTotal(0),
- mDirty(TRUE),
- mStep(1)
- {
- }
+ LLPath()
+ : mOpen(FALSE),
+ mTotal(0),
+ mDirty(TRUE),
+ mStep(1)
+ {
+ }
- virtual ~LLPath();
+ virtual ~LLPath();
- static S32 getNumPoints(const LLPathParams& params, F32 detail);
- static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
+ static S32 getNumPoints(const LLPathParams& params, F32 detail);
+ static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
- void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
- virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
- BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
+ void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
+ virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
+ BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
- BOOL isOpen() const { return mOpen; }
- F32 getStep() const { return mStep; }
- void setDirty() { mDirty = TRUE; }
+ BOOL isOpen() const { return mOpen; }
+ F32 getStep() const { return mStep; }
+ void setDirty() { mDirty = TRUE; }
- S32 getPathLength() const { return (S32)mPath.size(); }
+ S32 getPathLength() const { return (S32)mPath.size(); }
- void resizePath(S32 length) { mPath.resize(length); }
+ void resizePath(S32 length) { mPath.resize(length); }
- friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
+ friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
public:
- LLAlignedArray<PathPt, 64> mPath;
+ LLAlignedArray<PathPt, 64> mPath;
protected:
- BOOL mOpen;
- S32 mTotal;
- BOOL mDirty;
- F32 mStep;
+ BOOL mOpen;
+ S32 mTotal;
+ BOOL mDirty;
+ F32 mStep;
};
class LLDynamicPath : public LLPath
{
public:
- LLDynamicPath() : LLPath() { }
- /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
- BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
+ LLDynamicPath() : LLPath() { }
+ /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
+ BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
};
// Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
class LLVolumeFace
{
public:
- class VertexData
- {
- enum
- {
- POSITION = 0,
- NORMAL = 1
- };
-
- private:
- void init();
- public:
- VertexData();
- VertexData(const VertexData& rhs);
- const VertexData& operator=(const VertexData& rhs);
-
- ~VertexData();
- LLVector4a& getPosition();
- LLVector4a& getNormal();
- const LLVector4a& getPosition() const;
- const LLVector4a& getNormal() const;
- void setPosition(const LLVector4a& pos);
- void setNormal(const LLVector4a& norm);
-
-
- LLVector2 mTexCoord;
-
- bool operator<(const VertexData& rhs) const;
- bool operator==(const VertexData& rhs) const;
- bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;
-
- private:
- LLVector4a* mData;
- };
-
- LLVolumeFace();
- LLVolumeFace(const LLVolumeFace& src);
- LLVolumeFace& operator=(const LLVolumeFace& rhs);
-
- ~LLVolumeFace();
+ class VertexData
+ {
+ enum
+ {
+ POSITION = 0,
+ NORMAL = 1
+ };
+
+ private:
+ void init();
+ public:
+ VertexData();
+ VertexData(const VertexData& rhs);
+ const VertexData& operator=(const VertexData& rhs);
+
+ ~VertexData();
+ LLVector4a& getPosition();
+ LLVector4a& getNormal();
+ const LLVector4a& getPosition() const;
+ const LLVector4a& getNormal() const;
+ void setPosition(const LLVector4a& pos);
+ void setNormal(const LLVector4a& norm);
+
+
+ LLVector2 mTexCoord;
+
+ bool operator<(const VertexData& rhs) const;
+ bool operator==(const VertexData& rhs) const;
+ bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;
+
+ private:
+ LLVector4a* mData;
+ };
+
+ LLVolumeFace();
+ LLVolumeFace(const LLVolumeFace& src);
+ LLVolumeFace& operator=(const LLVolumeFace& rhs);
+
+ ~LLVolumeFace();
private:
- void freeData();
+ void freeData();
public:
- BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
- void createTangents();
-
- void resizeVertices(S32 num_verts);
- void allocateTangents(S32 num_verts);
- void allocateWeights(S32 num_verts);
+ BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
+ void createTangents();
+
+ void resizeVertices(S32 num_verts);
+ void allocateTangents(S32 num_verts);
+ void allocateWeights(S32 num_verts);
void allocateJointIndices(S32 num_verts);
- void resizeIndices(S32 num_indices);
- void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
+ void resizeIndices(S32 num_indices);
+ void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
- void pushVertex(const VertexData& cv);
- void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc);
- void pushIndex(const U16& idx);
+ void pushVertex(const VertexData& cv);
+ void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc);
+ void pushIndex(const U16& idx);
- void swapData(LLVolumeFace& rhs);
+ void swapData(LLVolumeFace& rhs);
- void getVertexData(U16 indx, LLVolumeFace::VertexData& cv);
+ void getVertexData(U16 indx, LLVolumeFace::VertexData& cv);
- class VertexMapData : public LLVolumeFace::VertexData
- {
- public:
- U16 mIndex;
+ class VertexMapData : public LLVolumeFace::VertexData
+ {
+ public:
+ U16 mIndex;
- bool operator==(const LLVolumeFace::VertexData& rhs) const;
+ bool operator==(const LLVolumeFace::VertexData& rhs) const;
- struct ComparePosition
- {
- bool operator()(const LLVector3& a, const LLVector3& b) const;
- };
+ struct ComparePosition
+ {
+ bool operator()(const LLVector3& a, const LLVector3& b) const;
+ };
- typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap;
- };
+ typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap;
+ };
// Eliminates non unique triangles, takes positions,
// normals and texture coordinates into account.
void remap();
- void optimize(F32 angle_cutoff = 2.f);
- bool cacheOptimize(bool gen_tangents = false);
+ void optimize(F32 angle_cutoff = 2.f);
+ bool cacheOptimize(bool gen_tangents = false);
- void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
+ void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
void destroyOctree();
// Get a reference to the octree, which may be null
- const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const;
-
- enum
- {
- SINGLE_MASK = 0x0001,
- CAP_MASK = 0x0002,
- END_MASK = 0x0004,
- SIDE_MASK = 0x0008,
- INNER_MASK = 0x0010,
- OUTER_MASK = 0x0020,
- HOLLOW_MASK = 0x0040,
- OPEN_MASK = 0x0080,
- FLAT_MASK = 0x0100,
- TOP_MASK = 0x0200,
- BOTTOM_MASK = 0x0400
- };
-
+ const LLVolumeOctree* getOctree() const;
+
+ enum
+ {
+ SINGLE_MASK = 0x0001,
+ CAP_MASK = 0x0002,
+ END_MASK = 0x0004,
+ SIDE_MASK = 0x0008,
+ INNER_MASK = 0x0010,
+ OUTER_MASK = 0x0020,
+ HOLLOW_MASK = 0x0040,
+ OPEN_MASK = 0x0080,
+ FLAT_MASK = 0x0100,
+ TOP_MASK = 0x0200,
+ BOTTOM_MASK = 0x0400
+ };
+
public:
- S32 mID;
- U32 mTypeMask;
-
- // Only used for INNER/OUTER faces
- S32 mBeginS;
- S32 mBeginT;
- S32 mNumS;
- S32 mNumT;
-
- LLVector4a* mExtents; //minimum and maximum point of face
- LLVector4a* mCenter;
- LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
-
- S32 mNumVertices; // num vertices == num normals == num texcoords
- S32 mNumAllocatedVertices;
- S32 mNumIndices;
-
- LLVector4a* mPositions; // Contains vertices, nortmals and texcoords
- LLVector4a* mNormals; // pointer into mPositions
- LLVector4a* mTangents;
- LLVector2* mTexCoords; // pointer into mPositions
-
- // mIndices contains mNumIndices amount of elements.
- // It contains triangles, each 3 indices describe one triangle.
+ S32 mID;
+ U32 mTypeMask;
+
+ // Only used for INNER/OUTER faces
+ S32 mBeginS;
+ S32 mBeginT;
+ S32 mNumS;
+ S32 mNumT;
+
+ LLVector4a* mExtents; //minimum and maximum point of face
+ LLVector4a* mCenter;
+ LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
+
+ S32 mNumVertices; // num vertices == num normals == num texcoords
+ S32 mNumAllocatedVertices;
+ S32 mNumIndices;
+
+ LLVector4a* mPositions; // Contains vertices, nortmals and texcoords
+ LLVector4a* mNormals; // pointer into mPositions
+ LLVector4a* mTangents;
+ LLVector2* mTexCoords; // pointer into mPositions
+
+ // mIndices contains mNumIndices amount of elements.
+ // It contains triangles, each 3 indices describe one triangle.
// If mIndices contains {0, 2, 3, 1, 2, 4}, it means there
// are two triangles {0, 2, 3} and {1, 2, 4} with values being
// indexes for mPositions/mNormals/mTexCoords
- U16* mIndices;
+ U16* mIndices;
- std::vector<S32> mEdge;
+ std::vector<S32> mEdge;
- //list of skin weights for rigged volumes
- // format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
- // mWeights.size() should be empty or match mVertices.size()
- LLVector4a* mWeights;
+ //list of skin weights for rigged volumes
+ // format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
+ // mWeights.size() should be empty or match mVertices.size()
+ LLVector4a* mWeights;
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
LLVector4a* mJustWeights;
@@ -978,8 +979,8 @@ public:
// vertices per joint.
LLJointRiggingInfoTab mJointRiggingInfoTab;
- //whether or not face has been cache optimized
- BOOL mOptimized;
+ //whether or not face has been cache optimized
+ BOOL mOptimized;
// if this is a mesh asset, scale and translation that were applied
// when encoding the source mesh into a unit cube
@@ -987,173 +988,175 @@ public:
LLVector3 mNormalizedScale = LLVector3(1,1,1);
private:
- LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree;
+ LLVolumeOctree* mOctree;
LLVolumeTriangle* mOctreeTriangles;
- BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
- BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
- BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
+ BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
+ BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
+ BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
};
class LLVolume : public LLRefCount
{
- friend class LLVolumeLODGroup;
+ friend class LLVolumeLODGroup;
protected:
- virtual ~LLVolume(); // use unref
+ virtual ~LLVolume(); // use unref
public:
- typedef std::vector<LLVolumeFace> face_list_t;
-
- struct FaceParams
- {
- LLFaceID mFaceID;
- S32 mBeginS;
- S32 mCountS;
- S32 mBeginT;
- S32 mCountT;
- };
-
- LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
-
- U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
- U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
- S32 getNumFaces() const;
- S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
- F32 getDetail() const { return mDetail; }
- F32 getSurfaceArea() const { return mSurfaceArea; }
- const LLVolumeParams& getParams() const { return mParams; }
- LLVolumeParams getCopyOfParams() const { return mParams; }
- const LLProfile& getProfile() const { return *mProfilep; }
- LLPath& getPath() const { return *mPathp; }
- void resizePath(S32 length);
- const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
- const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
-
-
- void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
-
- void regen();
+ typedef std::vector<LLVolumeFace> face_list_t;
+
+ struct FaceParams
+ {
+ LLFaceID mFaceID;
+ S32 mBeginS;
+ S32 mCountS;
+ S32 mBeginT;
+ S32 mCountT;
+ };
+
+ LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
+
+ U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
+ U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
+ S32 getNumFaces() const;
+ S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
+ F32 getDetail() const { return mDetail; }
+ F32 getSurfaceArea() const { return mSurfaceArea; }
+ const LLVolumeParams& getParams() const { return mParams; }
+ LLVolumeParams getCopyOfParams() const { return mParams; }
+ const LLProfile& getProfile() const { return *mProfilep; }
+ LLPath& getPath() const { return *mPathp; }
+ void resizePath(S32 length);
+ const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
+ const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
+
+
+ void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
+
+ void regen();
void genTangents(S32 face);
- BOOL isConvex() const;
- BOOL isCap(S32 face);
- BOOL isFlat(S32 face);
- BOOL isUnique() const { return mUnique; }
-
- S32 getSculptLevel() const { return mSculptLevel; }
- void setSculptLevel(S32 level) { mSculptLevel = level; }
-
-
- static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
-
- S32 getNumTriangles(S32* vcount = NULL) const;
-
- void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
- std::vector<LLVector3> &normals,
- const LLVector3& view_vec,
- const LLMatrix4& mat,
- const LLMatrix3& norm_mat,
- S32 face_index);
-
- //get the face index of the face that intersects with the given line segment at the point
- //closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
- //Line segment must be in volume space.
- S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = -1, // which face to check, -1 = ALL_SIDES
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
-
- LLFaceID generateFaceMask();
-
- BOOL isFaceMaskValid(LLFaceID face_mask);
- static S32 sNumMeshPoints;
-
- friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
- friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over
- // conversion if *(LLVolume*) to LLVolume&
- const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
-
- LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
-
- face_list_t& getVolumeFaces() { return mVolumeFaces; }
-
- U32 mFaceMask; // bit array of which faces exist in this volume
- LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
-
- void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);
- void copyVolumeFaces(const LLVolume* volume);
- void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
- void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
+ BOOL isConvex() const;
+ BOOL isCap(S32 face);
+ BOOL isFlat(S32 face);
+ BOOL isUnique() const { return mUnique; }
+
+ S32 getSculptLevel() const { return mSculptLevel; }
+ void setSculptLevel(S32 level) { mSculptLevel = level; }
+
+
+ static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
+
+ S32 getNumTriangles(S32* vcount = NULL) const;
+
+ void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
+ std::vector<LLVector3> &normals,
+ const LLVector3& view_vec,
+ const LLMatrix4& mat,
+ const LLMatrix3& norm_mat,
+ S32 face_index);
+
+ //get the face index of the face that intersects with the given line segment at the point
+ //closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
+ //Line segment must be in volume space.
+ S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face = -1, // which face to check, -1 = ALL_SIDES
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+ LLFaceID generateFaceMask();
+
+ BOOL isFaceMaskValid(LLFaceID face_mask);
+ static S32 sNumMeshPoints;
+
+ friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
+ friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over
+ // conversion if *(LLVolume*) to LLVolume&
+ const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
+
+ LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
+
+ face_list_t& getVolumeFaces() { return mVolumeFaces; }
+
+ U32 mFaceMask; // bit array of which faces exist in this volume
+ LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
+
+ void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);
+ void copyVolumeFaces(const LLVolume* volume);
+ void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
+ void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
// use meshoptimizer to optimize index buffer for vertex shader cache
// gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer
- bool cacheOptimize(bool gen_tangents = false);
+ bool cacheOptimize(bool gen_tangents = false);
private:
- void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
- F32 sculptGetSurfaceArea();
- void sculptGenerateEmptyPlaceholder();
- void sculptGenerateSpherePlaceholder();
- void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);
-
+ void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
+ F32 sculptGetSurfaceArea();
+ void sculptGenerateEmptyPlaceholder();
+ void sculptGenerateSpherePlaceholder();
+ void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);
+
protected:
- BOOL generate();
- void createVolumeFaces();
+ BOOL generate();
+ void createVolumeFaces();
public:
- bool unpackVolumeFaces(std::istream& is, S32 size);
- bool unpackVolumeFaces(U8* in_data, S32 size);
+ bool unpackVolumeFaces(std::istream& is, S32 size);
+ bool unpackVolumeFaces(U8* in_data, S32 size);
private:
- bool unpackVolumeFacesInternal(const LLSD& mdl);
+ bool unpackVolumeFacesInternal(const LLSD& mdl);
public:
- virtual void setMeshAssetLoaded(bool loaded);
- virtual bool isMeshAssetLoaded();
+ virtual void setMeshAssetLoaded(bool loaded);
+ virtual bool isMeshAssetLoaded();
virtual void setMeshAssetUnavaliable(bool unavaliable);
virtual bool isMeshAssetUnavaliable();
protected:
- BOOL mUnique;
- F32 mDetail;
- S32 mSculptLevel;
- F32 mSurfaceArea; //unscaled surface area
- bool mIsMeshAssetLoaded;
+ BOOL mUnique;
+ F32 mDetail;
+ S32 mSculptLevel;
+ F32 mSurfaceArea; //unscaled surface area
+ bool mIsMeshAssetLoaded;
bool mIsMeshAssetUnavaliable;
-
- const LLVolumeParams mParams;
- LLPath *mPathp;
- LLProfile *mProfilep;
- LLAlignedArray<LLVector4a,64> mMesh;
-
-
- BOOL mGenerateSingleFace;
- face_list_t mVolumeFaces;
+
+ const LLVolumeParams mParams;
+ LLPath *mPathp;
+ LLProfile *mProfilep;
+ LLAlignedArray<LLVector4a,64> mMesh;
+
+
+ BOOL mGenerateSingleFace;
+ face_list_t mVolumeFaces;
public:
- LLVector4a* mHullPoints;
- U16* mHullIndices;
- S32 mNumHullPoints;
- S32 mNumHullIndices;
+ LLVector4a* mHullPoints;
+ U16* mHullIndices;
+ S32 mNumHullPoints;
+ S32 mNumHullIndices;
};
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
+void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
+
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
-// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
+// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t);
+ F32& intersection_a, F32& intersection_b, F32& intersection_t);
BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t);
-
-
+ F32& intersection_a, F32& intersection_b, F32& intersection_t);
+
+
#endif
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index 343740692c..95c7cb0b5c 100644
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvolumeoctree.cpp
*
* $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$
*/
@@ -29,190 +29,190 @@
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size)
{
- LLVector4a fAWdU;
- LLVector4a dir;
- LLVector4a diff;
+ LLVector4a fAWdU;
+ LLVector4a dir;
+ LLVector4a diff;
- dir.setSub(end, start);
- dir.mul(0.5f);
+ dir.setSub(end, start);
+ dir.mul(0.5f);
- diff.setAdd(end,start);
- diff.mul(0.5f);
- diff.sub(center);
- fAWdU.setAbs(dir);
+ diff.setAdd(end,start);
+ diff.mul(0.5f);
+ diff.sub(center);
+ fAWdU.setAbs(dir);
- LLVector4a rhs;
- rhs.setAdd(size, fAWdU);
+ LLVector4a rhs;
+ rhs.setAdd(size, fAWdU);
- LLVector4a lhs;
- lhs.setAbs(diff);
+ LLVector4a lhs;
+ lhs.setAbs(diff);
- U32 grt = lhs.greaterThan(rhs).getGatheredBits();
+ U32 grt = lhs.greaterThan(rhs).getGatheredBits();
- if (grt & 0x7)
- {
- return false;
- }
+ if (grt & 0x7)
+ {
+ return false;
+ }
+
+ LLVector4a f;
+ f.setCross3(dir, diff);
+ f.setAbs(f);
- LLVector4a f;
- f.setCross3(dir, diff);
- f.setAbs(f);
+ LLVector4a v0, v1;
- LLVector4a v0, v1;
+ v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1));
+ v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2));
+ lhs.setMul(v0, v1);
- v0 = _mm_shuffle_ps(size, size,_MM_SHUFFLE(3,0,0,1));
- v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,1,2,2));
- lhs.setMul(v0, v1);
+ v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2));
+ v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1));
+ rhs.setMul(v0, v1);
+ rhs.add(lhs);
+
+ grt = f.greaterThan(rhs).getGatheredBits();
- v0 = _mm_shuffle_ps(size, size, _MM_SHUFFLE(3,1,2,2));
- v1 = _mm_shuffle_ps(fAWdU, fAWdU, _MM_SHUFFLE(3,0,0,1));
- rhs.setMul(v0, v1);
- rhs.add(lhs);
-
- grt = f.greaterThan(rhs).getGatheredBits();
-
- return (grt & 0x7) ? false : true;
+ return (grt & 0x7) ? false : true;
}
LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
- node->addListener(this);
+ node->addListener(this);
}
LLVolumeOctreeListener::~LLVolumeOctreeListener()
{
}
-
-void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,
+
+void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,
LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child)
{
- new LLVolumeOctreeListener(child);
+ new LLVolumeOctreeListener(child);
}
-LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
- const LLVolumeFace* face, F32* closest_t,
- LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
- : mFace(face),
- mStart(start),
- mDir(dir),
- mIntersection(intersection),
- mTexCoord(tex_coord),
- mNormal(normal),
- mTangent(tangent),
- mClosestT(closest_t),
- mHitFace(false)
+LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
+ LLVolumeFace* face, F32* closest_t,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
+ : mStart(start),
+ mDir(dir),
+ mIntersection(intersection),
+ mTexCoord(tex_coord),
+ mNormal(normal),
+ mTangent(tangent),
+ mFace(face),
+ mClosestT(closest_t),
+ mHitFace(false)
{
- mEnd.setAdd(mStart, mDir);
+ mEnd.setAdd(mStart, mDir);
}
void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
- LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
-
- if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
- {
- node->accept(this);
- for (S32 i = 0; i < node->getChildCount(); ++i)
- {
- traverse(node->getChild(i));
- }
- }
+ LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
+
+ if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
+ {
+ node->accept(this);
+ for (S32 i = 0; i < node->getChildCount(); ++i)
+ {
+ traverse(node->getChild(i));
+ }
+ }
}
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter =
- node->getDataBegin(); iter != node->getDataEnd(); ++iter)
- {
- const LLVolumeTriangle* tri = *iter;
-
- F32 a, b, t;
-
- if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2],
- mStart, mDir, a, b, t))
- {
- if ((t >= 0.f) && // if hit is after start
- (t <= 1.f) && // and before end
- (t < *mClosestT)) // and this hit is closer
- {
- *mClosestT = t;
- mHitFace = true;
-
- if (mIntersection != NULL)
- {
- LLVector4a intersect = mDir;
- intersect.mul(*mClosestT);
- intersect.add(mStart);
- *mIntersection = intersect;
- }
-
- U32 idx0 = tri->mIndex[0];
- U32 idx1 = tri->mIndex[1];
- U32 idx2 = tri->mIndex[2];
-
- if (mTexCoord != NULL)
- {
- LLVector2* tc = (LLVector2*) mFace->mTexCoords;
- *mTexCoord = ((1.f - a - b) * tc[idx0] +
- a * tc[idx1] +
- b * tc[idx2]);
-
- }
-
- if (mNormal != NULL)
- {
- LLVector4a* norm = mFace->mNormals;
-
- LLVector4a n1,n2,n3;
- n1 = norm[idx0];
- n1.mul(1.f-a-b);
-
- n2 = norm[idx1];
- n2.mul(a);
-
- n3 = norm[idx2];
- n3.mul(b);
-
- n1.add(n2);
- n1.add(n3);
-
- *mNormal = n1;
- }
-
- if (mTangent != NULL)
- {
- LLVector4a* tangents = mFace->mTangents;
-
- LLVector4a t1,t2,t3;
- t1 = tangents[idx0];
- t1.mul(1.f-a-b);
-
- t2 = tangents[idx1];
- t2.mul(a);
-
- t3 = tangents[idx2];
- t3.mul(b);
-
- t1.add(t2);
- t1.add(t3);
-
- *mTangent = t1;
- }
- }
- }
- }
+ node->getDataBegin(); iter != node->getDataEnd(); ++iter)
+ {
+ const LLVolumeTriangle* tri = *iter;
+
+ F32 a, b, t;
+
+ if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2],
+ mStart, mDir, a, b, t))
+ {
+ if ((t >= 0.f) && // if hit is after start
+ (t <= 1.f) && // and before end
+ (t < *mClosestT)) // and this hit is closer
+ {
+ *mClosestT = t;
+ mHitFace = true;
+ mHitTriangle = tri;
+ if (mIntersection != NULL)
+ {
+ LLVector4a intersect = mDir;
+ intersect.mul(*mClosestT);
+ intersect.add(mStart);
+ *mIntersection = intersect;
+ }
+
+ U32 idx0 = tri->mIndex[0];
+ U32 idx1 = tri->mIndex[1];
+ U32 idx2 = tri->mIndex[2];
+
+ if (mTexCoord != NULL)
+ {
+ LLVector2* tc = (LLVector2*) mFace->mTexCoords;
+ *mTexCoord = ((1.f - a - b) * tc[idx0] +
+ a * tc[idx1] +
+ b * tc[idx2]);
+
+ }
+
+ if (mNormal != NULL)
+ {
+ LLVector4a* norm = mFace->mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *mNormal = n1;
+ }
+
+ if (mTangent != NULL)
+ {
+ LLVector4a* tangents = mFace->mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *mTangent = t1;
+ }
+ }
+ }
+ }
}
const LLVector4a& LLVolumeTriangle::getPositionGroup() const
{
- return mPositionGroup;
+ return mPositionGroup;
}
const F32& LLVolumeTriangle::getBinRadius() const
{
- return mRadius;
+ return mRadius;
}
@@ -220,55 +220,55 @@ const F32& LLVolumeTriangle::getBinRadius() const
void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
- LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
+ LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
- //make sure bounds matches extents
- LLVector4a& min = node->mExtents[0];
- LLVector4a& max = node->mExtents[1];
+ //make sure bounds matches extents
+ LLVector4a& min = node->mExtents[0];
+ LLVector4a& max = node->mExtents[1];
- LLVector4a& center = node->mBounds[0];
- LLVector4a& size = node->mBounds[1];
+ LLVector4a& center = node->mBounds[0];
+ LLVector4a& size = node->mBounds[1];
- LLVector4a test_min, test_max;
- test_min.setSub(center, size);
- test_max.setAdd(center, size);
+ LLVector4a test_min, test_max;
+ test_min.setSub(center, size);
+ test_max.setAdd(center, size);
- if (!test_min.equals3(min, 0.001f) ||
- !test_max.equals3(max, 0.001f))
- {
- LL_ERRS() << "Bad bounding box data found." << LL_ENDL;
- }
+ if (!test_min.equals3(min, 0.001f) ||
+ !test_max.equals3(max, 0.001f))
+ {
+ LL_ERRS() << "Bad bounding box data found." << LL_ENDL;
+ }
- test_min.sub(LLVector4a(0.001f));
- test_max.add(LLVector4a(0.001f));
+ test_min.sub(LLVector4a(0.001f));
+ test_max.add(LLVector4a(0.001f));
- for (U32 i = 0; i < branch->getChildCount(); ++i)
- {
- LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0);
+ for (U32 i = 0; i < branch->getChildCount(); ++i)
+ {
+ LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0);
- //make sure all children fit inside this node
- if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) ||
- child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ))
- {
- LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL;
- }
- }
+ //make sure all children fit inside this node
+ if (child->mExtents[0].lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ) ||
+ child->mExtents[1].greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ))
+ {
+ LL_ERRS() << "Child protrudes from bounding box." << LL_ENDL;
+ }
+ }
- //children fit, check data
+ //children fit, check data
for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
- iter != branch->getDataEnd(); ++iter)
- {
- const LLVolumeTriangle* tri = *iter;
-
- //validate triangle
- for (U32 i = 0; i < 3; i++)
- {
- if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) ||
- tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ))
- {
- LL_ERRS() << "Triangle protrudes from node." << LL_ENDL;
- }
- }
- }
+ iter != branch->getDataEnd(); ++iter)
+ {
+ const LLVolumeTriangle* tri = *iter;
+
+ //validate triangle
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (tri->mV[i]->greaterThan(test_max).areAnySet(LLVector4Logical::MASK_XYZ) ||
+ tri->mV[i]->lessThan(test_min).areAnySet(LLVector4Logical::MASK_XYZ))
+ {
+ LL_ERRS() << "Triangle protrudes from node." << LL_ENDL;
+ }
+ }
+ }
}
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 96918912ed..0bbb793896 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvolumeoctree.h
* @brief LLVolume octree classes.
*
* $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$
*/
@@ -38,41 +38,41 @@ class alignas(16) LLVolumeTriangle : public LLRefCount
{
LL_ALIGN_NEW
public:
- LLVolumeTriangle()
- {
- mBinIndex = -1;
- }
+ LLVolumeTriangle()
+ {
+ mBinIndex = -1;
+ }
- LLVolumeTriangle(const LLVolumeTriangle& rhs)
- {
- *this = rhs;
- }
+ LLVolumeTriangle(const LLVolumeTriangle& rhs)
+ {
+ *this = rhs;
+ }
- const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
+ const LLVolumeTriangle& operator=(const LLVolumeTriangle& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
- ~LLVolumeTriangle()
- {
-
- }
+ ~LLVolumeTriangle()
+ {
+
+ }
- LL_ALIGN_16(LLVector4a mPositionGroup);
+ LL_ALIGN_16(LLVector4a mPositionGroup);
- const LLVector4a* mV[3];
- U16 mIndex[3];
+ const LLVector4a* mV[3];
+ U32 mIndex[3];
- F32 mRadius;
- mutable S32 mBinIndex;
+ F32 mRadius;
+ mutable S32 mBinIndex;
- virtual const LLVector4a& getPositionGroup() const;
- virtual const F32& getBinRadius() const;
-
- S32 getBinIndex() const { return mBinIndex; }
- void setBinIndex(S32 idx) const { mBinIndex = idx; }
+ virtual const LLVector4a& getPositionGroup() const;
+ virtual const F32& getBinRadius() const;
+
+ S32 getBinIndex() const { return mBinIndex; }
+ void setBinIndex(S32 idx) const { mBinIndex = idx; }
};
@@ -82,50 +82,52 @@ class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTrian
LL_ALIGN_NEW
public:
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
- ~LLVolumeOctreeListener();
-
- LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs)
- {
- *this = rhs;
- }
-
- const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
-
- //LISTENER FUNCTIONS
+ ~LLVolumeOctreeListener();
+
+ LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs)
+ {
+ *this = rhs;
+ }
+
+ const LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ //LISTENER FUNCTIONS
virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child);
- virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
+ virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { }
- virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
- virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
- virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
-
+ virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
+ virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
+ virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
+
public:
- LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
- LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
+ LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
- const LLVolumeFace* mFace;
- LLVector4a mStart;
- LLVector4a mDir;
- LLVector4a mEnd;
- LLVector4a* mIntersection;
- LLVector2* mTexCoord;
- LLVector4a* mNormal;
- LLVector4a* mTangent;
- F32* mClosestT;
- bool mHitFace;
-
- LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
- const LLVolumeFace* face, F32* closest_t,
- LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
+ LLVector4a mStart;
+ LLVector4a mDir;
+ LLVector4a mEnd;
+ LLVector4a* mIntersection;
+ LLVector2* mTexCoord;
+ LLVector4a* mNormal;
+ LLVector4a* mTangent;
+ F32* mClosestT;
+ LLVolumeFace* mFace;
+ bool mHitFace;
+ const LLVolumeTriangle* mHitTriangle = nullptr;
+
+ LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
+ LLVolumeFace* face,
+ F32* closest_t,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
@@ -137,4 +139,91 @@ class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolum
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);
};
+class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
+{
+public:
+ LLVolumeOctreeRebound()
+ {
+ }
+
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
+ { //this is a depth first traversal, so it's safe to assum all children have complete
+ //bounding data
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+
+ LLVolumeOctreeListener* node = (LLVolumeOctreeListener*)branch->getListener(0);
+
+ LLVector4a& min = node->mExtents[0];
+ LLVector4a& max = node->mExtents[1];
+
+ if (!branch->isEmpty())
+ { //node has data, find AABB that binds data set
+ const LLVolumeTriangle* tri = *(branch->getDataBegin());
+
+ //initialize min/max to first available vertex
+ min = *(tri->mV[0]);
+ max = *(tri->mV[0]);
+
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
+ { //for each triangle in node
+
+ //stretch by triangles in node
+ tri = *iter;
+
+ min.setMin(min, *tri->mV[0]);
+ min.setMin(min, *tri->mV[1]);
+ min.setMin(min, *tri->mV[2]);
+
+ max.setMax(max, *tri->mV[0]);
+ max.setMax(max, *tri->mV[1]);
+ max.setMax(max, *tri->mV[2]);
+ }
+ }
+ else if (branch->getChildCount() > 0)
+ { //no data, but child nodes exist
+ LLVolumeOctreeListener* child = (LLVolumeOctreeListener*)branch->getChild(0)->getListener(0);
+
+ //initialize min/max to extents of first child
+ min = child->mExtents[0];
+ max = child->mExtents[1];
+ }
+ else
+ {
+ llassert(!branch->isLeaf()); // Empty leaf
+ }
+
+ for (S32 i = 0; i < branch->getChildCount(); ++i)
+ { //stretch by child extents
+ LLVolumeOctreeListener* child = (LLVolumeOctreeListener*)branch->getChild(i)->getListener(0);
+ min.setMin(min, child->mExtents[0]);
+ max.setMax(max, child->mExtents[1]);
+ }
+
+ node->mBounds[0].setAdd(min, max);
+ node->mBounds[0].mul(0.5f);
+
+ node->mBounds[1].setSub(max, min);
+ node->mBounds[1].mul(0.5f);
+ }
+};
+
+class LLVolumeOctree : public LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>, public LLRefCount
+{
+public:
+ LLVolumeOctree(const LLVector4a& center, const LLVector4a& size)
+ :
+ LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, nullptr),
+ LLRefCount()
+ {
+ new LLVolumeOctreeListener(this);
+ }
+
+ LLVolumeOctree()
+ : LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(LLVector4a::getZero(), LLVector4a(1.f,1.f,1.f), nullptr),
+ LLRefCount()
+ {
+ new LLVolumeOctreeListener(this);
+ }
+};
+
#endif
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 567a9b9559..f5966b71de 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llpluginprocessparent.cpp
* @brief LLPluginProcessParent handles the parent side of the external-process plugin API.
*
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&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$
* @endcond
@@ -37,10 +37,10 @@
#include "llapr.h"
-//virtual
+//virtual
LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
{
-
+
}
bool LLPluginProcessParent::sUseReadThread = false;
@@ -54,29 +54,29 @@ LLThread *LLPluginProcessParent::sReadThread = NULL;
class LLPluginProcessParentPollThread: public LLThread
{
public:
- LLPluginProcessParentPollThread() :
- LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
- {
- }
+ LLPluginProcessParentPollThread() :
+ LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
+ {
+ }
protected:
- // Inherited from LLThread
- /*virtual*/ void run(void)
- {
- while(!isQuitting() && LLPluginProcessParent::getUseReadThread())
- {
- LLPluginProcessParent::poll(0.1f);
- checkPause();
- }
-
- // Final poll to clean up the pollset, etc.
- LLPluginProcessParent::poll(0.0f);
- }
-
- // Inherited from LLThread
- /*virtual*/ bool runCondition(void)
- {
- return(LLPluginProcessParent::canPollThreadRun());
- }
+ // Inherited from LLThread
+ /*virtual*/ void run(void)
+ {
+ while(!isQuitting() && LLPluginProcessParent::getUseReadThread())
+ {
+ LLPluginProcessParent::poll(0.1f);
+ checkPause();
+ }
+
+ // Final poll to clean up the pollset, etc.
+ LLPluginProcessParent::poll(0.0f);
+ }
+
+ // Inherited from LLThread
+ /*virtual*/ bool runCondition(void)
+ {
+ return(LLPluginProcessParent::canPollThreadRun());
+ }
};
@@ -104,33 +104,33 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
mIncomingQueueMutex(),
pProcessCreationThread(NULL)
{
- if(!sInstancesMutex)
- {
- sInstancesMutex = new LLMutex();
- }
-
- mOwner = owner;
- mBoundPort = 0;
- mState = STATE_UNINITIALIZED;
- mSleepTime = 0.0;
- mCPUUsage = 0.0;
- mDisableTimeout = false;
- mDebug = false;
- mBlocked = false;
- mPolledInput = false;
- mPollFD.client_data = NULL;
-
- mPluginLaunchTimeout = 60.0f;
- mPluginLockupTimeout = 15.0f;
-
- // Don't start the timer here -- start it when we actually launch the plugin process.
- mHeartbeat.stop();
-
+ if(!sInstancesMutex)
+ {
+ sInstancesMutex = new LLMutex();
+ }
+
+ mOwner = owner;
+ mBoundPort = 0;
+ mState = STATE_UNINITIALIZED;
+ mSleepTime = 0.0;
+ mCPUUsage = 0.0;
+ mDisableTimeout = false;
+ mDebug = false;
+ mBlocked = false;
+ mPolledInput = false;
+ mPollFD.client_data = NULL;
+
+ mPluginLaunchTimeout = 60.0f;
+ mPluginLockupTimeout = 15.0f;
+
+ // Don't start the timer here -- start it when we actually launch the plugin process.
+ mHeartbeat.stop();
+
}
LLPluginProcessParent::~LLPluginProcessParent()
{
- LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
+ LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
if (pProcessCreationThread)
{
if (!pProcessCreationThread->isStopped())
@@ -144,20 +144,20 @@ LLPluginProcessParent::~LLPluginProcessParent()
pProcessCreationThread = NULL;
}
- // Destroy any remaining shared memory regions
- sharedMemoryRegionsType::iterator iter;
- while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end())
- {
- // destroy the shared memory region
- iter->second->destroy();
- delete iter->second;
- iter->second = NULL;
-
- // and remove it from our map
- mSharedMemoryRegions.erase(iter);
- }
-
- LLProcess::kill(mProcess);
+ // Destroy any remaining shared memory regions
+ sharedMemoryRegionsType::iterator iter;
+ while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end())
+ {
+ // destroy the shared memory region
+ iter->second->destroy();
+ delete iter->second;
+ iter->second = NULL;
+
+ // and remove it from our map
+ mSharedMemoryRegions.erase(iter);
+ }
+
+ LLProcess::kill(mProcess);
if (!LLApp::isQuitting())
{ // If we are quitting, the network sockets will already have been destroyed.
killSockets();
@@ -227,7 +227,7 @@ void LLPluginProcessParent::requestShutdown()
namestream << "LLPluginProcessParentListener" << ++count;
//*HACK!*//
- // After requestShutdown has been called our previous owner will no longer call
+ // After requestShutdown has been called our previous owner will no longer call
// our idle() method. Tie into the event loop here to do that until we are good
// and finished.
LL_DEBUGS("LLPluginProcessParent") << "listening on \"mainloop\"" << LL_ENDL;
@@ -279,78 +279,78 @@ bool LLPluginProcessParent::wantsPolling() const
void LLPluginProcessParent::killSockets(void)
{
- {
- LLMutexLock lock(&mIncomingQueueMutex);
- killMessagePipe();
- }
+ {
+ LLMutexLock lock(&mIncomingQueueMutex);
+ killMessagePipe();
+ }
- mListenSocket.reset();
- mSocket.reset();
+ mListenSocket.reset();
+ mSocket.reset();
}
void LLPluginProcessParent::errorState(void)
{
- if(mState < STATE_RUNNING)
- setState(STATE_LAUNCH_FAILURE);
- else
- setState(STATE_ERROR);
+ if(mState < STATE_RUNNING)
+ setState(STATE_LAUNCH_FAILURE);
+ else
+ setState(STATE_ERROR);
}
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
-{
- mProcessParams.executable = launcher_filename;
- mProcessParams.cwd = plugin_dir;
- mPluginFile = plugin_filename;
- mPluginDir = plugin_dir;
- mCPUUsage = 0.0f;
- mDebug = debug;
- setState(STATE_INITIALIZED);
+{
+ mProcessParams.executable = launcher_filename;
+ mProcessParams.cwd = plugin_dir;
+ mPluginFile = plugin_filename;
+ mPluginDir = plugin_dir;
+ mCPUUsage = 0.0f;
+ mDebug = debug;
+ setState(STATE_INITIALIZED);
}
bool LLPluginProcessParent::accept()
{
- bool result = false;
-
- apr_status_t status = APR_EGENERAL;
- apr_socket_t *new_socket = NULL;
-
- status = apr_socket_accept(
- &new_socket,
- mListenSocket->getSocket(),
- gAPRPoolp);
-
-
- if(status == APR_SUCCESS)
- {
-// LL_INFOS() << "SUCCESS" << LL_ENDL;
- // Success. Create a message pipe on the new socket
-
- // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
- apr_pool_t* new_pool = NULL;
- status = apr_pool_create(&new_pool, gAPRPoolp);
-
- mSocket = LLSocket::create(new_socket, new_pool);
- new LLPluginMessagePipe(this, mSocket);
-
- result = true;
- }
- else if(APR_STATUS_IS_EAGAIN(status))
- {
-// LL_INFOS() << "EAGAIN" << LL_ENDL;
-
- // No incoming connections. This is not an error.
- status = APR_SUCCESS;
- }
- else
- {
-// LL_INFOS() << "Error:" << LL_ENDL;
- ll_apr_warn_status(status);
-
- // Some other error.
- errorState();
- }
-
- return result;
+ bool result = false;
+
+ apr_status_t status = APR_EGENERAL;
+ apr_socket_t *new_socket = NULL;
+
+ status = apr_socket_accept(
+ &new_socket,
+ mListenSocket->getSocket(),
+ gAPRPoolp);
+
+
+ if(status == APR_SUCCESS)
+ {
+// LL_INFOS() << "SUCCESS" << LL_ENDL;
+ // Success. Create a message pipe on the new socket
+
+ // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
+ apr_pool_t* new_pool = NULL;
+ status = apr_pool_create(&new_pool, gAPRPoolp);
+
+ mSocket = LLSocket::create(new_socket, new_pool);
+ new LLPluginMessagePipe(this, mSocket);
+
+ result = true;
+ }
+ else if(APR_STATUS_IS_EAGAIN(status))
+ {
+// LL_INFOS() << "EAGAIN" << LL_ENDL;
+
+ // No incoming connections. This is not an error.
+ status = APR_SUCCESS;
+ }
+ else
+ {
+// LL_INFOS() << "Error:" << LL_ENDL;
+ ll_apr_warn_status(status);
+
+ // Some other error.
+ errorState();
+ }
+
+ return result;
}
bool LLPluginProcessParent::createPluginProcess()
@@ -384,166 +384,166 @@ void LLPluginProcessParent::clearProcessCreationThread()
void LLPluginProcessParent::idle(void)
{
- bool idle_again;
+ bool idle_again;
- do
- {
- // process queued messages
+ do
+ {
+ // process queued messages
// Inside main thread, it is preferable not to block it on mutex.
- bool locked = mIncomingQueueMutex.trylock();
- while(locked && !mIncomingQueue.empty())
- {
- LLPluginMessage message = mIncomingQueue.front();
- mIncomingQueue.pop();
- mIncomingQueueMutex.unlock();
-
- receiveMessage(message);
-
- locked = mIncomingQueueMutex.trylock();
- }
+ bool locked = mIncomingQueueMutex.trylock();
+ while(locked && !mIncomingQueue.empty())
+ {
+ LLPluginMessage message = mIncomingQueue.front();
+ mIncomingQueue.pop();
+ mIncomingQueueMutex.unlock();
+
+ receiveMessage(message);
+
+ locked = mIncomingQueueMutex.trylock();
+ }
if (locked)
{
mIncomingQueueMutex.unlock();
}
-
- // Give time to network processing
- if(mMessagePipe)
- {
- // Drain any queued outgoing messages
- mMessagePipe->pumpOutput();
-
- // Only do input processing here if this instance isn't in a pollset.
- // If viewer and plugin are both shutting down, don't process further
- // input, viewer won't be able to handle it.
- if(!mPolledInput
- && !(mState >= STATE_GOODBYE && LLApp::isExiting()))
- {
- mMessagePipe->pumpInput();
- }
- }
-
- if(mState <= STATE_RUNNING)
- {
- if(APR_STATUS_IS_EOF(mSocketError))
- {
- // Plugin socket was closed. This covers both normal plugin termination and plugin crashes.
- errorState();
- }
- else if(mSocketError != APR_SUCCESS)
- {
- // The socket is in an error state -- the plugin is gone.
- LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL;
- errorState();
- }
- }
-
- // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
- // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
- // When in doubt, don't do it.
- idle_again = false;
- switch(mState)
- {
- case STATE_UNINITIALIZED:
- break;
-
- case STATE_INITIALIZED:
- {
-
- apr_status_t status = APR_SUCCESS;
- apr_sockaddr_t* addr = NULL;
- mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
- mBoundPort = 0;
-
- // This code is based on parts of LLSocket::create() in lliosocket.cpp.
-
- status = apr_sockaddr_info_get(
- &addr,
- "127.0.0.1",
- APR_INET,
- 0, // port 0 = ephemeral ("find me a port")
- 0,
- gAPRPoolp);
-
- if(ll_apr_warn_status(status))
- {
- killSockets();
- errorState();
- break;
- }
-
- // This allows us to reuse the address on quick down/up. This is unlikely to create problems.
- ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1));
-
- status = apr_socket_bind(mListenSocket->getSocket(), addr);
- if(ll_apr_warn_status(status))
- {
- killSockets();
- errorState();
- break;
- }
-
- // Get the actual port the socket was bound to
- {
- apr_sockaddr_t* bound_addr = NULL;
- if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket())))
- {
- killSockets();
- errorState();
- break;
- }
- mBoundPort = bound_addr->port;
-
- if(mBoundPort == 0)
- {
- LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;
-
- killSockets();
- errorState();
- break;
- }
- }
-
- LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL;
-
- // Make the listen socket non-blocking
- status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1);
- if(ll_apr_warn_status(status))
- {
- killSockets();
- errorState();
- break;
- }
-
- apr_socket_timeout_set(mListenSocket->getSocket(), 0);
- if(ll_apr_warn_status(status))
- {
- killSockets();
- errorState();
- break;
- }
-
- // If it's a stream based socket, we need to tell the OS
- // to keep a queue of incoming connections for ACCEPT.
- status = apr_socket_listen(
- mListenSocket->getSocket(),
- 10); // FIXME: Magic number for queue size
-
- if(ll_apr_warn_status(status))
- {
- killSockets();
- errorState();
- break;
- }
-
- // If we got here, we're listening.
- setState(STATE_LISTENING);
- }
- break;
-
- case STATE_LISTENING:
- {
- // Launch the plugin process.
+
+ // Give time to network processing
+ if(mMessagePipe)
+ {
+ // Drain any queued outgoing messages
+ mMessagePipe->pumpOutput();
+
+ // Only do input processing here if this instance isn't in a pollset.
+ // If viewer and plugin are both shutting down, don't process further
+ // input, viewer won't be able to handle it.
+ if(!mPolledInput
+ && !(mState >= STATE_GOODBYE && LLApp::isExiting()))
+ {
+ mMessagePipe->pumpInput();
+ }
+ }
+
+ if(mState <= STATE_RUNNING)
+ {
+ if(APR_STATUS_IS_EOF(mSocketError))
+ {
+ // Plugin socket was closed. This covers both normal plugin termination and plugin crashes.
+ errorState();
+ }
+ else if(mSocketError != APR_SUCCESS)
+ {
+ // The socket is in an error state -- the plugin is gone.
+ LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL;
+ errorState();
+ }
+ }
+
+ // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
+ // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
+ // When in doubt, don't do it.
+ idle_again = false;
+ switch(mState)
+ {
+ case STATE_UNINITIALIZED:
+ break;
+
+ case STATE_INITIALIZED:
+ {
+
+ apr_status_t status = APR_SUCCESS;
+ apr_sockaddr_t* addr = NULL;
+ mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mBoundPort = 0;
+
+ // This code is based on parts of LLSocket::create() in lliosocket.cpp.
+
+ status = apr_sockaddr_info_get(
+ &addr,
+ "127.0.0.1",
+ APR_INET,
+ 0, // port 0 = ephemeral ("find me a port")
+ 0,
+ gAPRPoolp);
+
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+
+ // This allows us to reuse the address on quick down/up. This is unlikely to create problems.
+ ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1));
+
+ status = apr_socket_bind(mListenSocket->getSocket(), addr);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+
+ // Get the actual port the socket was bound to
+ {
+ apr_sockaddr_t* bound_addr = NULL;
+ if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket())))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+ mBoundPort = bound_addr->port;
+
+ if(mBoundPort == 0)
+ {
+ LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;
+
+ killSockets();
+ errorState();
+ break;
+ }
+ }
+
+ LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL;
+
+ // Make the listen socket non-blocking
+ status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+
+ apr_socket_timeout_set(mListenSocket->getSocket(), 0);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+
+ // If it's a stream based socket, we need to tell the OS
+ // to keep a queue of incoming connections for ACCEPT.
+ status = apr_socket_listen(
+ mListenSocket->getSocket(),
+ 10); // FIXME: Magic number for queue size
+
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ errorState();
+ break;
+ }
+
+ // If we got here, we're listening.
+ setState(STATE_LISTENING);
+ }
+ break;
+
+ case STATE_LISTENING:
+ {
+ // Launch the plugin process.
if (mDebug && !pProcessCreationThread)
{
createPluginProcess();
@@ -566,36 +566,36 @@ void LLPluginProcessParent::idle(void)
errorState();
}
-
- if (mProcess)
- {
- if(mDebug)
- {
+
+ if (mProcess)
+ {
+ if(mDebug)
+ {
#if LL_DARWIN
- // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue.
-
- // The command we're constructing would look like this on the command line:
- // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
-
- LLProcess::Params params;
- params.executable = "/usr/bin/osascript";
- params.args.add("-e");
- params.args.add("tell application \"Terminal\"");
- params.args.add("-e");
- params.args.add(STRINGIZE("set win to do script \"gdb -pid "
- << mProcess->getProcessID() << "\""));
- params.args.add("-e");
- params.args.add("do script \"continue\" in win");
- params.args.add("-e");
- params.args.add("end tell");
- mDebugger = LLProcess::create(params);
+ // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue.
+
+ // The command we're constructing would look like this on the command line:
+ // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
+
+ LLProcess::Params params;
+ params.executable = "/usr/bin/osascript";
+ params.args.add("-e");
+ params.args.add("tell application \"Terminal\"");
+ params.args.add("-e");
+ params.args.add(STRINGIZE("set win to do script \"lldb -pid "
+ << mProcess->getProcessID() << "\""));
+ params.args.add("-e");
+ params.args.add("do script \"continue\" in win");
+ params.args.add("-e");
+ params.args.add("end tell");
+ mDebugger = LLProcess::create(params);
#endif
- }
-
- // This will allow us to time out if the process never starts.
- mHeartbeat.start();
- mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
+ }
+
+ // This will allow us to time out if the process never starts.
+ mHeartbeat.start();
+ mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
// pProcessCreationThread should have stopped by this point,
// but check just in case it paused on statistics sync
@@ -605,67 +605,67 @@ void LLPluginProcessParent::idle(void)
pProcessCreationThread = NULL;
}
- setState(STATE_LAUNCHED);
- }
- }
- break;
-
- case STATE_LAUNCHED:
- // waiting for the plugin to connect
- if(pluginLockedUpOrQuit())
- {
- errorState();
- }
- else
- {
- // Check for the incoming connection.
- if(accept())
- {
- // Stop listening on the server port
- mListenSocket.reset();
- setState(STATE_CONNECTED);
- }
- }
- break;
-
- case STATE_CONNECTED:
- // waiting for hello message from the plugin
-
- if(pluginLockedUpOrQuit())
- {
- errorState();
- }
- break;
-
- case STATE_HELLO:
- LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL;
-
- // Send the message to load the plugin
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin");
- message.setValue("file", mPluginFile);
- message.setValue("dir", mPluginDir);
- sendMessage(message);
- }
-
- setState(STATE_LOADING);
- break;
-
- case STATE_LOADING:
- // The load_plugin_response message will kick us from here into STATE_RUNNING
- if(pluginLockedUpOrQuit())
- {
- errorState();
- }
- break;
-
- case STATE_RUNNING:
- if(pluginLockedUpOrQuit())
- {
- errorState();
- }
- break;
-
+ setState(STATE_LAUNCHED);
+ }
+ }
+ break;
+
+ case STATE_LAUNCHED:
+ // waiting for the plugin to connect
+ if(pluginLockedUpOrQuit())
+ {
+ errorState();
+ }
+ else
+ {
+ // Check for the incoming connection.
+ if(accept())
+ {
+ // Stop listening on the server port
+ mListenSocket.reset();
+ setState(STATE_CONNECTED);
+ }
+ }
+ break;
+
+ case STATE_CONNECTED:
+ // waiting for hello message from the plugin
+
+ if(pluginLockedUpOrQuit())
+ {
+ errorState();
+ }
+ break;
+
+ case STATE_HELLO:
+ LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL;
+
+ // Send the message to load the plugin
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin");
+ message.setValue("file", mPluginFile);
+ message.setValue("dir", mPluginDir);
+ sendMessage(message);
+ }
+
+ setState(STATE_LOADING);
+ break;
+
+ case STATE_LOADING:
+ // The load_plugin_response message will kick us from here into STATE_RUNNING
+ if(pluginLockedUpOrQuit())
+ {
+ errorState();
+ }
+ break;
+
+ case STATE_RUNNING:
+ if(pluginLockedUpOrQuit())
+ {
+ errorState();
+ }
+ break;
+
case STATE_GOODBYE:
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shutdown_plugin");
@@ -674,292 +674,292 @@ void LLPluginProcessParent::idle(void)
setState(STATE_EXITING);
break;
- case STATE_EXITING:
- if (! LLProcess::isRunning(mProcess))
- {
- setState(STATE_CLEANUP);
- }
- else if(pluginLockedUp())
- {
- LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL;
- errorState();
- }
- break;
-
- case STATE_LAUNCH_FAILURE:
- if(mOwner != NULL)
- {
- mOwner->pluginLaunchFailed();
- }
- setState(STATE_CLEANUP);
- break;
-
- case STATE_ERROR:
- if(mOwner != NULL)
- {
- mOwner->pluginDied();
- }
- setState(STATE_CLEANUP);
- break;
-
- case STATE_CLEANUP:
- LLProcess::kill(mProcess);
- killSockets();
- setState(STATE_DONE);
+ case STATE_EXITING:
+ if (! LLProcess::isRunning(mProcess))
+ {
+ setState(STATE_CLEANUP);
+ }
+ else if(pluginLockedUp())
+ {
+ LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL;
+ errorState();
+ }
+ break;
+
+ case STATE_LAUNCH_FAILURE:
+ if(mOwner != NULL)
+ {
+ mOwner->pluginLaunchFailed();
+ }
+ setState(STATE_CLEANUP);
+ break;
+
+ case STATE_ERROR:
+ if(mOwner != NULL)
+ {
+ mOwner->pluginDied();
+ }
+ setState(STATE_CLEANUP);
+ break;
+
+ case STATE_CLEANUP:
+ LLProcess::kill(mProcess);
+ killSockets();
+ setState(STATE_DONE);
dirtyPollSet();
clearProcessCreationThread();
- break;
-
- case STATE_DONE:
- // just sit here.
- break;
- }
-
- } while (idle_again);
+ break;
+
+ case STATE_DONE:
+ // just sit here.
+ break;
+ }
+
+ } while (idle_again);
}
bool LLPluginProcessParent::isLoading(void)
{
- bool result = false;
-
- if(mState <= STATE_LOADING)
- result = true;
-
- return result;
+ bool result = false;
+
+ if(mState <= STATE_LOADING)
+ result = true;
+
+ return result;
}
bool LLPluginProcessParent::isRunning(void)
{
- bool result = false;
-
- if(mState == STATE_RUNNING)
- result = true;
-
- return result;
+ bool result = false;
+
+ if(mState == STATE_RUNNING)
+ result = true;
+
+ return result;
}
bool LLPluginProcessParent::isDone(void)
{
- bool result = false;
-
- if(mState == STATE_DONE)
- result = true;
-
- return result;
+ bool result = false;
+
+ if(mState == STATE_DONE)
+ result = true;
+
+ return result;
}
void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send)
{
- if(force_send || (sleep_time != mSleepTime))
- {
- // Cache the time locally
- mSleepTime = sleep_time;
-
- if(canSendMessage())
- {
- // and send to the plugin.
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time");
- message.setValueReal("time", mSleepTime);
- sendMessage(message);
- }
- else
- {
- // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later.
- }
- }
+ if(force_send || (sleep_time != mSleepTime))
+ {
+ // Cache the time locally
+ mSleepTime = sleep_time;
+
+ if(canSendMessage())
+ {
+ // and send to the plugin.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time");
+ message.setValueReal("time", mSleepTime);
+ sendMessage(message);
+ }
+ else
+ {
+ // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later.
+ }
+ }
}
void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
{
- if(message.hasValue("blocking_response"))
- {
- mBlocked = false;
-
- // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
- mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
- }
-
- std::string buffer = message.generate();
- LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;
- writeMessageRaw(buffer);
-
- // Try to send message immediately.
- if(mMessagePipe)
- {
- mMessagePipe->pumpOutput();
- }
+ if(message.hasValue("blocking_response"))
+ {
+ mBlocked = false;
+
+ // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
+ mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
+ }
+
+ std::string buffer = message.generate();
+ LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;
+ writeMessageRaw(buffer);
+
+ // Try to send message immediately.
+ if(mMessagePipe)
+ {
+ mMessagePipe->pumpOutput();
+ }
}
-//virtual
+//virtual
void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
{
- bool update_pollset = false;
-
- if(mMessagePipe)
- {
- // Unsetting an existing message pipe -- remove from the pollset
- mPollFD.client_data = NULL;
-
- // pollset needs an update
- update_pollset = true;
- }
- if(message_pipe != NULL)
- {
- // Set up the apr_pollfd_t
- mPollFD.p = gAPRPoolp;
- mPollFD.desc_type = APR_POLL_SOCKET;
- mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
- mPollFD.rtnevents = 0;
- mPollFD.desc.s = mSocket->getSocket();
- mPollFD.client_data = (void*)this;
-
- // pollset needs an update
- update_pollset = true;
- }
-
- mMessagePipe = message_pipe;
-
- if(update_pollset)
- {
- dirtyPollSet();
- }
+ bool update_pollset = false;
+
+ if(mMessagePipe)
+ {
+ // Unsetting an existing message pipe -- remove from the pollset
+ mPollFD.client_data = NULL;
+
+ // pollset needs an update
+ update_pollset = true;
+ }
+ if(message_pipe != NULL)
+ {
+ // Set up the apr_pollfd_t
+ mPollFD.p = gAPRPoolp;
+ mPollFD.desc_type = APR_POLL_SOCKET;
+ mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
+ mPollFD.rtnevents = 0;
+ mPollFD.desc.s = mSocket->getSocket();
+ mPollFD.client_data = (void*)this;
+
+ // pollset needs an update
+ update_pollset = true;
+ }
+
+ mMessagePipe = message_pipe;
+
+ if(update_pollset)
+ {
+ dirtyPollSet();
+ }
}
-//static
+//static
void LLPluginProcessParent::dirtyPollSet()
{
- sPollsetNeedsRebuild = true;
-
- if(sReadThread)
- {
- LL_DEBUGS("PluginPoll") << "unpausing read thread " << LL_ENDL;
- sReadThread->unpause();
- }
+ sPollsetNeedsRebuild = true;
+
+ if(sReadThread)
+ {
+ LL_DEBUGS("PluginPoll") << "unpausing read thread " << LL_ENDL;
+ sReadThread->unpause();
+ }
}
void LLPluginProcessParent::updatePollset()
{
- if(!sInstancesMutex)
- {
- // No instances have been created yet. There's no work to do.
- return;
- }
-
- LLMutexLock lock(sInstancesMutex);
-
- if(sPollSet)
- {
- LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL;
- // delete the existing pollset.
- apr_pollset_destroy(sPollSet);
- sPollSet = NULL;
- }
-
+ if(!sInstancesMutex)
+ {
+ // No instances have been created yet. There's no work to do.
+ return;
+ }
+
+ LLMutexLock lock(sInstancesMutex);
+
+ if(sPollSet)
+ {
+ LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL;
+ // delete the existing pollset.
+ apr_pollset_destroy(sPollSet);
+ sPollSet = NULL;
+ }
+
mapInstances_t::iterator iter;
- int count = 0;
-
- // Count the number of instances that want to be in the pollset
- for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
- {
- (*iter).second->mPolledInput = false;
+ int count = 0;
+
+ // Count the number of instances that want to be in the pollset
+ for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
+ {
+ (*iter).second->mPolledInput = false;
if ((*iter).second->wantsPolling())
- {
- // This instance has a socket that needs to be polled.
- ++count;
- }
- }
-
- if(sUseReadThread && sReadThread && !sReadThread->isQuitting())
- {
- if(!sPollSet && (count > 0))
- {
+ {
+ // This instance has a socket that needs to be polled.
+ ++count;
+ }
+ }
+
+ if(sUseReadThread && sReadThread && !sReadThread->isQuitting())
+ {
+ if(!sPollSet && (count > 0))
+ {
#ifdef APR_POLLSET_NOCOPY
- // The pollset doesn't exist yet. Create it now.
- apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY);
- if(status != APR_SUCCESS)
- {
+ // The pollset doesn't exist yet. Create it now.
+ apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY);
+ if(status != APR_SUCCESS)
+ {
#endif // APR_POLLSET_NOCOPY
- LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL;
- sPollSet = NULL;
+ LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL;
+ sPollSet = NULL;
#ifdef APR_POLLSET_NOCOPY
- }
- else
- {
- LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL;
-
- // Pollset was created, add all instances to it.
- for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
- {
+ }
+ else
+ {
+ LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL;
+
+ // Pollset was created, add all instances to it.
+ for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
+ {
if ((*iter).second->wantsPolling())
- {
- status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD));
- if(status == APR_SUCCESS)
- {
- (*iter).second->mPolledInput = true;
- }
- else
- {
- LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL;
- }
- }
- }
- }
+ {
+ status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD));
+ if(status == APR_SUCCESS)
+ {
+ (*iter).second->mPolledInput = true;
+ }
+ else
+ {
+ LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL;
+ }
+ }
+ }
+ }
#endif // APR_POLLSET_NOCOPY
- }
- }
+ }
+ }
}
void LLPluginProcessParent::setUseReadThread(bool use_read_thread)
{
- if(sUseReadThread != use_read_thread)
- {
- sUseReadThread = use_read_thread;
-
- if(sUseReadThread)
- {
- if(!sReadThread)
- {
- // start up the read thread
- LL_INFOS("PluginPoll") << "creating read thread " << LL_ENDL;
-
- // make sure the pollset gets rebuilt.
- sPollsetNeedsRebuild = true;
-
- sReadThread = new LLPluginProcessParentPollThread;
- sReadThread->start();
- }
- }
- else
- {
- if(sReadThread)
- {
- // shut down the read thread
- LL_INFOS("PluginPoll") << "destroying read thread " << LL_ENDL;
- delete sReadThread;
- sReadThread = NULL;
- }
- }
-
- }
+ if(sUseReadThread != use_read_thread)
+ {
+ sUseReadThread = use_read_thread;
+
+ if(sUseReadThread)
+ {
+ if(!sReadThread)
+ {
+ // start up the read thread
+ LL_INFOS("PluginPoll") << "creating read thread " << LL_ENDL;
+
+ // make sure the pollset gets rebuilt.
+ sPollsetNeedsRebuild = true;
+
+ sReadThread = new LLPluginProcessParentPollThread;
+ sReadThread->start();
+ }
+ }
+ else
+ {
+ if(sReadThread)
+ {
+ // shut down the read thread
+ LL_INFOS("PluginPoll") << "destroying read thread " << LL_ENDL;
+ delete sReadThread;
+ sReadThread = NULL;
+ }
+ }
+
+ }
}
void LLPluginProcessParent::poll(F64 timeout)
{
- if(sPollsetNeedsRebuild || !sUseReadThread)
- {
- sPollsetNeedsRebuild = false;
- updatePollset();
- }
-
- if(sPollSet)
- {
- apr_status_t status;
- apr_int32_t count;
- const apr_pollfd_t *descriptors;
- status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors);
- if(status == APR_SUCCESS)
- {
- // One or more of the descriptors signalled. Call them.
+ if(sPollsetNeedsRebuild || !sUseReadThread)
+ {
+ sPollsetNeedsRebuild = false;
+ updatePollset();
+ }
+
+ if(sPollSet)
+ {
+ apr_status_t status;
+ apr_int32_t count;
+ const apr_pollfd_t *descriptors;
+ status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors);
+ if(status == APR_SUCCESS)
+ {
+ // One or more of the descriptors signalled. Call them.
for (int i = 0; i < count; i++)
{
void *thatId = descriptors[i].client_data;
@@ -981,23 +981,23 @@ void LLPluginProcessParent::poll(F64 timeout)
that->mIncomingQueueMutex.unlock();
}
- }
- }
- else if(APR_STATUS_IS_TIMEUP(status))
- {
- // timed out with no incoming data. Just return.
- }
- else if(status == EBADF)
- {
- // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed.
- // The pollset has been or will be recreated, so just return.
- LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL;
- }
- else if(status != APR_SUCCESS)
- {
- LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL;
- }
- }
+ }
+ }
+ else if(APR_STATUS_IS_TIMEUP(status))
+ {
+ // timed out with no incoming data. Just return.
+ }
+ else if(status == EBADF)
+ {
+ // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed.
+ // The pollset has been or will be recreated, so just return.
+ LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL;
+ }
+ else if(status != APR_SUCCESS)
+ {
+ LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL;
+ }
+ }
// Remove instances in the done state from the sInstances map.
mapInstances_t::iterator itClean = sInstances.begin();
@@ -1012,293 +1012,293 @@ void LLPluginProcessParent::poll(F64 timeout)
void LLPluginProcessParent::servicePoll()
{
- bool result = true;
-
- // poll signalled on this object's socket. Try to process incoming messages.
- if(mMessagePipe)
- {
- result = mMessagePipe->pumpInput(0.0f);
- }
-
- if(!result)
- {
- // If we got a read error on input, remove this pipe from the pollset
- apr_pollset_remove(sPollSet, &mPollFD);
-
- // and tell the code not to re-add it
- mPollFD.client_data = NULL;
- }
+ bool result = true;
+
+ // poll signalled on this object's socket. Try to process incoming messages.
+ if(mMessagePipe)
+ {
+ result = mMessagePipe->pumpInput(0.0f);
+ }
+
+ if(!result)
+ {
+ // If we got a read error on input, remove this pipe from the pollset
+ apr_pollset_remove(sPollSet, &mPollFD);
+
+ // and tell the code not to re-add it
+ mPollFD.client_data = NULL;
+ }
}
void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
{
- LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
-
- LLPluginMessage parsed;
- if(LLSDParser::PARSE_FAILURE != parsed.parse(message))
- {
- if(parsed.hasValue("blocking_request"))
- {
- mBlocked = true;
- }
-
- if(mPolledInput)
- {
- // This is being called on the polling thread -- only do minimal processing/queueing.
- receiveMessageEarly(parsed);
- }
- else
- {
- // This is not being called on the polling thread -- do full message processing at this time.
- receiveMessage(parsed);
- }
- }
+ LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
+
+ LLPluginMessage parsed;
+ if(LLSDParser::PARSE_FAILURE != parsed.parse(message))
+ {
+ if(parsed.hasValue("blocking_request"))
+ {
+ mBlocked = true;
+ }
+
+ if(mPolledInput)
+ {
+ // This is being called on the polling thread -- only do minimal processing/queueing.
+ receiveMessageEarly(parsed);
+ }
+ else
+ {
+ // This is not being called on the polling thread -- do full message processing at this time.
+ receiveMessage(parsed);
+ }
+ }
}
void LLPluginProcessParent::receiveMessageEarly(const LLPluginMessage &message)
{
- // NOTE: this function will be called from the polling thread. It will be called with mIncomingQueueMutex _already locked_.
-
- bool handled = false;
-
- std::string message_class = message.getClass();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
- {
- // no internal messages need to be handled early.
- }
- else
- {
- // Call out to the owner and see if they to reply
- // TODO: Should this only happen when blocked?
- if(mOwner != NULL)
- {
- handled = mOwner->receivePluginMessageEarly(message);
- }
- }
-
- if(!handled)
- {
- // any message that wasn't handled early needs to be queued.
- mIncomingQueue.push(message);
- }
+ // NOTE: this function will be called from the polling thread. It will be called with mIncomingQueueMutex _already locked_.
+
+ bool handled = false;
+
+ std::string message_class = message.getClass();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
+ {
+ // no internal messages need to be handled early.
+ }
+ else
+ {
+ // Call out to the owner and see if they to reply
+ // TODO: Should this only happen when blocked?
+ if(mOwner != NULL)
+ {
+ handled = mOwner->receivePluginMessageEarly(message);
+ }
+ }
+
+ if(!handled)
+ {
+ // any message that wasn't handled early needs to be queued.
+ mIncomingQueue.push(message);
+ }
}
void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
- std::string message_class = message.getClass();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
- {
- // internal messages should be handled here
- std::string message_name = message.getName();
- if(message_name == "hello")
- {
- if(mState == STATE_CONNECTED)
- {
- // Plugin host has launched. Tell it which plugin to load.
- setState(STATE_HELLO);
- }
- else
- {
- LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL;
- errorState();
- }
-
- }
- else if(message_name == "load_plugin_response")
- {
- if(mState == STATE_LOADING)
- {
- // Plugin has been loaded.
-
- mPluginVersionString = message.getValue("plugin_version");
- LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL;
-
- // Check which message classes/versions the plugin supports.
- // TODO: check against current versions
- // TODO: kill plugin on major mismatches?
- mMessageClassVersions = message.getValueLLSD("versions");
- LLSD::map_iterator iter;
- for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++)
- {
- LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;
- }
-
- // Send initial sleep time
- llassert_always(mSleepTime != 0.f);
- setSleepTime(mSleepTime, true);
-
- setState(STATE_RUNNING);
- }
- else
- {
- LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL;
- errorState();
- }
- }
- else if(message_name == "heartbeat")
- {
- // this resets our timer.
- mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
-
- mCPUUsage = message.getValueReal("cpu_usage");
-
- LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
-
- }
- else if(message_name == "shm_add_response")
- {
- // Nothing to do here.
- }
- else if(message_name == "shm_remove_response")
- {
- std::string name = message.getValue("name");
- sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
-
- if(iter != mSharedMemoryRegions.end())
- {
- // destroy the shared memory region
- iter->second->destroy();
- delete iter->second;
- iter->second = NULL;
-
- // and remove it from our map
- mSharedMemoryRegions.erase(iter);
- }
- }
- else
- {
- LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL;
- }
- }
- else
- {
- if(mOwner != NULL)
- {
- mOwner->receivePluginMessage(message);
- }
- }
+ std::string message_class = message.getClass();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
+ {
+ // internal messages should be handled here
+ std::string message_name = message.getName();
+ if(message_name == "hello")
+ {
+ if(mState == STATE_CONNECTED)
+ {
+ // Plugin host has launched. Tell it which plugin to load.
+ setState(STATE_HELLO);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL;
+ errorState();
+ }
+
+ }
+ else if(message_name == "load_plugin_response")
+ {
+ if(mState == STATE_LOADING)
+ {
+ // Plugin has been loaded.
+
+ mPluginVersionString = message.getValue("plugin_version");
+ LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL;
+
+ // Check which message classes/versions the plugin supports.
+ // TODO: check against current versions
+ // TODO: kill plugin on major mismatches?
+ mMessageClassVersions = message.getValueLLSD("versions");
+ LLSD::map_iterator iter;
+ for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++)
+ {
+ LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;
+ }
+
+ // Send initial sleep time
+ llassert_always(mSleepTime != 0.f);
+ setSleepTime(mSleepTime, true);
+
+ setState(STATE_RUNNING);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL;
+ errorState();
+ }
+ }
+ else if(message_name == "heartbeat")
+ {
+ // this resets our timer.
+ mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
+
+ mCPUUsage = message.getValueReal("cpu_usage");
+
+ LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
+
+ }
+ else if(message_name == "shm_add_response")
+ {
+ // Nothing to do here.
+ }
+ else if(message_name == "shm_remove_response")
+ {
+ std::string name = message.getValue("name");
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // destroy the shared memory region
+ iter->second->destroy();
+ delete iter->second;
+ iter->second = NULL;
+
+ // and remove it from our map
+ mSharedMemoryRegions.erase(iter);
+ }
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL;
+ }
+ }
+ else
+ {
+ if(mOwner != NULL)
+ {
+ mOwner->receivePluginMessage(message);
+ }
+ }
}
std::string LLPluginProcessParent::addSharedMemory(size_t size)
{
- std::string name;
-
- LLPluginSharedMemory *region = new LLPluginSharedMemory;
-
- // This is a new region
- if(region->create(size))
- {
- name = region->getName();
-
- mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region));
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add");
- message.setValue("name", name);
- message.setValueS32("size", (S32)size);
- sendMessage(message);
- }
- else
- {
- LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL;
-
- // Don't leak
- delete region;
- }
-
- return name;
+ std::string name;
+
+ LLPluginSharedMemory *region = new LLPluginSharedMemory;
+
+ // This is a new region
+ if(region->create(size))
+ {
+ name = region->getName();
+
+ mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region));
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add");
+ message.setValue("name", name);
+ message.setValueS32("size", (S32)size);
+ sendMessage(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL;
+
+ // Don't leak
+ delete region;
+ }
+
+ return name;
}
void LLPluginProcessParent::removeSharedMemory(const std::string &name)
{
- sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
-
- if(iter != mSharedMemoryRegions.end())
- {
- // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end.
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
- LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL;
- }
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL;
+ }
}
size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name)
{
- size_t result = 0;
-
- sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
- if(iter != mSharedMemoryRegions.end())
- {
- result = iter->second->getSize();
- }
-
- return result;
+ size_t result = 0;
+
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ result = iter->second->getSize();
+ }
+
+ return result;
}
void *LLPluginProcessParent::getSharedMemoryAddress(const std::string &name)
{
- void *result = NULL;
-
- sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
- if(iter != mSharedMemoryRegions.end())
- {
- result = iter->second->getMappedAddress();
- }
-
- return result;
+ void *result = NULL;
+
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ result = iter->second->getMappedAddress();
+ }
+
+ return result;
}
std::string LLPluginProcessParent::getMessageClassVersion(const std::string &message_class)
{
- std::string result;
-
- if(mMessageClassVersions.has(message_class))
- {
- result = mMessageClassVersions[message_class].asString();
- }
-
- return result;
+ std::string result;
+
+ if(mMessageClassVersions.has(message_class))
+ {
+ result = mMessageClassVersions[message_class].asString();
+ }
+
+ return result;
}
std::string LLPluginProcessParent::getPluginVersion(void)
{
- return mPluginVersionString;
+ return mPluginVersionString;
}
void LLPluginProcessParent::setState(EState state)
{
- LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
- mState = state;
+ LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
+ mState = state;
};
bool LLPluginProcessParent::pluginLockedUpOrQuit()
{
- bool result = false;
-
- if (! LLProcess::isRunning(mProcess))
- {
- LL_WARNS("Plugin") << "child exited" << LL_ENDL;
- result = true;
- }
- else if(pluginLockedUp())
- {
- LL_WARNS("Plugin") << "timeout" << LL_ENDL;
- result = true;
- }
-
- return result;
+ bool result = false;
+
+ if (! LLProcess::isRunning(mProcess))
+ {
+ LL_WARNS("Plugin") << "child exited" << LL_ENDL;
+ result = true;
+ }
+ else if(pluginLockedUp())
+ {
+ LL_WARNS("Plugin") << "timeout" << LL_ENDL;
+ result = true;
+ }
+
+ return result;
}
bool LLPluginProcessParent::pluginLockedUp()
{
- if(mDisableTimeout || mDebug || mBlocked)
- {
- // Never time out a plugin process in these cases.
- return false;
- }
-
- // If the timer is running and has expired, the plugin has locked up.
- return (mHeartbeat.getStarted() && mHeartbeat.hasExpired());
+ if(mDisableTimeout || mDebug || mBlocked)
+ {
+ // Never time out a plugin process in these cases.
+ return false;
+ }
+
+ // If the timer is running and has expired, the plugin has locked up.
+ return (mHeartbeat.getStarted() && mHeartbeat.hasExpired());
}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index dac9c44f8a..855cb58832 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -5,21 +5,21 @@
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -122,13 +122,30 @@ public:
F32 mRoughnessFactor = 1.f;
F32 mAlphaCutoff = 0.5f;
- bool mDoubleSided = false;
AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE;
+ bool mDoubleSided = false;
+
// override specific flags for state that can't use off-by-epsilon or UUID hack
bool mOverrideDoubleSided = false;
bool mOverrideAlphaMode = false;
+ // *TODO: If/when we implement additional GLTF extensions, they may not be
+ // compatible with our GLTF terrain implementation. We may want to disallow
+ // materials with some features from being set on terrain, if their
+ // implementation on terrain is not compliant with the spec:
+ // - KHR_materials_transmission: Probably OK?
+ // - KHR_materials_ior: Probably OK?
+ // - KHR_materials_volume: Likely incompatible, as our terrain
+ // heightmaps cannot currently be described as finite enclosed
+ // volumes.
+ // See also LLPanelRegionTerrainInfo::validateMaterials
+ // These fields are local to viewer and are a part of local bitmap support
+ typedef std::map<LLUUID, LLUUID> local_tex_map_t;
+ local_tex_map_t mTrackingIdToLocalTexture;
+
+public:
+
// get a UUID based on a hash of this LLGLTFMaterial
LLUUID getHash() const;
@@ -197,7 +214,7 @@ public:
void writeToModel(tinygltf::Model& model, S32 mat_index) const;
virtual void applyOverride(const LLGLTFMaterial& override_mat);
-
+
// apply the given LLSD override data
void applyOverrideLLSD(const LLSD& data);
@@ -229,10 +246,6 @@ public:
virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id);
virtual void updateTextureTracking();
- // These fields are local to viewer and are a part of local bitmap support
- typedef std::map<LLUUID, LLUUID> local_tex_map_t;
- local_tex_map_t mTrackingIdToLocalTexture;
-
protected:
static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 9dddd29e8c..53d09df618 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llprimitive.cpp
* @brief LLPrimitive base class
*
* $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$
*/
@@ -57,9 +57,9 @@ const F32 OBJECT_TWIST_INC = 18.f;
// This is used for linear paths,
// since twist is used in a slightly different manner.
-const F32 OBJECT_TWIST_LINEAR_MIN = -180.f;
-const F32 OBJECT_TWIST_LINEAR_MAX = 180.f;
-const F32 OBJECT_TWIST_LINEAR_INC = 9.f;
+const F32 OBJECT_TWIST_LINEAR_MIN = -180.f;
+const F32 OBJECT_TWIST_LINEAR_MAX = 180.f;
+const F32 OBJECT_TWIST_LINEAR_INC = 9.f;
const F32 OBJECT_MIN_HOLE_SIZE = 0.05f;
const F32 OBJECT_MAX_HOLE_SIZE_X = 1.0f;
@@ -94,7 +94,7 @@ const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f;
// "Tension" => [0,10], increments of 0.1
const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f;
const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f;
-const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f;
+const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f;
// "Drag" => [0,10], increments of 0.1
const F32 FLEXIBLE_OBJECT_MIN_AIR_FRICTION = 0.0f;
@@ -112,7 +112,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY = 0.0f;
const F32 FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY = 10.0f;
// I'll explain later...
-const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f;
+const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f;
const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f;
const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
@@ -121,9 +121,9 @@ const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
// Texture rotations are sent over the wire as a S16. This is used to scale the actual float
-// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it
+// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it
// can't be divided by 2. See DEV-19108
-const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000);
+const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000);
struct material_id_type // originally from llrendermaterialtable
{
@@ -154,7 +154,7 @@ struct material_id_type // originally from llrendermaterialtable
const U8 material_id_type::s_null_id[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-//static
+//static
// LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global
// TODO -- eliminate this global from the codebase!
LLVolumeMgr* LLPrimitive::sVolumeManager = NULL;
@@ -162,61 +162,61 @@ LLVolumeMgr* LLPrimitive::sVolumeManager = NULL;
// static
void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager )
{
- if ( !volume_manager || sVolumeManager )
- {
- LL_ERRS() << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << LL_ENDL;
- }
- sVolumeManager = volume_manager;
+ if ( !volume_manager || sVolumeManager )
+ {
+ LL_ERRS() << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << LL_ENDL;
+ }
+ sVolumeManager = volume_manager;
}
// static
bool LLPrimitive::cleanupVolumeManager()
{
- BOOL res = FALSE;
- if (sVolumeManager)
- {
- res = sVolumeManager->cleanup();
- delete sVolumeManager;
- sVolumeManager = NULL;
- }
- return res;
+ BOOL res = FALSE;
+ if (sVolumeManager)
+ {
+ res = sVolumeManager->cleanup();
+ delete sVolumeManager;
+ sVolumeManager = NULL;
+ }
+ return res;
}
//===============================================================
LLPrimitive::LLPrimitive()
-: mTextureList(),
- mNumTEs(0),
- mMiscFlags(0),
- mNumBumpmapTEs(0)
+: mTextureList(),
+ mNumTEs(0),
+ mMiscFlags(0),
+ mNumBumpmapTEs(0)
{
- mPrimitiveCode = 0;
+ mPrimitiveCode = 0;
- mMaterial = LL_MCODE_STONE;
- mVolumep = NULL;
+ mMaterial = LL_MCODE_STONE;
+ mVolumep = NULL;
- mChanged = UNCHANGED;
+ mChanged = UNCHANGED;
- mPosition.setVec(0.f,0.f,0.f);
- mVelocity.setVec(0.f,0.f,0.f);
- mAcceleration.setVec(0.f,0.f,0.f);
+ mPosition.setVec(0.f,0.f,0.f);
+ mVelocity.setVec(0.f,0.f,0.f);
+ mAcceleration.setVec(0.f,0.f,0.f);
- mRotation.loadIdentity();
- mAngularVelocity.setVec(0.f,0.f,0.f);
-
- mScale.setVec(1.f,1.f,1.f);
+ mRotation.loadIdentity();
+ mAngularVelocity.setVec(0.f,0.f,0.f);
+
+ mScale.setVec(1.f,1.f,1.f);
}
//===============================================================
LLPrimitive::~LLPrimitive()
{
- clearTextureList();
- // Cleanup handled by volume manager
- if (mVolumep && sVolumeManager)
- {
- sVolumeManager->unrefVolume(mVolumep);
- }
- mVolumep = NULL;
+ clearTextureList();
+ // Cleanup handled by volume manager
+ if (mVolumep && sVolumeManager)
+ {
+ sVolumeManager->unrefVolume(mVolumep);
+ }
+ mVolumep = NULL;
}
void LLPrimitive::clearTextureList()
@@ -227,83 +227,83 @@ void LLPrimitive::clearTextureList()
// static
LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
{
- LLPrimitive *retval = new LLPrimitive();
+ LLPrimitive *retval = new LLPrimitive();
+
+ if (retval)
+ {
+ retval->init_primitive(p_code);
+ }
+ else
+ {
+ LL_ERRS() << "primitive allocation failed" << LL_ENDL;
+ }
- if (retval)
- {
- retval->init_primitive(p_code);
- }
- else
- {
- LL_ERRS() << "primitive allocation failed" << LL_ENDL;
- }
-
- return retval;
+ return retval;
}
//===============================================================
void LLPrimitive::init_primitive(LLPCode p_code)
{
- clearTextureList();
- mPrimitiveCode = p_code;
+ clearTextureList();
+ mPrimitiveCode = p_code;
}
void LLPrimitive::setPCode(const U8 p_code)
{
- mPrimitiveCode = p_code;
+ mPrimitiveCode = p_code;
}
//===============================================================
LLTextureEntry* LLPrimitive::getTE(const U8 index) const
{
- return mTextureList.getTexture(index);
+ return mTextureList.getTexture(index);
}
//===============================================================
void LLPrimitive::setNumTEs(const U8 num_tes)
{
- mTextureList.setSize(num_tes);
+ mTextureList.setSize(num_tes);
}
//===============================================================
void LLPrimitive::setAllTETextures(const LLUUID &tex_id)
{
- mTextureList.setAllIDs(tex_id);
+ mTextureList.setAllIDs(tex_id);
}
//===============================================================
void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
{
- if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0)
- {
- mNumBumpmapTEs++;
- }
+ if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0)
+ {
+ mNumBumpmapTEs++;
+ }
}
S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id)
{
- return mTextureList.setID(index, id);
+ return mTextureList.setID(index, id);
}
S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color)
{
- return mTextureList.setColor(index, color);
+ return mTextureList.setColor(index, color);
}
S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color)
{
- return mTextureList.setColor(index, color);
+ return mTextureList.setColor(index, color);
}
S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha)
{
- return mTextureList.setAlpha(index, alpha);
+ return mTextureList.setAlpha(index, alpha);
}
//===============================================================
S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t)
{
- return mTextureList.setScale(index, s, t);
+ return mTextureList.setScale(index, s, t);
}
@@ -311,7 +311,7 @@ S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t)
// voodoo related to texture coords
S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s)
{
- return mTextureList.setScaleS(index, s);
+ return mTextureList.setScaleS(index, s);
}
@@ -319,14 +319,14 @@ S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s)
// voodoo related to texture coords
S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t)
{
- return mTextureList.setScaleT(index, t);
+ return mTextureList.setScaleT(index, t);
}
//===============================================================
S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t)
{
- return mTextureList.setOffset(index, s, t);
+ return mTextureList.setOffset(index, s, t);
}
@@ -334,7 +334,7 @@ S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t)
// voodoo related to texture coords
S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s)
{
- return mTextureList.setOffsetS(index, s);
+ return mTextureList.setOffsetS(index, s);
}
@@ -342,289 +342,289 @@ S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s)
// voodoo related to texture coords
S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t)
{
- return mTextureList.setOffsetT(index, t);
+ return mTextureList.setOffsetT(index, t);
}
//===============================================================
S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
{
- return mTextureList.setRotation(index, r);
+ return mTextureList.setRotation(index, r);
}
S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
{
- return mTextureList.setMaterialID(index, pMaterialID);
+ return mTextureList.setMaterialID(index, pMaterialID);
}
S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
{
- return mTextureList.setMaterialParams(index, pMaterialParams);
+ return mTextureList.setMaterialParams(index, pMaterialParams);
}
LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index)
{
- return mTextureList.getMaterialParams(index);
+ return mTextureList.getMaterialParams(index);
}
//===============================================================
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
{
- updateNumBumpmap(index, bump);
- return mTextureList.setBumpShinyFullbright(index, bump);
+ updateNumBumpmap(index, bump);
+ return mTextureList.setBumpShinyFullbright(index, bump);
}
S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)
{
- return mTextureList.setMediaTexGen(index, media);
+ return mTextureList.setMediaTexGen(index, media);
}
S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)
{
- updateNumBumpmap(index, bump);
- return mTextureList.setBumpMap(index, bump);
+ updateNumBumpmap(index, bump);
+ return mTextureList.setBumpMap(index, bump);
}
S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)
{
- updateNumBumpmap(index, bump_shiny);
- return mTextureList.setBumpShiny(index, bump_shiny);
+ updateNumBumpmap(index, bump_shiny);
+ return mTextureList.setBumpShiny(index, bump_shiny);
}
S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen)
{
- return mTextureList.setTexGen(index, texgen);
+ return mTextureList.setTexGen(index, texgen);
}
S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny)
{
- return mTextureList.setShiny(index, shiny);
+ return mTextureList.setShiny(index, shiny);
}
S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright)
{
- return mTextureList.setFullbright(index, fullbright);
+ return mTextureList.setFullbright(index, fullbright);
}
S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags)
{
- return mTextureList.setMediaFlags(index, media_flags);
+ return mTextureList.setMediaFlags(index, media_flags);
}
S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
{
- return mTextureList.setGlow(index, glow);
+ return mTextureList.setGlow(index, glow);
}
void LLPrimitive::setAllTESelected(bool sel)
{
- for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
- {
- setTESelected(i, sel);
- }
+ for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
+ {
+ setTESelected(i, sel);
+ }
}
-
+
void LLPrimitive::setTESelected(const U8 te, bool sel)
{
- LLTextureEntry* tep = getTE(te);
- if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
- {
- LLMaterialID material_id = tep->getMaterialID();
- setTEMaterialID(te, material_id);
- }
+ LLTextureEntry* tep = getTE(te);
+ if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
+ {
+ LLMaterialID material_id = tep->getMaterialID();
+ setTEMaterialID(te, material_id);
+ }
}
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
- // TODO: Should this default to something valid?
- // Maybe volume?
- LLPCode pcode = 0;
-
- switch (legacy)
- {
- /*
- case BOX:
- pcode = LL_PCODE_CUBE;
- break;
- case CYLINDER:
- pcode = LL_PCODE_CYLINDER;
- break;
- case CONE:
- pcode = LL_PCODE_CONE;
- break;
- case HALF_CONE:
- pcode = LL_PCODE_CONE_HEMI;
- break;
- case HALF_CYLINDER:
- pcode = LL_PCODE_CYLINDER_HEMI;
- break;
- case HALF_SPHERE:
- pcode = LL_PCODE_SPHERE_HEMI;
- break;
- case PRISM:
- pcode = LL_PCODE_PRISM;
- break;
- case PYRAMID:
- pcode = LL_PCODE_PYRAMID;
- break;
- case SPHERE:
- pcode = LL_PCODE_SPHERE;
- break;
- case TETRAHEDRON:
- pcode = LL_PCODE_TETRAHEDRON;
- break;
- case DEMON:
- pcode = LL_PCODE_LEGACY_DEMON;
- break;
- case LSL_TEST:
- pcode = LL_PCODE_LEGACY_LSL_TEST;
- break;
- case ORACLE:
- pcode = LL_PCODE_LEGACY_ORACLE;
- break;
- case TEXTBUBBLE:
- pcode = LL_PCODE_LEGACY_TEXT_BUBBLE;
- break;
- case ATOR:
- pcode = LL_PCODE_LEGACY_ATOR;
- break;
- case BASIC_SHOT:
- pcode = LL_PCODE_LEGACY_SHOT;
- break;
- case BIG_SHOT:
- pcode = LL_PCODE_LEGACY_SHOT_BIG;
- break;
- case BIRD:
- pcode = LL_PCODE_LEGACY_BIRD;
- break;
- case ROCK:
- pcode = LL_PCODE_LEGACY_ROCK;
- break;
- case SMOKE:
- pcode = LL_PCODE_LEGACY_SMOKE;
- break;
- case SPARK:
- pcode = LL_PCODE_LEGACY_SPARK;
- break;
- */
- case PRIMITIVE_VOLUME:
- pcode = LL_PCODE_VOLUME;
- break;
- case GRASS:
- pcode = LL_PCODE_LEGACY_GRASS;
- break;
- case PART_SYS:
- pcode = LL_PCODE_LEGACY_PART_SYS;
- break;
- case PLAYER:
- pcode = LL_PCODE_LEGACY_AVATAR;
- break;
- case TREE:
- pcode = LL_PCODE_LEGACY_TREE;
- break;
- case TREE_NEW:
- pcode = LL_PCODE_TREE_NEW;
- break;
- default:
- LL_WARNS() << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << LL_ENDL;
- }
-
- return pcode;
+ // TODO: Should this default to something valid?
+ // Maybe volume?
+ LLPCode pcode = 0;
+
+ switch (legacy)
+ {
+ /*
+ case BOX:
+ pcode = LL_PCODE_CUBE;
+ break;
+ case CYLINDER:
+ pcode = LL_PCODE_CYLINDER;
+ break;
+ case CONE:
+ pcode = LL_PCODE_CONE;
+ break;
+ case HALF_CONE:
+ pcode = LL_PCODE_CONE_HEMI;
+ break;
+ case HALF_CYLINDER:
+ pcode = LL_PCODE_CYLINDER_HEMI;
+ break;
+ case HALF_SPHERE:
+ pcode = LL_PCODE_SPHERE_HEMI;
+ break;
+ case PRISM:
+ pcode = LL_PCODE_PRISM;
+ break;
+ case PYRAMID:
+ pcode = LL_PCODE_PYRAMID;
+ break;
+ case SPHERE:
+ pcode = LL_PCODE_SPHERE;
+ break;
+ case TETRAHEDRON:
+ pcode = LL_PCODE_TETRAHEDRON;
+ break;
+ case DEMON:
+ pcode = LL_PCODE_LEGACY_DEMON;
+ break;
+ case LSL_TEST:
+ pcode = LL_PCODE_LEGACY_LSL_TEST;
+ break;
+ case ORACLE:
+ pcode = LL_PCODE_LEGACY_ORACLE;
+ break;
+ case TEXTBUBBLE:
+ pcode = LL_PCODE_LEGACY_TEXT_BUBBLE;
+ break;
+ case ATOR:
+ pcode = LL_PCODE_LEGACY_ATOR;
+ break;
+ case BASIC_SHOT:
+ pcode = LL_PCODE_LEGACY_SHOT;
+ break;
+ case BIG_SHOT:
+ pcode = LL_PCODE_LEGACY_SHOT_BIG;
+ break;
+ case BIRD:
+ pcode = LL_PCODE_LEGACY_BIRD;
+ break;
+ case ROCK:
+ pcode = LL_PCODE_LEGACY_ROCK;
+ break;
+ case SMOKE:
+ pcode = LL_PCODE_LEGACY_SMOKE;
+ break;
+ case SPARK:
+ pcode = LL_PCODE_LEGACY_SPARK;
+ break;
+ */
+ case PRIMITIVE_VOLUME:
+ pcode = LL_PCODE_VOLUME;
+ break;
+ case GRASS:
+ pcode = LL_PCODE_LEGACY_GRASS;
+ break;
+ case PART_SYS:
+ pcode = LL_PCODE_LEGACY_PART_SYS;
+ break;
+ case PLAYER:
+ pcode = LL_PCODE_LEGACY_AVATAR;
+ break;
+ case TREE:
+ pcode = LL_PCODE_LEGACY_TREE;
+ break;
+ case TREE_NEW:
+ pcode = LL_PCODE_TREE_NEW;
+ break;
+ default:
+ LL_WARNS() << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << LL_ENDL;
+ }
+
+ return pcode;
}
U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode)
{
- U8 legacy;
- switch (pcode)
- {
+ U8 legacy;
+ switch (pcode)
+ {
/*
- case LL_PCODE_CUBE:
- legacy = BOX;
- break;
- case LL_PCODE_CYLINDER:
- legacy = CYLINDER;
- break;
- case LL_PCODE_CONE:
- legacy = CONE;
- break;
- case LL_PCODE_CONE_HEMI:
- legacy = HALF_CONE;
- break;
- case LL_PCODE_CYLINDER_HEMI:
- legacy = HALF_CYLINDER;
- break;
- case LL_PCODE_SPHERE_HEMI:
- legacy = HALF_SPHERE;
- break;
- case LL_PCODE_PRISM:
- legacy = PRISM;
- break;
- case LL_PCODE_PYRAMID:
- legacy = PYRAMID;
- break;
- case LL_PCODE_SPHERE:
- legacy = SPHERE;
- break;
- case LL_PCODE_TETRAHEDRON:
- legacy = TETRAHEDRON;
- break;
- case LL_PCODE_LEGACY_ATOR:
- legacy = ATOR;
- break;
- case LL_PCODE_LEGACY_SHOT:
- legacy = BASIC_SHOT;
- break;
- case LL_PCODE_LEGACY_SHOT_BIG:
- legacy = BIG_SHOT;
- break;
- case LL_PCODE_LEGACY_BIRD:
- legacy = BIRD;
- break;
- case LL_PCODE_LEGACY_DEMON:
- legacy = DEMON;
- break;
- case LL_PCODE_LEGACY_LSL_TEST:
- legacy = LSL_TEST;
- break;
- case LL_PCODE_LEGACY_ORACLE:
- legacy = ORACLE;
- break;
- case LL_PCODE_LEGACY_ROCK:
- legacy = ROCK;
- break;
- case LL_PCODE_LEGACY_TEXT_BUBBLE:
- legacy = TEXTBUBBLE;
- break;
- case LL_PCODE_LEGACY_SMOKE:
- legacy = SMOKE;
- break;
- case LL_PCODE_LEGACY_SPARK:
- legacy = SPARK;
- break;
+ case LL_PCODE_CUBE:
+ legacy = BOX;
+ break;
+ case LL_PCODE_CYLINDER:
+ legacy = CYLINDER;
+ break;
+ case LL_PCODE_CONE:
+ legacy = CONE;
+ break;
+ case LL_PCODE_CONE_HEMI:
+ legacy = HALF_CONE;
+ break;
+ case LL_PCODE_CYLINDER_HEMI:
+ legacy = HALF_CYLINDER;
+ break;
+ case LL_PCODE_SPHERE_HEMI:
+ legacy = HALF_SPHERE;
+ break;
+ case LL_PCODE_PRISM:
+ legacy = PRISM;
+ break;
+ case LL_PCODE_PYRAMID:
+ legacy = PYRAMID;
+ break;
+ case LL_PCODE_SPHERE:
+ legacy = SPHERE;
+ break;
+ case LL_PCODE_TETRAHEDRON:
+ legacy = TETRAHEDRON;
+ break;
+ case LL_PCODE_LEGACY_ATOR:
+ legacy = ATOR;
+ break;
+ case LL_PCODE_LEGACY_SHOT:
+ legacy = BASIC_SHOT;
+ break;
+ case LL_PCODE_LEGACY_SHOT_BIG:
+ legacy = BIG_SHOT;
+ break;
+ case LL_PCODE_LEGACY_BIRD:
+ legacy = BIRD;
+ break;
+ case LL_PCODE_LEGACY_DEMON:
+ legacy = DEMON;
+ break;
+ case LL_PCODE_LEGACY_LSL_TEST:
+ legacy = LSL_TEST;
+ break;
+ case LL_PCODE_LEGACY_ORACLE:
+ legacy = ORACLE;
+ break;
+ case LL_PCODE_LEGACY_ROCK:
+ legacy = ROCK;
+ break;
+ case LL_PCODE_LEGACY_TEXT_BUBBLE:
+ legacy = TEXTBUBBLE;
+ break;
+ case LL_PCODE_LEGACY_SMOKE:
+ legacy = SMOKE;
+ break;
+ case LL_PCODE_LEGACY_SPARK:
+ legacy = SPARK;
+ break;
*/
- case LL_PCODE_VOLUME:
- legacy = PRIMITIVE_VOLUME;
- break;
- case LL_PCODE_LEGACY_GRASS:
- legacy = GRASS;
- break;
- case LL_PCODE_LEGACY_PART_SYS:
- legacy = PART_SYS;
- break;
- case LL_PCODE_LEGACY_AVATAR:
- legacy = PLAYER;
- break;
- case LL_PCODE_LEGACY_TREE:
- legacy = TREE;
- break;
- case LL_PCODE_TREE_NEW:
- legacy = TREE_NEW;
- break;
- default:
- LL_WARNS() << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << LL_ENDL;
- return 0;
- }
- return legacy;
+ case LL_PCODE_VOLUME:
+ legacy = PRIMITIVE_VOLUME;
+ break;
+ case LL_PCODE_LEGACY_GRASS:
+ legacy = GRASS;
+ break;
+ case LL_PCODE_LEGACY_PART_SYS:
+ legacy = PART_SYS;
+ break;
+ case LL_PCODE_LEGACY_AVATAR:
+ legacy = PLAYER;
+ break;
+ case LL_PCODE_LEGACY_TREE:
+ legacy = TREE;
+ break;
+ case LL_PCODE_TREE_NEW:
+ legacy = TREE_NEW;
+ break;
+ default:
+ LL_WARNS() << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << LL_ENDL;
+ return 0;
+ }
+ return legacy;
}
@@ -632,491 +632,491 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode)
// Don't crash or LL_ERRS() here! This function is used for debug strings.
std::string LLPrimitive::pCodeToString(const LLPCode pcode)
{
- std::string pcode_string;
-
- U8 base_code = pcode & LL_PCODE_BASE_MASK;
- if (!pcode)
- {
- pcode_string = "null";
- }
- else if ((base_code) == LL_PCODE_LEGACY)
- {
- // It's a legacy object
- switch (pcode)
- {
- case LL_PCODE_LEGACY_GRASS:
- pcode_string = "grass";
- break;
- case LL_PCODE_LEGACY_PART_SYS:
- pcode_string = "particle system";
- break;
- case LL_PCODE_LEGACY_AVATAR:
- pcode_string = "avatar";
- break;
- case LL_PCODE_LEGACY_TEXT_BUBBLE:
- pcode_string = "text bubble";
- break;
- case LL_PCODE_LEGACY_TREE:
- pcode_string = "tree";
- break;
- case LL_PCODE_TREE_NEW:
- pcode_string = "tree_new";
- break;
- default:
- pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode);
- }
- }
- else
- {
- std::string shape;
- std::string mask;
- if (base_code == LL_PCODE_CUBE)
- {
- shape = "cube";
- }
- else if (base_code == LL_PCODE_CYLINDER)
- {
- shape = "cylinder";
- }
- else if (base_code == LL_PCODE_CONE)
- {
- shape = "cone";
- }
- else if (base_code == LL_PCODE_PRISM)
- {
- shape = "prism";
- }
- else if (base_code == LL_PCODE_PYRAMID)
- {
- shape = "pyramid";
- }
- else if (base_code == LL_PCODE_SPHERE)
- {
- shape = "sphere";
- }
- else if (base_code == LL_PCODE_TETRAHEDRON)
- {
- shape = "tetrahedron";
- }
- else if (base_code == LL_PCODE_VOLUME)
- {
- shape = "volume";
- }
- else if (base_code == LL_PCODE_APP)
- {
- shape = "app";
- }
- else
- {
- LL_WARNS() << "Unknown base mask for pcode: " << base_code << LL_ENDL;
- }
-
- U8 mask_code = pcode & (~LL_PCODE_BASE_MASK);
- if (base_code == LL_PCODE_APP)
- {
- mask = llformat( "%x", mask_code);
- }
- else if (mask_code & LL_PCODE_HEMI_MASK)
- {
- mask = "hemi";
- }
- else
- {
- mask = llformat( "%x", mask_code);
- }
-
- if (mask[0])
- {
- pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str());
- }
- else
- {
- pcode_string = llformat( "%s", shape.c_str());
- }
- }
-
- return pcode_string;
+ std::string pcode_string;
+
+ U8 base_code = pcode & LL_PCODE_BASE_MASK;
+ if (!pcode)
+ {
+ pcode_string = "null";
+ }
+ else if ((base_code) == LL_PCODE_LEGACY)
+ {
+ // It's a legacy object
+ switch (pcode)
+ {
+ case LL_PCODE_LEGACY_GRASS:
+ pcode_string = "grass";
+ break;
+ case LL_PCODE_LEGACY_PART_SYS:
+ pcode_string = "particle system";
+ break;
+ case LL_PCODE_LEGACY_AVATAR:
+ pcode_string = "avatar";
+ break;
+ case LL_PCODE_LEGACY_TEXT_BUBBLE:
+ pcode_string = "text bubble";
+ break;
+ case LL_PCODE_LEGACY_TREE:
+ pcode_string = "tree";
+ break;
+ case LL_PCODE_TREE_NEW:
+ pcode_string = "tree_new";
+ break;
+ default:
+ pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode);
+ }
+ }
+ else
+ {
+ std::string shape;
+ std::string mask;
+ if (base_code == LL_PCODE_CUBE)
+ {
+ shape = "cube";
+ }
+ else if (base_code == LL_PCODE_CYLINDER)
+ {
+ shape = "cylinder";
+ }
+ else if (base_code == LL_PCODE_CONE)
+ {
+ shape = "cone";
+ }
+ else if (base_code == LL_PCODE_PRISM)
+ {
+ shape = "prism";
+ }
+ else if (base_code == LL_PCODE_PYRAMID)
+ {
+ shape = "pyramid";
+ }
+ else if (base_code == LL_PCODE_SPHERE)
+ {
+ shape = "sphere";
+ }
+ else if (base_code == LL_PCODE_TETRAHEDRON)
+ {
+ shape = "tetrahedron";
+ }
+ else if (base_code == LL_PCODE_VOLUME)
+ {
+ shape = "volume";
+ }
+ else if (base_code == LL_PCODE_APP)
+ {
+ shape = "app";
+ }
+ else
+ {
+ LL_WARNS() << "Unknown base mask for pcode: " << base_code << LL_ENDL;
+ }
+
+ U8 mask_code = pcode & (~LL_PCODE_BASE_MASK);
+ if (base_code == LL_PCODE_APP)
+ {
+ mask = llformat( "%x", mask_code);
+ }
+ else if (mask_code & LL_PCODE_HEMI_MASK)
+ {
+ mask = "hemi";
+ }
+ else
+ {
+ mask = llformat( "%x", mask_code);
+ }
+
+ if (mask[0])
+ {
+ pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str());
+ }
+ else
+ {
+ pcode_string = llformat( "%s", shape.c_str());
+ }
+ }
+
+ return pcode_string;
}
void LLPrimitive::copyTEs(const LLPrimitive *primitivep)
{
- U32 i;
- if (primitivep->getExpectedNumTEs() != getExpectedNumTEs())
- {
- LL_WARNS() << "Primitives don't have same expected number of TE's" << LL_ENDL;
- }
- U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs());
- if (mTextureList.size() < getExpectedNumTEs())
- {
- mTextureList.setSize(getExpectedNumTEs());
- }
- for (i = 0; i < num_tes; i++)
- {
- mTextureList.copyTexture(i, *(primitivep->getTE(i)));
- }
-}
-
-S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& faceArray)
-{
- S32 i;
- for (i = 0; i < (S32)faceArray.size(); i++)
- {
- if (faceArray[i].mFaceID == face_ID)
- {
- return i;
- }
- }
- return -1;
+ U32 i;
+ if (primitivep->getExpectedNumTEs() != getExpectedNumTEs())
+ {
+ LL_WARNS() << "Primitives don't have same expected number of TE's" << LL_ENDL;
+ }
+ U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs());
+ if (mTextureList.size() < getExpectedNumTEs())
+ {
+ mTextureList.setSize(getExpectedNumTEs());
+ }
+ for (i = 0; i < num_tes; i++)
+ {
+ mTextureList.copyTexture(i, *(primitivep->getTE(i)));
+ }
+}
+
+S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& faceArray)
+{
+ S32 i;
+ for (i = 0; i < (S32)faceArray.size(); i++)
+ {
+ if (faceArray[i].mFaceID == face_ID)
+ {
+ return i;
+ }
+ }
+ return -1;
}
BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
{
- if (NO_LOD == detail)
- {
- // build the new object
- setChanged(GEOMETRY);
- sVolumeManager->unrefVolume(mVolumep);
- mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE);
- setNumTEs(mVolumep->getNumFaces());
- return FALSE;
- }
-
- LLVolume *volumep;
- if (unique_volume)
- {
- F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
- if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
- {
- return FALSE;
- }
- volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE);
- }
- else
- {
- if (mVolumep.notNull())
- {
- F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
- if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
- {
- return FALSE;
- }
- }
-
- volumep = sVolumeManager->refVolume(volume_params, detail);
- if (volumep == mVolumep)
- {
- sVolumeManager->unrefVolume( volumep ); // LLVolumeMgr::refVolume() creates a reference, but we don't need a second one.
- return TRUE;
- }
- }
-
- setChanged(GEOMETRY);
-
-
- if (!mVolumep)
- {
- mVolumep = volumep;
- //mFaceMask = mVolumep->generateFaceMask();
- setNumTEs(mVolumep->getNumFaces());
- return TRUE;
- }
-
-#if 0
- // #if 0'd out by davep
- // this is a lot of cruft to set texture entry values that just stay the same for LOD switch
- // or immediately get overridden by an object update message, also crashes occasionally
- U32 old_face_mask = mVolumep->mFaceMask;
-
- S32 face_bit = 0;
- S32 cur_mask = 0;
-
- // Grab copies of the old faces from the original shape, ordered by type.
- // We will use these to figure out what old texture info gets mapped to new
- // faces in the new shape.
- std::vector<LLProfile::Face> old_faces;
- for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
- {
- old_faces.push_back(mVolumep->getProfile().mFaces[face]);
- }
-
- // Copy the old texture info off to the side, but not in the order in which
- // they live in the mTextureList, rather in order of ther "face id" which
- // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex.
- //
- // Hence, some elements of old_tes::mEntryList will be invalid. It is
- // initialized to a size of 9 (max number of possible faces on a volume?)
- // and only the ones with valid types are filled in.
- LLPrimTextureList old_tes;
- old_tes.setSize(9);
- for (face_bit = 0; face_bit < 9; face_bit++)
- {
- cur_mask = 0x1 << face_bit;
- if (old_face_mask & cur_mask)
- {
- S32 te_index = face_index_from_id(cur_mask, old_faces);
- old_tes.copyTexture(face_bit, *(getTE(te_index)));
- //LL_INFOS() << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << LL_ENDL;
- }
- }
-
-
- // build the new object
- sVolumeManager->unrefVolume(mVolumep);
- mVolumep = volumep;
-
- U32 new_face_mask = mVolumep->mFaceMask;
- S32 i;
-
- if (old_face_mask == new_face_mask)
- {
- // nothing to do
- return TRUE;
- }
-
- if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)
- {
- LL_WARNS() << "Object with 0 faces found...INCORRECT!" << LL_ENDL;
- setNumTEs(mVolumep->getNumFaces());
- return TRUE;
- }
-
- // initialize face_mapping
- S32 face_mapping[9];
- for (face_bit = 0; face_bit < 9; face_bit++)
- {
- face_mapping[face_bit] = face_bit;
- }
-
- // The new shape may have more faces than the original, but we can't just
- // add them to the end -- the ordering matters and it may be that we must
- // insert the new faces in the middle of the list. When we add a face it
- // will pick up the texture/color info of one of the old faces an so we
- // now figure out which old face info gets mapped to each new face, and
- // store in the face_mapping lookup table.
- for (face_bit = 0; face_bit < 9; face_bit++)
- {
- cur_mask = 0x1 << face_bit;
- if (!(new_face_mask & cur_mask))
- {
- // Face doesn't exist in new map.
- face_mapping[face_bit] = -1;
- continue;
- }
- else if (old_face_mask & cur_mask)
- {
- // Face exists in new and old map.
- face_mapping[face_bit] = face_bit;
- continue;
- }
-
- // OK, how we've got a mismatch, where we have to fill a new face with one from
- // the old face.
- if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
- {
- // It's a top/bottom/hollow interior face.
- if (old_face_mask & LL_FACE_PATH_END)
- {
- face_mapping[face_bit] = 1;
- continue;
- }
- else
- {
- S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
- for (i = 0; i < 4; i++)
- {
- if (old_face_mask & cur_outer_mask)
- {
- face_mapping[face_bit] = 5 + i;
- break;
- }
- cur_outer_mask <<= 1;
- }
- if (i == 4)
- {
- LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL;
- }
- continue;
- }
- }
-
- if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
- {
- // A cut slice. Use the hollow interior if we have it.
- if (old_face_mask & LL_FACE_INNER_SIDE)
- {
- face_mapping[face_bit] = 2;
- continue;
- }
-
- // No interior, use the bottom face.
- // Could figure out which of the outer faces was nearest, but that would be harder.
- if (old_face_mask & LL_FACE_PATH_END)
- {
- face_mapping[face_bit] = 1;
- continue;
- }
- else
- {
- S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
- for (i = 0; i < 4; i++)
- {
- if (old_face_mask & cur_outer_mask)
- {
- face_mapping[face_bit] = 5 + i;
- break;
- }
- cur_outer_mask <<= 1;
- }
- if (i == 4)
- {
- LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL;
- }
- continue;
- }
- }
-
- // OK, the face that's missing is an outer face...
- // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
- S32 cur_outer = face_bit - 5;
- S32 min_dist = 5;
- S32 min_outer_bit = -1;
- S32 i;
- for (i = 0; i < 4; i++)
- {
- if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
- {
- S32 dist = abs(i - cur_outer);
- if (dist < min_dist)
- {
- min_dist = dist;
- min_outer_bit = i + 5;
- }
- }
- }
- if (-1 == min_outer_bit)
- {
- LL_INFOS() << (LLVolume *)mVolumep << LL_ENDL;
- LL_WARNS() << "Bad! No outer faces, impossible!" << LL_ENDL;
- }
- face_mapping[face_bit] = min_outer_bit;
- }
-
-
- setNumTEs(mVolumep->getNumFaces());
- for (face_bit = 0; face_bit < 9; face_bit++)
- {
- // For each possible face type on the new shape we check to see if that
- // face exists and if it does we create a texture entry that is a copy
- // of one of the originals. Since the originals might not have a
- // matching face, we use the face_mapping lookup table to figure out
- // which face information to copy.
- cur_mask = 0x1 << face_bit;
- if (new_face_mask & cur_mask)
- {
- if (-1 == face_mapping[face_bit])
- {
- LL_WARNS() << "No mapping from old face to new face!" << LL_ENDL;
- }
-
- S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
- setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit])));
- }
- }
+ if (NO_LOD == detail)
+ {
+ // build the new object
+ setChanged(GEOMETRY);
+ sVolumeManager->unrefVolume(mVolumep);
+ mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE);
+ setNumTEs(mVolumep->getNumFaces());
+ return FALSE;
+ }
+
+ LLVolume *volumep;
+ if (unique_volume)
+ {
+ F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
+ if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
+ {
+ return FALSE;
+ }
+ volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE);
+ }
+ else
+ {
+ if (mVolumep.notNull())
+ {
+ F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
+ if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
+ {
+ return FALSE;
+ }
+ }
+
+ volumep = sVolumeManager->refVolume(volume_params, detail);
+ if (volumep == mVolumep)
+ {
+ sVolumeManager->unrefVolume( volumep ); // LLVolumeMgr::refVolume() creates a reference, but we don't need a second one.
+ return TRUE;
+ }
+ }
+
+ setChanged(GEOMETRY);
+
+
+ if (!mVolumep)
+ {
+ mVolumep = volumep;
+ //mFaceMask = mVolumep->generateFaceMask();
+ setNumTEs(mVolumep->getNumFaces());
+ return TRUE;
+ }
+
+#if 0
+ // #if 0'd out by davep
+ // this is a lot of cruft to set texture entry values that just stay the same for LOD switch
+ // or immediately get overridden by an object update message, also crashes occasionally
+ U32 old_face_mask = mVolumep->mFaceMask;
+
+ S32 face_bit = 0;
+ S32 cur_mask = 0;
+
+ // Grab copies of the old faces from the original shape, ordered by type.
+ // We will use these to figure out what old texture info gets mapped to new
+ // faces in the new shape.
+ std::vector<LLProfile::Face> old_faces;
+ for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
+ {
+ old_faces.push_back(mVolumep->getProfile().mFaces[face]);
+ }
+
+ // Copy the old texture info off to the side, but not in the order in which
+ // they live in the mTextureList, rather in order of ther "face id" which
+ // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex.
+ //
+ // Hence, some elements of old_tes::mEntryList will be invalid. It is
+ // initialized to a size of 9 (max number of possible faces on a volume?)
+ // and only the ones with valid types are filled in.
+ LLPrimTextureList old_tes;
+ old_tes.setSize(9);
+ for (face_bit = 0; face_bit < 9; face_bit++)
+ {
+ cur_mask = 0x1 << face_bit;
+ if (old_face_mask & cur_mask)
+ {
+ S32 te_index = face_index_from_id(cur_mask, old_faces);
+ old_tes.copyTexture(face_bit, *(getTE(te_index)));
+ //LL_INFOS() << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << LL_ENDL;
+ }
+ }
+
+
+ // build the new object
+ sVolumeManager->unrefVolume(mVolumep);
+ mVolumep = volumep;
+
+ U32 new_face_mask = mVolumep->mFaceMask;
+ S32 i;
+
+ if (old_face_mask == new_face_mask)
+ {
+ // nothing to do
+ return TRUE;
+ }
+
+ if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)
+ {
+ LL_WARNS() << "Object with 0 faces found...INCORRECT!" << LL_ENDL;
+ setNumTEs(mVolumep->getNumFaces());
+ return TRUE;
+ }
+
+ // initialize face_mapping
+ S32 face_mapping[9];
+ for (face_bit = 0; face_bit < 9; face_bit++)
+ {
+ face_mapping[face_bit] = face_bit;
+ }
+
+ // The new shape may have more faces than the original, but we can't just
+ // add them to the end -- the ordering matters and it may be that we must
+ // insert the new faces in the middle of the list. When we add a face it
+ // will pick up the texture/color info of one of the old faces an so we
+ // now figure out which old face info gets mapped to each new face, and
+ // store in the face_mapping lookup table.
+ for (face_bit = 0; face_bit < 9; face_bit++)
+ {
+ cur_mask = 0x1 << face_bit;
+ if (!(new_face_mask & cur_mask))
+ {
+ // Face doesn't exist in new map.
+ face_mapping[face_bit] = -1;
+ continue;
+ }
+ else if (old_face_mask & cur_mask)
+ {
+ // Face exists in new and old map.
+ face_mapping[face_bit] = face_bit;
+ continue;
+ }
+
+ // OK, how we've got a mismatch, where we have to fill a new face with one from
+ // the old face.
+ if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
+ {
+ // It's a top/bottom/hollow interior face.
+ if (old_face_mask & LL_FACE_PATH_END)
+ {
+ face_mapping[face_bit] = 1;
+ continue;
+ }
+ else
+ {
+ S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
+ for (i = 0; i < 4; i++)
+ {
+ if (old_face_mask & cur_outer_mask)
+ {
+ face_mapping[face_bit] = 5 + i;
+ break;
+ }
+ cur_outer_mask <<= 1;
+ }
+ if (i == 4)
+ {
+ LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL;
+ }
+ continue;
+ }
+ }
+
+ if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
+ {
+ // A cut slice. Use the hollow interior if we have it.
+ if (old_face_mask & LL_FACE_INNER_SIDE)
+ {
+ face_mapping[face_bit] = 2;
+ continue;
+ }
+
+ // No interior, use the bottom face.
+ // Could figure out which of the outer faces was nearest, but that would be harder.
+ if (old_face_mask & LL_FACE_PATH_END)
+ {
+ face_mapping[face_bit] = 1;
+ continue;
+ }
+ else
+ {
+ S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
+ for (i = 0; i < 4; i++)
+ {
+ if (old_face_mask & cur_outer_mask)
+ {
+ face_mapping[face_bit] = 5 + i;
+ break;
+ }
+ cur_outer_mask <<= 1;
+ }
+ if (i == 4)
+ {
+ LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL;
+ }
+ continue;
+ }
+ }
+
+ // OK, the face that's missing is an outer face...
+ // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
+ S32 cur_outer = face_bit - 5;
+ S32 min_dist = 5;
+ S32 min_outer_bit = -1;
+ S32 i;
+ for (i = 0; i < 4; i++)
+ {
+ if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
+ {
+ S32 dist = abs(i - cur_outer);
+ if (dist < min_dist)
+ {
+ min_dist = dist;
+ min_outer_bit = i + 5;
+ }
+ }
+ }
+ if (-1 == min_outer_bit)
+ {
+ LL_INFOS() << (LLVolume *)mVolumep << LL_ENDL;
+ LL_WARNS() << "Bad! No outer faces, impossible!" << LL_ENDL;
+ }
+ face_mapping[face_bit] = min_outer_bit;
+ }
+
+
+ setNumTEs(mVolumep->getNumFaces());
+ for (face_bit = 0; face_bit < 9; face_bit++)
+ {
+ // For each possible face type on the new shape we check to see if that
+ // face exists and if it does we create a texture entry that is a copy
+ // of one of the originals. Since the originals might not have a
+ // matching face, we use the face_mapping lookup table to figure out
+ // which face information to copy.
+ cur_mask = 0x1 << face_bit;
+ if (new_face_mask & cur_mask)
+ {
+ if (-1 == face_mapping[face_bit])
+ {
+ LL_WARNS() << "No mapping from old face to new face!" << LL_ENDL;
+ }
+
+ S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
+ setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit])));
+ }
+ }
#else
- // build the new object
- sVolumeManager->unrefVolume(mVolumep);
- mVolumep = volumep;
+ // build the new object
+ sVolumeManager->unrefVolume(mVolumep);
+ mVolumep = volumep;
- setNumTEs(mVolumep->getNumFaces());
+ setNumTEs(mVolumep->getNumFaces());
#endif
- return TRUE;
+ return TRUE;
}
BOOL LLPrimitive::setMaterial(U8 material)
{
- if (material != mMaterial)
- {
- mMaterial = material;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ if (material != mMaterial)
+ {
+ mMaterial = material;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const
{
- S32 face_index;
- S32 i;
- U64 exception_faces;
- U8 *start_loc = cur_ptr;
-
- htolememcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size);
- cur_ptr += data_size;
-
- for (face_index = last_face_index-1; face_index >= 0; face_index--)
- {
- BOOL already_sent = FALSE;
- for (i = face_index+1; i <= last_face_index; i++)
- {
- if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
- {
- already_sent = TRUE;
- break;
- }
- }
-
- if (!already_sent)
- {
- exception_faces = 0;
- for (i = face_index; i >= 0; i--)
- {
- if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
- {
- exception_faces |= ((U64)1 << i);
- }
- }
-
- //assign exception faces to cur_ptr
- if (exception_faces >= ((U64)0x1 << 7))
- {
- if (exception_faces >= ((U64)0x1 << 14))
- {
- if (exception_faces >= ((U64)0x1 << 21))
- {
- if (exception_faces >= ((U64)0x1 << 28))
- {
- if (exception_faces >= ((U64)0x1 << 35))
- {
- if (exception_faces >= ((U64)0x1 << 42))
- {
- if (exception_faces >= ((U64)0x1 << 49))
- {
- *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80);
- }
- *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
- }
-
-
- *cur_ptr++ = (U8)(exception_faces & 0x7F);
-
- htolememcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size);
- cur_ptr += data_size;
- }
- }
- return (S32)(cur_ptr - start_loc);
+ S32 face_index;
+ S32 i;
+ U64 exception_faces;
+ U8 *start_loc = cur_ptr;
+
+ htolememcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size);
+ cur_ptr += data_size;
+
+ for (face_index = last_face_index-1; face_index >= 0; face_index--)
+ {
+ BOOL already_sent = FALSE;
+ for (i = face_index+1; i <= last_face_index; i++)
+ {
+ if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
+ {
+ already_sent = TRUE;
+ break;
+ }
+ }
+
+ if (!already_sent)
+ {
+ exception_faces = 0;
+ for (i = face_index; i >= 0; i--)
+ {
+ if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
+ {
+ exception_faces |= ((U64)1 << i);
+ }
+ }
+
+ //assign exception faces to cur_ptr
+ if (exception_faces >= ((U64)0x1 << 7))
+ {
+ if (exception_faces >= ((U64)0x1 << 14))
+ {
+ if (exception_faces >= ((U64)0x1 << 21))
+ {
+ if (exception_faces >= ((U64)0x1 << 28))
+ {
+ if (exception_faces >= ((U64)0x1 << 35))
+ {
+ if (exception_faces >= ((U64)0x1 << 42))
+ {
+ if (exception_faces >= ((U64)0x1 << 49))
+ {
+ *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80);
+ }
+ *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
+ }
+
+
+ *cur_ptr++ = (U8)(exception_faces & 0x7F);
+
+ htolememcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size);
+ cur_ptr += data_size;
+ }
+ }
+ return (S32)(cur_ptr - start_loc);
}
namespace
@@ -1136,7 +1136,7 @@ namespace
return false;
}
- // Extract the default value and fill the array.
+ // Extract the default value and fill the array.
htolememcpy(dest, source, type, size);
source += size;
for (S32 idx = 1; idx < dest_count; ++idx)
@@ -1149,7 +1149,7 @@ namespace
U64 index_flags(0);
U8 sbit(0);
- // Unpack the variable length bitfield. Each bit represents whether the following
+ // Unpack the variable length bitfield. Each bit represents whether the following
// value will be placed at the corresponding array index.
do
{
@@ -1203,194 +1203,194 @@ namespace
// Includes information about image ID, color, scale S,T, offset S,T and rotation
BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
{
- const U32 MAX_TES = 45;
-
- U8 image_ids[MAX_TES*16];
- U8 colors[MAX_TES*4];
- F32 scale_s[MAX_TES];
- F32 scale_t[MAX_TES];
- S16 offset_s[MAX_TES];
- S16 offset_t[MAX_TES];
- S16 image_rot[MAX_TES];
- U8 bump[MAX_TES];
- U8 media_flags[MAX_TES];
+ const U32 MAX_TES = 45;
+
+ U8 image_ids[MAX_TES*16];
+ U8 colors[MAX_TES*4];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
+ S16 offset_s[MAX_TES];
+ S16 offset_t[MAX_TES];
+ S16 image_rot[MAX_TES];
+ U8 bump[MAX_TES];
+ U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
- U8 material_data[MAX_TES*16];
-
- const U32 MAX_TE_BUFFER = 4096;
- U8 packed_buffer[MAX_TE_BUFFER];
- U8 *cur_ptr = packed_buffer;
-
- S32 last_face_index = llmin((U32) getNumTEs(), MAX_TES) - 1;
-
- if (last_face_index > -1)
- {
- // ...if we hit the front, send one image id
- S8 face_index;
- LLColor4U coloru;
- for (face_index = 0; face_index <= last_face_index; face_index++)
- {
- // Directly sending image_ids is not safe!
- memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
-
- // Cast LLColor4 to LLColor4U
- coloru.setVec( getTE(face_index)->getColor() );
-
- // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
- // as all zeros. However, the subtraction and addition must be done in unsigned
- // byte space, not in float space, otherwise off-by-one errors occur. JC
- colors[4*face_index] = 255 - coloru.mV[0];
- colors[4*face_index + 1] = 255 - coloru.mV[1];
- colors[4*face_index + 2] = 255 - coloru.mV[2];
- colors[4*face_index + 3] = 255 - coloru.mV[3];
-
- const LLTextureEntry* te = getTE(face_index);
- scale_s[face_index] = (F32) te->mScaleS;
- scale_t[face_index] = (F32) te->mScaleT;
- offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
- offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
- image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
- bump[face_index] = te->getBumpShinyFullbright();
- media_flags[face_index] = te->getMediaTexGen();
- glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
-
- // Directly sending material_ids is not safe!
- memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
- }
-
- cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
- }
- mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
-
- return FALSE;
+ U8 material_data[MAX_TES*16];
+
+ const U32 MAX_TE_BUFFER = 4096;
+ U8 packed_buffer[MAX_TE_BUFFER];
+ U8 *cur_ptr = packed_buffer;
+
+ S32 last_face_index = llmin((U32) getNumTEs(), MAX_TES) - 1;
+
+ if (last_face_index > -1)
+ {
+ // ...if we hit the front, send one image id
+ S8 face_index;
+ LLColor4U coloru;
+ for (face_index = 0; face_index <= last_face_index; face_index++)
+ {
+ // Directly sending image_ids is not safe!
+ memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
+
+ // Cast LLColor4 to LLColor4U
+ coloru.setVec( getTE(face_index)->getColor() );
+
+ // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
+ // as all zeros. However, the subtraction and addition must be done in unsigned
+ // byte space, not in float space, otherwise off-by-one errors occur. JC
+ colors[4*face_index] = 255 - coloru.mV[0];
+ colors[4*face_index + 1] = 255 - coloru.mV[1];
+ colors[4*face_index + 2] = 255 - coloru.mV[2];
+ colors[4*face_index + 3] = 255 - coloru.mV[3];
+
+ const LLTextureEntry* te = getTE(face_index);
+ scale_s[face_index] = (F32) te->mScaleS;
+ scale_t[face_index] = (F32) te->mScaleT;
+ offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
+ offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
+ image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
+ bump[face_index] = te->getBumpShinyFullbright();
+ media_flags[face_index] = te->getMediaTexGen();
+ glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
+ }
+
+ cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
+ }
+ mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
+
+ return FALSE;
}
BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
{
- const U32 MAX_TES = 45;
-
- U8 image_ids[MAX_TES*16];
- U8 colors[MAX_TES*4];
- F32 scale_s[MAX_TES];
- F32 scale_t[MAX_TES];
- S16 offset_s[MAX_TES];
- S16 offset_t[MAX_TES];
- S16 image_rot[MAX_TES];
- U8 bump[MAX_TES];
- U8 media_flags[MAX_TES];
+ const U32 MAX_TES = 45;
+
+ U8 image_ids[MAX_TES*16];
+ U8 colors[MAX_TES*4];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
+ S16 offset_s[MAX_TES];
+ S16 offset_t[MAX_TES];
+ S16 image_rot[MAX_TES];
+ U8 bump[MAX_TES];
+ U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
- U8 material_data[MAX_TES*16];
-
- const U32 MAX_TE_BUFFER = 4096;
- U8 packed_buffer[MAX_TE_BUFFER];
- U8 *cur_ptr = packed_buffer;
-
- S32 last_face_index = getNumTEs() - 1;
-
- if (last_face_index > -1)
- {
- // ...if we hit the front, send one image id
- S8 face_index;
- LLColor4U coloru;
- for (face_index = 0; face_index <= last_face_index; face_index++)
- {
- // Directly sending image_ids is not safe!
- memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
-
- // Cast LLColor4 to LLColor4U
- coloru.setVec( getTE(face_index)->getColor() );
-
- // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
- // as all zeros. However, the subtraction and addition must be done in unsigned
- // byte space, not in float space, otherwise off-by-one errors occur. JC
- colors[4*face_index] = 255 - coloru.mV[0];
- colors[4*face_index + 1] = 255 - coloru.mV[1];
- colors[4*face_index + 2] = 255 - coloru.mV[2];
- colors[4*face_index + 3] = 255 - coloru.mV[3];
-
- const LLTextureEntry* te = getTE(face_index);
- scale_s[face_index] = (F32) te->mScaleS;
- scale_t[face_index] = (F32) te->mScaleT;
- offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
- offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
- image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
- bump[face_index] = te->getBumpShinyFullbright();
- media_flags[face_index] = te->getMediaTexGen();
+ U8 material_data[MAX_TES*16];
+
+ const U32 MAX_TE_BUFFER = 4096;
+ U8 packed_buffer[MAX_TE_BUFFER];
+ U8 *cur_ptr = packed_buffer;
+
+ S32 last_face_index = getNumTEs() - 1;
+
+ if (last_face_index > -1)
+ {
+ // ...if we hit the front, send one image id
+ S8 face_index;
+ LLColor4U coloru;
+ for (face_index = 0; face_index <= last_face_index; face_index++)
+ {
+ // Directly sending image_ids is not safe!
+ memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
+
+ // Cast LLColor4 to LLColor4U
+ coloru.setVec( getTE(face_index)->getColor() );
+
+ // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
+ // as all zeros. However, the subtraction and addition must be done in unsigned
+ // byte space, not in float space, otherwise off-by-one errors occur. JC
+ colors[4*face_index] = 255 - coloru.mV[0];
+ colors[4*face_index + 1] = 255 - coloru.mV[1];
+ colors[4*face_index + 2] = 255 - coloru.mV[2];
+ colors[4*face_index + 3] = 255 - coloru.mV[3];
+
+ const LLTextureEntry* te = getTE(face_index);
+ scale_s[face_index] = (F32) te->mScaleS;
+ scale_t[face_index] = (F32) te->mScaleT;
+ offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
+ offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
+ image_rot[face_index] = (S16) ll_round(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
+ bump[face_index] = te->getBumpShinyFullbright();
+ media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
- // Directly sending material_ids is not safe!
- memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
- }
-
- cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
- *cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
- }
-
- dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
- return FALSE;
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
+ }
+
+ cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
+ }
+
+ dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
+ return FALSE;
}
S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
{
- S32 retval = 0;
+ S32 retval = 0;
// temp buffer for material ID processing
- // data will end up in tec.material_id[]
+ // data will end up in tec.material_id[]
material_id_type material_data[LLTEContents::MAX_TES];
- if (block_num < 0)
- {
- tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
- }
- else
- {
- tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
- }
-
- if (tec.size == 0)
- {
- tec.face_count = 0;
- return retval;
- }
+ if (block_num < 0)
+ {
+ tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
+ }
+ else
+ {
+ tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
+ }
+
+ if (tec.size == 0)
+ {
+ tec.face_count = 0;
+ return retval;
+ }
else if (tec.size >= LLTEContents::MAX_TE_BUFFER)
{
LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL;
@@ -1400,14 +1400,14 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name
// if block_num < 0 ask for block 0
mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, std::max(block_num, 0), LLTEContents::MAX_TE_BUFFER - 1);
- // The last field is not zero terminated.
+ // The last field is not zero terminated.
// Rather than special case the upack functions. Just make it 0x00 terminated.
tec.packed_buffer[tec.size] = 0x00;
++tec.size;
- tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
+ tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
- U8 *cur_ptr = tec.packed_buffer;
+ U8 *cur_ptr = tec.packed_buffer;
LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffere sized: " << tec.size << LL_ENDL;
U8 *buffer_end = tec.packed_buffer + tec.size;
@@ -1426,68 +1426,68 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name
return 0;
}
- if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID))
- {
- memset((void*)material_data, 0, sizeof(material_data));
- }
-
- for (U32 i = 0; i < tec.face_count; i++)
- {
- tec.material_ids[i].set(&(material_data[i]));
- }
-
- retval = 1;
- return retval;
- }
-
+ if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID))
+ {
+ memset((void*)material_data, 0, sizeof(material_data));
+ }
+
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ tec.material_ids[i].set(&(material_data[i]));
+ }
+
+ retval = 1;
+ return retval;
+ }
+
S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
{
- S32 retval = 0;
-
- LLColor4 color;
- for (U32 i = 0; i < tec.face_count; i++)
- {
- LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
- retval |= setTETexture(i, req_id);
- retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
- retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF);
- retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
- retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
- retval |= setTEMediaTexGen(i, tec.media_flags[i]);
- retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
- retval |= setTEMaterialID(i, tec.material_ids[i]);
-
- // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
- // as all zeros. However, the subtraction and addition must be done in unsigned
- // byte space, not in float space, otherwise off-by-one errors occur. JC
- color.mV[VRED] = F32(255 - tec.colors[i].mV[VRED]) / 255.f;
- color.mV[VGREEN] = F32(255 - tec.colors[i].mV[VGREEN]) / 255.f;
- color.mV[VBLUE] = F32(255 - tec.colors[i].mV[VBLUE]) / 255.f;
- color.mV[VALPHA] = F32(255 - tec.colors[i].mV[VALPHA]) / 255.f;
-
- retval |= setTEColor(i, color);
- }
-
- return retval;
+ S32 retval = 0;
+
+ LLColor4 color;
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
+ retval |= setTETexture(i, req_id);
+ retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
+ retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF);
+ retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
+ retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
+ retval |= setTEMediaTexGen(i, tec.media_flags[i]);
+ retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, tec.material_ids[i]);
+
+ // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
+ // as all zeros. However, the subtraction and addition must be done in unsigned
+ // byte space, not in float space, otherwise off-by-one errors occur. JC
+ color.mV[VRED] = F32(255 - tec.colors[i].mV[VRED]) / 255.f;
+ color.mV[VGREEN] = F32(255 - tec.colors[i].mV[VGREEN]) / 255.f;
+ color.mV[VBLUE] = F32(255 - tec.colors[i].mV[VBLUE]) / 255.f;
+ color.mV[VALPHA] = F32(255 - tec.colors[i].mV[VALPHA]) / 255.f;
+
+ retval |= setTEColor(i, color);
+ }
+
+ return retval;
}
S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
{
- LLTEContents tec;
- S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
- if (!retval)
- return retval;
- return applyParsedTEMessage(tec);
+ LLTEContents tec;
+ S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
+ if (!retval)
+ return retval;
+ return applyParsedTEMessage(tec);
}
S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
{
- // use a negative block_num to indicate a single-block read (a non-variable block)
- S32 retval = 0;
- const U32 MAX_TES = 45;
+ // use a negative block_num to indicate a single-block read (a non-variable block)
+ S32 retval = 0;
+ const U32 MAX_TES = 45;
- // Avoid construction of 32 UUIDs per call
- static LLMaterialID material_ids[MAX_TES];
+ // Avoid construction of 32 UUIDs per call
+ static LLMaterialID material_ids[MAX_TES];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1504,7 +1504,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
material_id_type material_data[MAX_TES];
-
+
memset((void*)scale_s, 0, sizeof(scale_s));
memset((void*)scale_t, 0, sizeof(scale_t));
memset((void*)offset_s, 0, sizeof(offset_s));
@@ -1514,32 +1514,32 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
memset((void*)media_flags, 0, sizeof(media_flags));
memset((void*)glow, 0, sizeof(glow));
- S32 size;
- U32 face_count = 0;
+ S32 size;
+ U32 face_count = 0;
- if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry"))
- {
- retval = TEM_INVALID;
- LL_WARNS() << "Bad texture entry block! Abort!" << LL_ENDL;
- return retval;
- }
+ if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry"))
+ {
+ retval = TEM_INVALID;
+ LL_WARNS() << "Bad texture entry block! Abort!" << LL_ENDL;
+ return retval;
+ }
- if (size == 0)
- {
- return retval;
- }
+ if (size == 0)
+ {
+ return retval;
+ }
else if (size >= MAX_TE_BUFFER)
{
LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL;
size = MAX_TE_BUFFER - 1;
}
- // The last field is not zero terminated.
+ // The last field is not zero terminated.
// Rather than special case the upack functions. Just make it 0x00 terminated.
packed_buffer[size] = 0x00;
++size;
- face_count = llmin((U32) getNumTEs(), MAX_TES);
- U32 i;
+ face_count = llmin((U32) getNumTEs(), MAX_TES);
+ U32 i;
U8 *cur_ptr = packed_buffer;
LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffer sized: " << size << LL_ENDL;
@@ -1560,81 +1560,81 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
return 0;
}
- if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, face_count, cur_ptr, buffer_end, MVT_LLUUID))
- {
- memset((void*)material_data, 0, sizeof(material_data));
- }
-
- for (i = 0; i < face_count; i++)
- {
- material_ids[i].set(&(material_data[i]));
- }
+ if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, face_count, cur_ptr, buffer_end, MVT_LLUUID))
+ {
+ memset((void*)material_data, 0, sizeof(material_data));
+ }
- LLColor4 color;
- for (i = 0; i < face_count; i++)
- {
+ for (i = 0; i < face_count; i++)
+ {
+ material_ids[i].set(&(material_data[i]));
+ }
+
+ LLColor4 color;
+ for (i = 0; i < face_count; i++)
+ {
retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
- retval |= setTEScale(i, scale_s[i], scale_t[i]);
- retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
- retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
- retval |= setTEBumpShinyFullbright(i, bump[i]);
- retval |= setTEMediaTexGen(i, media_flags[i]);
- retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
- retval |= setTEMaterialID(i, material_ids[i]);
-
- // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
- // as all zeros. However, the subtraction and addition must be done in unsigned
- // byte space, not in float space, otherwise off-by-one errors occur. JC
- color.mV[VRED] = F32(255 - colors[i].mV[VRED]) / 255.f;
- color.mV[VGREEN] = F32(255 - colors[i].mV[VGREEN]) / 255.f;
- color.mV[VBLUE] = F32(255 - colors[i].mV[VBLUE]) / 255.f;
- color.mV[VALPHA] = F32(255 - colors[i].mV[VALPHA]) / 255.f;
-
- retval |= setTEColor(i, color);
- }
+ retval |= setTEScale(i, scale_s[i], scale_t[i]);
+ retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
+ retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
+ retval |= setTEBumpShinyFullbright(i, bump[i]);
+ retval |= setTEMediaTexGen(i, media_flags[i]);
+ retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, material_ids[i]);
+
+ // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
+ // as all zeros. However, the subtraction and addition must be done in unsigned
+ // byte space, not in float space, otherwise off-by-one errors occur. JC
+ color.mV[VRED] = F32(255 - colors[i].mV[VRED]) / 255.f;
+ color.mV[VGREEN] = F32(255 - colors[i].mV[VGREEN]) / 255.f;
+ color.mV[VBLUE] = F32(255 - colors[i].mV[VBLUE]) / 255.f;
+ color.mV[VALPHA] = F32(255 - colors[i].mV[VALPHA]) / 255.f;
+
+ retval |= setTEColor(i, color);
+ }
- return retval;
+ return retval;
}
-U8 LLPrimitive::getExpectedNumTEs() const
+U8 LLPrimitive::getExpectedNumTEs() const
{
- U8 expected_face_count = 0;
- if (mVolumep)
- {
- expected_face_count = mVolumep->getNumFaces();
- }
- return expected_face_count;
+ U8 expected_face_count = 0;
+ if (mVolumep)
+ {
+ expected_face_count = mVolumep->getNumFaces();
+ }
+ return expected_face_count;
}
void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list)
{
- mTextureList.copy(other_list);
+ mTextureList.copy(other_list);
}
void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
{
- mTextureList.take(other_list);
+ mTextureList.take(other_list);
}
void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump)
{
- LLTextureEntry* te = getTE(index);
- if(!te)
- {
- return;
- }
+ LLTextureEntry* te = getTE(index);
+ if(!te)
+ {
+ return;
+ }
- U8 old_bump = te->getBumpmap();
- if(old_bump > 0)
- {
- mNumBumpmapTEs--;
- }
- if((bump & TEM_BUMP_MASK) > 0)
- {
- mNumBumpmapTEs++;
- }
+ U8 old_bump = te->getBumpmap();
+ if(old_bump > 0)
+ {
+ mNumBumpmapTEs--;
+ }
+ if((bump & TEM_BUMP_MASK) > 0)
+ {
+ mNumBumpmapTEs++;
+ }
- return;
+ return;
}
//============================================================================
@@ -1645,180 +1645,180 @@ void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump)
// static
bool LLPrimitive::getTESTAxes(const U8 face, U32* s_axis, U32* t_axis)
{
- if (face == 0)
- {
- *s_axis = VX; *t_axis = VY;
- return true;
- }
- else if (face == 1)
- {
- *s_axis = VX; *t_axis = VZ;
- return true;
- }
- else if (face == 2)
- {
- *s_axis = VY; *t_axis = VZ;
- return true;
- }
- else if (face == 3)
- {
- *s_axis = VX; *t_axis = VZ;
- return true;
- }
- else if (face == 4)
- {
- *s_axis = VY; *t_axis = VZ;
- return true;
- }
- else if (face >= 5)
- {
- *s_axis = VX; *t_axis = VY;
- return true;
- }
- else
- {
- // unknown face
- return false;
- }
+ if (face == 0)
+ {
+ *s_axis = VX; *t_axis = VY;
+ return true;
+ }
+ else if (face == 1)
+ {
+ *s_axis = VX; *t_axis = VZ;
+ return true;
+ }
+ else if (face == 2)
+ {
+ *s_axis = VY; *t_axis = VZ;
+ return true;
+ }
+ else if (face == 3)
+ {
+ *s_axis = VX; *t_axis = VZ;
+ return true;
+ }
+ else if (face == 4)
+ {
+ *s_axis = VY; *t_axis = VZ;
+ return true;
+ }
+ else if (face >= 5)
+ {
+ *s_axis = VX; *t_axis = VY;
+ return true;
+ }
+ else
+ {
+ // unknown face
+ return false;
+ }
}
//============================================================================
-//static
+//static
BOOL LLNetworkData::isValid(U16 param_type, U32 size)
{
- // ew - better mechanism needed
-
- switch(param_type)
- {
- case PARAMS_FLEXIBLE:
- return (size == 16);
- case PARAMS_LIGHT:
- return (size == 16);
- case PARAMS_SCULPT:
- return (size == 17);
- case PARAMS_LIGHT_IMAGE:
- return (size == 28);
+ // ew - better mechanism needed
+
+ switch(param_type)
+ {
+ case PARAMS_FLEXIBLE:
+ return (size == 16);
+ case PARAMS_LIGHT:
+ return (size == 16);
+ case PARAMS_SCULPT:
+ return (size == 17);
+ case PARAMS_LIGHT_IMAGE:
+ return (size == 28);
case PARAMS_EXTENDED_MESH:
return (size == 4);
case PARAMS_RENDER_MATERIAL:
return (size > 1);
case PARAMS_REFLECTION_PROBE:
return (size == 9);
- }
-
- return FALSE;
+ }
+
+ return FALSE;
}
//============================================================================
LLLightParams::LLLightParams()
{
- mColor.setToWhite();
- mRadius = 10.f;
- mCutoff = 0.0f;
- mFalloff = 0.75f;
+ mColor.setToWhite();
+ mRadius = 10.f;
+ mCutoff = 0.0f;
+ mFalloff = 0.75f;
- mType = PARAMS_LIGHT;
+ mType = PARAMS_LIGHT;
}
BOOL LLLightParams::pack(LLDataPacker &dp) const
{
- LLColor4U color4u(mColor);
- dp.packColor4U(color4u, "color");
- dp.packF32(mRadius, "radius");
- dp.packF32(mCutoff, "cutoff");
- dp.packF32(mFalloff, "falloff");
- return TRUE;
+ LLColor4U color4u(mColor);
+ dp.packColor4U(color4u, "color");
+ dp.packF32(mRadius, "radius");
+ dp.packF32(mCutoff, "cutoff");
+ dp.packF32(mFalloff, "falloff");
+ return TRUE;
}
BOOL LLLightParams::unpack(LLDataPacker &dp)
{
- LLColor4U color;
- dp.unpackColor4U(color, "color");
- setLinearColor(LLColor4(color));
-
- F32 radius;
- dp.unpackF32(radius, "radius");
- setRadius(radius);
+ LLColor4U color;
+ dp.unpackColor4U(color, "color");
+ setLinearColor(LLColor4(color));
- F32 cutoff;
- dp.unpackF32(cutoff, "cutoff");
- setCutoff(cutoff);
+ F32 radius;
+ dp.unpackF32(radius, "radius");
+ setRadius(radius);
- F32 falloff;
- dp.unpackF32(falloff, "falloff");
- setFalloff(falloff);
+ F32 cutoff;
+ dp.unpackF32(cutoff, "cutoff");
+ setCutoff(cutoff);
- return TRUE;
+ F32 falloff;
+ dp.unpackF32(falloff, "falloff");
+ setFalloff(falloff);
+
+ return TRUE;
}
bool LLLightParams::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_LIGHT)
- {
- return false;
- }
- const LLLightParams *param = (const LLLightParams*)&data;
- if (param->mColor != mColor ||
- param->mRadius != mRadius ||
- param->mCutoff != mCutoff ||
- param->mFalloff != mFalloff)
- {
- return false;
- }
- return true;
+ if (data.mType != PARAMS_LIGHT)
+ {
+ return false;
+ }
+ const LLLightParams *param = (const LLLightParams*)&data;
+ if (param->mColor != mColor ||
+ param->mRadius != mRadius ||
+ param->mCutoff != mCutoff ||
+ param->mFalloff != mFalloff)
+ {
+ return false;
+ }
+ return true;
}
void LLLightParams::copy(const LLNetworkData& data)
{
- const LLLightParams *param = (LLLightParams*)&data;
- mType = param->mType;
- mColor = param->mColor;
- mRadius = param->mRadius;
- mCutoff = param->mCutoff;
- mFalloff = param->mFalloff;
+ const LLLightParams *param = (LLLightParams*)&data;
+ mType = param->mType;
+ mColor = param->mColor;
+ mRadius = param->mRadius;
+ mCutoff = param->mCutoff;
+ mFalloff = param->mFalloff;
}
LLSD LLLightParams::asLLSD() const
{
- LLSD sd;
-
- sd["color"] = ll_sd_from_color4(getLinearColor());
- sd["radius"] = getRadius();
- sd["falloff"] = getFalloff();
- sd["cutoff"] = getCutoff();
-
- return sd;
+ LLSD sd;
+
+ sd["color"] = ll_sd_from_color4(getLinearColor());
+ sd["radius"] = getRadius();
+ sd["falloff"] = getFalloff();
+ sd["cutoff"] = getCutoff();
+
+ return sd;
}
bool LLLightParams::fromLLSD(LLSD& sd)
{
- const char *w;
- w = "color";
- if (sd.has(w))
- {
- setLinearColor( ll_color4_from_sd(sd["color"]) );
- } else goto fail;
- w = "radius";
- if (sd.has(w))
- {
- setRadius( (F32)sd[w].asReal() );
- } else goto fail;
- w = "falloff";
- if (sd.has(w))
- {
- setFalloff( (F32)sd[w].asReal() );
- } else goto fail;
- w = "cutoff";
- if (sd.has(w))
- {
- setCutoff( (F32)sd[w].asReal() );
- } else goto fail;
-
- return true;
+ const char *w;
+ w = "color";
+ if (sd.has(w))
+ {
+ setLinearColor( ll_color4_from_sd(sd["color"]) );
+ } else goto fail;
+ w = "radius";
+ if (sd.has(w))
+ {
+ setRadius( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "falloff";
+ if (sd.has(w))
+ {
+ setFalloff( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "cutoff";
+ if (sd.has(w))
+ {
+ setCutoff( (F32)sd[w].asReal() );
+ } else goto fail;
+
+ return true;
fail:
- return false;
+ return false;
}
//============================================================================
@@ -1832,39 +1832,39 @@ LLReflectionProbeParams::LLReflectionProbeParams()
BOOL LLReflectionProbeParams::pack(LLDataPacker &dp) const
{
- dp.packF32(mAmbiance, "ambiance");
+ dp.packF32(mAmbiance, "ambiance");
dp.packF32(mClipDistance, "clip_distance");
dp.packU8(mFlags, "flags");
- return TRUE;
+ return TRUE;
}
BOOL LLReflectionProbeParams::unpack(LLDataPacker &dp)
{
- F32 ambiance;
+ F32 ambiance;
F32 clip_distance;
- dp.unpackF32(ambiance, "ambiance");
- setAmbiance(ambiance);
-
+ dp.unpackF32(ambiance, "ambiance");
+ setAmbiance(ambiance);
+
dp.unpackF32(clip_distance, "clip_distance");
- setClipDistance(clip_distance);
-
+ setClipDistance(clip_distance);
+
dp.unpackU8(mFlags, "flags");
-
- return TRUE;
+
+ return TRUE;
}
bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_REFLECTION_PROBE)
- {
- return false;
- }
- const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data;
- if (param->mAmbiance != mAmbiance)
- {
- return false;
- }
+ if (data.mType != PARAMS_REFLECTION_PROBE)
+ {
+ return false;
+ }
+ const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data;
+ if (param->mAmbiance != mAmbiance)
+ {
+ return false;
+ }
if (param->mClipDistance != mClipDistance)
{
return false;
@@ -1873,25 +1873,25 @@ bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
{
return false;
}
- return true;
+ return true;
}
void LLReflectionProbeParams::copy(const LLNetworkData& data)
{
- const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data;
- mType = param->mType;
- mAmbiance = param->mAmbiance;
+ const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data;
+ mType = param->mType;
+ mAmbiance = param->mAmbiance;
mClipDistance = param->mClipDistance;
mFlags = param->mFlags;
}
LLSD LLReflectionProbeParams::asLLSD() const
{
- LLSD sd;
- sd["ambiance"] = getAmbiance();
+ LLSD sd;
+ sd["ambiance"] = getAmbiance();
sd["clip_distance"] = getClipDistance();
sd["flags"] = mFlags;
- return sd;
+ return sd;
}
bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
@@ -1903,10 +1903,10 @@ bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
return false;
}
- setAmbiance((F32)sd["ambiance"].asReal());
+ setAmbiance((F32)sd["ambiance"].asReal());
setClipDistance((F32)sd["clip_distance"].asReal());
mFlags = (U8) sd["flags"].asInteger();
-
+
return true;
}
@@ -1934,315 +1934,328 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic)
}
}
+
+void LLReflectionProbeParams::setIsMirror(bool is_mirror)
+{
+ if (is_mirror)
+ {
+ mFlags |= FLAG_MIRROR;
+ }
+ else
+ {
+ mFlags &= ~FLAG_MIRROR;
+ }
+}
+
//============================================================================
LLFlexibleObjectData::LLFlexibleObjectData()
{
- mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
- mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY;
- mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION;
- mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY;
- mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION;
- //mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE;
- //mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
- mUserForce = LLVector3(0.f, 0.f, 0.f);
+ mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
+ mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY;
+ mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION;
+ mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY;
+ mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION;
+ //mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE;
+ //mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
+ mUserForce = LLVector3(0.f, 0.f, 0.f);
- mType = PARAMS_FLEXIBLE;
+ mType = PARAMS_FLEXIBLE;
}
BOOL LLFlexibleObjectData::pack(LLDataPacker &dp) const
{
- // Custom, uber-svelte pack "softness" in upper bits of tension & drag
- U8 bit1 = (mSimulateLOD & 2) << 6;
- U8 bit2 = (mSimulateLOD & 1) << 7;
- dp.packU8((U8)(mTension*10.01f) + bit1, "tension");
- dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag");
- dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity");
- dp.packU8((U8)(mWindSensitivity*10.01f), "wind");
- dp.packVector3(mUserForce, "userforce");
- return TRUE;
+ // Custom, uber-svelte pack "softness" in upper bits of tension & drag
+ U8 bit1 = (mSimulateLOD & 2) << 6;
+ U8 bit2 = (mSimulateLOD & 1) << 7;
+ dp.packU8((U8)(mTension*10.01f) + bit1, "tension");
+ dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag");
+ dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity");
+ dp.packU8((U8)(mWindSensitivity*10.01f), "wind");
+ dp.packVector3(mUserForce, "userforce");
+ return TRUE;
}
BOOL LLFlexibleObjectData::unpack(LLDataPacker &dp)
{
- U8 tension, friction, gravity, wind;
- U8 bit1, bit2;
- dp.unpackU8(tension, "tension"); bit1 = (tension >> 6) & 2;
- mTension = ((F32)(tension&0x7f))/10.f;
- dp.unpackU8(friction, "drag"); bit2 = (friction >> 7) & 1;
- mAirFriction = ((F32)(friction&0x7f))/10.f;
- mSimulateLOD = bit1 | bit2;
- dp.unpackU8(gravity, "gravity"); mGravity = ((F32)gravity)/10.f - 10.f;
- dp.unpackU8(wind, "wind"); mWindSensitivity = ((F32)wind)/10.f;
- if (dp.hasNext())
- {
- dp.unpackVector3(mUserForce, "userforce");
- }
- else
- {
- mUserForce.setVec(0.f, 0.f, 0.f);
- }
- return TRUE;
+ U8 tension, friction, gravity, wind;
+ U8 bit1, bit2;
+ dp.unpackU8(tension, "tension"); bit1 = (tension >> 6) & 2;
+ mTension = ((F32)(tension&0x7f))/10.f;
+ dp.unpackU8(friction, "drag"); bit2 = (friction >> 7) & 1;
+ mAirFriction = ((F32)(friction&0x7f))/10.f;
+ mSimulateLOD = bit1 | bit2;
+ dp.unpackU8(gravity, "gravity"); mGravity = ((F32)gravity)/10.f - 10.f;
+ dp.unpackU8(wind, "wind"); mWindSensitivity = ((F32)wind)/10.f;
+ if (dp.hasNext())
+ {
+ dp.unpackVector3(mUserForce, "userforce");
+ }
+ else
+ {
+ mUserForce.setVec(0.f, 0.f, 0.f);
+ }
+ return TRUE;
}
bool LLFlexibleObjectData::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_FLEXIBLE)
- {
- return false;
- }
- LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
- return (mSimulateLOD == flex_data->mSimulateLOD &&
- mGravity == flex_data->mGravity &&
- mAirFriction == flex_data->mAirFriction &&
- mWindSensitivity == flex_data->mWindSensitivity &&
- mTension == flex_data->mTension &&
- mUserForce == flex_data->mUserForce);
- //mUsingCollisionSphere == flex_data->mUsingCollisionSphere &&
- //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere
+ if (data.mType != PARAMS_FLEXIBLE)
+ {
+ return false;
+ }
+ LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
+ return (mSimulateLOD == flex_data->mSimulateLOD &&
+ mGravity == flex_data->mGravity &&
+ mAirFriction == flex_data->mAirFriction &&
+ mWindSensitivity == flex_data->mWindSensitivity &&
+ mTension == flex_data->mTension &&
+ mUserForce == flex_data->mUserForce);
+ //mUsingCollisionSphere == flex_data->mUsingCollisionSphere &&
+ //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere
}
void LLFlexibleObjectData::copy(const LLNetworkData& data)
{
- const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
- mSimulateLOD = flex_data->mSimulateLOD;
- mGravity = flex_data->mGravity;
- mAirFriction = flex_data->mAirFriction;
- mWindSensitivity = flex_data->mWindSensitivity;
- mTension = flex_data->mTension;
- mUserForce = flex_data->mUserForce;
- //mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
- //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
+ const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
+ mSimulateLOD = flex_data->mSimulateLOD;
+ mGravity = flex_data->mGravity;
+ mAirFriction = flex_data->mAirFriction;
+ mWindSensitivity = flex_data->mWindSensitivity;
+ mTension = flex_data->mTension;
+ mUserForce = flex_data->mUserForce;
+ //mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
+ //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
}
LLSD LLFlexibleObjectData::asLLSD() const
{
- LLSD sd;
+ LLSD sd;
- sd["air_friction"] = getAirFriction();
- sd["gravity"] = getGravity();
- sd["simulate_lod"] = getSimulateLOD();
- sd["tension"] = getTension();
- sd["user_force"] = getUserForce().getValue();
- sd["wind_sensitivity"] = getWindSensitivity();
-
- return sd;
+ sd["air_friction"] = getAirFriction();
+ sd["gravity"] = getGravity();
+ sd["simulate_lod"] = getSimulateLOD();
+ sd["tension"] = getTension();
+ sd["user_force"] = getUserForce().getValue();
+ sd["wind_sensitivity"] = getWindSensitivity();
+
+ return sd;
}
bool LLFlexibleObjectData::fromLLSD(LLSD& sd)
{
- const char *w;
- w = "air_friction";
- if (sd.has(w))
- {
- setAirFriction( (F32)sd[w].asReal() );
- } else goto fail;
- w = "gravity";
- if (sd.has(w))
- {
- setGravity( (F32)sd[w].asReal() );
- } else goto fail;
- w = "simulate_lod";
- if (sd.has(w))
- {
- setSimulateLOD( sd[w].asInteger() );
- } else goto fail;
- w = "tension";
- if (sd.has(w))
- {
- setTension( (F32)sd[w].asReal() );
- } else goto fail;
- w = "user_force";
- if (sd.has(w))
- {
- LLVector3 user_force = ll_vector3_from_sd(sd[w], 0);
- setUserForce( user_force );
- } else goto fail;
- w = "wind_sensitivity";
- if (sd.has(w))
- {
- setWindSensitivity( (F32)sd[w].asReal() );
- } else goto fail;
-
- return true;
+ const char *w;
+ w = "air_friction";
+ if (sd.has(w))
+ {
+ setAirFriction( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "gravity";
+ if (sd.has(w))
+ {
+ setGravity( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "simulate_lod";
+ if (sd.has(w))
+ {
+ setSimulateLOD( sd[w].asInteger() );
+ } else goto fail;
+ w = "tension";
+ if (sd.has(w))
+ {
+ setTension( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "user_force";
+ if (sd.has(w))
+ {
+ LLVector3 user_force = ll_vector3_from_sd(sd[w], 0);
+ setUserForce( user_force );
+ } else goto fail;
+ w = "wind_sensitivity";
+ if (sd.has(w))
+ {
+ setWindSensitivity( (F32)sd[w].asReal() );
+ } else goto fail;
+
+ return true;
fail:
- return false;
+ return false;
}
//============================================================================
LLSculptParams::LLSculptParams()
{
- mType = PARAMS_SCULPT;
- mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
- mSculptType = LL_SCULPT_TYPE_SPHERE;
+ mType = PARAMS_SCULPT;
+ mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
+ mSculptType = LL_SCULPT_TYPE_SPHERE;
}
BOOL LLSculptParams::pack(LLDataPacker &dp) const
{
- dp.packUUID(mSculptTexture, "texture");
- dp.packU8(mSculptType, "type");
-
- return TRUE;
+ dp.packUUID(mSculptTexture, "texture");
+ dp.packU8(mSculptType, "type");
+
+ return TRUE;
}
BOOL LLSculptParams::unpack(LLDataPacker &dp)
{
- U8 type;
- LLUUID id;
- dp.unpackUUID(id, "texture");
- dp.unpackU8(type, "type");
+ U8 type;
+ LLUUID id;
+ dp.unpackUUID(id, "texture");
+ dp.unpackU8(type, "type");
- setSculptTexture(id, type);
- return TRUE;
+ setSculptTexture(id, type);
+ return TRUE;
}
bool LLSculptParams::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_SCULPT)
- {
- return false;
- }
-
- const LLSculptParams *param = (const LLSculptParams*)&data;
- if ( (param->mSculptTexture != mSculptTexture) ||
- (param->mSculptType != mSculptType) )
-
- {
- return false;
- }
-
- return true;
+ if (data.mType != PARAMS_SCULPT)
+ {
+ return false;
+ }
+
+ const LLSculptParams *param = (const LLSculptParams*)&data;
+ if ( (param->mSculptTexture != mSculptTexture) ||
+ (param->mSculptType != mSculptType) )
+
+ {
+ return false;
+ }
+
+ return true;
}
void LLSculptParams::copy(const LLNetworkData& data)
{
- const LLSculptParams *param = (LLSculptParams*)&data;
- setSculptTexture(param->mSculptTexture, param->mSculptType);
+ const LLSculptParams *param = (LLSculptParams*)&data;
+ setSculptTexture(param->mSculptTexture, param->mSculptType);
}
LLSD LLSculptParams::asLLSD() const
{
- LLSD sd;
-
- sd["texture"] = mSculptTexture;
- sd["type"] = mSculptType;
-
- return sd;
+ LLSD sd;
+
+ sd["texture"] = mSculptTexture;
+ sd["type"] = mSculptType;
+
+ return sd;
}
bool LLSculptParams::fromLLSD(LLSD& sd)
{
- const char *w;
- U8 type;
- w = "type";
- if (sd.has(w))
- {
- type = sd[w].asInteger();
- }
- else return false;
+ const char *w;
+ U8 type;
+ w = "type";
+ if (sd.has(w))
+ {
+ type = sd[w].asInteger();
+ }
+ else return false;
- w = "texture";
- if (sd.has(w))
- {
- setSculptTexture(sd[w], type);
- }
- else return false;
+ w = "texture";
+ if (sd.has(w))
+ {
+ setSculptTexture(sd[w], type);
+ }
+ else return false;
- return true;
+ return true;
}
void LLSculptParams::setSculptTexture(const LLUUID& texture_id, U8 sculpt_type)
{
- U8 type = sculpt_type & LL_SCULPT_TYPE_MASK;
- U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK;
- if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX)
- {
- mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
- mSculptType = LL_SCULPT_TYPE_SPHERE;
- }
- else
- {
- mSculptTexture = texture_id;
- mSculptType = sculpt_type;
- }
+ U8 type = sculpt_type & LL_SCULPT_TYPE_MASK;
+ U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK;
+ if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX)
+ {
+ mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
+ mSculptType = LL_SCULPT_TYPE_SPHERE;
+ }
+ else
+ {
+ mSculptTexture = texture_id;
+ mSculptType = sculpt_type;
+ }
}
//============================================================================
LLLightImageParams::LLLightImageParams()
{
- mType = PARAMS_LIGHT_IMAGE;
- mParams.setVec(F_PI*0.5f, 0.f, 0.f);
+ mType = PARAMS_LIGHT_IMAGE;
+ mParams.setVec(F_PI*0.5f, 0.f, 0.f);
}
BOOL LLLightImageParams::pack(LLDataPacker &dp) const
{
- dp.packUUID(mLightTexture, "texture");
- dp.packVector3(mParams, "params");
+ dp.packUUID(mLightTexture, "texture");
+ dp.packVector3(mParams, "params");
- return TRUE;
+ return TRUE;
}
BOOL LLLightImageParams::unpack(LLDataPacker &dp)
{
- dp.unpackUUID(mLightTexture, "texture");
- dp.unpackVector3(mParams, "params");
-
- return TRUE;
+ dp.unpackUUID(mLightTexture, "texture");
+ dp.unpackVector3(mParams, "params");
+
+ return TRUE;
}
bool LLLightImageParams::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_LIGHT_IMAGE)
- {
- return false;
- }
-
- const LLLightImageParams *param = (const LLLightImageParams*)&data;
- if ( (param->mLightTexture != mLightTexture) )
- {
- return false;
- }
-
- if ( (param->mParams != mParams ) )
- {
- return false;
- }
-
- return true;
+ if (data.mType != PARAMS_LIGHT_IMAGE)
+ {
+ return false;
+ }
+
+ const LLLightImageParams *param = (const LLLightImageParams*)&data;
+ if ( (param->mLightTexture != mLightTexture) )
+ {
+ return false;
+ }
+
+ if ( (param->mParams != mParams ) )
+ {
+ return false;
+ }
+
+ return true;
}
void LLLightImageParams::copy(const LLNetworkData& data)
{
- const LLLightImageParams *param = (LLLightImageParams*)&data;
- mLightTexture = param->mLightTexture;
- mParams = param->mParams;
+ const LLLightImageParams *param = (LLLightImageParams*)&data;
+ mLightTexture = param->mLightTexture;
+ mParams = param->mParams;
}
LLSD LLLightImageParams::asLLSD() const
{
- LLSD sd;
-
- sd["texture"] = mLightTexture;
- sd["params"] = mParams.getValue();
-
- return sd;
+ LLSD sd;
+
+ sd["texture"] = mLightTexture;
+ sd["params"] = mParams.getValue();
+
+ return sd;
}
bool LLLightImageParams::fromLLSD(LLSD& sd)
{
- if (sd.has("texture"))
- {
- setLightTexture( sd["texture"] );
- setParams( LLVector3( sd["params"] ) );
- return true;
- }
-
- return false;
+ if (sd.has("texture"))
+ {
+ setLightTexture( sd["texture"] );
+ setParams( LLVector3( sd["params"] ) );
+ return true;
+ }
+
+ return false;
}
//============================================================================
@@ -2250,63 +2263,63 @@ bool LLLightImageParams::fromLLSD(LLSD& sd)
LLExtendedMeshParams::LLExtendedMeshParams()
{
mType = PARAMS_EXTENDED_MESH;
- mFlags = 0;
+ mFlags = 0;
}
BOOL LLExtendedMeshParams::pack(LLDataPacker &dp) const
{
- dp.packU32(mFlags, "flags");
+ dp.packU32(mFlags, "flags");
- return TRUE;
+ return TRUE;
}
BOOL LLExtendedMeshParams::unpack(LLDataPacker &dp)
{
- dp.unpackU32(mFlags, "flags");
-
- return TRUE;
+ dp.unpackU32(mFlags, "flags");
+
+ return TRUE;
}
bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const
{
- if (data.mType != PARAMS_EXTENDED_MESH)
- {
- return false;
- }
+ if (data.mType != PARAMS_EXTENDED_MESH)
+ {
+ return false;
+ }
+
+ const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data;
+ if ( (param->mFlags != mFlags) )
+ {
+ return false;
+ }
- const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data;
- if ( (param->mFlags != mFlags) )
- {
- return false;
- }
-
- return true;
+ return true;
}
void LLExtendedMeshParams::copy(const LLNetworkData& data)
{
- const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data;
- mFlags = param->mFlags;
+ const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data;
+ mFlags = param->mFlags;
}
LLSD LLExtendedMeshParams::asLLSD() const
{
- LLSD sd;
-
- sd["flags"] = LLSD::Integer(mFlags);
-
- return sd;
+ LLSD sd;
+
+ sd["flags"] = LLSD::Integer(mFlags);
+
+ return sd;
}
bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
{
- if (sd.has("flags"))
- {
- setFlags( sd["flags"].asInteger());
- return true;
- }
-
- return false;
+ if (sd.has("flags"))
+ {
+ setFlags( sd["flags"].asInteger());
+ return true;
+ }
+
+ return false;
}
//============================================================================
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 9bc8b660d9..5622483861 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llprimitive.h
* @brief LLPrimitive base class
*
* $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$
*/
@@ -49,14 +49,14 @@ class LLVolumeMgr;
enum LLGeomType // NOTE: same vals as GL Ids
{
- LLInvalid = 0,
- LLLineLoop = 2,
- LLLineStrip = 3,
- LLTriangles = 4,
- LLTriStrip = 5,
- LLTriFan = 6,
- LLQuads = 7,
- LLQuadStrip = 8
+ LLInvalid = 0,
+ LLLineLoop = 2,
+ LLLineStrip = 3,
+ LLTriangles = 4,
+ LLTriStrip = 5,
+ LLTriFan = 6,
+ LLQuads = 7,
+ LLQuadStrip = 8
};
class LLVolume;
@@ -97,28 +97,28 @@ extern const char *SCULPT_DEFAULT_TEXTURE;
class LLNetworkData
{
public:
- // Extra parameter IDs
- enum
- {
- PARAMS_FLEXIBLE = 0x10,
- PARAMS_LIGHT = 0x20,
- PARAMS_SCULPT = 0x30,
- PARAMS_LIGHT_IMAGE = 0x40,
- PARAMS_RESERVED = 0x50, // Used on server-side
- PARAMS_MESH = 0x60,
+ // Extra parameter IDs
+ enum
+ {
+ PARAMS_FLEXIBLE = 0x10,
+ PARAMS_LIGHT = 0x20,
+ PARAMS_SCULPT = 0x30,
+ PARAMS_LIGHT_IMAGE = 0x40,
+ PARAMS_RESERVED = 0x50, // Used on server-side
+ PARAMS_MESH = 0x60,
PARAMS_EXTENDED_MESH = 0x70,
PARAMS_RENDER_MATERIAL = 0x80,
PARAMS_REFLECTION_PROBE = 0x90,
- };
-
+ };
+
public:
- U16 mType;
- virtual ~LLNetworkData() {};
- virtual BOOL pack(LLDataPacker &dp) const = 0;
- virtual BOOL unpack(LLDataPacker &dp) = 0;
- virtual bool operator==(const LLNetworkData& data) const = 0;
- virtual void copy(const LLNetworkData& data) = 0;
- static BOOL isValid(U16 param_type, U32 size);
+ U16 mType;
+ virtual ~LLNetworkData() {};
+ virtual BOOL pack(LLDataPacker &dp) const = 0;
+ virtual BOOL unpack(LLDataPacker &dp) = 0;
+ virtual bool operator==(const LLNetworkData& data) const = 0;
+ virtual void copy(const LLNetworkData& data) = 0;
+ static BOOL isValid(U16 param_type, U32 size);
};
extern const F32 LIGHT_MIN_RADIUS;
@@ -134,22 +134,22 @@ extern const F32 LIGHT_MAX_CUTOFF;
class LLLightParams : public LLNetworkData
{
private:
- LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity
- F32 mRadius;
- F32 mFalloff;
- F32 mCutoff;
+ LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity
+ F32 mRadius;
+ F32 mFalloff;
+ F32 mCutoff;
public:
- LLLightParams();
- /*virtual*/ BOOL pack(LLDataPacker &dp) const;
- /*virtual*/ BOOL unpack(LLDataPacker &dp);
- /*virtual*/ bool operator==(const LLNetworkData& data) const;
- /*virtual*/ void copy(const LLNetworkData& data);
- // LLSD implementations here are provided by Eddy Stryker.
- // NOTE: there are currently unused in protocols
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
+ LLLightParams();
+ /*virtual*/ BOOL pack(LLDataPacker &dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker &dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ // LLSD implementations here are provided by Eddy Stryker.
+ // NOTE: there are currently unused in protocols
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
// set the color by gamma corrected color value
// color - gamma corrected color value (directly taken from an on-screen color swatch)
@@ -157,19 +157,19 @@ public:
// set the color by linear color value
// color - linear color value (value as it appears in shaders)
- void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); }
- void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); }
- void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); }
- void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); }
+ void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); }
+ void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); }
+ void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); }
+ void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); }
// get the linear space color of this light. This value can be fed directly to shaders
- LLColor4 getLinearColor() const { return mColor; }
+ LLColor4 getLinearColor() const { return mColor; }
// get the sRGB (gamma corrected) color of this light, this is the value that should be displayed in the UI
- LLColor4 getSRGBColor() const { return srgbColor4(mColor); }
-
- F32 getRadius() const { return mRadius; }
- F32 getFalloff() const { return mFalloff; }
- F32 getCutoff() const { return mCutoff; }
+ LLColor4 getSRGBColor() const { return srgbColor4(mColor); }
+
+ F32 getRadius() const { return mRadius; }
+ F32 getFalloff() const { return mFalloff; }
+ F32 getCutoff() const { return mCutoff; }
};
extern const F32 REFLECTION_PROBE_MIN_AMBIANCE;
@@ -186,6 +186,7 @@ public:
{
FLAG_BOX_VOLUME = 0x01, // use a box influence volume
FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe
+ FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors.
};
protected:
@@ -209,15 +210,17 @@ public:
void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
void setIsBox(bool is_box);
void setIsDynamic(bool is_dynamic);
+ void setIsMirror(bool is_mirror);
F32 getAmbiance() const { return mAmbiance; }
F32 getClipDistance() const { return mClipDistance; }
bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; }
bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; }
+ bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; }
};
//-------------------------------------------------
-// This structure is also used in the part of the
+// This structure is also used in the part of the
// code that creates new flexible objects.
//-------------------------------------------------
@@ -225,11 +228,11 @@ public:
// array bounds.
enum EFlexibleObjectConst
{
- // "Softness" => [0,3], increments of 1
- // Represents powers of 2: 0 -> 1, 3 -> 8
- FLEXIBLE_OBJECT_MIN_SECTIONS = 0,
- FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS = 2,
- FLEXIBLE_OBJECT_MAX_SECTIONS = 3
+ // "Softness" => [0,3], increments of 1
+ // Represents powers of 2: 0 -> 1, 3 -> 8
+ FLEXIBLE_OBJECT_MIN_SECTIONS = 0,
+ FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS = 2,
+ FLEXIBLE_OBJECT_MAX_SECTIONS = 3
};
// "Tension" => [0,10], increments of 0.1
@@ -262,39 +265,39 @@ extern const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
class LLFlexibleObjectData : public LLNetworkData
{
protected:
- S32 mSimulateLOD; // 2^n = number of simulated sections
- F32 mGravity;
- F32 mAirFriction; // higher is more stable, but too much looks like it's underwater
- F32 mWindSensitivity; // interacts with tension, air friction, and gravity
- F32 mTension; //interacts in complex ways with other parameters
- LLVector3 mUserForce; // custom user-defined force vector
- //BOOL mUsingCollisionSphere;
- //BOOL mRenderingCollisionSphere;
+ S32 mSimulateLOD; // 2^n = number of simulated sections
+ F32 mGravity;
+ F32 mAirFriction; // higher is more stable, but too much looks like it's underwater
+ F32 mWindSensitivity; // interacts with tension, air friction, and gravity
+ F32 mTension; //interacts in complex ways with other parameters
+ LLVector3 mUserForce; // custom user-defined force vector
+ //BOOL mUsingCollisionSphere;
+ //BOOL mRenderingCollisionSphere;
public:
- void setSimulateLOD(S32 lod) { mSimulateLOD = llclamp(lod, (S32)FLEXIBLE_OBJECT_MIN_SECTIONS, (S32)FLEXIBLE_OBJECT_MAX_SECTIONS); }
- void setGravity(F32 gravity) { mGravity = llclamp(gravity, FLEXIBLE_OBJECT_MIN_GRAVITY, FLEXIBLE_OBJECT_MAX_GRAVITY); }
- void setAirFriction(F32 friction) { mAirFriction = llclamp(friction, FLEXIBLE_OBJECT_MIN_AIR_FRICTION, FLEXIBLE_OBJECT_MAX_AIR_FRICTION); }
- void setWindSensitivity(F32 wind) { mWindSensitivity = llclamp(wind, FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY, FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY); }
- void setTension(F32 tension) { mTension = llclamp(tension, FLEXIBLE_OBJECT_MIN_TENSION, FLEXIBLE_OBJECT_MAX_TENSION); }
- void setUserForce(LLVector3 &force) { mUserForce = force; }
-
- S32 getSimulateLOD() const { return mSimulateLOD; }
- F32 getGravity() const { return mGravity; }
- F32 getAirFriction() const { return mAirFriction; }
- F32 getWindSensitivity() const { return mWindSensitivity; }
- F32 getTension() const { return mTension; }
- LLVector3 getUserForce() const { return mUserForce; }
-
- //------ the constructor for the structure ------------
- LLFlexibleObjectData();
- BOOL pack(LLDataPacker &dp) const;
- BOOL unpack(LLDataPacker &dp);
- bool operator==(const LLNetworkData& data) const;
- void copy(const LLNetworkData& data);
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
+ void setSimulateLOD(S32 lod) { mSimulateLOD = llclamp(lod, (S32)FLEXIBLE_OBJECT_MIN_SECTIONS, (S32)FLEXIBLE_OBJECT_MAX_SECTIONS); }
+ void setGravity(F32 gravity) { mGravity = llclamp(gravity, FLEXIBLE_OBJECT_MIN_GRAVITY, FLEXIBLE_OBJECT_MAX_GRAVITY); }
+ void setAirFriction(F32 friction) { mAirFriction = llclamp(friction, FLEXIBLE_OBJECT_MIN_AIR_FRICTION, FLEXIBLE_OBJECT_MAX_AIR_FRICTION); }
+ void setWindSensitivity(F32 wind) { mWindSensitivity = llclamp(wind, FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY, FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY); }
+ void setTension(F32 tension) { mTension = llclamp(tension, FLEXIBLE_OBJECT_MIN_TENSION, FLEXIBLE_OBJECT_MAX_TENSION); }
+ void setUserForce(LLVector3 &force) { mUserForce = force; }
+
+ S32 getSimulateLOD() const { return mSimulateLOD; }
+ F32 getGravity() const { return mGravity; }
+ F32 getAirFriction() const { return mAirFriction; }
+ F32 getWindSensitivity() const { return mWindSensitivity; }
+ F32 getTension() const { return mTension; }
+ LLVector3 getUserForce() const { return mUserForce; }
+
+ //------ the constructor for the structure ------------
+ LLFlexibleObjectData();
+ BOOL pack(LLDataPacker &dp) const;
+ BOOL unpack(LLDataPacker &dp);
+ bool operator==(const LLNetworkData& data) const;
+ void copy(const LLNetworkData& data);
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
};// end of attributes structure
@@ -302,68 +305,68 @@ public:
class LLSculptParams : public LLNetworkData
{
protected:
- LLUUID mSculptTexture;
- U8 mSculptType;
-
+ LLUUID mSculptTexture;
+ U8 mSculptType;
+
public:
- LLSculptParams();
- /*virtual*/ BOOL pack(LLDataPacker &dp) const;
- /*virtual*/ BOOL unpack(LLDataPacker &dp);
- /*virtual*/ bool operator==(const LLNetworkData& data) const;
- /*virtual*/ void copy(const LLNetworkData& data);
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type);
- LLUUID getSculptTexture() const { return mSculptTexture; }
- U8 getSculptType() const { return mSculptType; }
+ LLSculptParams();
+ /*virtual*/ BOOL pack(LLDataPacker &dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker &dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type);
+ LLUUID getSculptTexture() const { return mSculptTexture; }
+ U8 getSculptType() const { return mSculptType; }
};
class LLLightImageParams : public LLNetworkData
{
protected:
- LLUUID mLightTexture;
- LLVector3 mParams;
-
+ LLUUID mLightTexture;
+ LLVector3 mParams;
+
public:
- LLLightImageParams();
- /*virtual*/ BOOL pack(LLDataPacker &dp) const;
- /*virtual*/ BOOL unpack(LLDataPacker &dp);
- /*virtual*/ bool operator==(const LLNetworkData& data) const;
- /*virtual*/ void copy(const LLNetworkData& data);
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- void setLightTexture(const LLUUID& id) { mLightTexture = id; }
- LLUUID getLightTexture() const { return mLightTexture; }
- bool isLightSpotlight() const { return mLightTexture.notNull(); }
- void setParams(const LLVector3& params) { mParams = params; }
- LLVector3 getParams() const { return mParams; }
-
+ LLLightImageParams();
+ /*virtual*/ BOOL pack(LLDataPacker &dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker &dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setLightTexture(const LLUUID& id) { mLightTexture = id; }
+ LLUUID getLightTexture() const { return mLightTexture; }
+ bool isLightSpotlight() const { return mLightTexture.notNull(); }
+ void setParams(const LLVector3& params) { mParams = params; }
+ LLVector3 getParams() const { return mParams; }
+
};
class LLExtendedMeshParams : public LLNetworkData
{
protected:
- U32 mFlags;
-
+ U32 mFlags;
+
public:
- static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0;
-
- LLExtendedMeshParams();
- /*virtual*/ BOOL pack(LLDataPacker &dp) const;
- /*virtual*/ BOOL unpack(LLDataPacker &dp);
- /*virtual*/ bool operator==(const LLNetworkData& data) const;
- /*virtual*/ void copy(const LLNetworkData& data);
- LLSD asLLSD() const;
- operator LLSD() const { return asLLSD(); }
- bool fromLLSD(LLSD& sd);
-
- void setFlags(const U32& flags) { mFlags = flags; }
+ static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0;
+
+ LLExtendedMeshParams();
+ /*virtual*/ BOOL pack(LLDataPacker &dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker &dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setFlags(const U32& flags) { mFlags = flags; }
U32 getFlags() const { return mFlags; }
-
+
};
class LLRenderMaterialParams : public LLNetworkData
@@ -382,7 +385,7 @@ public:
BOOL unpack(LLDataPacker& dp) override;
bool operator==(const LLNetworkData& data) const override;
void copy(const LLNetworkData& data) override;
-
+
void setMaterial(U8 te_idx, const LLUUID& id);
const LLUUID& getMaterial(U8 te_idx) const;
@@ -392,249 +395,249 @@ public:
// This code is not naming-standards compliant. Leaving it like this for
// now to make the connection to code in
-// BOOL packTEMessage(LLDataPacker &dp) const;
+// BOOL packTEMessage(LLDataPacker &dp) const;
// more obvious. This should be refactored to remove the duplication, at which
// point we can fix the names as well.
// - Vir
struct LLTEContents
{
- static const U32 MAX_TES = 45;
+ static const U32 MAX_TES = 45;
LLUUID image_data[MAX_TES];
LLColor4U colors[MAX_TES];
- F32 scale_s[MAX_TES];
- F32 scale_t[MAX_TES];
- S16 offset_s[MAX_TES];
- S16 offset_t[MAX_TES];
- S16 image_rot[MAX_TES];
- U8 bump[MAX_TES];
- U8 media_flags[MAX_TES];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
+ S16 offset_s[MAX_TES];
+ S16 offset_t[MAX_TES];
+ S16 image_rot[MAX_TES];
+ U8 bump[MAX_TES];
+ U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
- LLMaterialID material_ids[MAX_TES];
+ LLMaterialID material_ids[MAX_TES];
- static const U32 MAX_TE_BUFFER = 4096;
- U8 packed_buffer[MAX_TE_BUFFER];
+ static const U32 MAX_TE_BUFFER = 4096;
+ U8 packed_buffer[MAX_TE_BUFFER];
- U32 size;
- U32 face_count;
+ U32 size;
+ U32 face_count;
};
class LLPrimitive : public LLXform
{
public:
- // HACK for removing LLPrimitive's dependency on gVolumeMgr global.
- // If a different LLVolumeManager is instantiated and set early enough
- // then the LLPrimitive class will use it instead of gVolumeMgr.
- static LLVolumeMgr* getVolumeManager() { return sVolumeManager; }
- static void setVolumeManager( LLVolumeMgr* volume_manager);
- static bool cleanupVolumeManager();
-
- // these flags influence how the RigidBody representation is built
- static const U32 PRIM_FLAG_PHANTOM = 0x1 << 0;
- static const U32 PRIM_FLAG_VOLUME_DETECT = 0x1 << 1;
- static const U32 PRIM_FLAG_DYNAMIC = 0x1 << 2;
- static const U32 PRIM_FLAG_AVATAR = 0x1 << 3;
- static const U32 PRIM_FLAG_SCULPT = 0x1 << 4;
- // not used yet, but soon
- static const U32 PRIM_FLAG_COLLISION_CALLBACK = 0x1 << 5;
- static const U32 PRIM_FLAG_CONVEX = 0x1 << 6;
- static const U32 PRIM_FLAG_DEFAULT_VOLUME = 0x1 << 7;
- static const U32 PRIM_FLAG_SITTING = 0x1 << 8;
- static const U32 PRIM_FLAG_SITTING_ON_GROUND = 0x1 << 9; // Set along with PRIM_FLAG_SITTING
-
- LLPrimitive();
- virtual ~LLPrimitive();
-
- void clearTextureList();
-
- static LLPrimitive *createPrimitive(LLPCode p_code);
- void init_primitive(LLPCode p_code);
-
- void setPCode(const LLPCode pcode);
- const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume
- LLVolume *getVolume() const { return mVolumep; }
- virtual BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
-
- // Modify texture entry properties
- inline BOOL validTE(const U8 te_num) const;
- LLTextureEntry* getTE(const U8 te_num) const;
-
- virtual void setNumTEs(const U8 num_tes);
- virtual void setAllTESelected(bool sel);
- virtual void setAllTETextures(const LLUUID &tex_id);
- virtual void setTE(const U8 index, const LLTextureEntry& te);
- virtual S32 setTEColor(const U8 te, const LLColor4 &color);
- virtual S32 setTEColor(const U8 te, const LLColor3 &color);
- virtual S32 setTEAlpha(const U8 te, const F32 alpha);
- virtual S32 setTETexture(const U8 te, const LLUUID &tex_id);
- virtual S32 setTEScale (const U8 te, const F32 s, const F32 t);
- virtual S32 setTEScaleS(const U8 te, const F32 s);
- virtual S32 setTEScaleT(const U8 te, const F32 t);
- virtual S32 setTEOffset (const U8 te, const F32 s, const F32 t);
- virtual S32 setTEOffsetS(const U8 te, const F32 s);
- virtual S32 setTEOffsetT(const U8 te, const F32 t);
- virtual S32 setTERotation(const U8 te, const F32 r);
- virtual S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
- virtual S32 setTEBumpShiny(const U8 te, const U8 bump);
- virtual S32 setTEMediaTexGen(const U8 te, const U8 media);
- virtual S32 setTEBumpmap(const U8 te, const U8 bump);
- virtual S32 setTETexGen(const U8 te, const U8 texgen);
- virtual S32 setTEShiny(const U8 te, const U8 shiny);
- virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
- virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
- virtual S32 setTEGlow(const U8 te, const F32 glow);
- virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ // HACK for removing LLPrimitive's dependency on gVolumeMgr global.
+ // If a different LLVolumeManager is instantiated and set early enough
+ // then the LLPrimitive class will use it instead of gVolumeMgr.
+ static LLVolumeMgr* getVolumeManager() { return sVolumeManager; }
+ static void setVolumeManager( LLVolumeMgr* volume_manager);
+ static bool cleanupVolumeManager();
+
+ // these flags influence how the RigidBody representation is built
+ static const U32 PRIM_FLAG_PHANTOM = 0x1 << 0;
+ static const U32 PRIM_FLAG_VOLUME_DETECT = 0x1 << 1;
+ static const U32 PRIM_FLAG_DYNAMIC = 0x1 << 2;
+ static const U32 PRIM_FLAG_AVATAR = 0x1 << 3;
+ static const U32 PRIM_FLAG_SCULPT = 0x1 << 4;
+ // not used yet, but soon
+ static const U32 PRIM_FLAG_COLLISION_CALLBACK = 0x1 << 5;
+ static const U32 PRIM_FLAG_CONVEX = 0x1 << 6;
+ static const U32 PRIM_FLAG_DEFAULT_VOLUME = 0x1 << 7;
+ static const U32 PRIM_FLAG_SITTING = 0x1 << 8;
+ static const U32 PRIM_FLAG_SITTING_ON_GROUND = 0x1 << 9; // Set along with PRIM_FLAG_SITTING
+
+ LLPrimitive();
+ virtual ~LLPrimitive();
+
+ void clearTextureList();
+
+ static LLPrimitive *createPrimitive(LLPCode p_code);
+ void init_primitive(LLPCode p_code);
+
+ void setPCode(const LLPCode pcode);
+ const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume
+ LLVolume *getVolume() const { return mVolumep; }
+ virtual BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
+
+ // Modify texture entry properties
+ inline BOOL validTE(const U8 te_num) const;
+ LLTextureEntry* getTE(const U8 te_num) const;
+
+ virtual void setNumTEs(const U8 num_tes);
+ virtual void setAllTESelected(bool sel);
+ virtual void setAllTETextures(const LLUUID &tex_id);
+ virtual void setTE(const U8 index, const LLTextureEntry& te);
+ virtual S32 setTEColor(const U8 te, const LLColor4 &color);
+ virtual S32 setTEColor(const U8 te, const LLColor3 &color);
+ virtual S32 setTEAlpha(const U8 te, const F32 alpha);
+ virtual S32 setTETexture(const U8 te, const LLUUID &tex_id);
+ virtual S32 setTEScale (const U8 te, const F32 s, const F32 t);
+ virtual S32 setTEScaleS(const U8 te, const F32 s);
+ virtual S32 setTEScaleT(const U8 te, const F32 t);
+ virtual S32 setTEOffset (const U8 te, const F32 s, const F32 t);
+ virtual S32 setTEOffsetS(const U8 te, const F32 s);
+ virtual S32 setTEOffsetT(const U8 te, const F32 t);
+ virtual S32 setTERotation(const U8 te, const F32 r);
+ virtual S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
+ virtual S32 setTEBumpShiny(const U8 te, const U8 bump);
+ virtual S32 setTEMediaTexGen(const U8 te, const U8 media);
+ virtual S32 setTEBumpmap(const U8 te, const U8 bump);
+ virtual S32 setTETexGen(const U8 te, const U8 texgen);
+ virtual S32 setTEShiny(const U8 te, const U8 shiny);
+ virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
+ virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
+ virtual S32 setTEGlow(const U8 te, const F32 glow);
+ virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
- virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
- virtual void setTESelected(const U8 te, bool sel);
-
- LLMaterialPtr getTEMaterialParams(const U8 index);
-
- void copyTEs(const LLPrimitive *primitive);
- S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
- BOOL packTEMessage(LLMessageSystem *mesgsys) const;
- BOOL packTEMessage(LLDataPacker &dp) const;
- S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
- BOOL unpackTEMessage(LLDataPacker &dp);
- S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
- S32 applyParsedTEMessage(LLTEContents& tec);
-
+ virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
+ virtual void setTESelected(const U8 te, bool sel);
+
+ LLMaterialPtr getTEMaterialParams(const U8 index);
+
+ void copyTEs(const LLPrimitive *primitive);
+ S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
+ BOOL packTEMessage(LLMessageSystem *mesgsys) const;
+ BOOL packTEMessage(LLDataPacker &dp) const;
+ S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
+ BOOL unpackTEMessage(LLDataPacker &dp);
+ S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
+ S32 applyParsedTEMessage(LLTEContents& tec);
+
#ifdef CHECK_FOR_FINITE
- inline void setPosition(const LLVector3& pos);
- inline void setPosition(const F32 x, const F32 y, const F32 z);
- inline void addPosition(const LLVector3& pos);
-
- inline void setAngularVelocity(const LLVector3& avel);
- inline void setAngularVelocity(const F32 x, const F32 y, const F32 z);
- inline void setVelocity(const LLVector3& vel);
- inline void setVelocity(const F32 x, const F32 y, const F32 z);
- inline void setVelocityX(const F32 x);
- inline void setVelocityY(const F32 y);
- inline void setVelocityZ(const F32 z);
- inline void addVelocity(const LLVector3& vel);
- inline void setAcceleration(const LLVector3& accel);
- inline void setAcceleration(const F32 x, const F32 y, const F32 z);
+ inline void setPosition(const LLVector3& pos);
+ inline void setPosition(const F32 x, const F32 y, const F32 z);
+ inline void addPosition(const LLVector3& pos);
+
+ inline void setAngularVelocity(const LLVector3& avel);
+ inline void setAngularVelocity(const F32 x, const F32 y, const F32 z);
+ inline void setVelocity(const LLVector3& vel);
+ inline void setVelocity(const F32 x, const F32 y, const F32 z);
+ inline void setVelocityX(const F32 x);
+ inline void setVelocityY(const F32 y);
+ inline void setVelocityZ(const F32 z);
+ inline void addVelocity(const LLVector3& vel);
+ inline void setAcceleration(const LLVector3& accel);
+ inline void setAcceleration(const F32 x, const F32 y, const F32 z);
#else
- // Don't override the base LLXForm operators.
- // Special case for setPosition. If not check-for-finite, fall through to LLXform method.
- // void setPosition(F32 x, F32 y, F32 z)
- // void setPosition(LLVector3)
-
- void setAngularVelocity(const LLVector3& avel) { mAngularVelocity = avel; }
- void setAngularVelocity(const F32 x, const F32 y, const F32 z) { mAngularVelocity.setVec(x,y,z); }
- void setVelocity(const LLVector3& vel) { mVelocity = vel; }
- void setVelocity(const F32 x, const F32 y, const F32 z) { mVelocity.setVec(x,y,z); }
- void setVelocityX(const F32 x) { mVelocity.mV[VX] = x; }
- void setVelocityY(const F32 y) { mVelocity.mV[VY] = y; }
- void setVelocityZ(const F32 z) { mVelocity.mV[VZ] = z; }
- void addVelocity(const LLVector3& vel) { mVelocity += vel; }
- void setAcceleration(const LLVector3& accel) { mAcceleration = accel; }
- void setAcceleration(const F32 x, const F32 y, const F32 z) { mAcceleration.setVec(x,y,z); }
+ // Don't override the base LLXForm operators.
+ // Special case for setPosition. If not check-for-finite, fall through to LLXform method.
+ // void setPosition(F32 x, F32 y, F32 z)
+ // void setPosition(LLVector3)
+
+ void setAngularVelocity(const LLVector3& avel) { mAngularVelocity = avel; }
+ void setAngularVelocity(const F32 x, const F32 y, const F32 z) { mAngularVelocity.setVec(x,y,z); }
+ void setVelocity(const LLVector3& vel) { mVelocity = vel; }
+ void setVelocity(const F32 x, const F32 y, const F32 z) { mVelocity.setVec(x,y,z); }
+ void setVelocityX(const F32 x) { mVelocity.mV[VX] = x; }
+ void setVelocityY(const F32 y) { mVelocity.mV[VY] = y; }
+ void setVelocityZ(const F32 z) { mVelocity.mV[VZ] = z; }
+ void addVelocity(const LLVector3& vel) { mVelocity += vel; }
+ void setAcceleration(const LLVector3& accel) { mAcceleration = accel; }
+ void setAcceleration(const F32 x, const F32 y, const F32 z) { mAcceleration.setVec(x,y,z); }
#endif
-
- LLPCode getPCode() const { return mPrimitiveCode; }
- std::string getPCodeString() const { return pCodeToString(mPrimitiveCode); }
- const LLVector3& getAngularVelocity() const { return mAngularVelocity; }
- const LLVector3& getVelocity() const { return mVelocity; }
- const LLVector3& getAcceleration() const { return mAcceleration; }
- U8 getNumTEs() const { return mTextureList.size(); }
- U8 getExpectedNumTEs() const;
-
- U8 getMaterial() const { return mMaterial; }
-
- void setVolumeType(const U8 code);
- U8 getVolumeType();
-
- // clears existing textures
- // copies the contents of other_list into mEntryList
- void copyTextureList(const LLPrimTextureList& other_list);
-
- // clears existing textures
- // takes the contents of other_list and clears other_list
- void takeTextureList(LLPrimTextureList& other_list);
-
- inline BOOL isAvatar() const;
- inline BOOL isSittingAvatar() const;
- inline BOOL isSittingAvatarOnGround() const;
- inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;}
-
- void setFlags(U32 flags) { mMiscFlags = flags; }
- void addFlags(U32 flags) { mMiscFlags |= flags; }
- void removeFlags(U32 flags) { mMiscFlags &= ~flags; }
- U32 getFlags() const { return mMiscFlags; }
-
- static std::string pCodeToString(const LLPCode pcode);
- static LLPCode legacyToPCode(const U8 legacy);
- static U8 pCodeToLegacy(const LLPCode pcode);
- static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis);
+
+ LLPCode getPCode() const { return mPrimitiveCode; }
+ std::string getPCodeString() const { return pCodeToString(mPrimitiveCode); }
+ const LLVector3& getAngularVelocity() const { return mAngularVelocity; }
+ const LLVector3& getVelocity() const { return mVelocity; }
+ const LLVector3& getAcceleration() const { return mAcceleration; }
+ U8 getNumTEs() const { return mTextureList.size(); }
+ U8 getExpectedNumTEs() const;
+
+ U8 getMaterial() const { return mMaterial; }
+
+ void setVolumeType(const U8 code);
+ U8 getVolumeType();
+
+ // clears existing textures
+ // copies the contents of other_list into mEntryList
+ void copyTextureList(const LLPrimTextureList& other_list);
+
+ // clears existing textures
+ // takes the contents of other_list and clears other_list
+ void takeTextureList(LLPrimTextureList& other_list);
+
+ inline BOOL isAvatar() const;
+ inline BOOL isSittingAvatar() const;
+ inline BOOL isSittingAvatarOnGround() const;
+ inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;}
+
+ void setFlags(U32 flags) { mMiscFlags = flags; }
+ void addFlags(U32 flags) { mMiscFlags |= flags; }
+ void removeFlags(U32 flags) { mMiscFlags &= ~flags; }
+ U32 getFlags() const { return mMiscFlags; }
+
+ static std::string pCodeToString(const LLPCode pcode);
+ static LLPCode legacyToPCode(const U8 legacy);
+ static U8 pCodeToLegacy(const LLPCode pcode);
+ static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis);
BOOL hasRenderMaterialParams() const;
-
- inline static BOOL isPrimitive(const LLPCode pcode);
- inline static BOOL isApp(const LLPCode pcode);
+
+ inline static BOOL isPrimitive(const LLPCode pcode);
+ inline static BOOL isApp(const LLPCode pcode);
private:
- void updateNumBumpmap(const U8 index, const U8 bump);
+ void updateNumBumpmap(const U8 index, const U8 bump);
protected:
- LLPCode mPrimitiveCode; // Primitive code
- LLVector3 mVelocity; // how fast are we moving?
- LLVector3 mAcceleration; // are we under constant acceleration?
- LLVector3 mAngularVelocity; // angular velocity
- LLPointer<LLVolume> mVolumep;
- LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets
- U8 mMaterial; // Material code
- U8 mNumTEs; // # of faces on the primitve
- U8 mNumBumpmapTEs; // number of bumpmap TEs.
- U32 mMiscFlags; // home for misc bools
+ LLPCode mPrimitiveCode; // Primitive code
+ LLVector3 mVelocity; // how fast are we moving?
+ LLVector3 mAcceleration; // are we under constant acceleration?
+ LLVector3 mAngularVelocity; // angular velocity
+ LLPointer<LLVolume> mVolumep;
+ LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets
+ U8 mMaterial; // Material code
+ U8 mNumTEs; // # of faces on the primitve
+ U8 mNumBumpmapTEs; // number of bumpmap TEs.
+ U32 mMiscFlags; // home for misc bools
public:
- static LLVolumeMgr* sVolumeManager;
+ static LLVolumeMgr* sVolumeManager;
- enum
- {
- NO_LOD = -1
- };
+ enum
+ {
+ NO_LOD = -1
+ };
};
inline BOOL LLPrimitive::isAvatar() const
{
- return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode ) ? TRUE : FALSE;
+ return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode ) ? TRUE : FALSE;
}
inline BOOL LLPrimitive::isSittingAvatar() const
{
- // this is only used server-side
- return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode
- && ((getFlags() & (PRIM_FLAG_SITTING | PRIM_FLAG_SITTING_ON_GROUND)) != 0) ) ? TRUE : FALSE;
+ // this is only used server-side
+ return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode
+ && ((getFlags() & (PRIM_FLAG_SITTING | PRIM_FLAG_SITTING_ON_GROUND)) != 0) ) ? TRUE : FALSE;
}
inline BOOL LLPrimitive::isSittingAvatarOnGround() const
{
- // this is only used server-side
- return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode
- && ((getFlags() & PRIM_FLAG_SITTING_ON_GROUND) != 0) ) ? TRUE : FALSE;
+ // this is only used server-side
+ return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode
+ && ((getFlags() & PRIM_FLAG_SITTING_ON_GROUND) != 0) ) ? TRUE : FALSE;
}
// static
inline BOOL LLPrimitive::isPrimitive(const LLPCode pcode)
{
- LLPCode base_type = pcode & LL_PCODE_BASE_MASK;
+ LLPCode base_type = pcode & LL_PCODE_BASE_MASK;
- if (base_type && (base_type < LL_PCODE_APP))
- {
- return TRUE;
- }
- return FALSE;
+ if (base_type && (base_type < LL_PCODE_APP))
+ {
+ return TRUE;
+ }
+ return FALSE;
}
// static
inline BOOL LLPrimitive::isApp(const LLPCode pcode)
{
- LLPCode base_type = pcode & LL_PCODE_BASE_MASK;
+ LLPCode base_type = pcode & LL_PCODE_BASE_MASK;
- return (base_type == LL_PCODE_APP);
+ return (base_type == LL_PCODE_APP);
}
@@ -642,153 +645,153 @@ inline BOOL LLPrimitive::isApp(const LLPCode pcode)
// Special case for setPosition. If not check-for-finite, fall through to LLXform method.
void LLPrimitive::setPosition(const F32 x, const F32 y, const F32 z)
{
- if (llfinite(x) && llfinite(y) && llfinite(z))
- {
- LLXform::setPosition(x, y, z);
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setPosition(x,y,z) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ {
+ LLXform::setPosition(x, y, z);
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setPosition(x,y,z) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
// Special case for setPosition. If not check-for-finite, fall through to LLXform method.
void LLPrimitive::setPosition(const LLVector3& pos)
{
- if (pos.isFinite())
- {
- LLXform::setPosition(pos);
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setPosition(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+ if (pos.isFinite())
+ {
+ LLXform::setPosition(pos);
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setPosition(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
void LLPrimitive::setAngularVelocity(const LLVector3& avel)
-{
- if (avel.isFinite())
- {
- mAngularVelocity = avel;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL;
- }
+{
+ if (avel.isFinite())
+ {
+ mAngularVelocity = avel;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL;
+ }
}
-void LLPrimitive::setAngularVelocity(const F32 x, const F32 y, const F32 z)
-{
- if (llfinite(x) && llfinite(y) && llfinite(z))
- {
- mAngularVelocity.setVec(x,y,z);
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL;
- }
+void LLPrimitive::setAngularVelocity(const F32 x, const F32 y, const F32 z)
+{
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ {
+ mAngularVelocity.setVec(x,y,z);
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setAngularVelocity" << LL_ENDL;
+ }
}
-void LLPrimitive::setVelocity(const LLVector3& vel)
-{
- if (vel.isFinite())
- {
- mVelocity = vel;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+void LLPrimitive::setVelocity(const LLVector3& vel)
+{
+ if (vel.isFinite())
+ {
+ mVelocity = vel;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
-void LLPrimitive::setVelocity(const F32 x, const F32 y, const F32 z)
-{
- if (llfinite(x) && llfinite(y) && llfinite(z))
- {
- mVelocity.setVec(x,y,z);
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+void LLPrimitive::setVelocity(const F32 x, const F32 y, const F32 z)
+{
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ {
+ mVelocity.setVec(x,y,z);
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setVelocity(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
-void LLPrimitive::setVelocityX(const F32 x)
-{
- if (llfinite(x))
- {
- mVelocity.mV[VX] = x;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setVelocityX" << LL_ENDL;
- }
+void LLPrimitive::setVelocityX(const F32 x)
+{
+ if (llfinite(x))
+ {
+ mVelocity.mV[VX] = x;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setVelocityX" << LL_ENDL;
+ }
}
-void LLPrimitive::setVelocityY(const F32 y)
-{
- if (llfinite(y))
- {
- mVelocity.mV[VY] = y;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setVelocityY" << LL_ENDL;
- }
+void LLPrimitive::setVelocityY(const F32 y)
+{
+ if (llfinite(y))
+ {
+ mVelocity.mV[VY] = y;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setVelocityY" << LL_ENDL;
+ }
}
-void LLPrimitive::setVelocityZ(const F32 z)
-{
- if (llfinite(z))
- {
- mVelocity.mV[VZ] = z;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setVelocityZ" << LL_ENDL;
- }
+void LLPrimitive::setVelocityZ(const F32 z)
+{
+ if (llfinite(z))
+ {
+ mVelocity.mV[VZ] = z;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setVelocityZ" << LL_ENDL;
+ }
}
-void LLPrimitive::addVelocity(const LLVector3& vel)
-{
- if (vel.isFinite())
- {
- mVelocity += vel;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::addVelocity" << LL_ENDL;
- }
+void LLPrimitive::addVelocity(const LLVector3& vel)
+{
+ if (vel.isFinite())
+ {
+ mVelocity += vel;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::addVelocity" << LL_ENDL;
+ }
}
-void LLPrimitive::setAcceleration(const LLVector3& accel)
-{
- if (accel.isFinite())
- {
- mAcceleration = accel;
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+void LLPrimitive::setAcceleration(const LLVector3& accel)
+{
+ if (accel.isFinite())
+ {
+ mAcceleration = accel;
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(LLVector3) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
-void LLPrimitive::setAcceleration(const F32 x, const F32 y, const F32 z)
-{
- if (llfinite(x) && llfinite(y) && llfinite(z))
- {
- mAcceleration.setVec(x,y,z);
- }
- else
- {
- LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- }
+void LLPrimitive::setAcceleration(const F32 x, const F32 y, const F32 z)
+{
+ if (llfinite(x) && llfinite(y) && llfinite(z))
+ {
+ mAcceleration.setVec(x,y,z);
+ }
+ else
+ {
+ LL_ERRS() << "Non Finite in LLPrimitive::setAcceleration(F32,F32,F32) for " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ }
}
#endif // CHECK_FOR_FINITE
inline BOOL LLPrimitive::validTE(const U8 te_num) const
{
- return (mNumTEs && te_num < mNumTEs);
+ return (mNumTEs && te_num < mNumTEs);
}
#endif
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 684660e24a..ee2a4c769a 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lltextureentry.cpp
* @brief LLTextureEntry base class
*
* $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$
*/
@@ -52,10 +52,10 @@ const LLTextureEntry LLTextureEntry::null;
static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
-// static
+// static
LLTextureEntry* LLTextureEntry::newTextureEntry()
{
- return new LLTextureEntry();
+ return new LLTextureEntry();
}
//===============================================================
@@ -64,7 +64,7 @@ LLTextureEntry::LLTextureEntry()
, mSelected(false)
, mMaterialUpdatePending(false)
{
- init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
+ init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
@@ -72,7 +72,7 @@ LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
, mSelected(false)
, mMaterialUpdatePending(false)
{
- init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
+ init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
@@ -85,30 +85,30 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
{
- if (this != &rhs)
- {
- mID = rhs.mID;
- mScaleS = rhs.mScaleS;
- mScaleT = rhs.mScaleT;
- mOffsetS = rhs.mOffsetS;
- mOffsetT = rhs.mOffsetT;
- mRotation = rhs.mRotation;
- mColor = rhs.mColor;
- mBump = rhs.mBump;
- mMediaFlags = rhs.mMediaFlags;
- mGlow = rhs.mGlow;
- mMaterialID = rhs.mMaterialID;
- mMaterial = rhs.mMaterial;
- if (mMediaEntry != NULL) {
- delete mMediaEntry;
- }
- if (rhs.mMediaEntry != NULL) {
- // Make a copy
- mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
- }
- else {
- mMediaEntry = NULL;
- }
+ if (this != &rhs)
+ {
+ mID = rhs.mID;
+ mScaleS = rhs.mScaleS;
+ mScaleT = rhs.mScaleT;
+ mOffsetS = rhs.mOffsetS;
+ mOffsetT = rhs.mOffsetT;
+ mRotation = rhs.mRotation;
+ mColor = rhs.mColor;
+ mBump = rhs.mBump;
+ mMediaFlags = rhs.mMediaFlags;
+ mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
+ mMaterial = rhs.mMaterial;
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ if (rhs.mMediaEntry != NULL) {
+ // Make a copy
+ mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
+ }
+ else {
+ mMediaEntry = NULL;
+ }
mMaterialID = rhs.mMaterialID;
@@ -121,7 +121,7 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
{
mGLTFMaterial->addTextureEntry(this);
}
-
+
if (rhs.mGLTFMaterialOverrides.notNull())
{
mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides);
@@ -130,39 +130,39 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
{
mGLTFMaterialOverrides = nullptr;
}
- }
+ }
- return *this;
+ return *this;
}
void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump)
{
- setID(tex_id);
+ setID(tex_id);
- mScaleS = scale_s;
- mScaleT = scale_t;
- mOffsetS = offset_s;
- mOffsetT = offset_t;
- mRotation = rotation;
- mBump = bump;
- mMediaFlags = 0x0;
+ mScaleS = scale_s;
+ mScaleT = scale_t;
+ mOffsetS = offset_s;
+ mOffsetT = offset_t;
+ mRotation = rotation;
+ mBump = bump;
+ mMediaFlags = 0x0;
mGlow = 0;
- mMaterialID.clear();
-
- setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
- if (mMediaEntry != NULL) {
- delete mMediaEntry;
- }
- mMediaEntry = NULL;
+ mMaterialID.clear();
+
+ setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
+ if (mMediaEntry != NULL) {
+ delete mMediaEntry;
+ }
+ mMediaEntry = NULL;
}
LLTextureEntry::~LLTextureEntry()
{
- if(mMediaEntry)
- {
- delete mMediaEntry;
- mMediaEntry = NULL;
- }
+ if(mMediaEntry)
+ {
+ delete mMediaEntry;
+ mMediaEntry = NULL;
+ }
if (mGLTFMaterial)
{
@@ -173,64 +173,64 @@ LLTextureEntry::~LLTextureEntry()
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
{
- if (mID != rhs.mID) return(true);
- if (mScaleS != rhs.mScaleS) return(true);
- if (mScaleT != rhs.mScaleT) return(true);
- if (mOffsetS != rhs.mOffsetS) return(true);
- if (mOffsetT != rhs.mOffsetT) return(true);
- if (mRotation != rhs.mRotation) return(true);
- if (mColor != rhs.mColor) return (true);
- if (mBump != rhs.mBump) return (true);
- if (mMediaFlags != rhs.mMediaFlags) return (true);
- if (mGlow != rhs.mGlow) return (true);
- if (mMaterialID != rhs.mMaterialID) return (true);
- return(false);
+ if (mID != rhs.mID) return(true);
+ if (mScaleS != rhs.mScaleS) return(true);
+ if (mScaleT != rhs.mScaleT) return(true);
+ if (mOffsetS != rhs.mOffsetS) return(true);
+ if (mOffsetT != rhs.mOffsetT) return(true);
+ if (mRotation != rhs.mRotation) return(true);
+ if (mColor != rhs.mColor) return (true);
+ if (mBump != rhs.mBump) return (true);
+ if (mMediaFlags != rhs.mMediaFlags) return (true);
+ if (mGlow != rhs.mGlow) return (true);
+ if (mMaterialID != rhs.mMaterialID) return (true);
+ return(false);
}
bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
{
- if (mID != rhs.mID) return(false);
- if (mScaleS != rhs.mScaleS) return(false);
- if (mScaleT != rhs.mScaleT) return(false);
- if (mOffsetS != rhs.mOffsetS) return(false);
- if (mOffsetT != rhs.mOffsetT) return(false);
- if (mRotation != rhs.mRotation) return(false);
- if (mColor != rhs.mColor) return (false);
- if (mBump != rhs.mBump) return (false);
- if (mMediaFlags != rhs.mMediaFlags) return false;
- if (mGlow != rhs.mGlow) return false;
- if (mMaterialID != rhs.mMaterialID) return (false);
- return(true);
+ if (mID != rhs.mID) return(false);
+ if (mScaleS != rhs.mScaleS) return(false);
+ if (mScaleT != rhs.mScaleT) return(false);
+ if (mOffsetS != rhs.mOffsetS) return(false);
+ if (mOffsetT != rhs.mOffsetT) return(false);
+ if (mRotation != rhs.mRotation) return(false);
+ if (mColor != rhs.mColor) return (false);
+ if (mBump != rhs.mBump) return (false);
+ if (mMediaFlags != rhs.mMediaFlags) return false;
+ if (mGlow != rhs.mGlow) return false;
+ if (mMaterialID != rhs.mMaterialID) return (false);
+ return(true);
}
LLSD LLTextureEntry::asLLSD() const
{
- LLSD sd;
- asLLSD(sd);
- return sd;
+ LLSD sd;
+ asLLSD(sd);
+ return sd;
}
void LLTextureEntry::asLLSD(LLSD& sd) const
{
LL_PROFILE_ZONE_SCOPED;
- sd["imageid"] = mID;
- sd["colors"] = ll_sd_from_color4(mColor);
- sd["scales"] = mScaleS;
- sd["scalet"] = mScaleT;
- sd["offsets"] = mOffsetS;
- sd["offsett"] = mOffsetT;
- sd["imagerot"] = mRotation;
- sd["bump"] = getBumpShiny();
- sd["fullbright"] = getFullbright();
- sd["media_flags"] = mMediaFlags;
- if (hasMedia()) {
- LLSD mediaData;
+ sd["imageid"] = mID;
+ sd["colors"] = ll_sd_from_color4(mColor);
+ sd["scales"] = mScaleS;
+ sd["scalet"] = mScaleT;
+ sd["offsets"] = mOffsetS;
+ sd["offsett"] = mOffsetT;
+ sd["imagerot"] = mRotation;
+ sd["bump"] = getBumpShiny();
+ sd["fullbright"] = getFullbright();
+ sd["media_flags"] = mMediaFlags;
+ if (hasMedia()) {
+ LLSD mediaData;
if (NULL != getMediaData()) {
getMediaData()->asLLSD(mediaData);
}
- sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
- }
- sd["glow"] = mGlow;
+ sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
+ }
+ sd["glow"] = mGlow;
if (mGLTFMaterialOverrides.notNull())
{
@@ -241,65 +241,65 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
bool LLTextureEntry::fromLLSD(const LLSD& sd)
{
LL_PROFILE_ZONE_SCOPED;
- const char *w, *x;
- w = "imageid";
- if (sd.has(w))
- {
- setID( sd[w] );
- } else goto fail;
- w = "colors";
- if (sd.has(w))
- {
- setColor( ll_color4_from_sd(sd["colors"]) );
- } else goto fail;
- w = "scales";
- x = "scalet";
- if (sd.has(w) && sd.has(x))
- {
- setScale( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
- } else goto fail;
- w = "offsets";
- x = "offsett";
- if (sd.has(w) && sd.has(x))
- {
- setOffset( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
- } else goto fail;
- w = "imagerot";
- if (sd.has(w))
- {
- setRotation( (F32)sd[w].asReal() );
- } else goto fail;
- w = "bump";
- if (sd.has(w))
- {
- setBumpShiny( sd[w].asInteger() );
- } else goto fail;
- w = "fullbright";
- if (sd.has(w))
- {
- setFullbright( sd[w].asInteger() );
- } else goto fail;
- w = "media_flags";
- if (sd.has(w))
- {
- setMediaTexGen( sd[w].asInteger() );
- } else goto fail;
- // If the "has media" flag doesn't match the fact that
- // media data exists, updateMediaData will "fix" it
- // by either clearing or setting the flag
- w = TEXTURE_MEDIA_DATA_KEY;
- if (hasMedia() != sd.has(w))
- {
- LL_WARNS() << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
- ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << LL_ENDL;
- }
- updateMediaData(sd[w]);
-
- w = "glow";
- if (sd.has(w))
- {
- setGlow((F32)sd[w].asReal() );
- }
+ const char *w, *x;
+ w = "imageid";
+ if (sd.has(w))
+ {
+ setID( sd[w] );
+ } else goto fail;
+ w = "colors";
+ if (sd.has(w))
+ {
+ setColor( ll_color4_from_sd(sd["colors"]) );
+ } else goto fail;
+ w = "scales";
+ x = "scalet";
+ if (sd.has(w) && sd.has(x))
+ {
+ setScale( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
+ } else goto fail;
+ w = "offsets";
+ x = "offsett";
+ if (sd.has(w) && sd.has(x))
+ {
+ setOffset( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
+ } else goto fail;
+ w = "imagerot";
+ if (sd.has(w))
+ {
+ setRotation( (F32)sd[w].asReal() );
+ } else goto fail;
+ w = "bump";
+ if (sd.has(w))
+ {
+ setBumpShiny( sd[w].asInteger() );
+ } else goto fail;
+ w = "fullbright";
+ if (sd.has(w))
+ {
+ setFullbright( sd[w].asInteger() );
+ } else goto fail;
+ w = "media_flags";
+ if (sd.has(w))
+ {
+ setMediaTexGen( sd[w].asInteger() );
+ } else goto fail;
+ // If the "has media" flag doesn't match the fact that
+ // media data exists, updateMediaData will "fix" it
+ // by either clearing or setting the flag
+ w = TEXTURE_MEDIA_DATA_KEY;
+ if (hasMedia() != sd.has(w))
+ {
+ LL_WARNS() << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
+ ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << LL_ENDL;
+ }
+ updateMediaData(sd[w]);
+
+ w = "glow";
+ if (sd.has(w))
+ {
+ setGlow((F32)sd[w].asReal() );
+ }
w = "gltf_override";
if (sd.has(w))
@@ -319,217 +319,217 @@ bool LLTextureEntry::fromLLSD(const LLSD& sd)
}
}
- return true;
+ return true;
fail:
- return false;
+ return false;
}
-// virtual
+// virtual
// override this method for each derived class
LLTextureEntry* LLTextureEntry::newBlank() const
{
- return new LLTextureEntry();
+ return new LLTextureEntry();
}
-// virtual
+// virtual
LLTextureEntry* LLTextureEntry::newCopy() const
{
- return new LLTextureEntry(*this);
+ return new LLTextureEntry(*this);
}
S32 LLTextureEntry::setID(const LLUUID &tex_id)
{
- if (mID != tex_id)
- {
- mID = tex_id;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ if (mID != tex_id)
+ {
+ mID = tex_id;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setScale(F32 s, F32 t)
{
- S32 retval = 0;
+ S32 retval = 0;
- if ( (mScaleS != s)
- ||(mScaleT != t))
- {
- mScaleS = s;
- mScaleT = t;
+ if ( (mScaleS != s)
+ ||(mScaleT != t))
+ {
+ mScaleS = s;
+ mScaleT = t;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setScaleS(F32 s)
{
- S32 retval = TEM_CHANGE_NONE;
- if (mScaleS != s)
- {
- mScaleS = s;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ S32 retval = TEM_CHANGE_NONE;
+ if (mScaleS != s)
+ {
+ mScaleS = s;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setScaleT(F32 t)
{
- S32 retval = TEM_CHANGE_NONE;
- if (mScaleT != t)
- {
- mScaleT = t;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ S32 retval = TEM_CHANGE_NONE;
+ if (mScaleT != t)
+ {
+ mScaleT = t;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setColor(const LLColor4 &color)
{
- if (mColor != color)
- {
- mColor = color;
- return TEM_CHANGE_COLOR;
- }
- return TEM_CHANGE_NONE;
+ if (mColor != color)
+ {
+ mColor = color;
+ return TEM_CHANGE_COLOR;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setColor(const LLColor3 &color)
{
- if (mColor != color)
- {
- // This preserves alpha.
- mColor.setVec(color);
- return TEM_CHANGE_COLOR;
- }
- return TEM_CHANGE_NONE;
+ if (mColor != color)
+ {
+ // This preserves alpha.
+ mColor.setVec(color);
+ return TEM_CHANGE_COLOR;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setAlpha(const F32 alpha)
{
- if (mColor.mV[VW] != alpha)
- {
- mColor.mV[VW] = alpha;
- return TEM_CHANGE_COLOR;
- }
- return TEM_CHANGE_NONE;
+ if (mColor.mV[VW] != alpha)
+ {
+ mColor.mV[VW] = alpha;
+ return TEM_CHANGE_COLOR;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setOffset(F32 s, F32 t)
{
- S32 retval = 0;
+ S32 retval = 0;
- if ( (mOffsetS != s)
- ||(mOffsetT != t))
- {
- mOffsetS = s;
- mOffsetT = t;
+ if ( (mOffsetS != s)
+ ||(mOffsetT != t))
+ {
+ mOffsetS = s;
+ mOffsetT = t;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setOffsetS(F32 s)
{
- S32 retval = 0;
- if (mOffsetS != s)
- {
- mOffsetS = s;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ S32 retval = 0;
+ if (mOffsetS != s)
+ {
+ mOffsetS = s;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setOffsetT(F32 t)
{
- S32 retval = 0;
- if (mOffsetT != t)
- {
- mOffsetT = t;
- retval = TEM_CHANGE_TEXTURE;
- }
- return retval;
+ S32 retval = 0;
+ if (mOffsetT != t)
+ {
+ mOffsetT = t;
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ return retval;
}
S32 LLTextureEntry::setRotation(F32 theta)
{
- if (mRotation != theta && llfinite(theta))
- {
- mRotation = theta;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ if (mRotation != theta && llfinite(theta))
+ {
+ mRotation = theta;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setBumpShinyFullbright(U8 bump)
{
- if (mBump != bump)
- {
- mBump = bump;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ if (mBump != bump)
+ {
+ mBump = bump;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setMediaTexGen(U8 media)
{
- S32 result = TEM_CHANGE_NONE;
- result |= setTexGen(media & TEM_TEX_GEN_MASK);
- result |= setMediaFlags(media & TEM_MEDIA_MASK);
- return result;
+ S32 result = TEM_CHANGE_NONE;
+ result |= setTexGen(media & TEM_TEX_GEN_MASK);
+ result |= setMediaFlags(media & TEM_MEDIA_MASK);
+ return result;
}
S32 LLTextureEntry::setBumpmap(U8 bump)
{
- bump &= TEM_BUMP_MASK;
- if (getBumpmap() != bump)
- {
- mBump &= ~TEM_BUMP_MASK;
- mBump |= bump;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ bump &= TEM_BUMP_MASK;
+ if (getBumpmap() != bump)
+ {
+ mBump &= ~TEM_BUMP_MASK;
+ mBump |= bump;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setFullbright(U8 fullbright)
{
- fullbright &= TEM_FULLBRIGHT_MASK;
- if (getFullbright() != fullbright)
- {
- mBump &= ~(TEM_FULLBRIGHT_MASK<<TEM_FULLBRIGHT_SHIFT);
- mBump |= fullbright << TEM_FULLBRIGHT_SHIFT;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ fullbright &= TEM_FULLBRIGHT_MASK;
+ if (getFullbright() != fullbright)
+ {
+ mBump &= ~(TEM_FULLBRIGHT_MASK<<TEM_FULLBRIGHT_SHIFT);
+ mBump |= fullbright << TEM_FULLBRIGHT_SHIFT;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setShiny(U8 shiny)
{
- shiny &= TEM_SHINY_MASK;
- if (getShiny() != shiny)
- {
- mBump &= ~(TEM_SHINY_MASK<<TEM_SHINY_SHIFT);
- mBump |= shiny << TEM_SHINY_SHIFT;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ shiny &= TEM_SHINY_MASK;
+ if (getShiny() != shiny)
+ {
+ mBump &= ~(TEM_SHINY_MASK<<TEM_SHINY_SHIFT);
+ mBump |= shiny << TEM_SHINY_SHIFT;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
{
- bump_shiny &= TEM_BUMP_SHINY_MASK;
- if (getBumpShiny() != bump_shiny)
- {
- mBump &= ~TEM_BUMP_SHINY_MASK;
- mBump |= bump_shiny;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ bump_shiny &= TEM_BUMP_SHINY_MASK;
+ if (getBumpShiny() != bump_shiny)
+ {
+ mBump &= ~TEM_BUMP_SHINY_MASK;
+ mBump |= bump_shiny;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin)
-{
+{
if (material != getGLTFMaterial())
{
// assert on precondtion:
@@ -560,7 +560,7 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin
}
S32 LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat)
-{
+{
llassert(mat == nullptr || getGLTFMaterial() != nullptr); // if override is not null, base material must not be null
if (mat == mGLTFMaterialOverrides)
{
@@ -594,12 +594,12 @@ S32 LLTextureEntry::setBaseMaterial()
}
LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
-{
+{
if (mGLTFRenderMaterial.notNull())
{
return mGLTFRenderMaterial;
}
-
+
llassert(getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
return getGLTFMaterial();
}
@@ -616,76 +616,77 @@ S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat)
S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
- media_flags &= TEM_MEDIA_MASK;
- if (getMediaFlags() != media_flags)
- {
- mMediaFlags &= ~TEM_MEDIA_MASK;
- mMediaFlags |= media_flags;
-
- // Special code for media handling
- if( hasMedia() && mMediaEntry == NULL)
- {
- mMediaEntry = new LLMediaEntry;
- }
+ media_flags &= TEM_MEDIA_MASK;
+ if (getMediaFlags() != media_flags)
+ {
+ mMediaFlags &= ~TEM_MEDIA_MASK;
+ mMediaFlags |= media_flags;
+
+ // Special code for media handling
+ if( hasMedia() && mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
else if ( ! hasMedia() && mMediaEntry != NULL)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
-
- return TEM_CHANGE_MEDIA;
- }
- return TEM_CHANGE_NONE;
+
+ return TEM_CHANGE_MEDIA;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setTexGen(U8 tex_gen)
{
- tex_gen &= TEM_TEX_GEN_MASK;
- if (getTexGen() != tex_gen)
- {
- mMediaFlags &= ~TEM_TEX_GEN_MASK;
- mMediaFlags |= tex_gen;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ tex_gen &= TEM_TEX_GEN_MASK;
+ if (getTexGen() != tex_gen)
+ {
+ mMediaFlags &= ~TEM_TEX_GEN_MASK;
+ mMediaFlags |= tex_gen;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setGlow(F32 glow)
{
- if (mGlow != glow)
- {
- mGlow = glow;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ if (mGlow != glow)
+ {
+ mGlow = glow;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
{
- if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
- {
- if (mSelected)
- {
- mMaterialUpdatePending = true;
- mMaterialID = pMaterialID;
- return TEM_CHANGE_TEXTURE;
- }
+ if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
+ {
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
- mMaterialUpdatePending = false;
- mMaterialID = pMaterialID;
- return TEM_CHANGE_TEXTURE;
- }
- return TEM_CHANGE_NONE;
+ mMaterialUpdatePending = false;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
}
S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
{
- if (mSelected)
- {
- mMaterialUpdatePending = true;
- }
- mMaterial = pMaterialParams;
- return TEM_CHANGE_TEXTURE;
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ }
+ mMaterial = pMaterialParams;
+
+ return TEM_CHANGE_TEXTURE;
}
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
@@ -700,23 +701,23 @@ void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
bool LLTextureEntry::updateMediaData(const LLSD& media_data)
{
- if (media_data.isUndefined())
- {
- // clear the media data
+ if (media_data.isUndefined())
+ {
+ // clear the media data
clearMediaData();
- return false;
- }
- else {
- mMediaFlags |= MF_HAS_MEDIA;
- if (mMediaEntry == NULL)
- {
- mMediaEntry = new LLMediaEntry;
- }
- // *NOTE: this will *clobber* all of the fields in mMediaEntry
+ return false;
+ }
+ else {
+ mMediaFlags |= MF_HAS_MEDIA;
+ if (mMediaEntry == NULL)
+ {
+ mMediaEntry = new LLMediaEntry;
+ }
+ // *NOTE: this will *clobber* all of the fields in mMediaEntry
// with whatever fields are present (or not present) in media_data!
- mMediaEntry->fromLLSD(media_data);
- return true;
- }
+ mMediaEntry->fromLLSD(media_data);
+ return true;
+ }
}
void LLTextureEntry::clearMediaData()
@@ -726,7 +727,7 @@ void LLTextureEntry::clearMediaData()
delete mMediaEntry;
}
mMediaEntry = NULL;
-}
+}
void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
{
@@ -759,10 +760,10 @@ std::string LLTextureEntry::touchMediaVersionString(const std::string &in_versio
U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
{
U32 version = 0;
- if (!version_string.empty())
+ if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
- if (found != std::string::npos)
+ if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
@@ -776,13 +777,13 @@ U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_
LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
{
LLUUID id;
- if (!version_string.empty())
+ if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
- if (found != std::string::npos)
+ if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
- if (found != std::string::npos)
+ if (found != std::string::npos)
{
std::string v = version_string.substr(found + 1);
id.set(v);
@@ -795,5 +796,5 @@ LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &versi
//static
bool LLTextureEntry::isMediaVersionString(const std::string &version_string)
{
- return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX);
+ return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX);
}
diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp
index 143cf8e9c0..b56c9ab4f5 100644
--- a/indra/llprimitive/tests/llgltfmaterial_test.cpp
+++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp
@@ -1,26 +1,26 @@
-/**
+/**
* @file llgltfmaterial_test.cpp
*
- * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
+ * $/LicenseInfo$
*/
#include "linden_common.h"
@@ -143,7 +143,7 @@ namespace tut
#if LL_WINDOWS
// If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial)
// This test result will vary between compilers, so only test a single platform
- ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216);
+ ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 224);
#endif
#endif
ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4);
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 97759939c9..be5ad08fbe 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -422,27 +422,27 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
mUsingBinaryProgram = LLShaderMgr::instance()->loadCachedProgramBinary(this);
- if (!mUsingBinaryProgram)
- {
+ if (!mUsingBinaryProgram)
+ {
#if DEBUG_SHADER_INCLUDES
- fprintf(stderr, "--- %s ---\n", mName.c_str());
+ fprintf(stderr, "--- %s ---\n", mName.c_str());
#endif // DEBUG_SHADER_INCLUDES
//compile new source
- vector< pair<string, GLenum> >::iterator fileIter = mShaderFiles.begin();
- for (; fileIter != mShaderFiles.end(); fileIter++)
- {
- GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
- LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
- if (shaderhandle)
- {
- attachObject(shaderhandle);
- }
- else
- {
- success = FALSE;
- }
- }
+ vector< pair<string, GLenum> >::iterator fileIter = mShaderFiles.begin();
+ for (; fileIter != mShaderFiles.end(); fileIter++)
+ {
+ GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
+ LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
+ if (shaderhandle)
+ {
+ attachObject(shaderhandle);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
}
// Attach existing objects
@@ -606,19 +606,19 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attrib
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- BOOL res = TRUE;
- if (!mUsingBinaryProgram)
- {
- //before linking, make sure reserved attributes always have consistent locations
- for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
- {
- const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- glBindAttribLocation(mProgramObject, i, (const GLchar*)name);
- }
+ BOOL res = TRUE;
+ if (!mUsingBinaryProgram)
+ {
+ //before linking, make sure reserved attributes always have consistent locations
+ for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
+ {
+ const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
+ glBindAttribLocation(mProgramObject, i, (const GLchar*)name);
+ }
- //link the program
- res = link();
- }
+ //link the program
+ res = link();
+ }
mAttribute.clear();
U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
@@ -1184,12 +1184,14 @@ S32 LLGLSLShader::getTextureChannel(S32 uniform) const
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
-
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
+
+
S32 index = mTexture[uniform];
if (index != -1)
{
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index df568bfea5..ed0f27d143 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -49,13 +49,14 @@ public:
bool hasShadows = false;
bool hasAmbientOcclusion = false;
bool hasSrgb = false;
- bool encodesNormal = false; // include: shaders\class1\environment\encodeNormF.glsl
bool isDeferred = false;
bool hasScreenSpaceReflections = false;
bool disableTextureIndex = false;
bool hasAlphaMask = false;
bool hasReflectionProbes = false;
bool attachNothing = false;
+ bool hasHeroProbes = false;
+ bool isPBRTerrain = false;
};
// ============= Structure for caching shader uniforms ===============
@@ -233,7 +234,7 @@ public:
void addConstant(const LLGLSLShader::eShaderConsts shader_const);
//enable/disable texture channel for specified uniform
- //if given texture uniform is active in the shader,
+ //if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
@@ -255,7 +256,7 @@ public:
void bind();
//helper to conditionally bind mRiggedVariant instead of this
void bind(bool rigged);
-
+
bool isComplete() const { return mProgramObject != 0; }
LLUUID hash();
@@ -329,11 +330,11 @@ private:
};
//UI shader (declared here so llui_libtest will link properly)
-extern LLGLSLShader gUIProgram;
+extern LLGLSLShader gUIProgram;
//output vec4(color.rgb,color.a*tex0[tc0].a)
-extern LLGLSLShader gSolidColorProgram;
+extern LLGLSLShader gSolidColorProgram;
//Alpha mask shader (declared here so llappearance can access properly)
-extern LLGLSLShader gAlphaMaskProgram;
+extern LLGLSLShader gAlphaMaskProgram;
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
#define LL_SET_SHADER_LABEL(shader) shader.setLabel(#shader)
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 944a3d0235..a590a8e745 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llgltexture.cpp
* @brief Opengl texture implementation
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -29,365 +29,366 @@
LLGLTexture::LLGLTexture(BOOL usemipmaps)
{
- init();
- mUseMipMaps = usemipmaps;
+ init();
+ mUseMipMaps = usemipmaps;
}
LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
{
- init();
- mFullWidth = width ;
- mFullHeight = height ;
- mUseMipMaps = usemipmaps;
- mComponents = components ;
- setTexelsPerImage();
+ init();
+ mFullWidth = width ;
+ mFullHeight = height ;
+ mUseMipMaps = usemipmaps;
+ mComponents = components ;
+ setTexelsPerImage();
}
LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
{
- init();
- mUseMipMaps = usemipmaps ;
- // Create an empty image of the specified size and width
- mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+ init();
+ mUseMipMaps = usemipmaps ;
+ // Create an empty image of the specified size and width
+ mGLTexturep = new LLImageGL(raw, usemipmaps) ;
}
LLGLTexture::~LLGLTexture()
{
- cleanup();
+ cleanup();
}
void LLGLTexture::init()
{
- mBoostLevel = LLGLTexture::BOOST_NONE;
+ mBoostLevel = LLGLTexture::BOOST_NONE;
- mFullWidth = 0;
- mFullHeight = 0;
- mTexelsPerImage = 0 ;
- mUseMipMaps = FALSE ;
- mComponents = 0 ;
+ mFullWidth = 0;
+ mFullHeight = 0;
+ mTexelsPerImage = 0 ;
+ mUseMipMaps = FALSE ;
+ mComponents = 0 ;
- mTextureState = NO_DELETE ;
- mDontDiscard = FALSE;
- mNeedsGLTexture = FALSE ;
+ mTextureState = NO_DELETE ;
+ mDontDiscard = FALSE;
+ mNeedsGLTexture = FALSE ;
}
void LLGLTexture::cleanup()
{
- if(mGLTexturep)
- {
- mGLTexturep->cleanup();
- }
+ if(mGLTexturep)
+ {
+ mGLTexturep->cleanup();
+ }
}
// virtual
void LLGLTexture::dump()
{
- if(mGLTexturep)
- {
- mGLTexturep->dump();
- }
+ if(mGLTexturep)
+ {
+ mGLTexturep->dump();
+ }
}
void LLGLTexture::setBoostLevel(S32 level)
{
- if(mBoostLevel != level)
- {
- mBoostLevel = level ;
- if(mBoostLevel != LLGLTexture::BOOST_NONE
- && mBoostLevel != LLGLTexture::BOOST_ICON
- && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL)
- {
- setNoDelete() ;
- }
- }
+ if(mBoostLevel != level)
+ {
+ mBoostLevel = level ;
+ if(mBoostLevel != LLGLTexture::BOOST_NONE
+ && mBoostLevel != LLGLTexture::BOOST_ICON
+ && mBoostLevel != LLGLTexture::BOOST_THUMBNAIL
+ && mBoostLevel != LLGLTexture::BOOST_TERRAIN)
+ {
+ setNoDelete() ;
+ }
+ }
}
void LLGLTexture::forceActive()
{
- mTextureState = ACTIVE ;
+ mTextureState = ACTIVE ;
}
-void LLGLTexture::setActive()
-{
- if(mTextureState != NO_DELETE)
- {
- mTextureState = ACTIVE ;
- }
+void LLGLTexture::setActive()
+{
+ if(mTextureState != NO_DELETE)
+ {
+ mTextureState = ACTIVE ;
+ }
}
//set the texture to stay in memory
-void LLGLTexture::setNoDelete()
-{
- mTextureState = NO_DELETE ;
+void LLGLTexture::setNoDelete()
+{
+ mTextureState = NO_DELETE ;
}
-void LLGLTexture::generateGLTexture()
-{
- if(mGLTexturep.isNull())
- {
- mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
- }
+void LLGLTexture::generateGLTexture()
+{
+ if(mGLTexturep.isNull())
+ {
+ mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+ }
}
LLImageGL* LLGLTexture::getGLTexture() const
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull()) ;
- return mGLTexturep ;
+ return mGLTexturep ;
}
-BOOL LLGLTexture::createGLTexture()
+BOOL LLGLTexture::createGLTexture()
{
- if(mGLTexturep.isNull())
- {
- generateGLTexture() ;
- }
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
- return mGLTexturep->createGLTexture() ;
+ return mGLTexturep->createGLTexture() ;
}
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
{
- llassert(mGLTexturep.notNull());
+ llassert(mGLTexturep.notNull());
- BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ;
+ BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ;
- if(ret)
- {
- mFullWidth = mGLTexturep->getCurrentWidth() ;
- mFullHeight = mGLTexturep->getCurrentHeight() ;
- mComponents = mGLTexturep->getComponents() ;
- setTexelsPerImage();
- }
+ if(ret)
+ {
+ 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()) ;
-
- mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+ llassert(mGLTexturep.notNull()) ;
+
+ 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
+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
+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()) ;
-
- return mGLTexturep->getComponents() ;
+S8 LLGLTexture::getComponents() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getComponents() ;
}
-LLGLuint LLGLTexture::getTexName() const
-{
- llassert(mGLTexturep.notNull()) ;
+LLGLuint LLGLTexture::getTexName() const
+{
+ llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTexName() ;
+ return mGLTexturep->getTexName() ;
}
-BOOL LLGLTexture::hasGLTexture() const
+BOOL LLGLTexture::hasGLTexture() const
{
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getHasGLTexture() ;
- }
- return FALSE ;
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getHasGLTexture() ;
+ }
+ return FALSE ;
}
BOOL LLGLTexture::getBoundRecently() const
{
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getBoundRecently() ;
- }
- return FALSE ;
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getBoundRecently() ;
+ }
+ 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, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ;
+ return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ;
}
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ;
+ return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ;
}
void LLGLTexture::setGLTextureCreated (bool initialized)
{
- llassert(mGLTexturep.notNull()) ;
+ llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setGLTextureCreated (initialized) ;
+ mGLTexturep->setGLTextureCreated (initialized) ;
}
-void LLGLTexture::setCategory(S32 category)
+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);
+ return mGLTexturep->setTexName(texName);
}
void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
{
llassert(mGLTexturep.notNull());
- return mGLTexturep->setTarget(target, bind_target);
+ 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
+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()
+void LLGLTexture::destroyGLTexture()
{
- if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
- {
- mGLTexturep->destroyGLTexture() ;
- mTextureState = DELETED ;
- }
+ if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
+ {
+ mGLTexturep->destroyGLTexture() ;
+ mTextureState = DELETED ;
+ }
}
void LLGLTexture::setTexelsPerImage()
{
- U32 fullwidth = llmin(mFullWidth,U32(MAX_IMAGE_SIZE_DEFAULT));
- U32 fullheight = llmin(mFullHeight,U32(MAX_IMAGE_SIZE_DEFAULT));
- mTexelsPerImage = (U32)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;
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 88057d7920..fa6faa2583 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llgltexture.h
* @brief Object for managing opengl textures
*
* $LicenseInfo:firstyear=2012&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$
*/
@@ -40,86 +40,87 @@ class LLImageRaw;
class LLGLTexture : public LLTexture
{
public:
- enum
- {
- MAX_IMAGE_SIZE_DEFAULT = 1024,
- INVALID_DISCARD_LEVEL = 0x7fff
- };
-
- enum EBoostLevel
- {
- BOOST_NONE = 0,
- BOOST_AVATAR ,
+ enum
+ {
+ MAX_IMAGE_SIZE_DEFAULT = 2048,
+ INVALID_DISCARD_LEVEL = 0x7fff
+ };
+
+ enum EBoostLevel
+ {
+ BOOST_NONE = 0,
+ BOOST_AVATAR ,
BOOST_AVATAR_BAKED ,
- BOOST_SCULPTED ,
-
- BOOST_HIGH = 10,
- BOOST_BUMP ,
- BOOST_TERRAIN , // has to be high priority for minimap / low detail
- BOOST_SELECTED ,
- BOOST_AVATAR_BAKED_SELF ,
- BOOST_AVATAR_SELF , // needed for baking avatar
- BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay.
- BOOST_HUD ,
- BOOST_ICON ,
- BOOST_THUMBNAIL ,
- BOOST_UI ,
- BOOST_PREVIEW ,
- BOOST_MAP ,
- BOOST_MAP_VISIBLE ,
- BOOST_MAX_LEVEL,
-
- //other texture Categories
- LOCAL = BOOST_MAX_LEVEL,
- AVATAR_SCRATCH_TEX,
- DYNAMIC_TEX,
- MEDIA,
- ATLAS,
- OTHER,
- MAX_GL_IMAGE_CATEGORY
- };
-
- typedef enum
- {
- DELETED = 0, //removed from memory
- DELETION_CANDIDATE, //ready to be removed from memory
- INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
- ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
- NO_DELETE = 99 //stay in memory, can not be removed.
- } LLGLTextureState;
+ BOOST_SCULPTED ,
+ BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
+
+ BOOST_HIGH = 10,
+ BOOST_BUMP ,
+ BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
+ BOOST_SELECTED ,
+ BOOST_AVATAR_BAKED_SELF ,
+ BOOST_AVATAR_SELF , // needed for baking avatar
+ BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay.
+ BOOST_HUD ,
+ BOOST_ICON ,
+ BOOST_THUMBNAIL ,
+ BOOST_UI ,
+ BOOST_PREVIEW ,
+ BOOST_MAP ,
+ BOOST_MAP_VISIBLE ,
+ BOOST_MAX_LEVEL,
+
+ //other texture Categories
+ LOCAL = BOOST_MAX_LEVEL,
+ AVATAR_SCRATCH_TEX,
+ DYNAMIC_TEX,
+ MEDIA,
+ ATLAS,
+ OTHER,
+ MAX_GL_IMAGE_CATEGORY
+ };
+
+ typedef enum
+ {
+ DELETED = 0, //removed from memory
+ DELETION_CANDIDATE, //ready to be removed from memory
+ INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
+ ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
+ NO_DELETE = 99 //stay in memory, can not be removed.
+ } LLGLTextureState;
protected:
- virtual ~LLGLTexture();
- LOG_CLASS(LLGLTexture);
+ virtual ~LLGLTexture();
+ LOG_CLASS(LLGLTexture);
public:
- LLGLTexture(BOOL usemipmaps = TRUE);
- LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
- LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
-
- virtual void dump(); // debug info to LL_INFOS()
+ LLGLTexture(BOOL usemipmaps = TRUE);
+ LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
- virtual const LLUUID& getID() const;
+ virtual void dump(); // debug info to LL_INFOS()
- void setBoostLevel(S32 level);
- S32 getBoostLevel() { return mBoostLevel; }
+ virtual const LLUUID& getID() const;
- S32 getFullWidth() const { return mFullWidth; }
- S32 getFullHeight() const { return mFullHeight; }
+ void setBoostLevel(S32 level);
+ S32 getBoostLevel() { return mBoostLevel; }
- void generateGLTexture() ;
- void destroyGLTexture() ;
+ S32 getFullWidth() const { return mFullWidth; }
+ S32 getFullHeight() const { return mFullHeight; }
- //---------------------------------------------------------------------------------------------
- //functions to access LLImageGL
- //---------------------------------------------------------------------------------------------
- /*virtual*/S32 getWidth(S32 discard_level = -1) const;
- /*virtual*/S32 getHeight(S32 discard_level = -1) const;
+ void generateGLTexture() ;
+ void destroyGLTexture() ;
- BOOL hasGLTexture() const ;
- LLGLuint getTexName() const ;
- BOOL createGLTexture() ;
+ //---------------------------------------------------------------------------------------------
+ //functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+ /*virtual*/S32 getWidth(S32 discard_level = -1) const;
+ /*virtual*/S32 getHeight(S32 discard_level = -1) const;
+ BOOL hasGLTexture() const ;
+ LLGLuint getTexName() const ;
+ BOOL createGLTexture() ;
+
// Create a GL Texture from an image raw
// discard_level - mip level, 0 for highest resultion mip
// imageraw - the image to copy from
@@ -130,74 +131,74 @@ public:
// tex_name - if not null, will be set to the GL name of the texture created
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr);
- void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
- void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
- void setAddressMode(LLTexUnit::eTextureAddressMode mode);
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
- void setGLTextureCreated (bool initialized);
- void setCategory(S32 category) ;
+ void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setAddressMode(LLTexUnit::eTextureAddressMode mode);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0);
+ 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;
- S32 getDiscardLevel() const;
- S8 getComponents() const;
- BOOL getBoundRecently() const;
- S32Bytes getTextureMemory() const ;
- LLGLenum getPrimaryFormat() const;
- BOOL getIsAlphaMask() const ;
- LLTexUnit::eTextureType getTarget(void) const ;
- BOOL getMask(const LLVector2 &tc);
- F32 getTimePassedSinceLastBound();
- BOOL getMissed() const ;
- BOOL isJustBound()const ;
- void forceUpdateBindStats(void) const;
-
- U32 getTexelsInAtlas() const ;
- U32 getTexelsInGLTexture() const ;
- BOOL isGLTextureCreated() const ;
- S32 getDiscardLevelInAtlas() const ;
- LLGLTextureState getTextureState() const { return mTextureState; }
-
- //---------------------------------------------------------------------------------------------
- //end of functions to access LLImageGL
- //---------------------------------------------------------------------------------------------
-
- //-----------------
- /*virtual*/ void setActive() ;
- void forceActive() ;
- void setNoDelete() ;
- void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
- BOOL getDontDiscard() const { return mDontDiscard; }
- //-----------------
+ LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
+ S32 getMaxDiscardLevel() const;
+ S32 getDiscardLevel() const;
+ S8 getComponents() const;
+ BOOL getBoundRecently() const;
+ S32Bytes getTextureMemory() const ;
+ LLGLenum getPrimaryFormat() const;
+ BOOL getIsAlphaMask() const ;
+ LLTexUnit::eTextureType getTarget(void) const ;
+ BOOL getMask(const LLVector2 &tc);
+ F32 getTimePassedSinceLastBound();
+ BOOL getMissed() const ;
+ BOOL isJustBound()const ;
+ void forceUpdateBindStats(void) const;
+
+ U32 getTexelsInAtlas() const ;
+ U32 getTexelsInGLTexture() const ;
+ BOOL isGLTextureCreated() const ;
+ S32 getDiscardLevelInAtlas() const ;
+ LLGLTextureState getTextureState() const { return mTextureState; }
+
+ //---------------------------------------------------------------------------------------------
+ //end of functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+
+ //-----------------
+ /*virtual*/ void setActive() ;
+ void forceActive() ;
+ void setNoDelete() ;
+ void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
+ BOOL getDontDiscard() const { return mDontDiscard; }
+ //-----------------
private:
- void cleanup();
- void init();
+ void cleanup();
+ void init();
protected:
- void setTexelsPerImage();
+ void setTexelsPerImage();
public:
- /*virtual*/ LLImageGL* getGLTexture() const ;
+ /*virtual*/ LLImageGL* getGLTexture() const ;
protected:
- S32 mBoostLevel; // enum describing priority level
- U32 mFullWidth;
- U32 mFullHeight;
- BOOL mUseMipMaps;
- S8 mComponents;
- U32 mTexelsPerImage; // Texels per image.
- mutable S8 mNeedsGLTexture;
-
- //GL texture
- LLPointer<LLImageGL> mGLTexturep ;
- S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
+ S32 mBoostLevel; // enum describing priority level
+ U32 mFullWidth;
+ U32 mFullHeight;
+ BOOL mUseMipMaps;
+ S8 mComponents;
+ U32 mTexelsPerImage; // Texels per image.
+ mutable S8 mNeedsGLTexture;
+
+ //GL texture
+ LLPointer<LLImageGL> mGLTexturep ;
+ S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
protected:
- LLGLTextureState mTextureState ;
+ LLGLTextureState mTextureState ;
};
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 1073db3bfd..358b35f36b 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1,25 +1,25 @@
- /**
+ /**
* @file llrender.cpp
* @brief LLRender 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$
*/
@@ -51,8 +51,8 @@ extern void APIENTRY gl_debug_callback(GLenum source,
thread_local LLRender gGL;
// Handy copies of last good GL matrices
-F32 gGLModelView[16];
-F32 gGLLastModelView[16];
+F32 gGLModelView[16];
+F32 gGLLastModelView[16];
F32 gGLLastProjection[16];
F32 gGLProjection[16];
@@ -60,7 +60,7 @@ F32 gGLProjection[16];
F32 gGLDeltaModelView[16];
F32 gGLInverseDeltaModelView[16];
-S32 gGLViewport[4];
+S32 gGLViewport[4];
U32 LLRender::sUICalls = 0;
@@ -80,113 +80,113 @@ static std::unordered_map<U64, LLVBCache> sVBCache;
static const GLenum sGLTextureType[] =
{
- GL_TEXTURE_2D,
- GL_TEXTURE_RECTANGLE,
- GL_TEXTURE_CUBE_MAP,
+ GL_TEXTURE_2D,
+ GL_TEXTURE_RECTANGLE,
+ GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_CUBE_MAP_ARRAY,
- GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_2D_MULTISAMPLE,
GL_TEXTURE_3D
};
static const GLint sGLAddressMode[] =
-{
- GL_REPEAT,
- GL_MIRRORED_REPEAT,
- GL_CLAMP_TO_EDGE
+{
+ GL_REPEAT,
+ GL_MIRRORED_REPEAT,
+ GL_CLAMP_TO_EDGE
};
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
static const GLenum sGLBlendFactor[] =
{
- GL_ONE,
- GL_ZERO,
- GL_DST_COLOR,
- GL_SRC_COLOR,
- GL_ONE_MINUS_DST_COLOR,
- GL_ONE_MINUS_SRC_COLOR,
- GL_DST_ALPHA,
- GL_SRC_ALPHA,
- GL_ONE_MINUS_DST_ALPHA,
- GL_ONE_MINUS_SRC_ALPHA,
-
- GL_ZERO // 'BF_UNDEF'
+ GL_ONE,
+ GL_ZERO,
+ GL_DST_COLOR,
+ GL_SRC_COLOR,
+ GL_ONE_MINUS_DST_COLOR,
+ GL_ONE_MINUS_SRC_COLOR,
+ GL_DST_ALPHA,
+ GL_SRC_ALPHA,
+ GL_ONE_MINUS_DST_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA,
+
+ GL_ZERO // 'BF_UNDEF'
};
LLTexUnit::LLTexUnit(S32 index)
- : mCurrTexType(TT_NONE),
+ : mCurrTexType(TT_NONE),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR),
- mHasMipMaps(false),
- mIndex(index)
+ mHasMipMaps(false),
+ mIndex(index)
{
- llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
+ llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
}
//static
U32 LLTexUnit::getInternalType(eTextureType type)
{
- return sGLTextureType[type];
+ return sGLTextureType[type];
}
void LLTexUnit::refreshState(void)
{
- // We set dirty to true so that the tex unit knows to ignore caching
- // and we reset the cached tex unit state
+ // We set dirty to true so that the tex unit knows to ignore caching
+ // and we reset the cached tex unit state
- gGL.flush();
+ gGL.flush();
+
+ glActiveTexture(GL_TEXTURE0 + mIndex);
- glActiveTexture(GL_TEXTURE0 + mIndex);
-
- if (mCurrTexType != TT_NONE)
- {
- glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
- }
- else
- {
- glBindTexture(GL_TEXTURE_2D, 0);
- }
+ if (mCurrTexType != TT_NONE)
+ {
+ glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
setTextureColorSpace(mTexColorSpace);
}
void LLTexUnit::activate(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0) return;
- if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
- {
- gGL.flush();
- glActiveTexture(GL_TEXTURE0 + mIndex);
- gGL.mCurrTextureUnitIndex = mIndex;
- }
+ if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
+ {
+ gGL.flush();
+ glActiveTexture(GL_TEXTURE0 + mIndex);
+ gGL.mCurrTextureUnitIndex = mIndex;
+ }
}
void LLTexUnit::enable(eTextureType type)
{
- if (mIndex < 0) return;
+ if (mIndex < 0) return;
- if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
- {
- activate();
- if (mCurrTexType != TT_NONE && !gGL.mDirty)
- {
- disable(); // Force a disable of a previous texture type if it's enabled.
- }
- mCurrTexType = type;
+ if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
+ {
+ activate();
+ if (mCurrTexType != TT_NONE && !gGL.mDirty)
+ {
+ disable(); // Force a disable of a previous texture type if it's enabled.
+ }
+ mCurrTexType = type;
- gGL.flush();
- }
+ gGL.flush();
+ }
}
void LLTexUnit::disable(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0) return;
- if (mCurrTexType != TT_NONE)
- {
- unbind(mCurrTexType);
- mCurrTexType = TT_NONE;
- }
+ if (mCurrTexType != TT_NONE)
+ {
+ unbind(mCurrTexType);
+ mCurrTexType = TT_NONE;
+ }
}
void LLTexUnit::bindFast(LLTexture* texture)
@@ -211,231 +211,231 @@ void LLTexUnit::bindFast(LLTexture* texture)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- stop_glerror();
- if (mIndex >= 0)
- {
- gGL.flush();
-
- LLImageGL* gl_tex = NULL ;
-
- if (texture != NULL && (gl_tex = texture->getGLTexture()))
- {
- if (gl_tex->getTexName()) //if texture exists
- {
- //in audit, replace the selected texture by the default one.
- if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
- {
- activate();
- enable(gl_tex->getTarget());
- mCurrTexture = gl_tex->getTexName();
- glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
- if(gl_tex->updateBindStats())
- {
- texture->setActive() ;
- texture->updateBindStatsForTester() ;
- }
- mHasMipMaps = gl_tex->mHasMipMaps;
- if (gl_tex->mTexOptionsDirty)
- {
- gl_tex->mTexOptionsDirty = false;
- setTextureAddressMode(gl_tex->mAddressMode);
- setTextureFilteringOption(gl_tex->mFilterOption);
+ stop_glerror();
+ if (mIndex >= 0)
+ {
+ gGL.flush();
+
+ LLImageGL* gl_tex = NULL ;
+
+ if (texture != NULL && (gl_tex = texture->getGLTexture()))
+ {
+ if (gl_tex->getTexName()) //if texture exists
+ {
+ //in audit, replace the selected texture by the default one.
+ if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
+ {
+ activate();
+ enable(gl_tex->getTarget());
+ mCurrTexture = gl_tex->getTexName();
+ glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
+ if(gl_tex->updateBindStats())
+ {
+ texture->setActive() ;
+ texture->updateBindStatsForTester() ;
+ }
+ mHasMipMaps = gl_tex->mHasMipMaps;
+ if (gl_tex->mTexOptionsDirty)
+ {
+ gl_tex->mTexOptionsDirty = false;
+ setTextureAddressMode(gl_tex->mAddressMode);
+ setTextureFilteringOption(gl_tex->mFilterOption);
}
setTextureColorSpace(mTexColorSpace);
- }
- }
- else
- {
- //if deleted, will re-generate it immediately
- texture->forceImmediateUpdate() ;
-
- gl_tex->forceUpdateBindStats() ;
- return texture->bindDefaultImage(mIndex);
- }
- }
- else
- {
- if (texture)
- {
- LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL;
- }
- else
- {
- LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
- }
- return false;
- }
- }
- else
- { // mIndex < 0
- return false;
- }
-
- return true;
+ }
+ }
+ else
+ {
+ //if deleted, will re-generate it immediately
+ texture->forceImmediateUpdate() ;
+
+ gl_tex->forceUpdateBindStats() ;
+ return texture->bindDefaultImage(mIndex);
+ }
+ }
+ else
+ {
+ if (texture)
+ {
+ LL_DEBUGS() << "NULL LLTexUnit::bind GL image" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
+ }
+ return false;
+ }
+ }
+ else
+ { // mIndex < 0
+ return false;
+ }
+
+ return true;
}
bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename)
{
- stop_glerror();
- if (mIndex < 0) return false;
+ stop_glerror();
+ if (mIndex < 0) return false;
U32 texname = usename ? usename : texture->getTexName();
- if(!texture)
- {
- LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
- return false;
- }
-
- if(!texname)
- {
- if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
- {
- return bind(LLImageGL::sDefaultGLTexture) ;
- }
- stop_glerror();
- return false ;
- }
-
- if ((mCurrTexture != texname) || forceBind)
- {
- gGL.flush();
- stop_glerror();
- activate();
- stop_glerror();
- enable(texture->getTarget());
- stop_glerror();
- mCurrTexture = texname;
- glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
- stop_glerror();
+ if(!texture)
+ {
+ LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
+ return false;
+ }
+
+ if(!texname)
+ {
+ if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
+ {
+ return bind(LLImageGL::sDefaultGLTexture) ;
+ }
+ stop_glerror();
+ return false ;
+ }
+
+ if ((mCurrTexture != texname) || forceBind)
+ {
+ gGL.flush();
+ stop_glerror();
+ activate();
+ stop_glerror();
+ enable(texture->getTarget());
+ stop_glerror();
+ mCurrTexture = texname;
+ glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
+ stop_glerror();
texture->updateBindStats();
- mHasMipMaps = texture->mHasMipMaps;
- if (texture->mTexOptionsDirty)
- {
- stop_glerror();
- texture->mTexOptionsDirty = false;
- setTextureAddressMode(texture->mAddressMode);
- setTextureFilteringOption(texture->mFilterOption);
- stop_glerror();
- }
+ mHasMipMaps = texture->mHasMipMaps;
+ if (texture->mTexOptionsDirty)
+ {
+ stop_glerror();
+ texture->mTexOptionsDirty = false;
+ setTextureAddressMode(texture->mAddressMode);
+ setTextureFilteringOption(texture->mFilterOption);
+ stop_glerror();
+ }
setTextureColorSpace(mTexColorSpace);
- }
+ }
- stop_glerror();
+ stop_glerror();
- return true;
+ return true;
}
bool LLTexUnit::bind(LLCubeMap* cubeMap)
{
- if (mIndex < 0) return false;
+ if (mIndex < 0) return false;
- gGL.flush();
+ gGL.flush();
- if (cubeMap == NULL)
- {
- LL_WARNS() << "NULL LLTexUnit::bind cubemap" << LL_ENDL;
- return false;
- }
+ if (cubeMap == NULL)
+ {
+ LL_WARNS() << "NULL LLTexUnit::bind cubemap" << LL_ENDL;
+ return false;
+ }
- if (mCurrTexture != cubeMap->mImages[0]->getTexName())
- {
- if (LLCubeMap::sUseCubeMaps)
- {
- activate();
- enable(LLTexUnit::TT_CUBE_MAP);
+ if (mCurrTexture != cubeMap->mImages[0]->getTexName())
+ {
+ if (LLCubeMap::sUseCubeMaps)
+ {
+ activate();
+ enable(LLTexUnit::TT_CUBE_MAP);
mCurrTexture = cubeMap->mImages[0]->getTexName();
- glBindTexture(GL_TEXTURE_CUBE_MAP, mCurrTexture);
- mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
- cubeMap->mImages[0]->updateBindStats();
- if (cubeMap->mImages[0]->mTexOptionsDirty)
- {
- cubeMap->mImages[0]->mTexOptionsDirty = false;
- setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
- setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, mCurrTexture);
+ mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
+ cubeMap->mImages[0]->updateBindStats();
+ if (cubeMap->mImages[0]->mTexOptionsDirty)
+ {
+ cubeMap->mImages[0]->mTexOptionsDirty = false;
+ setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
+ setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
}
setTextureColorSpace(mTexColorSpace);
- return true;
- }
- else
- {
- LL_WARNS() << "Using cube map without extension!" << LL_ENDL;
- return false;
- }
- }
- return true;
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "Using cube map without extension!" << LL_ENDL;
+ return false;
+ }
+ }
+ return true;
}
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
{
- if (mIndex < 0) return false;
+ if (mIndex < 0) return false;
- gGL.flush();
+ gGL.flush();
- if (bindDepth)
- {
+ if (bindDepth)
+ {
llassert(renderTarget->getDepth()); // target MUST have a depth buffer attachment
- bindManual(renderTarget->getUsage(), renderTarget->getDepth());
- }
- else
- {
- bindManual(renderTarget->getUsage(), renderTarget->getTexture());
- }
+ bindManual(renderTarget->getUsage(), renderTarget->getDepth());
+ }
+ else
+ {
+ bindManual(renderTarget->getUsage(), renderTarget->getTexture());
+ }
- return true;
+ return true;
}
bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
{
- if (mIndex < 0)
- {
- return false;
- }
-
- if(mCurrTexture != texture)
- {
- gGL.flush();
-
- activate();
- enable(type);
- mCurrTexture = texture;
- glBindTexture(sGLTextureType[type], texture);
+ if (mIndex < 0)
+ {
+ return false;
+ }
+
+ if(mCurrTexture != texture)
+ {
+ gGL.flush();
+
+ activate();
+ enable(type);
+ mCurrTexture = texture;
+ glBindTexture(sGLTextureType[type], texture);
mHasMipMaps = hasMips;
setTextureColorSpace(mTexColorSpace);
- }
- return true;
+ }
+ return true;
}
void LLTexUnit::unbind(eTextureType type)
{
- stop_glerror();
+ stop_glerror();
- if (mIndex < 0) return;
+ if (mIndex < 0) return;
- //always flush and activate for consistency
- // some code paths assume unbind always flushes and sets the active texture
- gGL.flush();
- activate();
+ //always flush and activate for consistency
+ // some code paths assume unbind always flushes and sets the active texture
+ gGL.flush();
+ activate();
- // Disabled caching of binding state.
- if (mCurrTexType == type)
- {
- mCurrTexture = 0;
+ // Disabled caching of binding state.
+ if (mCurrTexType == type)
+ {
+ mCurrTexture = 0;
// Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
mTexColorSpace = TCS_LINEAR;
- if (type == LLTexUnit::TT_TEXTURE)
- {
- glBindTexture(sGLTextureType[type], sWhiteTexture);
- }
- else
- {
- glBindTexture(sGLTextureType[type], 0);
- }
- stop_glerror();
- }
+ if (type == LLTexUnit::TT_TEXTURE)
+ {
+ glBindTexture(sGLTextureType[type], sWhiteTexture);
+ }
+ else
+ {
+ glBindTexture(sGLTextureType[type], 0);
+ }
+ stop_glerror();
+ }
}
void LLTexUnit::unbindFast(eTextureType type)
@@ -462,184 +462,184 @@ void LLTexUnit::unbindFast(eTextureType type)
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
{
- if (mIndex < 0 || mCurrTexture == 0) return;
+ if (mIndex < 0 || mCurrTexture == 0) return;
- gGL.flush();
+ gGL.flush();
- activate();
+ activate();
- glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
- glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
- if (mCurrTexType == TT_CUBE_MAP)
- {
- glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
- }
+ glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
+ glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
+ if (mCurrTexType == TT_CUBE_MAP)
+ {
+ glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
+ }
}
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
- if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
-
- gGL.flush();
-
- if (option == TFO_POINT)
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
- else
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
-
- if (option >= TFO_TRILINEAR && mHasMipMaps)
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- }
- else if (option >= TFO_BILINEAR)
- {
- if (mHasMipMaps)
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- }
- else
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
- }
- else
- {
- if (mHasMipMaps)
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- }
- else
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- }
-
- if (gGLManager.mGLVersion >= 4.59f)
- {
- if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
- {
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy);
- }
- else
- {
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f);
- }
- }
+ if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
+
+ gGL.flush();
+
+ if (option == TFO_POINT)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ if (option >= TFO_TRILINEAR && mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ }
+ else if (option >= TFO_BILINEAR)
+ {
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+ }
+ else
+ {
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ }
+
+ if (gGLManager.mGLVersion >= 4.59f)
+ {
+ if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
+ {
+ glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy);
+ }
+ else
+ {
+ glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f);
+ }
+ }
}
GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
{
- switch(src)
- {
- // All four cases should return the same value.
- case TBS_PREV_COLOR:
- case TBS_PREV_ALPHA:
- case TBS_ONE_MINUS_PREV_COLOR:
- case TBS_ONE_MINUS_PREV_ALPHA:
- return GL_PREVIOUS;
-
- // All four cases should return the same value.
- case TBS_TEX_COLOR:
- case TBS_TEX_ALPHA:
- case TBS_ONE_MINUS_TEX_COLOR:
- case TBS_ONE_MINUS_TEX_ALPHA:
- return GL_TEXTURE;
-
- // All four cases should return the same value.
- case TBS_VERT_COLOR:
- case TBS_VERT_ALPHA:
- case TBS_ONE_MINUS_VERT_COLOR:
- case TBS_ONE_MINUS_VERT_ALPHA:
- return GL_PRIMARY_COLOR;
-
- // All four cases should return the same value.
- case TBS_CONST_COLOR:
- case TBS_CONST_ALPHA:
- case TBS_ONE_MINUS_CONST_COLOR:
- case TBS_ONE_MINUS_CONST_ALPHA:
- return GL_CONSTANT;
-
- default:
- LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL;
- return GL_PRIMARY_COLOR;
- }
+ switch(src)
+ {
+ // All four cases should return the same value.
+ case TBS_PREV_COLOR:
+ case TBS_PREV_ALPHA:
+ case TBS_ONE_MINUS_PREV_COLOR:
+ case TBS_ONE_MINUS_PREV_ALPHA:
+ return GL_PREVIOUS;
+
+ // All four cases should return the same value.
+ case TBS_TEX_COLOR:
+ case TBS_TEX_ALPHA:
+ case TBS_ONE_MINUS_TEX_COLOR:
+ case TBS_ONE_MINUS_TEX_ALPHA:
+ return GL_TEXTURE;
+
+ // All four cases should return the same value.
+ case TBS_VERT_COLOR:
+ case TBS_VERT_ALPHA:
+ case TBS_ONE_MINUS_VERT_COLOR:
+ case TBS_ONE_MINUS_VERT_ALPHA:
+ return GL_PRIMARY_COLOR;
+
+ // All four cases should return the same value.
+ case TBS_CONST_COLOR:
+ case TBS_CONST_ALPHA:
+ case TBS_ONE_MINUS_CONST_COLOR:
+ case TBS_ONE_MINUS_CONST_ALPHA:
+ return GL_CONSTANT;
+
+ default:
+ LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL;
+ return GL_PRIMARY_COLOR;
+ }
}
GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
{
- switch(src)
- {
- // All four cases should return the same value.
- case TBS_PREV_COLOR:
- case TBS_TEX_COLOR:
- case TBS_VERT_COLOR:
- case TBS_CONST_COLOR:
- return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
-
- // All four cases should return the same value.
- case TBS_PREV_ALPHA:
- case TBS_TEX_ALPHA:
- case TBS_VERT_ALPHA:
- case TBS_CONST_ALPHA:
- return GL_SRC_ALPHA;
-
- // All four cases should return the same value.
- case TBS_ONE_MINUS_PREV_COLOR:
- case TBS_ONE_MINUS_TEX_COLOR:
- case TBS_ONE_MINUS_VERT_COLOR:
- case TBS_ONE_MINUS_CONST_COLOR:
- return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR;
-
- // All four cases should return the same value.
- case TBS_ONE_MINUS_PREV_ALPHA:
- case TBS_ONE_MINUS_TEX_ALPHA:
- case TBS_ONE_MINUS_VERT_ALPHA:
- case TBS_ONE_MINUS_CONST_ALPHA:
- return GL_ONE_MINUS_SRC_ALPHA;
-
- default:
- LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL;
- return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
- }
+ switch(src)
+ {
+ // All four cases should return the same value.
+ case TBS_PREV_COLOR:
+ case TBS_TEX_COLOR:
+ case TBS_VERT_COLOR:
+ case TBS_CONST_COLOR:
+ return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
+
+ // All four cases should return the same value.
+ case TBS_PREV_ALPHA:
+ case TBS_TEX_ALPHA:
+ case TBS_VERT_ALPHA:
+ case TBS_CONST_ALPHA:
+ return GL_SRC_ALPHA;
+
+ // All four cases should return the same value.
+ case TBS_ONE_MINUS_PREV_COLOR:
+ case TBS_ONE_MINUS_TEX_COLOR:
+ case TBS_ONE_MINUS_VERT_COLOR:
+ case TBS_ONE_MINUS_CONST_COLOR:
+ return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR;
+
+ // All four cases should return the same value.
+ case TBS_ONE_MINUS_PREV_ALPHA:
+ case TBS_ONE_MINUS_TEX_ALPHA:
+ case TBS_ONE_MINUS_VERT_ALPHA:
+ case TBS_ONE_MINUS_CONST_ALPHA:
+ return GL_ONE_MINUS_SRC_ALPHA;
+
+ default:
+ LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL;
+ return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
+ }
}
void LLTexUnit::setColorScale(S32 scale)
{
- if (mCurrColorScale != scale || gGL.mDirty)
- {
- mCurrColorScale = scale;
- gGL.flush();
- glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
- }
+ if (mCurrColorScale != scale || gGL.mDirty)
+ {
+ mCurrColorScale = scale;
+ gGL.flush();
+ glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
+ }
}
void LLTexUnit::setAlphaScale(S32 scale)
{
- if (mCurrAlphaScale != scale || gGL.mDirty)
- {
- mCurrAlphaScale = scale;
- gGL.flush();
- glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
- }
+ if (mCurrAlphaScale != scale || gGL.mDirty)
+ {
+ mCurrAlphaScale = scale;
+ gGL.flush();
+ glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
+ }
}
-// Useful for debugging that you've manually assigned a texture operation to the correct
+// Useful for debugging that you've manually assigned a texture operation to the correct
// texture unit based on the currently set active texture in opengl.
void LLTexUnit::debugTextureUnit(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0) return;
- GLint activeTexture;
- glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
- if ((GL_TEXTURE0 + mIndex) != activeTexture)
- {
- U32 set_unit = (activeTexture - GL_TEXTURE0);
- LL_WARNS() << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << LL_ENDL;
- }
+ GLint activeTexture;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
+ if ((GL_TEXTURE0 + mIndex) != activeTexture)
+ {
+ U32 set_unit = (activeTexture - GL_TEXTURE0);
+ LL_WARNS() << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << LL_ENDL;
+ }
}
void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
@@ -656,46 +656,46 @@ LLLightState::LLLightState(S32 index)
mSpotExponent(0.f),
mSpotCutoff(180.f)
{
- if (mIndex == 0)
- {
- mDiffuse.set(1,1,1,1);
+ if (mIndex == 0)
+ {
+ mDiffuse.set(1,1,1,1);
mDiffuseB.set(0,0,0,0);
- mSpecular.set(1,1,1,1);
- }
+ mSpecular.set(1,1,1,1);
+ }
mSunIsPrimary = true;
- mAmbient.set(0,0,0,1);
- mPosition.set(0,0,1,0);
- mSpotDirection.set(0,0,-1);
+ mAmbient.set(0,0,0,1);
+ mPosition.set(0,0,1,0);
+ mSpotDirection.set(0,0,-1);
}
void LLLightState::enable()
{
- mEnabled = true;
+ mEnabled = true;
}
void LLLightState::disable()
{
- mEnabled = false;
+ mEnabled = false;
}
void LLLightState::setDiffuse(const LLColor4& diffuse)
{
- if (mDiffuse != diffuse)
- {
- ++gGL.mLightHash;
- mDiffuse = diffuse;
- }
+ if (mDiffuse != diffuse)
+ {
+ ++gGL.mLightHash;
+ mDiffuse = diffuse;
+ }
}
void LLLightState::setDiffuseB(const LLColor4& diffuse)
{
if (mDiffuseB != diffuse)
- {
- ++gGL.mLightHash;
- mDiffuseB = diffuse;
- }
+ {
+ ++gGL.mLightHash;
+ mDiffuseB = diffuse;
+ }
}
void LLLightState::setSunPrimary(bool v)
@@ -703,7 +703,7 @@ void LLLightState::setSunPrimary(bool v)
if (mSunIsPrimary != v)
{
++gGL.mLightHash;
- mSunIsPrimary = v;
+ mSunIsPrimary = v;
}
}
@@ -727,134 +727,134 @@ void LLLightState::setFalloff(F32 v)
void LLLightState::setAmbient(const LLColor4& ambient)
{
- if (mAmbient != ambient)
- {
- ++gGL.mLightHash;
- mAmbient = ambient;
- }
+ if (mAmbient != ambient)
+ {
+ ++gGL.mLightHash;
+ mAmbient = ambient;
+ }
}
void LLLightState::setSpecular(const LLColor4& specular)
{
- if (mSpecular != specular)
- {
- ++gGL.mLightHash;
- mSpecular = specular;
- }
+ if (mSpecular != specular)
+ {
+ ++gGL.mLightHash;
+ mSpecular = specular;
+ }
}
void LLLightState::setPosition(const LLVector4& position)
{
- //always set position because modelview matrix may have changed
- ++gGL.mLightHash;
- mPosition = position;
- //transform position by current modelview matrix
- glh::vec4f pos(position.mV);
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_vec(pos);
- mPosition.set(pos.v);
+ //always set position because modelview matrix may have changed
+ ++gGL.mLightHash;
+ mPosition = position;
+ //transform position by current modelview matrix
+ glh::vec4f pos(position.mV);
+ const glh::matrix4f& mat = gGL.getModelviewMatrix();
+ mat.mult_matrix_vec(pos);
+ mPosition.set(pos.v);
}
void LLLightState::setConstantAttenuation(const F32& atten)
{
- if (mConstantAtten != atten)
- {
- mConstantAtten = atten;
- ++gGL.mLightHash;
- }
+ if (mConstantAtten != atten)
+ {
+ mConstantAtten = atten;
+ ++gGL.mLightHash;
+ }
}
void LLLightState::setLinearAttenuation(const F32& atten)
{
- if (mLinearAtten != atten)
- {
- ++gGL.mLightHash;
- mLinearAtten = atten;
- }
+ if (mLinearAtten != atten)
+ {
+ ++gGL.mLightHash;
+ mLinearAtten = atten;
+ }
}
void LLLightState::setQuadraticAttenuation(const F32& atten)
{
- if (mQuadraticAtten != atten)
- {
- ++gGL.mLightHash;
- mQuadraticAtten = atten;
- }
+ if (mQuadraticAtten != atten)
+ {
+ ++gGL.mLightHash;
+ mQuadraticAtten = atten;
+ }
}
void LLLightState::setSpotExponent(const F32& exponent)
{
- if (mSpotExponent != exponent)
- {
- ++gGL.mLightHash;
- mSpotExponent = exponent;
- }
+ if (mSpotExponent != exponent)
+ {
+ ++gGL.mLightHash;
+ mSpotExponent = exponent;
+ }
}
void LLLightState::setSpotCutoff(const F32& cutoff)
{
- if (mSpotCutoff != cutoff)
- {
- ++gGL.mLightHash;
- mSpotCutoff = cutoff;
- }
+ if (mSpotCutoff != cutoff)
+ {
+ ++gGL.mLightHash;
+ mSpotCutoff = cutoff;
+ }
}
void LLLightState::setSpotDirection(const LLVector3& direction)
{
- //always set direction because modelview matrix may have changed
- ++gGL.mLightHash;
- mSpotDirection = direction;
- //transform direction by current modelview matrix
- glh::vec3f dir(direction.mV);
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_dir(dir);
+ //always set direction because modelview matrix may have changed
+ ++gGL.mLightHash;
+ mSpotDirection = direction;
+ //transform direction by current modelview matrix
+ glh::vec3f dir(direction.mV);
+ const glh::matrix4f& mat = gGL.getModelviewMatrix();
+ mat.mult_matrix_dir(dir);
- mSpotDirection.set(dir.v);
+ mSpotDirection.set(dir.v);
}
LLRender::LLRender()
: mDirty(false),
mCount(0),
- mQuadCycle(0),
+ mQuadCycle(0),
mMode(LLRender::TRIANGLES),
mCurrTextureUnitIndex(0)
-{
- for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
- {
+{
+ for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
+ {
mTexUnits[i].mIndex = i;
- }
+ }
- for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i)
- {
+ for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i)
+ {
mLightState[i].mIndex = i;
- }
+ }
- for (U32 i = 0; i < 4; i++)
- {
- mCurrColorMask[i] = true;
- }
+ for (U32 i = 0; i < 4; i++)
+ {
+ mCurrColorMask[i] = true;
+ }
- mCurrBlendColorSFactor = BF_UNDEF;
- mCurrBlendAlphaSFactor = BF_UNDEF;
- mCurrBlendColorDFactor = BF_UNDEF;
- mCurrBlendAlphaDFactor = BF_UNDEF;
+ mCurrBlendColorSFactor = BF_UNDEF;
+ mCurrBlendAlphaSFactor = BF_UNDEF;
+ mCurrBlendColorDFactor = BF_UNDEF;
+ mCurrBlendAlphaDFactor = BF_UNDEF;
- mMatrixMode = LLRender::MM_MODELVIEW;
+ mMatrixMode = LLRender::MM_MODELVIEW;
+
+ for (U32 i = 0; i < NUM_MATRIX_MODES; ++i)
+ {
+ mMatIdx[i] = 0;
+ mMatHash[i] = 0;
+ mCurMatHash[i] = 0xFFFFFFFF;
+ }
- for (U32 i = 0; i < NUM_MATRIX_MODES; ++i)
- {
- mMatIdx[i] = 0;
- mMatHash[i] = 0;
- mCurMatHash[i] = 0xFFFFFFFF;
- }
-
- mLightHash = 0;
+ mLightHash = 0;
}
LLRender::~LLRender()
{
- shutdown();
+ shutdown();
}
bool LLRender::init(bool needs_vertex_buffer)
@@ -923,22 +923,22 @@ void LLRender::shutdown()
void LLRender::refreshState(void)
{
- mDirty = true;
-
- U32 active_unit = mCurrTextureUnitIndex;
+ mDirty = true;
- for (U32 i = 0; i < mTexUnits.size(); i++)
- {
- mTexUnits[i].refreshState();
- }
+ U32 active_unit = mCurrTextureUnitIndex;
- mTexUnits[active_unit].activate();
-
- setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
+ for (U32 i = 0; i < mTexUnits.size(); i++)
+ {
+ mTexUnits[i].refreshState();
+ }
+
+ mTexUnits[active_unit].activate();
+ setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
+
flush();
- mDirty = false;
+ mDirty = false;
}
void LLRender::syncLightState()
@@ -990,36 +990,36 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
- static const U32 name[] =
- {
- LLShaderMgr::MODELVIEW_MATRIX,
- LLShaderMgr::PROJECTION_MATRIX,
- LLShaderMgr::TEXTURE_MATRIX0,
- LLShaderMgr::TEXTURE_MATRIX1,
- LLShaderMgr::TEXTURE_MATRIX2,
- LLShaderMgr::TEXTURE_MATRIX3,
- };
+ static const U32 name[] =
+ {
+ LLShaderMgr::MODELVIEW_MATRIX,
+ LLShaderMgr::PROJECTION_MATRIX,
+ LLShaderMgr::TEXTURE_MATRIX0,
+ LLShaderMgr::TEXTURE_MATRIX1,
+ LLShaderMgr::TEXTURE_MATRIX2,
+ LLShaderMgr::TEXTURE_MATRIX3,
+ };
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- static glh::matrix4f cached_mvp;
+ 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;
-
- static glh::matrix4f cached_normal;
- static U32 cached_normal_hash = 0xFFFFFFFF;
+ static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
+ static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
+
+ static glh::matrix4f cached_normal;
+ static U32 cached_normal_hash = 0xFFFFFFFF;
- if (shader)
- {
- //llassert(shader);
+ if (shader)
+ {
+ //llassert(shader);
- bool mvp_done = false;
+ bool mvp_done = false;
- U32 i = MM_MODELVIEW;
- if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW])
- { //update modelview, normal, and MVP
- glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
+ U32 i = MM_MODELVIEW;
+ if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW])
+ { //update modelview, normal, and MVP
+ glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
// if MDV has changed, update the cached inverse as well
if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW])
@@ -1027,240 +1027,240 @@ void LLRender::syncMatrices()
cached_inv_mdv = mat.inverse();
}
- shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m);
- shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW];
+ 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);
- if (loc > -1)
- {
- if (cached_normal_hash != mMatHash[i])
- {
- cached_normal = cached_inv_mdv.transpose();
- cached_normal_hash = mMatHash[i];
- }
+ //update normal matrix
+ S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX);
+ if (loc > -1)
+ {
+ if (cached_normal_hash != mMatHash[i])
+ {
+ cached_normal = cached_inv_mdv.transpose();
+ cached_normal_hash = mMatHash[i];
+ }
- glh::matrix4f& norm = cached_normal;
+ glh::matrix4f& norm = cached_normal;
- F32 norm_mat[] =
- {
- norm.m[0], norm.m[1], norm.m[2],
- norm.m[4], norm.m[5], norm.m[6],
- norm.m[8], norm.m[9], norm.m[10]
- };
+ F32 norm_mat[] =
+ {
+ norm.m[0], norm.m[1], norm.m[2],
+ norm.m[4], norm.m[5], norm.m[6],
+ norm.m[8], norm.m[9], norm.m[10]
+ };
- shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
- }
+ 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);
+ {
+ 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);
- if (loc > -1)
- {
- U32 proj = MM_PROJECTION;
-
- if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
- {
- cached_mvp = mat;
- cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
- cached_mvp_mdv_hash = mMatHash[i];
- cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
- }
-
- shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
- }
- }
-
- i = MM_PROJECTION;
- if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION])
- { //update projection matrix, normal, and MVP
- glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
+ //update MVP matrix
+ mvp_done = true;
+ loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
+ if (loc > -1)
+ {
+ U32 proj = MM_PROJECTION;
+
+ if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+ {
+ cached_mvp = mat;
+ cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
+ cached_mvp_mdv_hash = mMatHash[i];
+ cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
+ }
+
+ shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+ }
+ }
+
+ i = MM_PROJECTION;
+ if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION])
+ { //update projection matrix, normal, and MVP
+ glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
// GZ: This was previously disabled seemingly due to a bug involving the deferred renderer's regular pushing and popping of mats.
- // We're reenabling this and cleaning up the code around that - that would've been the appropriate course initially.
- // Anything beyond the standard proj and inv proj mats are special cases. Please setup special uniforms accordingly in the future.
+ // We're reenabling this and cleaning up the code around that - that would've been the appropriate course initially.
+ // Anything beyond the standard proj and inv proj mats are special cases. Please setup special uniforms accordingly in the future.
if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX))
{
- glh::matrix4f inv_proj = mat.inverse();
- shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ glh::matrix4f inv_proj = mat.inverse();
+ shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
}
- // Used by some full screen effects - such as full screen lights, glow, etc.
+ // Used by some full screen effects - such as full screen lights, glow, etc.
if (shader->getUniformLocation(LLShaderMgr::IDENTITY_MATRIX))
{
shader->uniformMatrix4fv(LLShaderMgr::IDENTITY_MATRIX, 1, GL_FALSE, glh::matrix4f::identity().m);
}
- shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m);
- shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION];
-
- if (!mvp_done)
- {
- //update MVP matrix
- S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
- if (loc > -1)
- {
- if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
- {
- U32 mdv = MM_MODELVIEW;
- cached_mvp = mat;
- cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
- cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
- cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
- }
-
- shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
- }
- }
- }
-
- for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
- {
- if (mMatHash[i] != shader->mMatHash[i])
- {
- shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m);
- shader->mMatHash[i] = mMatHash[i];
- }
- }
-
-
- if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics)
- { //also sync light state
- syncLightState();
- }
- }
+ shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m);
+ shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION];
+
+ if (!mvp_done)
+ {
+ //update MVP matrix
+ S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
+ if (loc > -1)
+ {
+ if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+ {
+ U32 mdv = MM_MODELVIEW;
+ cached_mvp = mat;
+ cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
+ cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
+ cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
+ }
+
+ shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+ }
+ }
+ }
+
+ for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
+ {
+ if (mMatHash[i] != shader->mMatHash[i])
+ {
+ shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m);
+ shader->mMatHash[i] = mMatHash[i];
+ }
+ }
+
+
+ if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics)
+ { //also sync light state
+ syncLightState();
+ }
+ }
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
- flush();
+ flush();
- {
- glh::matrix4f trans_mat(1,0,0,x,
- 0,1,0,y,
- 0,0,1,z,
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
- mMatHash[mMatrixMode]++;
- }
+ {
+ glh::matrix4f trans_mat(1,0,0,x,
+ 0,1,0,y,
+ 0,0,1,z,
+ 0,0,0,1);
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
- flush();
-
- {
- glh::matrix4f scale_mat(x,0,0,0,
- 0,y,0,0,
- 0,0,z,0,
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
- mMatHash[mMatrixMode]++;
- }
+ flush();
+
+ {
+ glh::matrix4f scale_mat(x,0,0,0,
+ 0,y,0,0,
+ 0,0,z,0,
+ 0,0,0,1);
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar)
{
- flush();
-
- {
+ flush();
- glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left),
- 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom),
- 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear),
- 0,0,0,1);
+ {
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat);
- mMatHash[mMatrixMode]++;
- }
+ glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left),
+ 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom),
+ 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear),
+ 0,0,0,1);
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
- flush();
-
- {
- F32 r = a * DEG_TO_RAD;
+ flush();
- F32 c = cosf(r);
- F32 s = sinf(r);
+ {
+ F32 r = a * DEG_TO_RAD;
- F32 ic = 1.f-c;
+ F32 c = cosf(r);
+ F32 s = sinf(r);
- glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0,
- x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0,
- x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0,
- 0,0,0,1);
+ F32 ic = 1.f-c;
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat);
- mMatHash[mMatrixMode]++;
- }
+ glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0,
+ x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0,
+ x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0,
+ 0,0,0,1);
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::pushMatrix()
{
- flush();
-
- {
- if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
- {
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
- ++mMatIdx[mMatrixMode];
- }
- else
- {
- LL_WARNS() << "Matrix stack overflow." << LL_ENDL;
- }
- }
+ flush();
+
+ {
+ if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
+ {
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
+ ++mMatIdx[mMatrixMode];
+ }
+ else
+ {
+ LL_WARNS() << "Matrix stack overflow." << LL_ENDL;
+ }
+ }
}
void LLRender::popMatrix()
{
- flush();
- {
- if (mMatIdx[mMatrixMode] > 0)
- {
- --mMatIdx[mMatrixMode];
- mMatHash[mMatrixMode]++;
- }
- else
- {
- LL_WARNS() << "Matrix stack underflow." << LL_ENDL;
- }
- }
+ flush();
+ {
+ if (mMatIdx[mMatrixMode] > 0)
+ {
+ --mMatIdx[mMatrixMode];
+ mMatHash[mMatrixMode]++;
+ }
+ else
+ {
+ LL_WARNS() << "Matrix stack underflow." << LL_ENDL;
+ }
+ }
}
void LLRender::loadMatrix(const GLfloat* m)
{
- flush();
- {
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m);
- mMatHash[mMatrixMode]++;
- }
+ flush();
+ {
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::multMatrix(const GLfloat* m)
{
- flush();
- {
- glh::matrix4f mat((GLfloat*) m);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat);
- mMatHash[mMatrixMode]++;
- }
+ flush();
+ {
+ glh::matrix4f mat((GLfloat*) m);
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat);
+ mMatHash[mMatrixMode]++;
+ }
}
void LLRender::matrixMode(eMatrixMode mode)
{
- if (mode == MM_TEXTURE)
- {
+ if (mode == MM_TEXTURE)
+ {
U32 tex_index = gGL.getCurrentTexUnitIndex();
// the shaders don't actually reference anything beyond texture_matrix0/1 outside of terrain rendering
llassert(tex_index <= 3);
@@ -1272,360 +1272,360 @@ void LLRender::matrixMode(eMatrixMode mode)
LL_WARNS_ONCE() << "Attempted to assign matrix mode out of bounds: " << mode << LL_ENDL;
mode = MM_TEXTURE0;
}
- }
+ }
- mMatrixMode = mode;
+ mMatrixMode = mode;
}
LLRender::eMatrixMode LLRender::getMatrixMode()
{
- if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3)
- { //always return MM_TEXTURE if current matrix mode points at any texture matrix
- return MM_TEXTURE;
- }
+ if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3)
+ { //always return MM_TEXTURE if current matrix mode points at any texture matrix
+ return MM_TEXTURE;
+ }
- return mMatrixMode;
+ return mMatrixMode;
}
void LLRender::loadIdentity()
{
- flush();
+ flush();
- {
- llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
+ {
+ llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
+ mMatHash[mMatrixMode]++;
+ }
}
const glh::matrix4f& LLRender::getModelviewMatrix()
{
- return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
+ return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
}
const glh::matrix4f& LLRender::getProjectionMatrix()
{
- return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
+ return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
}
void LLRender::translateUI(F32 x, F32 y, F32 z)
{
- if (mUIOffset.empty())
- {
- LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL;
- }
+ if (mUIOffset.empty())
+ {
+ LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL;
+ }
- mUIOffset.back().mV[0] += x;
- mUIOffset.back().mV[1] += y;
- mUIOffset.back().mV[2] += z;
+ mUIOffset.back().mV[0] += x;
+ mUIOffset.back().mV[1] += y;
+ mUIOffset.back().mV[2] += z;
}
void LLRender::scaleUI(F32 x, F32 y, F32 z)
{
- if (mUIScale.empty())
- {
- LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL;
- }
+ if (mUIScale.empty())
+ {
+ LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL;
+ }
- mUIScale.back().scaleVec(LLVector3(x,y,z));
+ mUIScale.back().scaleVec(LLVector3(x,y,z));
}
void LLRender::pushUIMatrix()
{
- if (mUIOffset.empty())
- {
- mUIOffset.push_back(LLVector3(0,0,0));
- }
- else
- {
- mUIOffset.push_back(mUIOffset.back());
- }
-
- if (mUIScale.empty())
- {
- mUIScale.push_back(LLVector3(1,1,1));
- }
- else
- {
- mUIScale.push_back(mUIScale.back());
- }
+ if (mUIOffset.empty())
+ {
+ mUIOffset.push_back(LLVector3(0,0,0));
+ }
+ else
+ {
+ mUIOffset.push_back(mUIOffset.back());
+ }
+
+ if (mUIScale.empty())
+ {
+ mUIScale.push_back(LLVector3(1,1,1));
+ }
+ else
+ {
+ mUIScale.push_back(mUIScale.back());
+ }
}
void LLRender::popUIMatrix()
{
- if (mUIOffset.empty())
- {
- LL_ERRS() << "UI offset stack blown." << LL_ENDL;
- }
- mUIOffset.pop_back();
- mUIScale.pop_back();
+ if (mUIOffset.empty())
+ {
+ LL_ERRS() << "UI offset stack blown." << LL_ENDL;
+ }
+ mUIOffset.pop_back();
+ mUIScale.pop_back();
}
LLVector3 LLRender::getUITranslation()
{
- if (mUIOffset.empty())
- {
- return LLVector3(0,0,0);
- }
- return mUIOffset.back();
+ if (mUIOffset.empty())
+ {
+ return LLVector3(0,0,0);
+ }
+ return mUIOffset.back();
}
LLVector3 LLRender::getUIScale()
{
- if (mUIScale.empty())
- {
- return LLVector3(1,1,1);
- }
- return mUIScale.back();
+ if (mUIScale.empty())
+ {
+ return LLVector3(1,1,1);
+ }
+ return mUIScale.back();
}
void LLRender::loadUIIdentity()
{
- if (mUIOffset.empty())
- {
- LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL;
- }
- mUIOffset.back().setVec(0,0,0);
- mUIScale.back().setVec(1,1,1);
+ if (mUIOffset.empty())
+ {
+ LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL;
+ }
+ mUIOffset.back().setVec(0,0,0);
+ mUIScale.back().setVec(1,1,1);
}
void LLRender::setColorMask(bool writeColor, bool writeAlpha)
{
- setColorMask(writeColor, writeColor, writeColor, writeAlpha);
+ setColorMask(writeColor, writeColor, writeColor, writeAlpha);
}
void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
{
- flush();
+ flush();
- if (mCurrColorMask[0] != writeColorR ||
- mCurrColorMask[1] != writeColorG ||
- mCurrColorMask[2] != writeColorB ||
- mCurrColorMask[3] != writeAlpha)
- {
- mCurrColorMask[0] = writeColorR;
- mCurrColorMask[1] = writeColorG;
- mCurrColorMask[2] = writeColorB;
- mCurrColorMask[3] = writeAlpha;
-
- glColorMask(writeColorR ? GL_TRUE : GL_FALSE,
- writeColorG ? GL_TRUE : GL_FALSE,
- writeColorB ? GL_TRUE : GL_FALSE,
- writeAlpha ? GL_TRUE : GL_FALSE);
- }
+ if (mCurrColorMask[0] != writeColorR ||
+ mCurrColorMask[1] != writeColorG ||
+ mCurrColorMask[2] != writeColorB ||
+ mCurrColorMask[3] != writeAlpha)
+ {
+ mCurrColorMask[0] = writeColorR;
+ mCurrColorMask[1] = writeColorG;
+ mCurrColorMask[2] = writeColorB;
+ mCurrColorMask[3] = writeAlpha;
+
+ glColorMask(writeColorR ? GL_TRUE : GL_FALSE,
+ writeColorG ? GL_TRUE : GL_FALSE,
+ writeColorB ? GL_TRUE : GL_FALSE,
+ writeAlpha ? GL_TRUE : GL_FALSE);
+ }
}
void LLRender::setSceneBlendType(eBlendType type)
{
- switch (type)
- {
- case BT_ALPHA:
- blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA);
- break;
- case BT_ADD:
- blendFunc(BF_ONE, BF_ONE);
- break;
- case BT_ADD_WITH_ALPHA:
- blendFunc(BF_SOURCE_ALPHA, BF_ONE);
- break;
- case BT_MULT:
- blendFunc(BF_DEST_COLOR, BF_ZERO);
- break;
- case BT_MULT_ALPHA:
- blendFunc(BF_DEST_ALPHA, BF_ZERO);
- break;
- case BT_MULT_X2:
- blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR);
- break;
- case BT_REPLACE:
- blendFunc(BF_ONE, BF_ZERO);
- break;
- default:
- LL_ERRS() << "Unknown Scene Blend Type: " << type << LL_ENDL;
- break;
- }
+ switch (type)
+ {
+ case BT_ALPHA:
+ blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA);
+ break;
+ case BT_ADD:
+ blendFunc(BF_ONE, BF_ONE);
+ break;
+ case BT_ADD_WITH_ALPHA:
+ blendFunc(BF_SOURCE_ALPHA, BF_ONE);
+ break;
+ case BT_MULT:
+ blendFunc(BF_DEST_COLOR, BF_ZERO);
+ break;
+ case BT_MULT_ALPHA:
+ blendFunc(BF_DEST_ALPHA, BF_ZERO);
+ break;
+ case BT_MULT_X2:
+ blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR);
+ break;
+ case BT_REPLACE:
+ blendFunc(BF_ONE, BF_ZERO);
+ break;
+ default:
+ LL_ERRS() << "Unknown Scene Blend Type: " << type << LL_ENDL;
+ break;
+ }
}
void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
{
- llassert(sfactor < BF_UNDEF);
- llassert(dfactor < BF_UNDEF);
- if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
- mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
- {
- mCurrBlendColorSFactor = sfactor;
- mCurrBlendAlphaSFactor = sfactor;
- mCurrBlendColorDFactor = dfactor;
- mCurrBlendAlphaDFactor = dfactor;
- flush();
- glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
- }
+ llassert(sfactor < BF_UNDEF);
+ llassert(dfactor < BF_UNDEF);
+ if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
+ mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
+ {
+ mCurrBlendColorSFactor = sfactor;
+ mCurrBlendAlphaSFactor = sfactor;
+ mCurrBlendColorDFactor = dfactor;
+ mCurrBlendAlphaDFactor = dfactor;
+ flush();
+ glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
+ }
}
void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
- eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
-{
- llassert(color_sfactor < BF_UNDEF);
- llassert(color_dfactor < BF_UNDEF);
- llassert(alpha_sfactor < BF_UNDEF);
- llassert(alpha_dfactor < BF_UNDEF);
-
- if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
- mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
- {
- mCurrBlendColorSFactor = color_sfactor;
- mCurrBlendAlphaSFactor = alpha_sfactor;
- mCurrBlendColorDFactor = color_dfactor;
- mCurrBlendAlphaDFactor = alpha_dfactor;
- flush();
-
+ eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
+{
+ llassert(color_sfactor < BF_UNDEF);
+ llassert(color_dfactor < BF_UNDEF);
+ llassert(alpha_sfactor < BF_UNDEF);
+ llassert(alpha_dfactor < BF_UNDEF);
+
+ if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
+ mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
+ {
+ mCurrBlendColorSFactor = color_sfactor;
+ mCurrBlendAlphaSFactor = alpha_sfactor;
+ mCurrBlendColorDFactor = color_dfactor;
+ mCurrBlendAlphaDFactor = alpha_dfactor;
+ flush();
+
glBlendFuncSeparate(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
- }
+ }
}
LLTexUnit* LLRender::getTexUnit(U32 index)
{
- if (index < mTexUnits.size())
- {
- return &mTexUnits[index];
- }
- else
- {
- LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL;
- return &mDummyTexUnit;
- }
+ if (index < mTexUnits.size())
+ {
+ return &mTexUnits[index];
+ }
+ else
+ {
+ LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL;
+ return &mDummyTexUnit;
+ }
}
LLLightState* LLRender::getLight(U32 index)
{
- if (index < mLightState.size())
- {
- return &mLightState[index];
- }
-
- return NULL;
+ if (index < mLightState.size())
+ {
+ return &mLightState[index];
+ }
+
+ return NULL;
}
void LLRender::setAmbientLightColor(const LLColor4& color)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE
- if (color != mAmbientLightColor)
- {
- ++mLightHash;
- mAmbientLightColor = color;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE
+ if (color != mAmbientLightColor)
+ {
+ ++mLightHash;
+ mAmbientLightColor = color;
+ }
}
bool LLRender::verifyTexUnitActive(U32 unitToVerify)
{
- if (mCurrTextureUnitIndex == unitToVerify)
- {
- return true;
- }
- else
- {
- LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL;
- return false;
- }
+ if (mCurrTextureUnitIndex == unitToVerify)
+ {
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL;
+ return false;
+ }
}
void LLRender::clearErrors()
{
- while (glGetError())
- {
- //loop until no more error flags left
- }
+ while (glGetError())
+ {
+ //loop until no more error flags left
+ }
}
void LLRender::begin(const GLuint& mode)
{
- if (mode != mMode)
- {
- if (mode == LLRender::QUADS)
- {
- mQuadCycle = 1;
- }
-
- if (mMode == LLRender::QUADS ||
- mMode == LLRender::LINES ||
- mMode == LLRender::TRIANGLES ||
- mMode == LLRender::POINTS)
- {
- flush();
- }
- else if (mCount != 0)
- {
- LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL;
- }
-
- mMode = mode;
- }
+ if (mode != mMode)
+ {
+ if (mode == LLRender::QUADS)
+ {
+ mQuadCycle = 1;
+ }
+
+ if (mMode == LLRender::QUADS ||
+ mMode == LLRender::LINES ||
+ mMode == LLRender::TRIANGLES ||
+ mMode == LLRender::POINTS)
+ {
+ flush();
+ }
+ else if (mCount != 0)
+ {
+ LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL;
+ }
+
+ mMode = mode;
+ }
}
void LLRender::end()
-{
- if (mCount == 0)
- {
- return;
- //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL;
- }
-
- if ((mMode != LLRender::QUADS &&
- mMode != LLRender::LINES &&
- mMode != LLRender::TRIANGLES &&
- mMode != LLRender::POINTS) ||
- mCount > 2048)
- {
- flush();
- }
+{
+ if (mCount == 0)
+ {
+ return;
+ //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL;
+ }
+
+ if ((mMode != LLRender::QUADS &&
+ mMode != LLRender::LINES &&
+ mMode != LLRender::TRIANGLES &&
+ mMode != LLRender::POINTS) ||
+ mCount > 2048)
+ {
+ flush();
+ }
}
void LLRender::flush()
{
- if (mCount > 0)
- {
+ if (mCount > 0)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
llassert(LLGLSLShader::sCurBoundShaderPtr != nullptr);
- if (!mUIOffset.empty())
- {
- sUICalls++;
- sUIVerts += mCount;
- }
-
- //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
- U32 count = mCount;
-
- if (mMode == LLRender::QUADS && !sGLCoreProfile)
- {
- if (mCount%4 != 0)
- {
- count -= (mCount % 4);
- LL_WARNS() << "Incomplete quad requested." << LL_ENDL;
- }
- }
-
- if (mMode == LLRender::TRIANGLES)
- {
- if (mCount%3 != 0)
- {
- count -= (mCount % 3);
- LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
- }
- }
-
- if (mMode == LLRender::LINES)
- {
- if (mCount%2 != 0)
- {
- count -= (mCount % 2);
- LL_WARNS() << "Incomplete line requested." << LL_ENDL;
- }
- }
-
- mCount = 0;
+ if (!mUIOffset.empty())
+ {
+ sUICalls++;
+ sUIVerts += mCount;
+ }
+
+ //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+ U32 count = mCount;
+
+ if (mMode == LLRender::QUADS && !sGLCoreProfile)
+ {
+ if (mCount%4 != 0)
+ {
+ count -= (mCount % 4);
+ LL_WARNS() << "Incomplete quad requested." << LL_ENDL;
+ }
+ }
+
+ if (mMode == LLRender::TRIANGLES)
+ {
+ if (mCount%3 != 0)
+ {
+ count -= (mCount % 3);
+ LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
+ }
+ }
+
+ if (mMode == LLRender::LINES)
+ {
+ if (mCount%2 != 0)
+ {
+ count -= (mCount % 2);
+ LL_WARNS() << "Incomplete line requested." << LL_ENDL;
+ }
+ }
+
+ mCount = 0;
if (mBuffer)
{
@@ -1649,8 +1649,8 @@ void LLRender::flush()
hash.finalize();
}
-
-
+
+
U64 vhash = hash.digest();
// check the VB cache before making a new vertex buffer
@@ -1660,7 +1660,7 @@ void LLRender::flush()
// Most of our usage of the "immediate mode" style draw calls is actually
// sending the same geometry over and over again.
// To leverage this, we maintain a running hash of the vertex stream being
- // built up before a flush, and then check that hash against a VB
+ // built up before a flush, and then check that hash against a VB
// cache just before creating a vertex buffer in VRAM
std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
@@ -1739,528 +1739,504 @@ void LLRender::flush()
LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
}
-
- mVerticesp[0] = mVerticesp[count];
- mTexcoordsp[0] = mTexcoordsp[count];
- mColorsp[0] = mColorsp[count];
-
- mCount = 0;
- }
+
+ mVerticesp[0] = mVerticesp[count];
+ mTexcoordsp[0] = mTexcoordsp[count];
+ mColorsp[0] = mColorsp[count];
+
+ mCount = 0;
+ }
}
void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
-{
- //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
- if (mCount > 2048)
- { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below
- switch (mMode)
- {
- case LLRender::POINTS: flush(); break;
- case LLRender::TRIANGLES: if (mCount%3==0) flush(); break;
- case LLRender::QUADS: if(mCount%4 == 0) flush(); break;
- case LLRender::LINES: if (mCount%2 == 0) flush(); break;
- }
- }
-
- if (mCount > 4094)
- {
- // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
- return;
- }
-
- if (mUIOffset.empty())
- {
- mVerticesp[mCount] = LLVector3(x,y,z);
- }
- else
- {
- LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
- mVerticesp[mCount] = vert;
- }
-
- if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
- {
- mQuadCycle++;
- if (mQuadCycle == 4)
- { //copy two vertices so fourth quad element will add a triangle
- mQuadCycle = 0;
-
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-3];
- mColorsp[mCount] = mColorsp[mCount-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
-
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-2];
- mColorsp[mCount] = mColorsp[mCount-2];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
- }
- }
-
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+{
+ //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
+ if (mCount > 2048)
+ { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below
+ switch (mMode)
+ {
+ case LLRender::POINTS: flush(); break;
+ case LLRender::TRIANGLES: if (mCount%3==0) flush(); break;
+ case LLRender::QUADS: if(mCount%4 == 0) flush(); break;
+ case LLRender::LINES: if (mCount%2 == 0) flush(); break;
+ }
+ }
+
+ if (mCount > 4094)
+ {
+ // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
+ return;
+ }
+
+ if (mUIOffset.empty())
+ {
+ mVerticesp[mCount] = LLVector3(x,y,z);
+ }
+ else
+ {
+ LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
+ mVerticesp[mCount] = vert;
+ }
+
+ if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
+ {
+ mQuadCycle++;
+ if (mQuadCycle == 4)
+ { //copy two vertices so fourth quad element will add a triangle
+ mQuadCycle = 0;
+
+ mCount++;
+ mVerticesp[mCount] = mVerticesp[mCount-3];
+ mColorsp[mCount] = mColorsp[mCount-3];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
+
+ mCount++;
+ mVerticesp[mCount] = mVerticesp[mCount-2];
+ mColorsp[mCount] = mColorsp[mCount-2];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
+ }
+ }
+
+ mCount++;
+ mVerticesp[mCount] = mVerticesp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
{
- if (mCount + vert_count > 4094)
- {
- // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
- return;
- }
-
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy two
- mVerticesp[mCount++] = verts[i-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
- {
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
-
- mCount++;
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
-
- if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen
- mVerticesp[mCount] = mVerticesp[mCount-1];
+ if (mCount + vert_count > 4094)
+ {
+ // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
+ return;
+ }
+
+ if (sGLCoreProfile && mMode == LLRender::QUADS)
+ { //quads are deprecated, convert to triangle list
+ S32 i = 0;
+
+ while (i < vert_count)
+ {
+ //read first three
+ mVerticesp[mCount++] = verts[i++];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount++] = verts[i++];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount++] = verts[i++];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ //copy two
+ mVerticesp[mCount++] = verts[i-3];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount++] = verts[i-1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ //copy last one
+ mVerticesp[mCount++] = verts[i++];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < vert_count; i++)
+ {
+ mVerticesp[mCount] = verts[i];
+
+ mCount++;
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ }
+ }
+
+ if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen
+ mVerticesp[mCount] = mVerticesp[mCount-1];
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count)
{
- if (mCount + vert_count > 4094)
- {
- // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
- return;
- }
-
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount++] = uvs[i-3];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount++] = uvs[i-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
- {
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
-
- mCount++;
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
-
- if (mCount > 0)
- {
- mVerticesp[mCount] = mVerticesp[mCount - 1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
- }
+ if (mCount + vert_count > 4094)
+ {
+ // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
+ return;
+ }
+
+ if (sGLCoreProfile && mMode == LLRender::QUADS)
+ { //quads are deprecated, convert to triangle list
+ S32 i = 0;
+
+ while (i < vert_count)
+ {
+ //read first three
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount++] = uvs[i++];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount++] = uvs[i++];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount++] = uvs[i++];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ //copy last two
+ mVerticesp[mCount] = verts[i-3];
+ mTexcoordsp[mCount++] = uvs[i-3];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ mVerticesp[mCount] = verts[i-1];
+ mTexcoordsp[mCount++] = uvs[i-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+
+ //copy last one
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount++] = uvs[i++];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < vert_count; i++)
+ {
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+
+ mCount++;
+ mColorsp[mCount] = mColorsp[mCount-1];
+ }
+ }
+
+ if (mCount > 0)
+ {
+ mVerticesp[mCount] = mVerticesp[mCount - 1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
+ }
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
{
- if (mCount + vert_count > 4094)
- {
- // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
- return;
- }
-
-
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount] = uvs[i-3];
- mColorsp[mCount++] = colors[i-3];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount] = uvs[i-1];
- mColorsp[mCount++] = colors[i-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
- }
- }
- else
- {
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount] = colors[i];
-
- mCount++;
- }
- }
-
- if (mCount > 0)
- {
- mVerticesp[mCount] = mVerticesp[mCount - 1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
- mColorsp[mCount] = mColorsp[mCount - 1];
- }
+ if (mCount + vert_count > 4094)
+ {
+ // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
+ return;
+ }
+
+
+ if (sGLCoreProfile && mMode == LLRender::QUADS)
+ { //quads are deprecated, convert to triangle list
+ S32 i = 0;
+
+ while (i < vert_count)
+ {
+ //read first three
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount++] = colors[i++];
+
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount++] = colors[i++];
+
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount++] = colors[i++];
+
+ //copy last two
+ mVerticesp[mCount] = verts[i-3];
+ mTexcoordsp[mCount] = uvs[i-3];
+ mColorsp[mCount++] = colors[i-3];
+
+ mVerticesp[mCount] = verts[i-1];
+ mTexcoordsp[mCount] = uvs[i-1];
+ mColorsp[mCount++] = colors[i-1];
+
+ //copy last one
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount++] = colors[i++];
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < vert_count; i++)
+ {
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount] = colors[i];
+
+ mCount++;
+ }
+ }
+
+ if (mCount > 0)
+ {
+ mVerticesp[mCount] = mVerticesp[mCount - 1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
+ mColorsp[mCount] = mColorsp[mCount - 1];
+ }
}
void LLRender::vertex2i(const GLint& x, const GLint& y)
{
- vertex3f((GLfloat) x, (GLfloat) y, 0);
+ vertex3f((GLfloat) x, (GLfloat) y, 0);
}
void LLRender::vertex2f(const GLfloat& x, const GLfloat& y)
-{
- vertex3f(x,y,0);
+{
+ vertex3f(x,y,0);
}
void LLRender::vertex2fv(const GLfloat* v)
-{
- vertex3f(v[0], v[1], 0);
+{
+ vertex3f(v[0], v[1], 0);
}
void LLRender::vertex3fv(const GLfloat* v)
{
- vertex3f(v[0], v[1], v[2]);
+ vertex3f(v[0], v[1], v[2]);
}
void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
-{
- mTexcoordsp[mCount] = LLVector2(x,y);
+{
+ mTexcoordsp[mCount] = LLVector2(x,y);
}
void LLRender::texCoord2i(const GLint& x, const GLint& y)
-{
- texCoord2f((GLfloat) x, (GLfloat) y);
+{
+ texCoord2f((GLfloat) x, (GLfloat) y);
}
void LLRender::texCoord2fv(const GLfloat* tc)
-{
- texCoord2f(tc[0], tc[1]);
+{
+ texCoord2f(tc[0], tc[1]);
}
void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
{
- if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
- {
- mColorsp[mCount] = LLColor4U(r,g,b,a);
- }
- else
- { //not using shaders or shader reads color from a uniform
- diffuseColor4ub(r,g,b,a);
- }
+ if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
+ {
+ mColorsp[mCount] = LLColor4U(r,g,b,a);
+ }
+ else
+ { //not using shaders or shader reads color from a uniform
+ diffuseColor4ub(r,g,b,a);
+ }
}
void LLRender::color4ubv(const GLubyte* c)
{
- color4ub(c[0], c[1], c[2], c[3]);
+ color4ub(c[0], c[1], c[2], c[3]);
}
void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a)
{
- color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255),
- (GLubyte) (llclamp(g, 0.f, 1.f)*255),
- (GLubyte) (llclamp(b, 0.f, 1.f)*255),
- (GLubyte) (llclamp(a, 0.f, 1.f)*255));
+ color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255),
+ (GLubyte) (llclamp(g, 0.f, 1.f)*255),
+ (GLubyte) (llclamp(b, 0.f, 1.f)*255),
+ (GLubyte) (llclamp(a, 0.f, 1.f)*255));
}
void LLRender::color4fv(const GLfloat* c)
-{
- color4f(c[0],c[1],c[2],c[3]);
+{
+ color4f(c[0],c[1],c[2],c[3]);
}
void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
-{
- color4f(r,g,b,1);
+{
+ color4f(r,g,b,1);
}
void LLRender::color3fv(const GLfloat* c)
-{
- color4f(c[0],c[1],c[2],1);
+{
+ color4f(c[0],c[1],c[2],1);
}
void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
- }
- else
- {
- glColor3f(r,g,b);
- }
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
+ }
}
void LLRender::diffuseColor3fv(const F32* c)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
- }
- else
- {
- glColor3fv(c);
- }
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
+ }
}
void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
- }
- else
- {
- glColor4f(r,g,b,a);
- }
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
+ }
}
void LLRender::diffuseColor4fv(const F32* c)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c);
- }
- else
- {
- glColor4fv(c);
- }
+ if (shader)
+ {
+ shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c);
+ }
}
void LLRender::diffuseColor4ubv(const U8* c)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
- }
- else
- {
- glColor4ubv(c);
- }
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
+ }
}
void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader != NULL);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader != NULL);
- if (shader)
- {
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
- }
- else
- {
- glColor4ub(r,g,b,a);
- }
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
+ }
}
void LLRender::debugTexUnits(void)
{
- LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
- std::string active_enabled = "false";
- for (U32 i = 0; i < mTexUnits.size(); i++)
- {
- if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
- {
- if (i == mCurrTextureUnitIndex) active_enabled = "true";
- LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
- LL_INFOS("TextureUnit") << "Enabled As: " ;
- switch (getTexUnit(i)->mCurrTexType)
- {
- case LLTexUnit::TT_TEXTURE:
- LL_CONT << "Texture 2D";
- break;
- case LLTexUnit::TT_RECT_TEXTURE:
- LL_CONT << "Texture Rectangle";
- break;
- case LLTexUnit::TT_CUBE_MAP:
- LL_CONT << "Cube Map";
- break;
- default:
- LL_CONT << "ARGH!!! NONE!";
- break;
- }
- LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
- }
- }
- LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
+ LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
+ std::string active_enabled = "false";
+ for (U32 i = 0; i < mTexUnits.size(); i++)
+ {
+ if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
+ {
+ if (i == mCurrTextureUnitIndex) active_enabled = "true";
+ LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
+ LL_INFOS("TextureUnit") << "Enabled As: " ;
+ switch (getTexUnit(i)->mCurrTexType)
+ {
+ case LLTexUnit::TT_TEXTURE:
+ LL_CONT << "Texture 2D";
+ break;
+ case LLTexUnit::TT_RECT_TEXTURE:
+ LL_CONT << "Texture Rectangle";
+ break;
+ case LLTexUnit::TT_CUBE_MAP:
+ LL_CONT << "Cube Map";
+ break;
+ default:
+ LL_CONT << "ARGH!!! NONE!";
+ break;
+ }
+ LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
+ }
+ }
+ 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 ret;
+ ret.set_value(src);
+ return ret;
}
glh::matrix4f get_current_modelview()
{
- return copy_matrix(gGLModelView);
+ return copy_matrix(gGLModelView);
}
glh::matrix4f get_current_projection()
{
- return copy_matrix(gGLProjection);
+ return copy_matrix(gGLProjection);
}
glh::matrix4f get_last_modelview()
{
- return copy_matrix(gGLLastModelView);
+ return copy_matrix(gGLLastModelView);
}
glh::matrix4f get_last_projection()
{
- return copy_matrix(gGLLastProjection);
+ 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];
- }
+ for (U32 i = 0; i < 16; i++)
+ {
+ dst[i] = src.m[i];
+ }
}
void set_current_modelview(const glh::matrix4f& mat)
{
- copy_matrix(mat, gGLModelView);
+ copy_matrix(mat, gGLModelView);
}
void set_current_projection(glh::matrix4f& mat)
{
- copy_matrix(mat, gGLProjection);
+ 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);
+ 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;
+ 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);
+ 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);
+ 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);
-
+ 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/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 7f0643c3e8..9cd7527d3e 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrendertarget.cpp
* @brief LLRenderTarget 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$
*/
@@ -44,7 +44,7 @@ void check_framebuffer_status()
break;
default:
LL_WARNS() << "check_framebuffer_status failed -- " << std::hex << status << LL_ENDL;
- ll_fail("check_framebuffer_status failed");
+ ll_fail("check_framebuffer_status failed");
break;
}
}
@@ -75,10 +75,10 @@ LLRenderTarget::~LLRenderTarget()
}
void LLRenderTarget::resize(U32 resx, U32 resy)
-{
+{
//for accounting, get the number of pixels added/subtracted
S32 pix_diff = (resx*resy)-(mResX*mResY);
-
+
mResX = resx;
mResY = resy;
@@ -92,7 +92,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
}
if (mDepth)
- {
+ {
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
@@ -100,7 +100,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
sBytesAllocated += pix_diff*4;
}
}
-
+
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage, LLTexUnit::eTextureMipGeneration generateMipMaps)
{
@@ -112,7 +112,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
release();
-
+
mResX = resx;
mResY = resy;
@@ -125,7 +125,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
// Calculate the number of mip levels based upon resolution that we should have.
mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0));
}
-
+
if (depth)
{
if (!allocateDepth())
@@ -140,12 +140,12 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
-
+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
-
+
return addColorAttachment(color_fmt);
}
@@ -190,7 +190,7 @@ void LLRenderTarget::releaseColorAttachment()
llassert(!isBoundInStack());
llassert(mTex.size() == 1); //cannot use releaseColorAttachment with LLRenderTarget managed color targets
llassert(mFBO != 0); // mFBO must be valid
-
+
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
@@ -238,12 +238,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
return false;
}
}
-
+
sBytesAllocated += mResX*mResY*4;
stop_glerror();
-
+
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
@@ -266,15 +266,15 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
-
+
if (mFBO)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
LLTexUnit::getInternalType(mUsage), tex, 0);
-
+
check_framebuffer_status();
-
+
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
@@ -286,8 +286,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bindTarget();
flush();
}
-
-
+
+
return true;
}
@@ -296,7 +296,7 @@ bool LLRenderTarget::allocateDepth()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLImageGL::generateTextures(1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
-
+
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
@@ -336,7 +336,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
-
+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
check_framebuffer_status();
@@ -355,7 +355,7 @@ void LLRenderTarget::release()
if (mDepth)
{
LLImageGL::deleteTextures(1, &mDepth);
-
+
mDepth = 0;
sBytesAllocated -= mResX*mResY*4;
@@ -408,7 +408,7 @@ void LLRenderTarget::release()
mTex.clear();
mInternalFormat.clear();
-
+
mResX = mResY = 0;
}
@@ -417,7 +417,7 @@ void LLRenderTarget::bindTarget()
LL_PROFILE_GPU_ZONE("bindTarget");
llassert(mFBO);
llassert(!isBoundInStack());
-
+
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
@@ -427,7 +427,7 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffers(mTex.size(), drawbuffers);
-
+
if (mTex.empty())
{ //no color buffer to draw to
glDrawBuffer(GL_NONE);
@@ -452,7 +452,7 @@ void LLRenderTarget::clear(U32 mask_in)
if (mUseDepth)
{
mask |= GL_DEPTH_BUFFER_BIT;
-
+
}
if (mFBO)
{
@@ -560,11 +560,38 @@ bool LLRenderTarget::isBoundInStack() const
{
LLRenderTarget* cur = sBoundTarget;
while (cur && cur != this)
- {
+ {
cur = cur->mPreviousRT;
}
return cur == this;
}
+void LLRenderTarget::swapFBORefs(LLRenderTarget& other)
+{
+ // Must be initialized
+ llassert(mFBO);
+ llassert(other.mFBO);
+ // Must be unbound
+ // *NOTE: mPreviousRT can be non-null even if this target is unbound - presumably for debugging purposes?
+ llassert(sCurFBO != mFBO);
+ llassert(sCurFBO != other.mFBO);
+ llassert(!isBoundInStack());
+ llassert(!other.isBoundInStack());
+
+ // Must be same type
+ llassert(sUseFBO == other.sUseFBO);
+ llassert(mResX == other.mResX);
+ llassert(mResY == other.mResY);
+ llassert(mInternalFormat == other.mInternalFormat);
+ llassert(mTex.size() == other.mTex.size());
+ llassert(mDepth == other.mDepth);
+ llassert(mUseDepth == other.mUseDepth);
+ llassert(mGenerateMipMaps == other.mGenerateMipMaps);
+ llassert(mMipLevels == other.mMipLevels);
+ llassert(mUsage == other.mUsage);
+
+ std::swap(mFBO, other.mFBO);
+ std::swap(mTex, other.mTex);
+}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index b5745b5b49..da401572d1 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrendertarget.h
* @brief Off screen render target abstraction. Loose wrapper for GL_EXT_framebuffer_objects.
*
* $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$
*/
@@ -37,56 +37,56 @@
SAMPLE USAGE:
- LLRenderTarget target;
+ LLRenderTarget target;
- ...
+ ...
- //allocate a 256x256 RGBA render target with depth buffer
- target.allocate(256,256,GL_RGBA,TRUE);
+ //allocate a 256x256 RGBA render target with depth buffer
+ target.allocate(256,256,GL_RGBA,TRUE);
- //render to contents of offscreen buffer
- target.bindTarget();
- target.clear();
- ... <issue drawing commands> ...
- target.flush();
+ //render to contents of offscreen buffer
+ target.bindTarget();
+ target.clear();
+ ... <issue drawing commands> ...
+ target.flush();
- ...
+ ...
- //use target as a texture
- gGL.getTexUnit(INDEX)->bind(&target);
- ... <issue drawing commands> ...
+ //use target as a texture
+ gGL.getTexUnit(INDEX)->bind(&target);
+ ... <issue drawing commands> ...
*/
class LLRenderTarget
{
public:
- //whether or not to use FBO implementation
- static bool sUseFBO;
- static U32 sBytesAllocated;
- static U32 sCurFBO;
- static U32 sCurResX;
- static U32 sCurResY;
+ //whether or not to use FBO implementation
+ static bool sUseFBO;
+ static U32 sBytesAllocated;
+ static U32 sCurFBO;
+ static U32 sCurResX;
+ static U32 sCurResY;
- LLRenderTarget();
- ~LLRenderTarget();
+ LLRenderTarget();
+ ~LLRenderTarget();
- //allocate resources for rendering
- //must be called before use
- //multiple calls will release previously allocated resources
+ //allocate resources for rendering
+ //must be called before use
+ //multiple calls will release previously allocated resources
// resX - width
// resY - height
// color_fmt - GL color format (e.g. GL_RGB)
// depth - if true, allocate a depth buffer
// usage - deprecated, should always be TT_TEXTURE
- bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureMipGeneration generateMipMaps = LLTexUnit::TMG_NONE);
+ bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureMipGeneration generateMipMaps = LLTexUnit::TMG_NONE);
- //resize existing attachments to use new resolution and color format
- // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
- // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
- // DO use for render targets that resize often and aren't likely to ruin someone's day if they break
- void resize(U32 resx, U32 resy);
+ //resize existing attachments to use new resolution and color format
+ // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
+ // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
+ // DO use for render targets that resize often and aren't likely to ruin someone's day if they break
+ void resize(U32 resx, U32 resy);
//point this render target at a particular LLImageGL
// Intended usage:
@@ -96,95 +96,98 @@ public:
// < issue GL calls>
// target.flush();
// target.releaseColorAttachment();
- //
+ //
// attachment -- LLImageGL to render into
// use_name -- optional texture name to target instead of attachment->getTexName()
// NOTE: setColorAttachment and releaseColorAttachment cannot be used in conjuction with
- // addColorAttachment, allocateDepth, resize, etc.
+ // addColorAttachment, allocateDepth, resize, etc.
void setColorAttachment(LLImageGL* attachment, LLGLuint use_name = 0);
// detach from current color attachment
void releaseColorAttachment();
- //add color buffer attachment
- //limit of 4 color attachments per render target
- bool addColorAttachment(U32 color_fmt);
+ //add color buffer attachment
+ //limit of 4 color attachments per render target
+ bool addColorAttachment(U32 color_fmt);
- //allocate a depth texture
- bool allocateDepth();
+ //allocate a depth texture
+ bool allocateDepth();
- //share depth buffer with provided render target
- void shareDepthBuffer(LLRenderTarget& target);
+ //share depth buffer with provided render target
+ void shareDepthBuffer(LLRenderTarget& target);
- //free any allocated resources
- //safe to call redundantly
+ //free any allocated resources
+ //safe to call redundantly
// asserts that this target is not currently bound or present in the RT stack
- void release();
+ void release();
- //bind target for rendering
- //applies appropriate viewport
- // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget
+ //bind target for rendering
+ //applies appropriate viewport
+ // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget
// and restores previous binding on flush() (maintains a stack of Render Targets)
// Asserts that this target is not currently bound in the stack
- void bindTarget();
+ void bindTarget();
- //clear render targer, clears depth buffer if present,
- //uses scissor rect if in copy-to-texture mode
+ //clear render targer, clears depth buffer if present,
+ //uses scissor rect if in copy-to-texture mode
// asserts that this target is currently bound
- void clear(U32 mask = 0xFFFFFFFF);
+ void clear(U32 mask = 0xFFFFFFFF);
+
+ //get applied viewport
+ void getViewport(S32* viewport);
- //get applied viewport
- void getViewport(S32* viewport);
+ //get X resolution
+ U32 getWidth() const { return mResX; }
- //get X resolution
- U32 getWidth() const { return mResX; }
+ //get Y resolution
+ U32 getHeight() const { return mResY; }
- //get Y resolution
- U32 getHeight() const { return mResY; }
+ LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
- LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
+ U32 getTexture(U32 attachment = 0) const;
+ U32 getNumTextures() const;
- U32 getTexture(U32 attachment = 0) const;
- U32 getNumTextures() const;
+ U32 getDepth(void) const { return mDepth; }
- U32 getDepth(void) const { return mDepth; }
+ void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
- void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
-
- //flush rendering operations
- //must be called when rendering is complete
- //should be used 1:1 with bindTarget
- // call bindTarget once, do all your rendering, call flush once
+ //flush rendering operations
+ //must be called when rendering is complete
+ //should be used 1:1 with bindTarget
+ // call bindTarget once, do all your rendering, call flush once
// If an LLRenderTarget was bound when bindTarget was called, binds that RenderTarget for rendering (maintains RT stack)
// asserts that this target is currently bound
- void flush();
+ void flush();
- //Returns TRUE if target is ready to be rendered into.
- //That is, if the target has been allocated with at least
- //one renderable attachment (i.e. color buffer, depth buffer).
- bool isComplete() const;
+ //Returns TRUE if target is ready to be rendered into.
+ //That is, if the target has been allocated with at least
+ //one renderable attachment (i.e. color buffer, depth buffer).
+ bool isComplete() const;
// Returns true if this RenderTarget is bound somewhere in the stack
bool isBoundInStack() const;
- static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+ static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+
+ // *HACK
+ void swapFBORefs(LLRenderTarget& other);
protected:
- U32 mResX;
- U32 mResY;
- std::vector<U32> mTex;
- std::vector<U32> mInternalFormat;
- U32 mFBO;
+ U32 mResX;
+ U32 mResY;
+ std::vector<U32> mTex;
+ std::vector<U32> mInternalFormat;
+ U32 mFBO;
LLRenderTarget* mPreviousRT = nullptr;
U32 mDepth;
bool mUseDepth;
- LLTexUnit::eTextureMipGeneration mGenerateMipMaps;
- U32 mMipLevels;
-
- LLTexUnit::eTextureType mUsage;
+ LLTexUnit::eTextureMipGeneration mGenerateMipMaps;
+ U32 mMipLevels;
- static LLRenderTarget* sBoundTarget;
+ LLTexUnit::eTextureType mUsage;
+
+ static LLRenderTarget* sBoundTarget;
};
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 85644a95fb..636e13719a 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llshadermgr.cpp
* @brief Shader manager implementation.
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -44,6 +44,7 @@ using std::make_pair;
using std::string;
LLShaderMgr * LLShaderMgr::sInstance = NULL;
+bool LLShaderMgr::sMirrorsEnabled = false;
LLShaderMgr::LLShaderMgr()
{
@@ -57,90 +58,90 @@ LLShaderMgr::~LLShaderMgr()
// static
LLShaderMgr * LLShaderMgr::instance()
{
- if(NULL == sInstance)
- {
- LL_ERRS("Shaders") << "LLShaderMgr should already have been instantiated by the application!" << LL_ENDL;
- }
+ if(NULL == sInstance)
+ {
+ LL_ERRS("Shaders") << "LLShaderMgr should already have been instantiated by the application!" << LL_ENDL;
+ }
- return sInstance;
+ return sInstance;
}
BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
- llassert_always(shader != NULL);
- LLShaderFeatures *features = & shader->mFeatures;
-
- if (features->attachNothing)
- {
- return TRUE;
- }
- //////////////////////////////////////
- // Attach Vertex Shader Features First
- //////////////////////////////////////
-
- // NOTE order of shader object attaching is VERY IMPORTANT!!!
- if (features->calculatesAtmospherics)
- {
- if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
- {
- return FALSE;
- }
- }
-
- if (features->calculatesLighting || features->calculatesAtmospherics)
- {
- if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl"))
- {
- return FALSE;
- }
- }
-
- if (features->calculatesLighting)
- {
- if (features->isSpecular)
- {
+ llassert_always(shader != NULL);
+ LLShaderFeatures *features = & shader->mFeatures;
+
+ if (features->attachNothing)
+ {
+ return TRUE;
+ }
+ //////////////////////////////////////
+ // Attach Vertex Shader Features First
+ //////////////////////////////////////
+
+ // NOTE order of shader object attaching is VERY IMPORTANT!!!
+ if (features->calculatesAtmospherics)
+ {
+ if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->calculatesLighting || features->calculatesAtmospherics)
+ {
+ if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->calculatesLighting)
+ {
+ if (features->isSpecular)
+ {
if (!shader->attachVertexObject("lighting/lightFuncSpecularV.glsl"))
- {
- return FALSE;
- }
-
- if (!features->isAlphaLighting)
- {
+ {
+ return FALSE;
+ }
+
+ if (!features->isAlphaLighting)
+ {
if (!shader->attachVertexObject("lighting/sumLightsSpecularV.glsl"))
- {
- return FALSE;
- }
- }
-
+ {
+ return FALSE;
+ }
+ }
+
if (!shader->attachVertexObject("lighting/lightSpecularV.glsl"))
- {
- return FALSE;
- }
- }
- else
- {
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
if (!shader->attachVertexObject("lighting/lightFuncV.glsl"))
- {
- return FALSE;
- }
-
- if (!features->isAlphaLighting)
- {
+ {
+ return FALSE;
+ }
+
+ if (!features->isAlphaLighting)
+ {
if (!shader->attachVertexObject("lighting/sumLightsV.glsl"))
- {
- return FALSE;
- }
- }
-
+ {
+ return FALSE;
+ }
+ }
+
if (!shader->attachVertexObject("lighting/lightV.glsl"))
- {
- return FALSE;
- }
- }
- }
-
- // NOTE order of shader object attaching is VERY IMPORTANT!!!
- if (features->calculatesAtmospherics)
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ // NOTE order of shader object attaching is VERY IMPORTANT!!!
+ if (features->calculatesAtmospherics)
{
if (!shader->attachVertexObject("environment/srgbF.glsl")) // NOTE -- "F" suffix is superfluous here, there is nothing fragment specific in srgbF
{
@@ -152,38 +153,44 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
if (!shader->attachVertexObject("windlight/atmosphericsV.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- if (features->hasSkinning)
- {
+ if (features->hasSkinning)
+ {
if (!shader->attachVertexObject("avatar/avatarSkinV.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- if (features->hasObjectSkinning)
- {
+ if (features->hasObjectSkinning)
+ {
shader->mRiggedVariant = shader;
if (!shader->attachVertexObject("avatar/objectSkinV.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
if (!shader->attachVertexObject("deferred/textureUtilV.glsl"))
{
return FALSE;
}
+
+ ///////////////////////////////////////
+ // Attach Fragment Shader Features Next
+ ///////////////////////////////////////
- ///////////////////////////////////////
- // Attach Fragment Shader Features Next
- ///////////////////////////////////////
+ // NOTE order of shader object attaching is VERY IMPORTANT!!!
+
+ if (!shader->attachFragmentObject("deferred/globalF.glsl"))
+ {
+ return FALSE;
+ }
-// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred)
{
if (!shader->attachFragmentObject("environment/srgbF.glsl"))
@@ -192,46 +199,46 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
- if(features->calculatesAtmospherics || features->hasGamma || features->isDeferred)
- {
- if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
- {
- return FALSE;
- }
- }
+ if(features->calculatesAtmospherics || features->hasGamma || features->isDeferred)
+ {
+ if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
+ {
+ return FALSE;
+ }
+ }
if (features->calculatesLighting || features->calculatesAtmospherics)
- {
+ {
if (!shader->attachFragmentObject("windlight/atmosphericsHelpersF.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
// we want this BEFORE shadows and AO because those facilities use pos/norm access
if (features->isDeferred || features->hasReflectionProbes)
- {
+ {
if (!shader->attachFragmentObject("deferred/deferredUtil.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- if (features->hasScreenSpaceReflections || features->hasReflectionProbes)
- {
+ if (features->hasScreenSpaceReflections || features->hasReflectionProbes)
+ {
if (!shader->attachFragmentObject("deferred/screenSpaceReflUtil.glsl"))
{
return FALSE;
}
- }
+ }
if (features->hasShadows)
- {
+ {
if (!shader->attachFragmentObject("deferred/shadowUtil.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
if (features->hasReflectionProbes)
{
@@ -242,105 +249,105 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
if (features->hasAmbientOcclusion)
- {
+ {
if (!shader->attachFragmentObject("deferred/aoUtil.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- if (features->hasGamma || features->isDeferred)
- {
+ if (features->hasGamma || features->isDeferred)
+ {
if (!shader->attachFragmentObject("windlight/gammaF.glsl"))
- {
- return FALSE;
- }
- }
-
- if (features->encodesNormal)
- {
- if (!shader->attachFragmentObject("environment/encodeNormF.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- if (features->hasAtmospherics || features->isDeferred)
+ if (features->hasAtmospherics || features->isDeferred)
{
if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) {
return FALSE;
}
if (!shader->attachFragmentObject("windlight/atmosphericsF.glsl"))
- {
- return FALSE;
- }
- }
-
- // NOTE order of shader object attaching is VERY IMPORTANT!!!
- if (features->hasAtmospherics)
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->isPBRTerrain)
{
- if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
+ if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl"))
{
return FALSE;
}
}
-
- if (features->hasLighting)
- {
- if (features->disableTextureIndex)
- {
- if (features->hasAlphaMask)
- {
+
+ // NOTE order of shader object attaching is VERY IMPORTANT!!!
+ if (features->hasAtmospherics)
+ {
+ if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->hasLighting)
+ {
+ if (features->disableTextureIndex)
+ {
+ if (features->hasAlphaMask)
+ {
if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
- {
- return FALSE;
- }
- }
- else
- {
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl"))
- {
- return FALSE;
- }
- }
- }
- else
- {
- if (features->hasAlphaMask)
- {
+ {
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ if (features->hasAlphaMask)
+ {
if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl"))
- {
- return FALSE;
- }
- }
- else
- {
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
if (!shader->attachFragmentObject("lighting/lightF.glsl"))
- {
- return FALSE;
- }
- }
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
- }
- }
-
- if (features->mIndexedTextureChannels <= 1)
- {
- if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl"))
- {
- return FALSE;
- }
- }
- else
- {
+ {
+ return FALSE;
+ }
+ }
+ shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
+ }
+ }
+
+ if (features->mIndexedTextureChannels <= 1)
+ {
+ if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl"))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
if (!shader->attachVertexObject("objects/indexedTextureV.glsl"))
- {
- return FALSE;
- }
- }
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//============================================================================
@@ -348,20 +355,20 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
static std::string get_shader_log(GLuint ret)
{
- std::string res;
-
- //get log length
- GLint length;
+ std::string res;
+
+ //get log length
+ GLint length;
glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &length);
- if (length > 0)
- {
- //the log could be any size, so allocate appropriately
- GLchar* log = new GLchar[length];
+ if (length > 0)
+ {
+ //the log could be any size, so allocate appropriately
+ GLchar* log = new GLchar[length];
glGetShaderInfoLog(ret, length, &length, log);
- res = std::string((char *)log);
- delete[] log;
- }
- return res;
+ res = std::string((char *)log);
+ delete[] log;
+ }
+ return res;
}
static std::string get_program_log(GLuint ret)
@@ -369,7 +376,7 @@ static std::string get_program_log(GLuint ret)
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
std::string res;
- //get log length
+ //get log length
GLint length;
glGetProgramiv(ret, GL_INFO_LOG_LENGTH, &length);
if (length > 0)
@@ -401,16 +408,16 @@ static std::string get_object_log(GLuint ret)
//dump shader source for debugging
void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text)
{
- char num_str[16]; // U32 = max 10 digits
+ char num_str[16]; // U32 = max 10 digits
- LL_SHADER_LOADING_WARNS() << "\n";
+ LL_SHADER_LOADING_WARNS() << "\n";
- for (U32 i = 0; i < shader_code_count; i++)
- {
- snprintf(num_str, sizeof(num_str), "%4d: ", i+1);
- std::string line_number(num_str);
- LL_CONT << line_number << shader_code_text[i];
- }
+ for (U32 i = 0; i < shader_code_count; i++)
+ {
+ snprintf(num_str, sizeof(num_str), "%4d: ", i+1);
+ std::string line_number(num_str);
+ LL_CONT << line_number << shader_code_text[i];
+ }
LL_CONT << LL_ENDL;
}
@@ -424,11 +431,11 @@ void LLShaderMgr::dumpObjectLog(GLuint ret, BOOL warns, const std::string& filen
fname = "unknown shader file";
}
- if (log.length() > 0)
- {
+ if (log.length() > 0)
+ {
LL_SHADER_LOADING_WARNS() << "Shader loading from " << fname << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "\n" << log << LL_ENDL;
- }
+ }
}
GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines, S32 texture_index_channels)
@@ -442,25 +449,25 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
#endif
- GLenum error = GL_NO_ERROR;
-
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL;
- }
+ GLenum error = GL_NO_ERROR;
- if (filename.empty())
- {
- return 0;
- }
+ error = glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL;
+ }
+
+ if (filename.empty())
+ {
+ return 0;
+ }
- //read in from file
- LLFILE* file = NULL;
+ //read in from file
+ LLFILE* file = NULL;
- S32 try_gpu_class = shader_level;
- S32 gpu_class;
+ S32 try_gpu_class = shader_level;
+ S32 gpu_class;
std::string open_file_name;
@@ -485,7 +492,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
{
//find the most relevant file
for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
- { //search from the current gpu class down to class 1 to find the most relevant shader
+ { //search from the current gpu class down to class 1 to find the most relevant shader
std::stringstream fname;
fname << getShaderDirPrefix();
fname << gpu_class << "/" << filename;
@@ -506,7 +513,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
*/
LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL;
- file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */
+ file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */
if (file)
{
LL_DEBUGS("ShaderLoading") << "Loading file: " << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL;
@@ -514,31 +521,31 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
}
}
-
- if (file == NULL)
- {
- LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
- return 0;
- }
-
- //we can't have any lines longer than 1024 characters
- //or any shaders longer than 4096 lines... deal - DaveP
+
+ if (file == NULL)
+ {
+ LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
+ return 0;
+ }
+
+ //we can't have any lines longer than 1024 characters
+ //or any shaders longer than 4096 lines... deal - DaveP
GLchar buff[1024];
GLchar *extra_code_text[1024];
GLchar *shader_code_text[4096 + LL_ARRAY_SIZE(extra_code_text)] = { NULL };
GLuint extra_code_count = 0, shader_code_count = 0;
BOOST_STATIC_ASSERT(LL_ARRAY_SIZE(extra_code_text) < LL_ARRAY_SIZE(shader_code_text));
-
-
- S32 major_version = gGLManager.mGLSLVersionMajor;
- S32 minor_version = gGLManager.mGLSLVersionMinor;
-
- if (major_version == 1 && minor_version < 30)
- {
+
+
+ S32 major_version = gGLManager.mGLSLVersionMajor;
+ S32 minor_version = gGLManager.mGLSLVersionMinor;
+
+ if (major_version == 1 && minor_version < 30)
+ {
llassert(false); // GL 3.1 or later required
- }
- else
- {
+ }
+ else
+ {
if (major_version >= 4)
{
//set version to 400 or 420
@@ -554,32 +561,48 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
else if (major_version == 3)
{
if (minor_version < 10)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 300\n");
+ }
+ else if (minor_version <= 19)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 310\n");
+ }
+ else if (minor_version <= 29)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 320\n");
+ }
+ else
{
- shader_code_text[shader_code_count++] = strdup("#version 300\n");
- }
- else if (minor_version <= 19)
- {
- shader_code_text[shader_code_count++] = strdup("#version 310\n");
+ shader_code_text[shader_code_count++] = strdup("#version 330\n");
}
- else if (minor_version <= 29)
+ }
+ else
+ {
+ if (type == GL_GEOMETRY_SHADER)
{
- shader_code_text[shader_code_count++] = strdup("#version 320\n");
+ //set version to 1.50
+ shader_code_text[shader_code_count++] = strdup("#version 150\n");
+ //some implementations of GLSL 1.30 require integer precision be explicitly declared
+ extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
+ extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
}
else
{
- shader_code_text[shader_code_count++] = strdup("#version 330\n");
+ //set version to 1.40
+ shader_code_text[shader_code_count++] = strdup("#version 140\n");
+ //some implementations of GLSL 1.30 require integer precision be explicitly declared
+ extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
+ extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
}
- }
- else
- {
- //set version to 1.40
- shader_code_text[shader_code_count++] = strdup("#version 140\n");
- //some implementations of GLSL 1.30 require integer precision be explicitly declared
- extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
- extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
- }
+ }
+
+ extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
+ }
- extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
+ if (sMirrorsEnabled)
+ {
+ extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n");
}
// Use alpha float to store bit flags
@@ -587,127 +610,128 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.34\n"); // bit 0
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.67\n"); // bit 1
+ extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_HDRI 1.0\n"); // bit 2
extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n");
- if (defines)
- {
- for (auto iter = defines->begin(); iter != defines->end(); ++iter)
- {
- std::string define = "#define " + iter->first + " " + iter->second + "\n";
- extra_code_text[extra_code_count++] = (GLchar *) strdup(define.c_str());
- }
- }
-
- if( gGLManager.mIsAMD )
- {
- extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" );
- }
-
- if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER)
- {
- //use specified number of texture channels for indexed texture rendering
-
- /* prepend shader code that looks like this:
-
- uniform sampler2D tex0;
- uniform sampler2D tex1;
- uniform sampler2D tex2;
- .
- .
- .
- uniform sampler2D texN;
-
- flat in int vary_texture_index;
-
- vec4 ret = vec4(1,0,1,1);
-
- vec4 diffuseLookup(vec2 texcoord)
- {
- switch (vary_texture_index)
- {
- case 0: ret = texture(tex0, texcoord); break;
- case 1: ret = texture(tex1, texcoord); break;
- case 2: ret = texture(tex2, texcoord); break;
- .
- .
- .
- case N: return texture(texN, texcoord); break;
- }
-
- return ret;
- }
- */
-
- extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n");
-
- //uniform declartion
- for (S32 i = 0; i < texture_index_channels; ++i)
- {
- std::string decl = llformat("uniform sampler2D tex%d;\n", i);
- extra_code_text[extra_code_count++] = strdup(decl.c_str());
- }
-
- if (texture_index_channels > 1)
- {
- extra_code_text[extra_code_count++] = strdup("flat in int vary_texture_index;\n");
- }
-
- extra_code_text[extra_code_count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
- extra_code_text[extra_code_count++] = strdup("{\n");
-
-
- if (texture_index_channels == 1)
- { //don't use flow control, that's silly
- extra_code_text[extra_code_count++] = strdup("return texture(tex0, texcoord);\n");
- extra_code_text[extra_code_count++] = strdup("}\n");
- }
- else if (major_version > 1 || minor_version >= 30)
- { //switches are supported in GLSL 1.30 and later
- if (gGLManager.mIsNVIDIA)
- { //switches are unreliable on some NVIDIA drivers
- for (U32 i = 0; i < texture_index_channels; ++i)
- {
- std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
- extra_code_text[extra_code_count++] = strdup(if_string.c_str());
- }
- extra_code_text[extra_code_count++] = strdup("\treturn vec4(1,0,1,1);\n");
- extra_code_text[extra_code_count++] = strdup("}\n");
- }
- else
- {
- extra_code_text[extra_code_count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
- extra_code_text[extra_code_count++] = strdup("\tswitch (vary_texture_index)\n");
- extra_code_text[extra_code_count++] = strdup("\t{\n");
-
- //switch body
- for (S32 i = 0; i < texture_index_channels; ++i)
- {
- std::string case_str = llformat("\t\tcase %d: return texture(tex%d, texcoord);\n", i, i);
- extra_code_text[extra_code_count++] = strdup(case_str.c_str());
- }
-
- extra_code_text[extra_code_count++] = strdup("\t}\n");
- extra_code_text[extra_code_count++] = strdup("\treturn ret;\n");
- extra_code_text[extra_code_count++] = strdup("}\n");
- }
- }
- else
- { //should never get here. Indexed texture rendering requires GLSL 1.30 or later
- // (for passing integers between vertex and fragment shaders)
- LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL;
- }
- }
-
- //copy file into memory
- enum {
- flag_write_to_out_of_extra_block_area = 0x01
- , flag_extra_block_marker_was_found = 0x02
- };
-
- unsigned char flags = flag_write_to_out_of_extra_block_area;
-
- GLuint out_of_extra_block_counter = 0, start_shader_code = shader_code_count, file_lines_count = 0;
-
+ if (defines)
+ {
+ for (auto iter = defines->begin(); iter != defines->end(); ++iter)
+ {
+ std::string define = "#define " + iter->first + " " + iter->second + "\n";
+ extra_code_text[extra_code_count++] = (GLchar *) strdup(define.c_str());
+ }
+ }
+
+ if( gGLManager.mIsAMD )
+ {
+ extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" );
+ }
+
+ if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER)
+ {
+ //use specified number of texture channels for indexed texture rendering
+
+ /* prepend shader code that looks like this:
+
+ uniform sampler2D tex0;
+ uniform sampler2D tex1;
+ uniform sampler2D tex2;
+ .
+ .
+ .
+ uniform sampler2D texN;
+
+ flat in int vary_texture_index;
+
+ vec4 ret = vec4(1,0,1,1);
+
+ vec4 diffuseLookup(vec2 texcoord)
+ {
+ switch (vary_texture_index)
+ {
+ case 0: ret = texture(tex0, texcoord); break;
+ case 1: ret = texture(tex1, texcoord); break;
+ case 2: ret = texture(tex2, texcoord); break;
+ .
+ .
+ .
+ case N: return texture(texN, texcoord); break;
+ }
+
+ return ret;
+ }
+ */
+
+ extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n");
+
+ //uniform declartion
+ for (S32 i = 0; i < texture_index_channels; ++i)
+ {
+ std::string decl = llformat("uniform sampler2D tex%d;\n", i);
+ extra_code_text[extra_code_count++] = strdup(decl.c_str());
+ }
+
+ if (texture_index_channels > 1)
+ {
+ extra_code_text[extra_code_count++] = strdup("flat in int vary_texture_index;\n");
+ }
+
+ extra_code_text[extra_code_count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
+ extra_code_text[extra_code_count++] = strdup("{\n");
+
+
+ if (texture_index_channels == 1)
+ { //don't use flow control, that's silly
+ extra_code_text[extra_code_count++] = strdup("return texture(tex0, texcoord);\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
+ }
+ else if (major_version > 1 || minor_version >= 30)
+ { //switches are supported in GLSL 1.30 and later
+ if (gGLManager.mIsNVIDIA)
+ { //switches are unreliable on some NVIDIA drivers
+ for (U32 i = 0; i < texture_index_channels; ++i)
+ {
+ std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
+ extra_code_text[extra_code_count++] = strdup(if_string.c_str());
+ }
+ extra_code_text[extra_code_count++] = strdup("\treturn vec4(1,0,1,1);\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
+ }
+ else
+ {
+ extra_code_text[extra_code_count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
+ extra_code_text[extra_code_count++] = strdup("\tswitch (vary_texture_index)\n");
+ extra_code_text[extra_code_count++] = strdup("\t{\n");
+
+ //switch body
+ for (S32 i = 0; i < texture_index_channels; ++i)
+ {
+ std::string case_str = llformat("\t\tcase %d: return texture(tex%d, texcoord);\n", i, i);
+ extra_code_text[extra_code_count++] = strdup(case_str.c_str());
+ }
+
+ extra_code_text[extra_code_count++] = strdup("\t}\n");
+ extra_code_text[extra_code_count++] = strdup("\treturn ret;\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
+ }
+ }
+ else
+ { //should never get here. Indexed texture rendering requires GLSL 1.30 or later
+ // (for passing integers between vertex and fragment shaders)
+ LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL;
+ }
+ }
+
+ //copy file into memory
+ enum {
+ flag_write_to_out_of_extra_block_area = 0x01
+ , flag_extra_block_marker_was_found = 0x02
+ };
+
+ unsigned char flags = flag_write_to_out_of_extra_block_area;
+
+ GLuint out_of_extra_block_counter = 0, start_shader_code = shader_code_count, file_lines_count = 0;
+
#define TOUCH_SHADERS 0
#if TOUCH_SHADERS
@@ -715,13 +739,13 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
bool touched = false;
#endif
- while(NULL != fgets((char *)buff, 1024, file)
- && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)))
- {
- file_lines_count++;
-
- bool extra_block_area_found = NULL != strstr((const char*)buff, "[EXTRA_CODE_HERE]");
+ while(NULL != fgets((char *)buff, 1024, file)
+ && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)))
+ {
+ file_lines_count++;
+ bool extra_block_area_found = NULL != strstr((const char*)buff, "[EXTRA_CODE_HERE]");
+
#if TOUCH_SHADERS
if (NULL != strstr((const char*)buff, marker))
{
@@ -729,67 +753,67 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
#endif
- if(extra_block_area_found && !(flag_extra_block_marker_was_found & flags))
- {
- if(!(flag_write_to_out_of_extra_block_area & flags))
- {
- //shift
- for(GLuint to = start_shader_code, from = extra_code_count + start_shader_code;
- from < shader_code_count; ++to, ++from)
- {
- shader_code_text[to] = shader_code_text[from];
- }
-
- shader_code_count -= extra_code_count;
- }
-
- //copy extra code
- for(GLuint n = 0; n < extra_code_count
- && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)); ++n)
- {
- shader_code_text[shader_code_count++] = extra_code_text[n];
- }
-
- extra_code_count = 0;
-
- flags &= ~flag_write_to_out_of_extra_block_area;
- flags |= flag_extra_block_marker_was_found;
- }
+ if(extra_block_area_found && !(flag_extra_block_marker_was_found & flags))
+ {
+ if(!(flag_write_to_out_of_extra_block_area & flags))
+ {
+ //shift
+ for(GLuint to = start_shader_code, from = extra_code_count + start_shader_code;
+ from < shader_code_count; ++to, ++from)
+ {
+ shader_code_text[to] = shader_code_text[from];
+ }
+
+ shader_code_count -= extra_code_count;
+ }
+
+ //copy extra code
+ for(GLuint n = 0; n < extra_code_count
+ && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)); ++n)
+ {
+ shader_code_text[shader_code_count++] = extra_code_text[n];
+ }
+
+ extra_code_count = 0;
+
+ flags &= ~flag_write_to_out_of_extra_block_area;
+ flags |= flag_extra_block_marker_was_found;
+ }
else
{
shader_code_text[shader_code_count] = (GLchar *)strdup((char *)buff);
-
+
if(flag_write_to_out_of_extra_block_area & flags)
{
shader_code_text[extra_code_count + start_shader_code + out_of_extra_block_counter]
= shader_code_text[shader_code_count];
out_of_extra_block_counter++;
-
+
if(out_of_extra_block_counter == extra_code_count)
{
shader_code_count += extra_code_count;
flags &= ~flag_write_to_out_of_extra_block_area;
}
}
-
+
++shader_code_count;
- }
- } //while
-
- if(!(flag_extra_block_marker_was_found & flags))
- {
- for(GLuint n = start_shader_code; n < extra_code_count + start_shader_code; ++n)
- {
- shader_code_text[n] = extra_code_text[n - start_shader_code];
- }
-
- if (file_lines_count < extra_code_count)
- {
- shader_code_count += extra_code_count;
- }
-
- extra_code_count = 0;
- }
+ }
+ } //while
+
+ if(!(flag_extra_block_marker_was_found & flags))
+ {
+ for(GLuint n = start_shader_code; n < extra_code_count + start_shader_code; ++n)
+ {
+ shader_code_text[n] = extra_code_text[n - start_shader_code];
+ }
+
+ if (file_lines_count < extra_code_count)
+ {
+ shader_code_count += extra_code_count;
+ }
+
+ extra_code_count = 0;
+ }
#if TOUCH_SHADERS
if (!touched)
@@ -798,106 +822,106 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
#endif
- fclose(file);
+ fclose(file);
- //create shader object
+ //create shader object
GLuint ret = glCreateShader(type);
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShader: " << error << " for file: " << open_file_name << LL_ENDL;
- if (ret)
- {
- glDeleteShader(ret); //no longer need handle
- ret = 0;
- }
- }
-
- //load source
- if (ret)
- {
- glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL);
-
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSource: " << error << " for file: " << open_file_name << LL_ENDL;
- glDeleteShader(ret); //no longer need handle
- ret = 0;
- }
- }
-
- //compile source
- if (ret)
- {
- glCompileShader(ret);
-
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShader: " << error << " for file: " << open_file_name << LL_ENDL;
- glDeleteShader(ret); //no longer need handle
- ret = 0;
- }
- }
-
- if (error == GL_NO_ERROR)
- {
- //check for errors
- GLint success = GL_TRUE;
+ error = glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShader: " << error << " for file: " << open_file_name << LL_ENDL;
+ if (ret)
+ {
+ glDeleteShader(ret); //no longer need handle
+ ret = 0;
+ }
+ }
+
+ //load source
+ if (ret)
+ {
+ glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL);
+
+ error = glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSource: " << error << " for file: " << open_file_name << LL_ENDL;
+ glDeleteShader(ret); //no longer need handle
+ ret = 0;
+ }
+ }
+
+ //compile source
+ if (ret)
+ {
+ glCompileShader(ret);
+
+ error = glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShader: " << error << " for file: " << open_file_name << LL_ENDL;
+ glDeleteShader(ret); //no longer need handle
+ ret = 0;
+ }
+ }
+
+ if (error == GL_NO_ERROR)
+ {
+ //check for errors
+ GLint success = GL_TRUE;
glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
- error = glGetError();
- if (error != GL_NO_ERROR || success == GL_FALSE)
- {
- //an error occured, print log
- LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
- dumpObjectLog(ret, TRUE, open_file_name);
- dumpShaderSource(shader_code_count, shader_code_text);
- glDeleteShader(ret); //no longer need handle
- ret = 0;
- }
- }
- else
- {
- ret = 0;
- }
- stop_glerror();
-
- //free memory
- for (GLuint i = 0; i < shader_code_count; i++)
- {
- free(shader_code_text[i]);
- }
-
- //successfully loaded, save results
- if (ret)
- {
- // Add shader file to map
+ error = glGetError();
+ if (error != GL_NO_ERROR || success == GL_FALSE)
+ {
+ //an error occured, print log
+ LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
+ dumpObjectLog(ret, TRUE, open_file_name);
+ dumpShaderSource(shader_code_count, shader_code_text);
+ glDeleteShader(ret); //no longer need handle
+ ret = 0;
+ }
+ }
+ else
+ {
+ ret = 0;
+ }
+ stop_glerror();
+
+ //free memory
+ for (GLuint i = 0; i < shader_code_count; i++)
+ {
+ free(shader_code_text[i]);
+ }
+
+ //successfully loaded, save results
+ if (ret)
+ {
+ // Add shader file to map
if (type == GL_VERTEX_SHADER) {
mVertexShaderObjects[filename] = ret;
}
else if (type == GL_FRAGMENT_SHADER) {
mFragmentShaderObjects[filename] = ret;
}
- shader_level = try_gpu_class;
- }
- else
- {
- if (shader_level > 1)
- {
- shader_level--;
- return loadShaderFile(filename, shader_level, type, defines, texture_index_channels);
- }
- LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
- }
- return ret;
+ shader_level = try_gpu_class;
+ }
+ else
+ {
+ if (shader_level > 1)
+ {
+ shader_level--;
+ return loadShaderFile(filename, shader_level, type, defines, texture_index_channels);
+ }
+ LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
+ }
+ return ret;
}
BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
{
- //check for errors
+ //check for errors
{
LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER("glLinkProgram");
glLinkProgram(obj);
@@ -917,238 +941,238 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
}
}
- std::string log = get_program_log(obj);
- LLStringUtil::toLower(log);
- if (log.find("software") != std::string::npos)
- {
- LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
- success = GL_FALSE;
- suppress_errors = FALSE;
- }
- return success;
+ std::string log = get_program_log(obj);
+ LLStringUtil::toLower(log);
+ if (log.find("software") != std::string::npos)
+ {
+ LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
+ success = GL_FALSE;
+ suppress_errors = FALSE;
+ }
+ return success;
}
BOOL LLShaderMgr::validateProgramObject(GLuint obj)
{
- //check program validity against current GL
- glValidateProgram(obj);
- GLint success = GL_TRUE;
+ //check program validity against current GL
+ glValidateProgram(obj);
+ GLint success = GL_TRUE;
glGetProgramiv(obj, GL_LINK_STATUS, &success);
- if (success == GL_FALSE)
- {
- LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL;
- dumpObjectLog(obj);
- }
- else
- {
- dumpObjectLog(obj, FALSE);
- }
-
- return success;
+ if (success == GL_FALSE)
+ {
+ LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL;
+ dumpObjectLog(obj);
+ }
+ else
+ {
+ dumpObjectLog(obj, FALSE);
+ }
+
+ return success;
}
void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version)
{
- LL_INFOS() << "Initializing shader cache" << LL_ENDL;
-
- mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled;
-
- if(!mShaderCacheEnabled || mShaderCacheInitialized)
- return;
-
- mShaderCacheInitialized = true;
-
- mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
- LLFile::mkdir(mShaderCacheDir);
-
- {
- std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
- if (gDirUtilp->fileExists(meta_out_path))
- {
- LL_INFOS() << "Loading shader cache metadata" << LL_ENDL;
-
- llifstream instream(meta_out_path);
- LLSD in_data;
- LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED);
- instream.close();
-
- if (old_cache_version == current_cache_version)
- {
- for (const auto& data_pair : llsd::inMap(in_data))
- {
- ProgramBinaryData binary_info = ProgramBinaryData();
- binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
- binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger();
- binary_info.mLastUsedTime = data_pair.second["last_used"].asReal();
- mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
- }
- }
- else
- {
- LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL;
- clearShaderCache();
- }
- }
- }
+ LL_INFOS() << "Initializing shader cache" << LL_ENDL;
+
+ mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled;
+
+ if(!mShaderCacheEnabled || mShaderCacheInitialized)
+ return;
+
+ mShaderCacheInitialized = true;
+
+ mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
+ LLFile::mkdir(mShaderCacheDir);
+
+ {
+ std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
+ if (gDirUtilp->fileExists(meta_out_path))
+ {
+ LL_INFOS() << "Loading shader cache metadata" << LL_ENDL;
+
+ llifstream instream(meta_out_path);
+ LLSD in_data;
+ LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED);
+ instream.close();
+
+ if (old_cache_version == current_cache_version)
+ {
+ for (const auto& data_pair : llsd::inMap(in_data))
+ {
+ ProgramBinaryData binary_info = ProgramBinaryData();
+ binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
+ binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger();
+ binary_info.mLastUsedTime = data_pair.second["last_used"].asReal();
+ mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL;
+ clearShaderCache();
+ }
+ }
+ }
}
void LLShaderMgr::clearShaderCache()
{
- std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
- LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL;
- const std::string mask = "*";
- gDirUtilp->deleteFilesInDir(shader_cache, mask);
- mShaderBinaryCache.clear();
+ std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
+ LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL;
+ const std::string mask = "*";
+ gDirUtilp->deleteFilesInDir(shader_cache, mask);
+ mShaderBinaryCache.clear();
}
void LLShaderMgr::persistShaderCacheMetadata()
{
- if(!mShaderCacheEnabled) return;
-
- LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL;
-
- LLSD out = LLSD::emptyMap();
-
- static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
- const F32 current_time = LLTimer::getTotalSeconds();
- for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();)
- {
- const ProgramBinaryData& shader_metadata = it->second;
- if ((shader_metadata.mLastUsedTime + LRU_TIME) < current_time)
- {
- std::string shader_path = gDirUtilp->add(mShaderCacheDir, it->first.asString() + ".shaderbin");
- LLFile::remove(shader_path);
- it = mShaderBinaryCache.erase(it);
- }
- else
- {
- LLSD data = LLSD::emptyMap();
- data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat);
- data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength);
- data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime);
- out[it->first.asString()] = data;
- ++it;
- }
- }
-
- std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
- llofstream outstream(meta_out_path);
- LLSDSerialize::toNotation(out, outstream);
- outstream.close();
+ if(!mShaderCacheEnabled) return;
+
+ LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL;
+
+ LLSD out = LLSD::emptyMap();
+
+ static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
+ const F32 current_time = LLTimer::getTotalSeconds();
+ for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();)
+ {
+ const ProgramBinaryData& shader_metadata = it->second;
+ if ((shader_metadata.mLastUsedTime + LRU_TIME) < current_time)
+ {
+ std::string shader_path = gDirUtilp->add(mShaderCacheDir, it->first.asString() + ".shaderbin");
+ LLFile::remove(shader_path);
+ it = mShaderBinaryCache.erase(it);
+ }
+ else
+ {
+ LLSD data = LLSD::emptyMap();
+ data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat);
+ data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength);
+ data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime);
+ out[it->first.asString()] = data;
+ ++it;
+ }
+ }
+
+ std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
+ llofstream outstream(meta_out_path);
+ LLSDSerialize::toNotation(out, outstream);
+ outstream.close();
}
bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader)
{
- if (!mShaderCacheEnabled) return false;
-
- glProgramParameteri(shader->mProgramObject, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
-
- auto binary_iter = mShaderBinaryCache.find(shader->mShaderHash);
- if (binary_iter != mShaderBinaryCache.end())
- {
- std::string in_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
- auto& shader_info = binary_iter->second;
- if (shader_info.mBinaryLength > 0)
- {
- std::vector<U8> in_data;
- in_data.resize(shader_info.mBinaryLength);
-
- LLUniqueFile filep = LLFile::fopen(in_path, "rb");
- if (filep)
- {
- size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep);
- filep.close();
-
- if (result == in_data.size())
- {
- GLenum error = glGetError(); // Clear current error
- glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength);
-
- error = glGetError();
- GLint success = GL_TRUE;
- glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
- if (error == GL_NO_ERROR && success == GL_TRUE)
- {
- binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds();
- LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
- return true;
- }
- }
- }
- }
- //an error occured, normally we would print log but in this case it means the shader needs recompiling.
- LL_INFOS() << "Failed to load cached binary for shader: " << shader->mName << " falling back to compilation" << LL_ENDL;
- LLFile::remove(in_path);
- mShaderBinaryCache.erase(binary_iter);
- }
- return false;
+ if (!mShaderCacheEnabled) return false;
+
+ glProgramParameteri(shader->mProgramObject, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
+
+ auto binary_iter = mShaderBinaryCache.find(shader->mShaderHash);
+ if (binary_iter != mShaderBinaryCache.end())
+ {
+ std::string in_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
+ auto& shader_info = binary_iter->second;
+ if (shader_info.mBinaryLength > 0)
+ {
+ std::vector<U8> in_data;
+ in_data.resize(shader_info.mBinaryLength);
+
+ LLUniqueFile filep = LLFile::fopen(in_path, "rb");
+ if (filep)
+ {
+ size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep);
+ filep.close();
+
+ if (result == in_data.size())
+ {
+ GLenum error = glGetError(); // Clear current error
+ glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength);
+
+ error = glGetError();
+ GLint success = GL_TRUE;
+ glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
+ if (error == GL_NO_ERROR && success == GL_TRUE)
+ {
+ binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds();
+ LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
+ return true;
+ }
+ }
+ }
+ }
+ //an error occured, normally we would print log but in this case it means the shader needs recompiling.
+ LL_INFOS() << "Failed to load cached binary for shader: " << shader->mName << " falling back to compilation" << LL_ENDL;
+ LLFile::remove(in_path);
+ mShaderBinaryCache.erase(binary_iter);
+ }
+ return false;
}
bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader)
{
- if (!mShaderCacheEnabled) return true;
-
- ProgramBinaryData binary_info = ProgramBinaryData();
- glGetProgramiv(shader->mProgramObject, GL_PROGRAM_BINARY_LENGTH, &binary_info.mBinaryLength);
- if (binary_info.mBinaryLength > 0)
- {
- std::vector<U8> program_binary;
- program_binary.resize(binary_info.mBinaryLength);
-
- GLenum error = glGetError(); // Clear current error
- glGetProgramBinary(shader->mProgramObject, program_binary.size() * sizeof(U8), nullptr, &binary_info.mBinaryFormat, program_binary.data());
- error = glGetError();
- if (error == GL_NO_ERROR)
- {
- std::string out_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
- LLUniqueFile outfile = LLFile::fopen(out_path, "wb");
- if (outfile)
- {
- fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile);
- outfile.close();
-
- binary_info.mLastUsedTime = LLTimer::getTotalSeconds();
-
- mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info);
- return true;
- }
- }
- }
- return false;
+ if (!mShaderCacheEnabled) return true;
+
+ ProgramBinaryData binary_info = ProgramBinaryData();
+ glGetProgramiv(shader->mProgramObject, GL_PROGRAM_BINARY_LENGTH, &binary_info.mBinaryLength);
+ if (binary_info.mBinaryLength > 0)
+ {
+ std::vector<U8> program_binary;
+ program_binary.resize(binary_info.mBinaryLength);
+
+ GLenum error = glGetError(); // Clear current error
+ glGetProgramBinary(shader->mProgramObject, program_binary.size() * sizeof(U8), nullptr, &binary_info.mBinaryFormat, program_binary.data());
+ error = glGetError();
+ if (error == GL_NO_ERROR)
+ {
+ std::string out_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
+ LLUniqueFile outfile = LLFile::fopen(out_path, "wb");
+ if (outfile)
+ {
+ fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile);
+ outfile.close();
+
+ binary_info.mLastUsedTime = LLTimer::getTotalSeconds();
+
+ mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info);
+ return true;
+ }
+ }
+ }
+ return false;
}
//virtual
void LLShaderMgr::initAttribsAndUniforms()
{
- //MUST match order of enum in LLVertexBuffer.h
- mReservedAttribs.push_back("position");
- mReservedAttribs.push_back("normal");
- mReservedAttribs.push_back("texcoord0");
- mReservedAttribs.push_back("texcoord1");
- mReservedAttribs.push_back("texcoord2");
- mReservedAttribs.push_back("texcoord3");
- mReservedAttribs.push_back("diffuse_color");
- mReservedAttribs.push_back("emissive");
- mReservedAttribs.push_back("tangent");
- mReservedAttribs.push_back("weight");
- mReservedAttribs.push_back("weight4");
- mReservedAttribs.push_back("clothing");
- mReservedAttribs.push_back("texture_index");
-
- //matrix state
- mReservedUniforms.push_back("modelview_matrix");
- mReservedUniforms.push_back("projection_matrix");
- mReservedUniforms.push_back("inv_proj");
- mReservedUniforms.push_back("modelview_projection_matrix");
+ //MUST match order of enum in LLVertexBuffer.h
+ mReservedAttribs.push_back("position");
+ mReservedAttribs.push_back("normal");
+ mReservedAttribs.push_back("texcoord0");
+ mReservedAttribs.push_back("texcoord1");
+ mReservedAttribs.push_back("texcoord2");
+ mReservedAttribs.push_back("texcoord3");
+ mReservedAttribs.push_back("diffuse_color");
+ mReservedAttribs.push_back("emissive");
+ mReservedAttribs.push_back("tangent");
+ mReservedAttribs.push_back("weight");
+ mReservedAttribs.push_back("weight4");
+ mReservedAttribs.push_back("clothing");
+ mReservedAttribs.push_back("texture_index");
+
+ //matrix state
+ mReservedUniforms.push_back("modelview_matrix");
+ mReservedUniforms.push_back("projection_matrix");
+ mReservedUniforms.push_back("inv_proj");
+ mReservedUniforms.push_back("modelview_projection_matrix");
mReservedUniforms.push_back("inv_modelview");
mReservedUniforms.push_back("identity_matrix");
- mReservedUniforms.push_back("normal_matrix");
- mReservedUniforms.push_back("texture_matrix0");
- mReservedUniforms.push_back("texture_matrix1");
- mReservedUniforms.push_back("texture_matrix2");
- mReservedUniforms.push_back("texture_matrix3");
- mReservedUniforms.push_back("object_plane_s");
- mReservedUniforms.push_back("object_plane_t");
+ mReservedUniforms.push_back("normal_matrix");
+ mReservedUniforms.push_back("texture_matrix0");
+ mReservedUniforms.push_back("texture_matrix1");
+ mReservedUniforms.push_back("texture_matrix2");
+ mReservedUniforms.push_back("texture_matrix3");
+ mReservedUniforms.push_back("object_plane_s");
+ mReservedUniforms.push_back("object_plane_t");
mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF)
mReservedUniforms.push_back("texture_normal_transform"); // (GLTF)
@@ -1157,130 +1181,134 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1);
- mReservedUniforms.push_back("viewport");
+ mReservedUniforms.push_back("viewport");
- mReservedUniforms.push_back("light_position");
- mReservedUniforms.push_back("light_direction");
- mReservedUniforms.push_back("light_attenuation");
+ mReservedUniforms.push_back("light_position");
+ mReservedUniforms.push_back("light_direction");
+ mReservedUniforms.push_back("light_attenuation");
mReservedUniforms.push_back("light_deferred_attenuation");
- mReservedUniforms.push_back("light_diffuse");
- mReservedUniforms.push_back("light_ambient");
- mReservedUniforms.push_back("light_count");
- mReservedUniforms.push_back("light");
- mReservedUniforms.push_back("light_col");
- mReservedUniforms.push_back("far_z");
+ mReservedUniforms.push_back("light_diffuse");
+ mReservedUniforms.push_back("light_ambient");
+ mReservedUniforms.push_back("light_count");
+ mReservedUniforms.push_back("light");
+ mReservedUniforms.push_back("light_col");
+ mReservedUniforms.push_back("far_z");
- llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
//NOTE: MUST match order in eGLSLReservedUniforms
- mReservedUniforms.push_back("proj_mat");
- mReservedUniforms.push_back("proj_near");
- mReservedUniforms.push_back("proj_p");
- mReservedUniforms.push_back("proj_n");
- mReservedUniforms.push_back("proj_origin");
- mReservedUniforms.push_back("proj_range");
- mReservedUniforms.push_back("proj_ambiance");
- mReservedUniforms.push_back("proj_shadow_idx");
- mReservedUniforms.push_back("shadow_fade");
- mReservedUniforms.push_back("proj_focus");
- mReservedUniforms.push_back("proj_lod");
- mReservedUniforms.push_back("proj_ambient_lod");
-
- llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
-
- mReservedUniforms.push_back("color");
+ mReservedUniforms.push_back("proj_mat");
+ mReservedUniforms.push_back("proj_near");
+ mReservedUniforms.push_back("proj_p");
+ mReservedUniforms.push_back("proj_n");
+ mReservedUniforms.push_back("proj_origin");
+ mReservedUniforms.push_back("proj_range");
+ mReservedUniforms.push_back("proj_ambiance");
+ mReservedUniforms.push_back("proj_shadow_idx");
+ mReservedUniforms.push_back("shadow_fade");
+ mReservedUniforms.push_back("proj_focus");
+ mReservedUniforms.push_back("proj_lod");
+ mReservedUniforms.push_back("proj_ambient_lod");
+
+ llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
+
+ mReservedUniforms.push_back("color");
mReservedUniforms.push_back("emissiveColor");
mReservedUniforms.push_back("metallicFactor");
mReservedUniforms.push_back("roughnessFactor");
+ mReservedUniforms.push_back("mirror_flag");
+ mReservedUniforms.push_back("clipPlane");
+ mReservedUniforms.push_back("clipSign");
- mReservedUniforms.push_back("diffuseMap");
+ mReservedUniforms.push_back("diffuseMap");
mReservedUniforms.push_back("altDiffuseMap");
- mReservedUniforms.push_back("specularMap");
+ mReservedUniforms.push_back("specularMap");
mReservedUniforms.push_back("emissiveMap");
- mReservedUniforms.push_back("bumpMap");
+ mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("bumpMap2");
- mReservedUniforms.push_back("environmentMap");
+ mReservedUniforms.push_back("environmentMap");
mReservedUniforms.push_back("sceneMap");
mReservedUniforms.push_back("sceneDepth");
mReservedUniforms.push_back("reflectionProbes");
mReservedUniforms.push_back("irradianceProbes");
- mReservedUniforms.push_back("cloud_noise_texture");
+ mReservedUniforms.push_back("heroProbes");
+ 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");
- mReservedUniforms.push_back("ambient_color");
+ mReservedUniforms.push_back("fullbright");
+ mReservedUniforms.push_back("lightnorm");
+ mReservedUniforms.push_back("sunlight_color");
+ mReservedUniforms.push_back("ambient_color");
mReservedUniforms.push_back("sky_hdr_scale");
mReservedUniforms.push_back("sky_sunlight_scale");
mReservedUniforms.push_back("sky_ambient_scale");
- mReservedUniforms.push_back("blue_horizon");
+ mReservedUniforms.push_back("blue_horizon");
mReservedUniforms.push_back("blue_density");
mReservedUniforms.push_back("haze_horizon");
- mReservedUniforms.push_back("haze_density");
- mReservedUniforms.push_back("cloud_shadow");
- mReservedUniforms.push_back("density_multiplier");
- mReservedUniforms.push_back("distance_multiplier");
- mReservedUniforms.push_back("max_y");
- mReservedUniforms.push_back("glow");
- mReservedUniforms.push_back("cloud_color");
- mReservedUniforms.push_back("cloud_pos_density1");
- mReservedUniforms.push_back("cloud_pos_density2");
- mReservedUniforms.push_back("cloud_scale");
- mReservedUniforms.push_back("gamma");
- mReservedUniforms.push_back("scene_light_strength");
+ mReservedUniforms.push_back("haze_density");
+ mReservedUniforms.push_back("cloud_shadow");
+ mReservedUniforms.push_back("density_multiplier");
+ mReservedUniforms.push_back("distance_multiplier");
+ mReservedUniforms.push_back("max_y");
+ mReservedUniforms.push_back("glow");
+ mReservedUniforms.push_back("cloud_color");
+ mReservedUniforms.push_back("cloud_pos_density1");
+ mReservedUniforms.push_back("cloud_pos_density2");
+ mReservedUniforms.push_back("cloud_scale");
+ mReservedUniforms.push_back("gamma");
+ mReservedUniforms.push_back("scene_light_strength");
- llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
- mReservedUniforms.push_back("center");
- mReservedUniforms.push_back("size");
- mReservedUniforms.push_back("falloff");
+ mReservedUniforms.push_back("center");
+ mReservedUniforms.push_back("size");
+ mReservedUniforms.push_back("falloff");
- mReservedUniforms.push_back("box_center");
- mReservedUniforms.push_back("box_size");
+ mReservedUniforms.push_back("box_center");
+ mReservedUniforms.push_back("box_size");
- mReservedUniforms.push_back("minLuminance");
- mReservedUniforms.push_back("maxExtractAlpha");
- mReservedUniforms.push_back("lumWeights");
- mReservedUniforms.push_back("warmthWeights");
- mReservedUniforms.push_back("warmthAmount");
- mReservedUniforms.push_back("glowStrength");
- mReservedUniforms.push_back("glowDelta");
- mReservedUniforms.push_back("glowNoiseMap");
+ mReservedUniforms.push_back("minLuminance");
+ mReservedUniforms.push_back("maxExtractAlpha");
+ mReservedUniforms.push_back("lumWeights");
+ mReservedUniforms.push_back("warmthWeights");
+ mReservedUniforms.push_back("warmthAmount");
+ mReservedUniforms.push_back("glowStrength");
+ mReservedUniforms.push_back("glowDelta");
+ mReservedUniforms.push_back("glowNoiseMap");
- llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1);
- mReservedUniforms.push_back("minimum_alpha");
- mReservedUniforms.push_back("emissive_brightness");
+ mReservedUniforms.push_back("minimum_alpha");
+ mReservedUniforms.push_back("emissive_brightness");
// Deferred
- mReservedUniforms.push_back("shadow_matrix");
- mReservedUniforms.push_back("env_mat");
- mReservedUniforms.push_back("shadow_clip");
- mReservedUniforms.push_back("sun_wash");
- mReservedUniforms.push_back("shadow_noise");
- mReservedUniforms.push_back("blur_size");
- mReservedUniforms.push_back("ssao_radius");
- mReservedUniforms.push_back("ssao_max_radius");
- mReservedUniforms.push_back("ssao_factor");
- mReservedUniforms.push_back("ssao_factor_inv");
- mReservedUniforms.push_back("ssao_effect_mat");
- mReservedUniforms.push_back("screen_res");
- mReservedUniforms.push_back("near_clip");
- mReservedUniforms.push_back("shadow_offset");
- mReservedUniforms.push_back("shadow_bias");
- mReservedUniforms.push_back("spot_shadow_bias");
- mReservedUniforms.push_back("spot_shadow_offset");
- mReservedUniforms.push_back("sun_dir");
+ mReservedUniforms.push_back("shadow_matrix");
+ mReservedUniforms.push_back("env_mat");
+ mReservedUniforms.push_back("shadow_clip");
+ mReservedUniforms.push_back("sun_wash");
+ mReservedUniforms.push_back("shadow_noise");
+ mReservedUniforms.push_back("blur_size");
+ mReservedUniforms.push_back("ssao_radius");
+ mReservedUniforms.push_back("ssao_max_radius");
+ mReservedUniforms.push_back("ssao_factor");
+ mReservedUniforms.push_back("ssao_factor_inv");
+ mReservedUniforms.push_back("ssao_effect_mat");
+ mReservedUniforms.push_back("screen_res");
+ mReservedUniforms.push_back("near_clip");
+ mReservedUniforms.push_back("shadow_offset");
+ mReservedUniforms.push_back("shadow_bias");
+ 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");
- mReservedUniforms.push_back("norm_cutoff");
- mReservedUniforms.push_back("shadow_target_width");
-
- llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH + 1);
+ mReservedUniforms.push_back("shadow_res");
+ mReservedUniforms.push_back("proj_shadow_res");
+ mReservedUniforms.push_back("depth_cutoff");
+ mReservedUniforms.push_back("norm_cutoff");
+ mReservedUniforms.push_back("shadow_target_width");
+
+ llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH + 1);
mReservedUniforms.push_back("iterationCount");
mReservedUniforms.push_back("rayStep");
@@ -1294,90 +1322,114 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("inv_modelview_delta");
mReservedUniforms.push_back("cube_snapshot");
- mReservedUniforms.push_back("tc_scale");
- mReservedUniforms.push_back("rcp_screen_res");
- mReservedUniforms.push_back("rcp_frame_opt");
- mReservedUniforms.push_back("rcp_frame_opt2");
-
- mReservedUniforms.push_back("focal_distance");
- mReservedUniforms.push_back("blur_constant");
- mReservedUniforms.push_back("tan_pixel_angle");
- mReservedUniforms.push_back("magnification");
- mReservedUniforms.push_back("max_cof");
- mReservedUniforms.push_back("res_scale");
- mReservedUniforms.push_back("dof_width");
- mReservedUniforms.push_back("dof_height");
-
- mReservedUniforms.push_back("depthMap");
- mReservedUniforms.push_back("shadowMap0");
- mReservedUniforms.push_back("shadowMap1");
- mReservedUniforms.push_back("shadowMap2");
- mReservedUniforms.push_back("shadowMap3");
- mReservedUniforms.push_back("shadowMap4");
- mReservedUniforms.push_back("shadowMap5");
-
- llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
-
- mReservedUniforms.push_back("normalMap");
- mReservedUniforms.push_back("positionMap");
- mReservedUniforms.push_back("diffuseRect");
- mReservedUniforms.push_back("specularRect");
+ mReservedUniforms.push_back("tc_scale");
+ mReservedUniforms.push_back("rcp_screen_res");
+ mReservedUniforms.push_back("rcp_frame_opt");
+ mReservedUniforms.push_back("rcp_frame_opt2");
+
+ mReservedUniforms.push_back("focal_distance");
+ mReservedUniforms.push_back("blur_constant");
+ mReservedUniforms.push_back("tan_pixel_angle");
+ mReservedUniforms.push_back("magnification");
+ mReservedUniforms.push_back("max_cof");
+ mReservedUniforms.push_back("res_scale");
+ mReservedUniforms.push_back("dof_width");
+ mReservedUniforms.push_back("dof_height");
+
+ mReservedUniforms.push_back("depthMap");
+ mReservedUniforms.push_back("shadowMap0");
+ mReservedUniforms.push_back("shadowMap1");
+ mReservedUniforms.push_back("shadowMap2");
+ mReservedUniforms.push_back("shadowMap3");
+ mReservedUniforms.push_back("shadowMap4");
+ mReservedUniforms.push_back("shadowMap5");
+
+ llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
+
+ mReservedUniforms.push_back("normalMap");
+ mReservedUniforms.push_back("positionMap");
+ mReservedUniforms.push_back("diffuseRect");
+ mReservedUniforms.push_back("specularRect");
mReservedUniforms.push_back("emissiveRect");
mReservedUniforms.push_back("exposureMap");
mReservedUniforms.push_back("brdfLut");
- mReservedUniforms.push_back("noiseMap");
- mReservedUniforms.push_back("lightFunc");
- mReservedUniforms.push_back("lightMap");
- mReservedUniforms.push_back("bloomMap");
- mReservedUniforms.push_back("projectionMap");
- mReservedUniforms.push_back("norm_mat");
- mReservedUniforms.push_back("texture_gamma");
-
- mReservedUniforms.push_back("specular_color");
- mReservedUniforms.push_back("env_intensity");
-
- mReservedUniforms.push_back("matrixPalette");
- mReservedUniforms.push_back("translationPalette");
-
- mReservedUniforms.push_back("screenTex");
- mReservedUniforms.push_back("screenDepth");
- mReservedUniforms.push_back("refTex");
- mReservedUniforms.push_back("eyeVec");
- mReservedUniforms.push_back("time");
- mReservedUniforms.push_back("waveDir1");
- mReservedUniforms.push_back("waveDir2");
- mReservedUniforms.push_back("lightDir");
- mReservedUniforms.push_back("specular");
- mReservedUniforms.push_back("lightExp");
- mReservedUniforms.push_back("waterFogColor");
+ mReservedUniforms.push_back("noiseMap");
+ mReservedUniforms.push_back("lightFunc");
+ mReservedUniforms.push_back("lightMap");
+ mReservedUniforms.push_back("bloomMap");
+ mReservedUniforms.push_back("projectionMap");
+ mReservedUniforms.push_back("norm_mat");
+ mReservedUniforms.push_back("texture_gamma");
+
+ mReservedUniforms.push_back("specular_color");
+ mReservedUniforms.push_back("env_intensity");
+
+ mReservedUniforms.push_back("matrixPalette");
+ mReservedUniforms.push_back("translationPalette");
+
+ mReservedUniforms.push_back("screenTex");
+ mReservedUniforms.push_back("screenDepth");
+ mReservedUniforms.push_back("refTex");
+ mReservedUniforms.push_back("eyeVec");
+ mReservedUniforms.push_back("time");
+ mReservedUniforms.push_back("waveDir1");
+ mReservedUniforms.push_back("waveDir2");
+ mReservedUniforms.push_back("lightDir");
+ mReservedUniforms.push_back("specular");
+ mReservedUniforms.push_back("lightExp");
+ mReservedUniforms.push_back("waterFogColor");
mReservedUniforms.push_back("waterFogColorLinear");
- mReservedUniforms.push_back("waterFogDensity");
- mReservedUniforms.push_back("waterFogKS");
- mReservedUniforms.push_back("refScale");
- mReservedUniforms.push_back("waterHeight");
- mReservedUniforms.push_back("waterPlane");
- mReservedUniforms.push_back("normScale");
- mReservedUniforms.push_back("fresnelScale");
- mReservedUniforms.push_back("fresnelOffset");
- mReservedUniforms.push_back("blurMultiplier");
- mReservedUniforms.push_back("sunAngle");
- mReservedUniforms.push_back("scaledAngle");
- mReservedUniforms.push_back("sunAngle2");
-
- mReservedUniforms.push_back("camPosLocal");
-
- mReservedUniforms.push_back("gWindDir");
- mReservedUniforms.push_back("gSinWaveParams");
- mReservedUniforms.push_back("gGravity");
-
- mReservedUniforms.push_back("detail_0");
- mReservedUniforms.push_back("detail_1");
- mReservedUniforms.push_back("detail_2");
- mReservedUniforms.push_back("detail_3");
- mReservedUniforms.push_back("alpha_ramp");
-
- mReservedUniforms.push_back("origin");
- mReservedUniforms.push_back("display_gamma");
+ mReservedUniforms.push_back("waterFogDensity");
+ mReservedUniforms.push_back("waterFogKS");
+ mReservedUniforms.push_back("refScale");
+ mReservedUniforms.push_back("waterHeight");
+ mReservedUniforms.push_back("waterPlane");
+ mReservedUniforms.push_back("normScale");
+ mReservedUniforms.push_back("fresnelScale");
+ mReservedUniforms.push_back("fresnelOffset");
+ mReservedUniforms.push_back("blurMultiplier");
+ mReservedUniforms.push_back("sunAngle");
+ mReservedUniforms.push_back("scaledAngle");
+ mReservedUniforms.push_back("sunAngle2");
+
+ mReservedUniforms.push_back("camPosLocal");
+
+ mReservedUniforms.push_back("gWindDir");
+ mReservedUniforms.push_back("gSinWaveParams");
+ mReservedUniforms.push_back("gGravity");
+
+ mReservedUniforms.push_back("detail_0");
+ mReservedUniforms.push_back("detail_1");
+ mReservedUniforms.push_back("detail_2");
+ mReservedUniforms.push_back("detail_3");
+
+ mReservedUniforms.push_back("alpha_ramp");
+
+ mReservedUniforms.push_back("detail_0_base_color");
+ mReservedUniforms.push_back("detail_1_base_color");
+ mReservedUniforms.push_back("detail_2_base_color");
+ mReservedUniforms.push_back("detail_3_base_color");
+ mReservedUniforms.push_back("detail_0_normal");
+ mReservedUniforms.push_back("detail_1_normal");
+ mReservedUniforms.push_back("detail_2_normal");
+ mReservedUniforms.push_back("detail_3_normal");
+ mReservedUniforms.push_back("detail_0_metallic_roughness");
+ mReservedUniforms.push_back("detail_1_metallic_roughness");
+ mReservedUniforms.push_back("detail_2_metallic_roughness");
+ mReservedUniforms.push_back("detail_3_metallic_roughness");
+ mReservedUniforms.push_back("detail_0_emissive");
+ mReservedUniforms.push_back("detail_1_emissive");
+ mReservedUniforms.push_back("detail_2_emissive");
+ mReservedUniforms.push_back("detail_3_emissive");
+
+ mReservedUniforms.push_back("baseColorFactors");
+ mReservedUniforms.push_back("metallicFactors");
+ mReservedUniforms.push_back("roughnessFactors");
+ mReservedUniforms.push_back("emissiveColors");
+ mReservedUniforms.push_back("minimum_alphas");
+
+ mReservedUniforms.push_back("origin");
+ mReservedUniforms.push_back("display_gamma");
mReservedUniforms.push_back("inscatter");
mReservedUniforms.push_back("sun_size");
@@ -1397,6 +1449,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("cloud_variance");
mReservedUniforms.push_back("reflection_probe_ambiance");
mReservedUniforms.push_back("max_probe_lod");
+ mReservedUniforms.push_back("probe_strength");
mReservedUniforms.push_back("sh_input_r");
mReservedUniforms.push_back("sh_input_g");
@@ -1407,17 +1460,19 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("sun_up_factor");
mReservedUniforms.push_back("moonlight_color");
- llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
+ mReservedUniforms.push_back("debug_normal_draw_length");
- std::set<std::string> dupe_check;
+ llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
- for (U32 i = 0; i < mReservedUniforms.size(); ++i)
- {
- if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
- {
- LL_ERRS() << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << LL_ENDL;
- }
- dupe_check.insert(mReservedUniforms[i]);
- }
+ std::set<std::string> dupe_check;
+
+ for (U32 i = 0; i < mReservedUniforms.size(); ++i)
+ {
+ if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
+ {
+ LL_ERRS() << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << LL_ENDL;
+ }
+ dupe_check.insert(mReservedUniforms[i]);
+ }
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index e655dda98d..eb13418cd7 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llshadermgr.h
* @brief Shader Manager
*
* $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$
*/
@@ -33,8 +33,8 @@
class LLShaderMgr
{
public:
- LLShaderMgr();
- virtual ~LLShaderMgr();
+ LLShaderMgr();
+ virtual ~LLShaderMgr();
// clang-format off
typedef enum
@@ -85,6 +85,9 @@ public:
EMISSIVE_COLOR, // "emissiveColor"
METALLIC_FACTOR, // "metallicFactor"
ROUGHNESS_FACTOR, // "roughnessFactor"
+ MIRROR_FLAG, // "mirror_flag"
+ CLIP_PLANE, // "clipPlane"
+ CLIP_SIGN, // "clipSign"
DIFFUSE_MAP, // "diffuseMap"
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
SPECULAR_MAP, // "specularMap"
@@ -96,6 +99,7 @@ public:
SCENE_DEPTH, // "sceneDepth"
REFLECTION_PROBES, // "reflectionProbes"
IRRADIANCE_PROBES, // "irradianceProbes"
+ HERO_PROBE, // "heroProbes"
CLOUD_NOISE_MAP, // "cloud_noise_texture"
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
FULLBRIGHT, // "fullbright"
@@ -251,8 +255,32 @@ public:
TERRAIN_DETAIL1, // "detail_1"
TERRAIN_DETAIL2, // "detail_2"
TERRAIN_DETAIL3, // "detail_3"
+
TERRAIN_ALPHARAMP, // "alpha_ramp"
+ TERRAIN_DETAIL0_BASE_COLOR, // "detail_0_base_color" (GLTF)
+ TERRAIN_DETAIL1_BASE_COLOR, // "detail_1_base_color" (GLTF)
+ TERRAIN_DETAIL2_BASE_COLOR, // "detail_2_base_color" (GLTF)
+ TERRAIN_DETAIL3_BASE_COLOR, // "detail_3_base_color" (GLTF)
+ TERRAIN_DETAIL0_NORMAL, // "detail_0_normal" (GLTF)
+ TERRAIN_DETAIL1_NORMAL, // "detail_1_normal" (GLTF)
+ TERRAIN_DETAIL2_NORMAL, // "detail_2_normal" (GLTF)
+ TERRAIN_DETAIL3_NORMAL, // "detail_3_normal" (GLTF)
+ TERRAIN_DETAIL0_METALLIC_ROUGHNESS, // "detail_0_metallic_roughness" (GLTF)
+ TERRAIN_DETAIL1_METALLIC_ROUGHNESS, // "detail_1_metallic_roughness" (GLTF)
+ TERRAIN_DETAIL2_METALLIC_ROUGHNESS, // "detail_2_metallic_roughness" (GLTF)
+ TERRAIN_DETAIL3_METALLIC_ROUGHNESS, // "detail_3_metallic_roughness" (GLTF)
+ TERRAIN_DETAIL0_EMISSIVE, // "detail_0_emissive" (GLTF)
+ TERRAIN_DETAIL1_EMISSIVE, // "detail_1_emissive" (GLTF)
+ TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF)
+ TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF)
+
+ TERRAIN_BASE_COLOR_FACTORS, // "baseColorFactors" (GLTF)
+ TERRAIN_METALLIC_FACTORS, // "metallicFactors" (GLTF)
+ TERRAIN_ROUGHNESS_FACTORS, // "roughnessFactors" (GLTF)
+ TERRAIN_EMISSIVE_COLORS, // "emissiveColors" (GLTF)
+ TERRAIN_MINIMUM_ALPHAS, // "minimum_alphas" (GLTF)
+
SHINY_ORIGIN, // "origin"
DISPLAY_GAMMA, // "display_gamma"
@@ -279,6 +307,7 @@ public:
REFLECTION_PROBE_AMBIANCE, // "reflection_probe_ambiance"
REFLECTION_PROBE_MAX_LOD, // "max_probe_lod"
+ REFLECTION_PROBE_STRENGTH, // "probe_strength"
SH_INPUT_L1R, // "sh_input_r"
SH_INPUT_L1G, // "sh_input_g"
SH_INPUT_L1B, // "sh_input_b"
@@ -287,27 +316,30 @@ public:
WATER_EDGE_FACTOR, // "water_edge"
SUN_UP_FACTOR, // "sun_up_factor"
MOONLIGHT_COLOR, // "moonlight_color"
+
+ DEBUG_NORMAL_DRAW_LENGTH, // "debug_normal_draw_length"
+
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// clang-format on
- // singleton pattern implementation
- static LLShaderMgr * instance();
+ // singleton pattern implementation
+ static LLShaderMgr * instance();
- virtual void initAttribsAndUniforms(void);
+ virtual void initAttribsAndUniforms(void);
- BOOL attachShaderFeatures(LLGLSLShader * shader);
- void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = "");
+ BOOL attachShaderFeatures(LLGLSLShader * shader);
+ void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = "");
void dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text);
- BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE);
- BOOL validateProgramObject(GLuint obj);
- GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
+ BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE);
+ BOOL validateProgramObject(GLuint obj);
+ GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
- // Implemented in the application to actually point to the shader directory.
- virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
+ // Implemented in the application to actually point to the shader directory.
+ virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
- // Implemented in the application to actually update out of date uniforms for a particular shader
- virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual
+ // Implemented in the application to actually update out of date uniforms for a particular shader
+ virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual
void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version);
void clearShaderCache();
@@ -317,14 +349,14 @@ public:
bool saveCachedProgramBinary(LLGLSLShader* shader);
public:
- // Map of shader names to compiled
+ // Map of shader names to compiled
std::map<std::string, GLuint> mVertexShaderObjects;
std::map<std::string, GLuint> mFragmentShaderObjects;
- //global (reserved slot) shader parameters
- std::vector<std::string> mReservedAttribs;
+ //global (reserved slot) shader parameters
+ std::vector<std::string> mReservedAttribs;
- std::vector<std::string> mReservedUniforms;
+ std::vector<std::string> mReservedUniforms;
struct ProgramBinaryData
{
@@ -336,11 +368,12 @@ public:
bool mShaderCacheInitialized = false;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
+ static bool sMirrorsEnabled;
protected:
- // our parameter manager singleton instance
- static LLShaderMgr * sInstance;
+ // our parameter manager singleton instance
+ static LLShaderMgr * sInstance;
}; //LLShaderMgr
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index c98de6bf06..1d81c3778b 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvertexbuffer.cpp
* @brief LLVertexBuffer implementation
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -41,25 +41,25 @@
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
U32 nhpo2(U32 v)
{
- U32 r = 1;
- while (r < v) {
- r *= 2;
- }
- return r;
+ U32 r = 1;
+ while (r < v) {
+ r *= 2;
+ }
+ return r;
}
//which power of 2 is i?
//assumes i is a power of 2 > 0
U32 wpo2(U32 i)
{
- llassert(i > 0);
- llassert(nhpo2(i) == i);
+ llassert(i > 0);
+ llassert(nhpo2(i) == i);
- U32 r = 0;
+ U32 r = 0;
- while (i >>= 1) ++r;
+ while (i >>= 1) ++r;
- return r;
+ return r;
}
struct CompareMappedRegion
@@ -381,7 +381,7 @@ public:
Entry& entry = entries.back();
name = entry.mGLName;
data = entry.mData;
-
+
entries.pop_back();
if (entries.empty())
{
@@ -474,9 +474,9 @@ public:
}
#if 0
- LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent",
- mDistributed / 1000000,
- mAllocated / 1000000,
+ LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent",
+ mDistributed / 1000000,
+ mAllocated / 1000000,
(mAllocated + mReserved) / 1000000, // total bytes
((mAllocated+mReserved-mDistributed)*100)/llmax(mDistributed, (U64) 1), // overhead percent
(mHits*100)/llmax(mMisses+mHits, (U32)1)) // hit rate percent
@@ -522,7 +522,7 @@ U64 LLVertexBuffer::getBytesAllocated()
}
//============================================================================
-//
+//
//static
U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0;
@@ -533,50 +533,50 @@ U32 LLVertexBuffer::sVertexCount = 0;
//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware
const U32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
{
- sizeof(LLVector4), // TYPE_VERTEX,
- sizeof(LLVector4), // TYPE_NORMAL,
- sizeof(LLVector2), // TYPE_TEXCOORD0,
- sizeof(LLVector2), // TYPE_TEXCOORD1,
- sizeof(LLVector2), // TYPE_TEXCOORD2,
- sizeof(LLVector2), // TYPE_TEXCOORD3,
- sizeof(LLColor4U), // TYPE_COLOR,
- sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
- sizeof(LLVector4), // TYPE_TANGENT,
- sizeof(F32), // TYPE_WEIGHT,
- sizeof(LLVector4), // TYPE_WEIGHT4,
- sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
- sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
+ sizeof(LLVector4), // TYPE_VERTEX,
+ sizeof(LLVector4), // TYPE_NORMAL,
+ sizeof(LLVector2), // TYPE_TEXCOORD0,
+ sizeof(LLVector2), // TYPE_TEXCOORD1,
+ sizeof(LLVector2), // TYPE_TEXCOORD2,
+ sizeof(LLVector2), // TYPE_TEXCOORD3,
+ sizeof(LLColor4U), // TYPE_COLOR,
+ sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
+ sizeof(LLVector4), // TYPE_TANGENT,
+ sizeof(F32), // TYPE_WEIGHT,
+ sizeof(LLVector4), // TYPE_WEIGHT4,
+ sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
+ sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
static const std::string vb_type_name[] =
{
- "TYPE_VERTEX",
- "TYPE_NORMAL",
- "TYPE_TEXCOORD0",
- "TYPE_TEXCOORD1",
- "TYPE_TEXCOORD2",
- "TYPE_TEXCOORD3",
- "TYPE_COLOR",
- "TYPE_EMISSIVE",
- "TYPE_TANGENT",
- "TYPE_WEIGHT",
- "TYPE_WEIGHT4",
- "TYPE_CLOTHWEIGHT",
- "TYPE_TEXTURE_INDEX",
- "TYPE_MAX",
- "TYPE_INDEX",
+ "TYPE_VERTEX",
+ "TYPE_NORMAL",
+ "TYPE_TEXCOORD0",
+ "TYPE_TEXCOORD1",
+ "TYPE_TEXCOORD2",
+ "TYPE_TEXCOORD3",
+ "TYPE_COLOR",
+ "TYPE_EMISSIVE",
+ "TYPE_TANGENT",
+ "TYPE_WEIGHT",
+ "TYPE_WEIGHT4",
+ "TYPE_CLOTHWEIGHT",
+ "TYPE_TEXTURE_INDEX",
+ "TYPE_MAX",
+ "TYPE_INDEX",
};
const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
- GL_TRIANGLES,
- GL_TRIANGLE_STRIP,
- GL_TRIANGLE_FAN,
- GL_POINTS,
- GL_LINES,
- GL_LINE_STRIP,
- GL_QUADS,
- GL_LINE_LOOP,
+ GL_TRIANGLES,
+ GL_TRIANGLE_STRIP,
+ GL_TRIANGLE_FAN,
+ GL_POINTS,
+ GL_LINES,
+ GL_LINE_STRIP,
+ GL_QUADS,
+ GL_LINE_LOOP,
};
//static
@@ -598,7 +598,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
else
- { //was disabled
+ { //was disabled
if (data_mask & mask)
{ //needs to be enabled
glEnableVertexAttribArray(loc);
@@ -627,18 +627,18 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
-
- gGL.syncMatrices();
+ llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
- U32 mask = LLVertexBuffer::MAP_VERTEX;
- if (tc)
- {
- mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
- }
+ gGL.syncMatrices();
- unbind();
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ if (tc)
+ {
+ mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
+ }
+ unbind();
+
gGL.begin(mode);
if (tc != nullptr)
@@ -657,7 +657,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
U16 idx = indicesp[i];
gGL.vertex3fv(pos[idx].getF32ptr());
}
-}
+ }
gGL.end();
gGL.flush();
}
@@ -672,32 +672,32 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
llassert(start < (U32)mNumVerts);
llassert(end < (U32)mNumVerts);
- if (start >= (U32) mNumVerts ||
- end >= (U32) mNumVerts)
- {
- LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL;
- }
+ if (start >= (U32) mNumVerts ||
+ end >= (U32) mNumVerts)
+ {
+ LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL;
+ }
- llassert(mNumIndices >= 0);
+ llassert(mNumIndices >= 0);
- if (indices_offset >= (U32) mNumIndices ||
- indices_offset + count > (U32) mNumIndices)
- {
- LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL;
- }
+ if (indices_offset >= (U32) mNumIndices ||
+ indices_offset + count > (U32) mNumIndices)
+ {
+ LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL;
+ }
- {
- U16* idx = (U16*) mMappedIndexData+indices_offset;
- for (U32 i = 0; i < count; ++i)
- {
+ {
+ U16* idx = (U16*) mMappedIndexData+indices_offset;
+ for (U32 i = 0; i < count; ++i)
+ {
llassert(idx[i] >= start);
llassert(idx[i] <= end);
- if (idx[i] < start || idx[i] > end)
- {
- LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL;
- }
- }
+ if (idx[i] < start || idx[i] > end)
+ {
+ LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL;
+ }
+ }
LLVector4a* v = (LLVector4a*)mMappedData;
@@ -709,29 +709,29 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
}
}
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader && shader->mFeatures.mIndexedTextureChannels > 1)
- {
- LLVector4a* v = (LLVector4a*) mMappedData;
-
- for (U32 i = start; i < end; i++)
- {
+ if (shader && shader->mFeatures.mIndexedTextureChannels > 1)
+ {
+ LLVector4a* v = (LLVector4a*) mMappedData;
+
+ for (U32 i = start; i < end; i++)
+ {
U32 idx = (U32) (v[i][3]+0.25f);
- if (idx >= shader->mFeatures.mIndexedTextureChannels)
- {
- LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL;
- }
- }
- }
- }
+ if (idx >= shader->mFeatures.mIndexedTextureChannels)
+ {
+ LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL;
+ }
+ }
+ }
+ }
return true;
}
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
void LLVertexBuffer::setLabel(const char* label) {
- LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label);
+ LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label);
}
#endif
@@ -741,8 +741,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
llassert(mGLBuffer == sGLRenderBuffer);
llassert(mGLIndices == sGLRenderIndices);
gGL.syncMatrices();
- glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
- (GLvoid*) (indices_offset * sizeof(U16)));
+ glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType,
+ (GLvoid*) (indices_offset * (size_t) mIndicesStride));
}
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
@@ -756,7 +756,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
llassert(first + count <= mNumVerts);
llassert(mGLBuffer == sGLRenderBuffer);
llassert(mGLIndices == sGLRenderIndices);
-
+
gGL.syncMatrices();
glDrawArrays(sGLMode[mode], first, count);
}
@@ -778,21 +778,21 @@ void LLVertexBuffer::initClass(LLWindow* window)
#endif
}
-//static
+//static
void LLVertexBuffer::unbind()
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- sGLRenderBuffer = 0;
- sGLRenderIndices = 0;
+ sGLRenderBuffer = 0;
+ sGLRenderIndices = 0;
}
//static
void LLVertexBuffer::cleanupClass()
{
- unbind();
-
+ unbind();
+
delete sVBOPool;
sVBOPool = nullptr;
@@ -812,71 +812,71 @@ void LLVertexBuffer::cleanupClass()
//----------------------------------------------------------------------------
-LLVertexBuffer::LLVertexBuffer(U32 typemask)
-: LLRefCount(),
- mTypeMask(typemask)
+LLVertexBuffer::LLVertexBuffer(U32 typemask)
+: LLRefCount(),
+ mTypeMask(typemask)
{
- //zero out offsets
- for (U32 i = 0; i < TYPE_MAX; i++)
- {
- mOffsets[i] = 0;
- }
+ //zero out offsets
+ for (U32 i = 0; i < TYPE_MAX; i++)
+ {
+ mOffsets[i] = 0;
+ }
}
//static
U32 LLVertexBuffer::calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices)
{
U32 offset = 0;
- for (U32 i=0; i<TYPE_TEXTURE_INDEX; i++)
- {
- U32 mask = 1<<i;
- if (typemask & mask)
- {
- if (offsets && LLVertexBuffer::sTypeSize[i])
- {
- offsets[i] = offset;
- offset += LLVertexBuffer::sTypeSize[i]*num_vertices;
- offset = (offset + 0xF) & ~0xF;
- }
- }
- }
-
- offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12;
-
- return offset;
+ for (U32 i=0; i<TYPE_TEXTURE_INDEX; i++)
+ {
+ U32 mask = 1<<i;
+ if (typemask & mask)
+ {
+ if (offsets && LLVertexBuffer::sTypeSize[i])
+ {
+ offsets[i] = offset;
+ offset += LLVertexBuffer::sTypeSize[i]*num_vertices;
+ offset = (offset + 0xF) & ~0xF;
+ }
+ }
+ }
+
+ offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12;
+
+ return offset;
}
-//static
+//static
U32 LLVertexBuffer::calcVertexSize(const U32& typemask)
{
U32 size = 0;
- for (U32 i = 0; i < TYPE_TEXTURE_INDEX; i++)
- {
- U32 mask = 1<<i;
- if (typemask & mask)
- {
- size += LLVertexBuffer::sTypeSize[i];
- }
- }
-
- return size;
+ for (U32 i = 0; i < TYPE_TEXTURE_INDEX; i++)
+ {
+ U32 mask = 1<<i;
+ if (typemask & mask)
+ {
+ size += LLVertexBuffer::sTypeSize[i];
+ }
+ }
+
+ return size;
}
// protected, use unref()
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
- destroyGLBuffer();
- destroyGLIndices();
-
- if (mMappedData)
- {
- LL_ERRS() << "Failed to clear vertex buffer's vertices" << LL_ENDL;
- }
- if (mMappedIndexData)
- {
- LL_ERRS() << "Failed to clear vertex buffer's indices" << LL_ENDL;
- }
+ destroyGLBuffer();
+ destroyGLIndices();
+
+ if (mMappedData)
+ {
+ LL_ERRS() << "Failed to clear vertex buffer's vertices" << LL_ENDL;
+ }
+ if (mMappedIndexData)
+ {
+ LL_ERRS() << "Failed to clear vertex buffer's indices" << LL_ENDL;
+ }
};
//----------------------------------------------------------------------------
@@ -914,54 +914,54 @@ void LLVertexBuffer::genIndices(U32 size)
bool LLVertexBuffer::createGLBuffer(U32 size)
{
- if (mGLBuffer || mMappedData)
- {
- destroyGLBuffer();
- }
-
- if (size == 0)
- {
- return true;
- }
-
- bool success = true;
-
- genBuffer(size);
-
- if (!mMappedData)
- {
- success = false;
- }
- return success;
+ if (mGLBuffer || mMappedData)
+ {
+ destroyGLBuffer();
+ }
+
+ if (size == 0)
+ {
+ return true;
+ }
+
+ bool success = true;
+
+ genBuffer(size);
+
+ if (!mMappedData)
+ {
+ success = false;
+ }
+ return success;
}
bool LLVertexBuffer::createGLIndices(U32 size)
{
- if (mGLIndices)
- {
- destroyGLIndices();
- }
-
- if (size == 0)
- {
- return true;
- }
-
- bool success = true;
-
- genIndices(size);
-
- if (!mMappedIndexData)
- {
- success = false;
- }
- return success;
+ if (mGLIndices)
+ {
+ destroyGLIndices();
+ }
+
+ if (size == 0)
+ {
+ return true;
+ }
+
+ bool success = true;
+
+ genIndices(size);
+
+ if (!mMappedIndexData)
+ {
+ success = false;
+ }
+ return success;
}
void LLVertexBuffer::destroyGLBuffer()
{
- if (mGLBuffer || mMappedData)
- {
+ if (mGLBuffer || mMappedData)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
//llassert(sVBOPool);
if (sVBOPool)
@@ -972,13 +972,13 @@ void LLVertexBuffer::destroyGLBuffer()
mSize = 0;
mGLBuffer = 0;
mMappedData = nullptr;
- }
+ }
}
void LLVertexBuffer::destroyGLIndices()
{
- if (mGLIndices || mMappedIndexData)
- {
+ if (mGLIndices || mMappedIndexData)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
//llassert(sVBOPool);
if (sVBOPool)
@@ -989,22 +989,22 @@ void LLVertexBuffer::destroyGLIndices()
mIndicesSize = 0;
mGLIndices = 0;
mMappedIndexData = nullptr;
- }
+ }
}
bool LLVertexBuffer::updateNumVerts(U32 nverts)
{
- llassert(nverts >= 0);
+ llassert(nverts >= 0);
- bool success = true;
+ bool success = true;
- if (nverts > 65536)
- {
- LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
- nverts = 65536;
- }
+ if (nverts > 65536)
+ {
+ LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
+ nverts = 65536;
+ }
- U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
+ U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
if (needed_size != mSize)
{
@@ -1012,42 +1012,42 @@ bool LLVertexBuffer::updateNumVerts(U32 nverts)
}
llassert(mSize == needed_size);
- mNumVerts = nverts;
- return success;
+ mNumVerts = nverts;
+ return success;
}
bool LLVertexBuffer::updateNumIndices(U32 nindices)
{
- llassert(nindices >= 0);
+ llassert(nindices >= 0);
- bool success = true;
+ bool success = true;
- U32 needed_size = sizeof(U16) * nindices;
+ U32 needed_size = sizeof(U16) * nindices;
- if (needed_size != mIndicesSize)
- {
- success &= createGLIndices(needed_size);
- }
+ if (needed_size != mIndicesSize)
+ {
+ success &= createGLIndices(needed_size);
+ }
llassert(mIndicesSize == needed_size);
- mNumIndices = nindices;
- return success;
+ mNumIndices = nindices;
+ return success;
}
bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices)
{
- if (nverts < 0 || nindices < 0 ||
- nverts > 65536)
- {
- LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
- }
+ if (nverts < 0 || nindices < 0 ||
+ nverts > 65536)
+ {
+ LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
+ }
- bool success = true;
+ bool success = true;
- success &= updateNumVerts(nverts);
- success &= updateNumIndices(nindices);
-
- return success;
+ success &= updateNumVerts(nverts);
+ success &= updateNumIndices(nindices);
+
+ return success;
}
//----------------------------------------------------------------------------
@@ -1056,17 +1056,17 @@ bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices)
// otherwise return false
bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end)
{
-
- if (end < region.mStart ||
- start > region.mEnd)
- { //gap exists, do not merge
- return false;
- }
+
+ if (end < region.mStart ||
+ start > region.mEnd)
+ { //gap exists, do not merge
+ return false;
+ }
region.mStart = llmin(region.mStart, start);
region.mEnd = llmax(region.mEnd, end);
- return true;
+ return true;
}
@@ -1074,7 +1074,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end)
U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 index, S32 count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
-
+
if (count == -1)
{
count = mNumVerts - index;
@@ -1083,24 +1083,24 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
U32 start = mOffsets[type] + sTypeSize[type] * index;
U32 end = start + sTypeSize[type] * count-1;
- bool flagged = false;
- // flag region as mapped
- for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
- {
- MappedRegion& region = mMappedVertexRegions[i];
+ bool flagged = false;
+ // flag region as mapped
+ for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
+ {
+ MappedRegion& region = mMappedVertexRegions[i];
if (expand_region(region, start, end))
{
flagged = true;
break;
}
- }
+ }
- if (!flagged)
- {
- //didn't expand an existing region, make a new one
+ if (!flagged)
+ {
+ //didn't expand an existing region, make a new one
mMappedVertexRegions.push_back({ start, end });
- }
-
+ }
+
return mMappedData+mOffsets[type]+sTypeSize[type]*index;
}
@@ -1108,11 +1108,11 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
-
- if (count == -1)
- {
- count = mNumIndices-index;
- }
+
+ if (count == -1)
+ {
+ count = mNumIndices-index;
+ }
U32 start = sizeof(U16) * index;
U32 end = start + sizeof(U16) * count-1;
@@ -1139,7 +1139,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
}
// flush the given byte range
-// target -- "targret" parameter for glBufferSubData
+// target -- "target" parameter for glBufferSubData
// start -- first byte to copy
// end -- last byte to copy (NOT last byte + 1)
// data -- mMappedData or mMappedIndexData
@@ -1175,23 +1175,23 @@ void LLVertexBuffer::unmapBuffer()
}
};
- if (!mMappedVertexRegions.empty())
- {
+ if (!mMappedVertexRegions.empty())
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex");
if (sGLRenderBuffer != mGLBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
}
-
+
U32 start = 0;
U32 end = 0;
std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion());
- for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
- {
- const MappedRegion& region = mMappedVertexRegions[i];
+ for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
+ {
+ const MappedRegion& region = mMappedVertexRegions[i];
if (region.mStart == end + 1)
{
end = region.mEnd;
@@ -1202,15 +1202,15 @@ void LLVertexBuffer::unmapBuffer()
start = region.mStart;
end = region.mEnd;
}
- }
+ }
flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start);
- mMappedVertexRegions.clear();
- }
-
- if (!mMappedIndexRegions.empty())
- {
+ mMappedVertexRegions.clear();
+ }
+
+ if (!mMappedIndexRegions.empty())
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index");
if (mGLIndices != sGLRenderIndices)
@@ -1240,114 +1240,120 @@ void LLVertexBuffer::unmapBuffer()
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start);
- mMappedIndexRegions.clear();
- }
+ mMappedIndexRegions.clear();
+ }
}
//----------------------------------------------------------------------------
template <class T,LLVertexBuffer::AttributeType type> struct VertexBufferStrider
{
- typedef LLStrider<T> strider_t;
- static bool get(LLVertexBuffer& vbo,
- strider_t& strider,
- S32 index, S32 count)
- {
- if (type == LLVertexBuffer::TYPE_INDEX)
- {
- U8* ptr = vbo.mapIndexBuffer(index, count);
-
- if (ptr == NULL)
- {
- LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
- return false;
- }
-
- strider = (T*)ptr;
- strider.setStride(0);
- return true;
- }
- else if (vbo.hasDataType(type))
- {
+ typedef LLStrider<T> strider_t;
+ static bool get(LLVertexBuffer& vbo,
+ strider_t& strider,
+ S32 index, S32 count)
+ {
+ if (type == LLVertexBuffer::TYPE_INDEX)
+ {
+ U8* ptr = vbo.mapIndexBuffer(index, count);
+
+ if (ptr == NULL)
+ {
+ LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
+ return false;
+ }
+
+ strider = (T*)ptr;
+ strider.setStride(0);
+ return true;
+ }
+ else if (vbo.hasDataType(type))
+ {
U32 stride = LLVertexBuffer::sTypeSize[type];
- U8* ptr = vbo.mapVertexBuffer(type, index, count);
-
- if (ptr == NULL)
- {
- LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
- return false;
- }
-
- strider = (T*)ptr;
- strider.setStride(stride);
- return true;
- }
- else
- {
- LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL;
- }
- return false;
- }
+ U8* ptr = vbo.mapVertexBuffer(type, index, count);
+
+ if (ptr == NULL)
+ {
+ LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
+ return false;
+ }
+
+ strider = (T*)ptr;
+ strider.setStride(stride);
+ return true;
+ }
+ else
+ {
+ LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL;
+ }
+ return false;
+ }
};
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector4a,TYPE_VERTEX>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector4a,TYPE_VERTEX>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count);
+ llassert(mIndicesStride == 2); // cannot access 32-bit indices with U16 strider
+ llassert(mIndicesType == GL_UNSIGNED_SHORT);
+ return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count);
+}
+bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
+{
+ return VertexBufferStrider<LLVector4a, TYPE_NORMAL>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getEmissiveStrider(LLStrider<LLColor4U>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLColor4U,TYPE_EMISSIVE>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLColor4U,TYPE_EMISSIVE>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count);
+ return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 index, S32 count)
{
- return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count);
+ return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count);
}
//----------------------------------------------------------------------------
@@ -1367,7 +1373,7 @@ void LLVertexBuffer::setBuffer()
// this Vertex Buffer must provide all necessary attributes for currently bound shader
llassert_msg((data_mask & mTypeMask) == data_mask,
- "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x"
+ "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x"
<< std::hex << data_mask << " mTypeMask: 0x" << mTypeMask << " Missing: 0x" << (data_mask & ~mTypeMask) << std::dec);
if (sGLRenderBuffer != mGLBuffer)
@@ -1382,7 +1388,7 @@ void LLVertexBuffer::setBuffer()
setupVertexBuffer();
sLastMask = data_mask;
}
-
+
if (mGLIndices != sGLRenderIndices)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
@@ -1503,4 +1509,39 @@ void LLVertexBuffer::setColorData(const LLColor4U* data)
flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data);
}
+void LLVertexBuffer::setNormalData(const LLVector4a* data)
+{
+ llassert(sGLRenderBuffer == mGLBuffer);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + sTypeSize[TYPE_NORMAL] * getNumVerts() - 1, (U8*) data);
+}
+
+void LLVertexBuffer::setTangentData(const LLVector4a* data)
+{
+ llassert(sGLRenderBuffer == mGLBuffer);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + sTypeSize[TYPE_TANGENT] * getNumVerts() - 1, (U8*) data);
+}
+
+void LLVertexBuffer::setWeight4Data(const LLVector4a* data)
+{
+ llassert(sGLRenderBuffer == mGLBuffer);
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + sTypeSize[TYPE_WEIGHT4] * getNumVerts() - 1, (U8*) data);
+}
+
+void LLVertexBuffer::setIndexData(const U16* data)
+{
+ llassert(sGLRenderIndices == mGLIndices);
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16) * getNumIndices() - 1, (U8*) data);
+}
+
+void LLVertexBuffer::setIndexData(const U32* data)
+{
+ llassert(sGLRenderIndices == mGLIndices);
+ if (mIndicesType != GL_UNSIGNED_INT)
+ { // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices
+ mIndicesType = GL_UNSIGNED_INT;
+ mIndicesStride = 4;
+ mNumIndices /= 2;
+ }
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U32) * getNumIndices() - 1, (U8*)data);
+}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 545917cdec..669d89aabf 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvertexbuffer.h
* @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -51,51 +51,51 @@
//============================================================================
-// base class
+// base class
class LLPrivateMemoryPool;
class LLVertexBuffer final : public LLRefCount
{
public:
- struct MappedRegion
- {
+ struct MappedRegion
+ {
U32 mStart;
U32 mEnd;
- };
+ };
- LLVertexBuffer(const LLVertexBuffer& rhs)
- {
- *this = rhs;
- }
+ LLVertexBuffer(const LLVertexBuffer& rhs)
+ {
+ *this = rhs;
+ }
- const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
+ const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
- static void initClass(LLWindow* window);
- static void cleanupClass();
- static void setupClientArrays(U32 data_mask);
- static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
- static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp);
+ static void initClass(LLWindow* window);
+ static void cleanupClass();
+ static void setupClientArrays(U32 data_mask);
+ static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
+ static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp);
- static void unbind(); //unbind any bound vertex buffer
+ static void unbind(); //unbind any bound vertex buffer
- //get the size of a vertex with the given typemask
- static U32 calcVertexSize(const U32& typemask);
+ //get the size of a vertex with the given typemask
+ static U32 calcVertexSize(const U32& typemask);
- //get the size of a buffer with the given typemask and vertex count
- //fill offsets with the offset of each vertex component array into the buffer
- // indexed by the following enum
- static U32 calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices);
+ //get the size of a buffer with the given typemask and vertex count
+ //fill offsets with the offset of each vertex component array into the buffer
+ // indexed by the following enum
+ static U32 calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices);
- //WARNING -- when updating these enums you MUST
- // 1 - update LLVertexBuffer::sTypeSize
+ //WARNING -- when updating these enums you MUST
+ // 1 - update LLVertexBuffer::sTypeSize
// 2 - update LLVertexBuffer::vb_type_name
- // 3 - add a strider accessor
- // 4 - modify LLVertexBuffer::setupVertexBuffer
- // 6 - modify LLViewerShaderMgr::mReservedAttribs
-
+ // 3 - add a strider accessor
+ // 4 - modify LLVertexBuffer::setupVertexBuffer
+ // 6 - modify LLViewerShaderMgr::mReservedAttribs
+
// clang-format off
enum AttributeType { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms()
TYPE_VERTEX = 0, // "position"
@@ -112,158 +112,161 @@ public:
TYPE_CLOTHWEIGHT, // "clothing"
TYPE_TEXTURE_INDEX, // "texture_index"
TYPE_MAX, // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer
- TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer
+ TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer
};
// clang-format on
enum {
- MAP_VERTEX = (1<<TYPE_VERTEX),
- MAP_NORMAL = (1<<TYPE_NORMAL),
- MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
- MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
- MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
- MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
- MAP_COLOR = (1<<TYPE_COLOR),
- MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
- MAP_TANGENT = (1<<TYPE_TANGENT),
- MAP_WEIGHT = (1<<TYPE_WEIGHT),
- MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
- MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
- MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
- };
-
+ MAP_VERTEX = (1<<TYPE_VERTEX),
+ MAP_NORMAL = (1<<TYPE_NORMAL),
+ MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
+ MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
+ MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
+ MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
+ MAP_COLOR = (1<<TYPE_COLOR),
+ MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
+ MAP_TANGENT = (1<<TYPE_TANGENT),
+ MAP_WEIGHT = (1<<TYPE_WEIGHT),
+ MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
+ MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
+ MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
+ };
+
protected:
- friend class LLRender;
+ friend class LLRender;
- ~LLVertexBuffer(); // use unref()
+ ~LLVertexBuffer(); // use unref()
- void setupVertexBuffer();
+ void setupVertexBuffer();
- void genBuffer(U32 size);
- void genIndices(U32 size);
- bool createGLBuffer(U32 size);
- bool createGLIndices(U32 size);
- void destroyGLBuffer();
- void destroyGLIndices();
- bool updateNumVerts(U32 nverts);
- bool updateNumIndices(U32 nindices);
+ void genBuffer(U32 size);
+ void genIndices(U32 size);
+ bool createGLBuffer(U32 size);
+ bool createGLIndices(U32 size);
+ void destroyGLBuffer();
+ void destroyGLIndices();
+ bool updateNumVerts(U32 nverts);
+ bool updateNumIndices(U32 nindices);
public:
- LLVertexBuffer(U32 typemask);
-
+ LLVertexBuffer(U32 typemask);
+
// allocate buffer
- bool allocateBuffer(U32 nverts, U32 nindices);
+ bool allocateBuffer(U32 nverts, U32 nindices);
- // map for data access (see also getFooStrider below)
- U8* mapVertexBuffer(AttributeType type, U32 index, S32 count = -1);
- U8* mapIndexBuffer(U32 index, S32 count = -1);
- void unmapBuffer();
+ // map for data access (see also getFooStrider below)
+ U8* mapVertexBuffer(AttributeType type, U32 index, S32 count = -1);
+ U8* mapIndexBuffer(U32 index, S32 count = -1);
+ void unmapBuffer();
- // set for rendering
+ // set for rendering
// assumes (and will assert on) the following:
// - this buffer has no pending unampBuffer call
// - a shader is currently bound
// - This buffer has sufficient attributes within it to satisfy the needs of the currently bound shader
- void setBuffer();
-
- // Only call each getVertexPointer, etc, once before calling unmapBuffer()
- // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
- // example:
- // vb->getVertexBuffer(verts);
- // vb->getNormalStrider(norms);
- // setVertsNorms(verts, norms);
- // vb->unmapBuffer();
- bool getVertexStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
- bool getVertexStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
- bool getIndexStrider(LLStrider<U16>& strider, U32 index=0, S32 count = -1);
- bool getTexCoord0Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
- bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
- bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
- bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
- bool getEmissiveStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
- bool getWeightStrider(LLStrider<F32>& strider, U32 index=0, S32 count = -1);
- bool getWeight4Strider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
- bool getClothWeightStrider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
- bool getBasecolorTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getNormalTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getMetallicRoughnessTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
- bool getEmissiveTexcoordStrider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
-
+ void setBuffer();
+
+ // Only call each getVertexPointer, etc, once before calling unmapBuffer()
+ // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
+ // example:
+ // vb->getVertexBuffer(verts);
+ // vb->getNormalStrider(norms);
+ // setVertsNorms(verts, norms);
+ // vb->unmapBuffer();
+ bool getVertexStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
+ bool getVertexStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
+ bool getIndexStrider(LLStrider<U16>& strider, U32 index=0, S32 count = -1);
+ bool getTexCoord0Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
+ bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
+ bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
+ bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
+ bool getNormalStrider(LLStrider<LLVector4a>& strider, U32 index = 0, S32 count = -1);
+ bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
+ bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
+ bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
+ bool getEmissiveStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
+ bool getWeightStrider(LLStrider<F32>& strider, U32 index=0, S32 count = -1);
+ bool getWeight4Strider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
+ bool getClothWeightStrider(LLStrider<LLVector4>& strider, U32 index=0, S32 count = -1);
+
void setPositionData(const LLVector4a* data);
+ void setNormalData(const LLVector4a* data);
+ void setTangentData(const LLVector4a* data);
+ void setWeight4Data(const LLVector4a* data);
void setTexCoordData(const LLVector2* data);
void setColorData(const LLColor4U* data);
-
-
- U32 getNumVerts() const { return mNumVerts; }
- U32 getNumIndices() const { return mNumIndices; }
-
- U32 getTypeMask() const { return mTypeMask; }
- bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
+ void setIndexData(const U16* data);
+ void setIndexData(const U32* data);
+
+ U32 getNumVerts() const { return mNumVerts; }
+ U32 getNumIndices() const { return mNumIndices; }
+
+ U32 getTypeMask() const { return mTypeMask; }
+ bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
U32 getSize() const { return mSize; }
- U32 getIndicesSize() const { return mIndicesSize; }
- U8* getMappedData() const { return mMappedData; }
- U8* getMappedIndices() const { return mMappedIndexData; }
- U32 getOffset(AttributeType type) const { return mOffsets[type]; }
-
+ U32 getIndicesSize() const { return mIndicesSize; }
+ U8* getMappedData() const { return mMappedData; }
+ U8* getMappedIndices() const { return mMappedIndexData; }
+ U32 getOffset(AttributeType type) const { return mOffsets[type]; }
+
// these functions assume (and assert on) the current VBO being bound
// Detailed error checking can be enabled by setting gDebugGL to true
- void draw(U32 mode, U32 count, U32 indices_offset) const;
- void drawArrays(U32 mode, U32 offset, U32 count) const;
+ void draw(U32 mode, U32 count, U32 indices_offset) const;
+ void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
- //for debugging, validate data in given range is valid
- bool validateRange(U32 start, U32 end, U32 count, U32 offset) const;
+ //for debugging, validate data in given range is valid
+ bool validateRange(U32 start, U32 end, U32 count, U32 offset) const;
- #ifdef LL_PROFILER_ENABLE_RENDER_DOC
- void setLabel(const char* label);
- #endif
+ #ifdef LL_PROFILER_ENABLE_RENDER_DOC
+ void setLabel(const char* label);
+ #endif
+
+protected:
+ U32 mGLBuffer = 0; // GL VBO handle
+ U32 mGLIndices = 0; // GL IBO handle
+ U32 mNumVerts = 0; // Number of vertices allocated
+ U32 mNumIndices = 0; // Number of indices allocated
+ U32 mIndicesType = GL_UNSIGNED_SHORT; // type of indices in index buffer
+ U32 mIndicesStride = 2; // size of each index in bytes
+ U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute
-protected:
- U32 mGLBuffer = 0; // GL VBO handle
- U32 mGLIndices = 0; // GL IBO handle
- U32 mNumVerts = 0; // Number of vertices allocated
- U32 mNumIndices = 0; // Number of indices allocated
- U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute
+ U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped)
+ U8* mMappedIndexData = nullptr; // pointer to currently mapped indices (NULL if unmapped)
- U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped)
- U8* mMappedIndexData = nullptr; // pointer to currently mapped indices (NULL if unmapped)
+ U32 mTypeMask = 0; // bitmask of present vertex attributes
+
+ U32 mSize = 0; // size in bytes of mMappedData
+ U32 mIndicesSize = 0; // size in bytes of mMappedIndexData
- U32 mTypeMask = 0; // bitmask of present vertex attributes
-
- U32 mSize = 0; // size in bytes of mMappedData
- U32 mIndicesSize = 0; // size in bytes of mMappedIndexData
-
- std::vector<MappedRegion> mMappedVertexRegions; // list of mMappedData byte ranges that must be sent to GL
- std::vector<MappedRegion> mMappedIndexRegions; // list of mMappedIndexData byte ranges that must be sent to GL
+ std::vector<MappedRegion> mMappedVertexRegions; // list of mMappedData byte ranges that must be sent to GL
+ std::vector<MappedRegion> mMappedIndexRegions; // list of mMappedIndexData byte ranges that must be sent to GL
private:
// DEPRECATED
- // These function signatures are deprecated, but for some reason
+ // These function signatures are deprecated, but for some reason
// there are classes in an external package that depend on LLVertexBuffer
-
+
// TODO: move these classes into viewer repository
friend class LLNavShapeVBOManager;
friend class LLNavMeshVBOManager;
-
+
LLVertexBuffer(U32 typemask, U32 usage)
: LLVertexBuffer(typemask)
{}
- bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); }
+ bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); }
public:
static U64 getBytesAllocated();
- static const U32 sTypeSize[TYPE_MAX];
- static const U32 sGLMode[LLRender::NUM_MODES];
- static U32 sGLRenderBuffer;
- static U32 sGLRenderIndices;
- static U32 sLastMask;
- static U32 sVertexCount;
+ static const U32 sTypeSize[TYPE_MAX];
+ static const U32 sGLMode[LLRender::NUM_MODES];
+ static U32 sGLRenderBuffer;
+ static U32 sGLRenderIndices;
+ static U32 sLastMask;
+ static U32 sVertexCount;
};
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a6ae041935..738d8e540d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -38,6 +38,7 @@ include(OpenGL)
include(OpenSSL)
include(PNG)
include(TemplateCheck)
+include(TinyEXR)
include(ThreeJS)
include(Tracy)
include(UI)
@@ -72,8 +73,12 @@ if (NOT HAVOK_TPV)
endif()
endif (NOT HAVOK_TPV)
-
set(viewer_SOURCE_FILES
+ gltfscenemanager.cpp
+ gltf/asset.cpp
+ gltf/accessor.cpp
+ gltf/primitive.cpp
+ gltf/animation.cpp
groupchatlistener.cpp
llaccountingcostmanager.cpp
llaisapi.cpp
@@ -313,6 +318,7 @@ set(viewer_SOURCE_FILES
llgiveinventory.cpp
llglsandbox.cpp
llgltfmateriallist.cpp
+ llgltfmaterialpreviewmgr.cpp
llgroupactions.cpp
llgroupiconctrl.cpp
llgrouplist.cpp
@@ -523,6 +529,7 @@ set(viewer_SOURCE_FILES
llrecentpeople.cpp
llreflectionmap.cpp
llreflectionmapmanager.cpp
+ llheroprobemanager.cpp
llregioninfomodel.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
@@ -726,7 +733,13 @@ set(VIEWER_BINARY_NAME "secondlife-bin" CACHE STRING
set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
+ gltfscenemanager.h
groupchatlistener.h
+ gltf/asset.h
+ gltf/accessor.h
+ gltf/buffer_util.h
+ gltf/primitive.h
+ gltf/animation.h
llaccountingcost.h
llaccountingcostmanager.h
llaisapi.h
@@ -969,6 +982,7 @@ set(viewer_HEADER_FILES
llgesturemgr.h
llgiveinventory.h
llgltfmateriallist.h
+ llgltfmaterialpreviewmgr.h
llgroupactions.h
llgroupiconctrl.h
llgrouplist.h
@@ -1165,6 +1179,7 @@ set(viewer_HEADER_FILES
llrecentpeople.h
llreflectionmap.h
llreflectionmapmanager.h
+ llheroprobemanager.h
llregioninfomodel.h
llregionposition.h
llremoteparcelrequest.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 2f7c256b49..e1eeefa755 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8732,7 +8732,7 @@
<key>OctreeAlphaDistanceFactor</key>
<map>
<key>Comment</key>
- <string>Multiplier on alpha object distance for determining octree node size </string>
+ <string>Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8741,7 +8741,7 @@
<array>
<real>0.1</real>
<real>0.0</real>
- <real>0.0</real>
+ <real>64.0</real>
</array>
</map>
@@ -8861,17 +8861,6 @@
<key>Value</key>
<real>32.0</real>
</map>
- <key>RenderCloudShadowAmbianceFactor</key>
- <map>
- <key>Comment</key>
- <string>Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.1</real>
- </map>
<key>RenderCPUBasis</key>
<map>
<key>Comment</key>
@@ -9186,6 +9175,17 @@
<real>0.00</real>
</array>
</map>
+ <key>RenderMirrors</key>
+ <map>
+ <key>Comment</key>
+ <string>Renders realtime mirrors.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderScreenSpaceReflections</key>
<map>
<key>Comment</key>
@@ -9296,6 +9296,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderDesaturateIrradiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Desaturate irradiance to remove blue tint</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderDebugAlphaMask</key>
<map>
<key>Comment</key>
@@ -9362,6 +9373,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderHDRIExposure</key>
+ <map>
+ <key>Comment</key>
+ <string>Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>RenderHDRIRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Rotation (in degrees) of environment when previewing an HDRI.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>RenderHDRISplitScreen</key>
+ <map>
+ <key>Comment</key>
+ <string>What percentage of screen to render using HDRI vs EEP sky.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderHDRIIrradianceOnly</key>
+ <map>
+ <key>Comment</key>
+ <string>Only use HDRI sky for irradiance map when RenderHDRISplitScreen is 0</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxOpenGLVersion</key>
<map>
<key>Comment</key>
@@ -9395,6 +9450,17 @@
<key>Value</key>
<integer>16</integer>
</map>
+ <key>RenderMaxTextureResolution</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum texture resolution to download for non-boosted textures.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>2048</integer>
+ </map>
<key>RenderDebugTextureBind</key>
<map>
<key>Comment</key>
@@ -10390,6 +10456,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderHeroProbeResolution</key>
+ <map>
+ <key>Comment</key>
+ <string>Resolution to render hero probes used for mirrors, water, etc.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1024</integer>
+ </map>
+ <key>RenderHeroProbeDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Distance in meters for hero probes to render out to.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8</real>
+ </map>
+ <key>RenderHeroProbeUpdateRate</key>
+ <map>
+ <key>Comment</key>
+ <string>How many frames to wait for until it's time to render the probe. E.g., every other frame (1), every two frames (2), every three frames (3) etc.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
+ <key>RenderHeroProbeConservativeUpdateMultiplier</key>
+ <map>
+ <key>Comment</key>
+ <string>How many probe updates to wait until it's time to update faces that are not directly facing the camera. Acts as a multiplier. E.g., frames to the periphery of the camera updating once every 3 updates, vs ones directly facing the camera updating every update.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
<key>RenderReflectionProbeVolumes</key>
<map>
<key>Comment</key>
@@ -10602,38 +10712,49 @@
<integer>3</integer>
</map>
<key>RenderReflectionRes</key>
- <map>
- <key>Comment</key>
- <string>Reflection map resolution.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>64</integer>
- </map>
- <key>RenderResolutionDivisor</key>
- <map>
- <key>Comment</key>
- <string>Divisor for rendering 3D scene at reduced resolution.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>RenderShaderLightingMaxLevel</key>
- <map>
- <key>Comment</key>
- <string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>3</integer>
- </map>
+ <map>
+ <key>Comment</key>
+ <string>Reflection map resolution.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>64</integer>
+ </map>
+ <key>RenderReservedTextureIndices</key>
+ <map>
+ <key>Comment</key>
+ <string>Count of texture indices to reserve for shadow and reflection maps when using indexed texture rendering. Probably only want to set from the login screen.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>14</integer>
+ </map>
+ <key>RenderResolutionDivisor</key>
+ <map>
+ <key>Comment</key>
+ <string>Divisor for rendering 3D scene at reduced resolution.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderShaderLightingMaxLevel</key>
+ <map>
+ <key>Comment</key>
+ <string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>3</integer>
+ </map>
<key>RenderSkyAutoAdjustLegacy</key>
<map>
<key>Comment</key>
@@ -10756,6 +10877,17 @@
<key>Value</key>
<real>0.5</real>
</map>
+ <key>RenderDiffuseLuminanceScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Luminance adjustment for diffuse surfaces to aid auto-exposure behavior</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
<key>RenderShaderLODThreshold</key>
<map>
<key>Comment</key>
@@ -10814,7 +10946,7 @@
<key>RenderTerrainScale</key>
<map>
<key>Comment</key>
- <string>Terrain detail texture scale</string>
+ <string>Terrain detail texture scale (meters)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10822,6 +10954,83 @@
<key>Value</key>
<real>12.0</real>
</map>
+ <key>RenderTerrainPBREnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Enable PBR Terrain features.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRForce</key>
+ <map>
+ <key>Comment</key>
+ <string>Force-load PBR terrain if enabled</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features, in accordance with the GLTF specification when possible, which reduces the number of texture binds.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRScale</key>
+ <map>
+ <key>Comment</key>
+ <string>PBR terrain detail texture scale (meters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8.0</real>
+ </map>
+ <key>RenderTerrainPBRPlanarSampleCount</key>
+ <map>
+ <key>Comment</key>
+ <string>How many UV planes to sample PBR terrain textures from. 1 is "flat", 3 is triplanar mapping (aka box mapping)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <real>3</real>
+ </map>
+ <key>RenderTerrainPBRTriplanarBlendFactor</key>
+ <map>
+ <key>Comment</key>
+ <string>Higher values create sharper transitions, but are more likely to produce artifacts.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8.0</real>
+ </map>
+ <key>RenderTerrainPBRNormalsEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Change normal gen for PBR Terrain.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderTrackerBeacon</key>
<map>
<key>Comment</key>
@@ -13752,6 +13961,17 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>UIPreviewMaterial</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not PBR material swatch is enabled</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
<key>UIResizeBarHeight</key>
<map>
<key>Comment</key>
@@ -15667,7 +15887,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>2048</integer>
+ <integer>1024</integer>
</map>
<key>max_texture_dimension_Y</key>
<map>
@@ -15678,7 +15898,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>2048</integer>
+ <integer>1024</integer>
</map>
<!-- End of back compatibility settings -->
<key>teleport_offer_invitation_max_length</key>
@@ -16554,6 +16774,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LocalTerrainAsset1</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset2</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset3</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset4</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
index d9a6c9e5f1..43863dd37a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file avatarEyesV.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$
*/
@@ -26,6 +26,7 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
in vec3 position;
in vec3 normal;
@@ -35,14 +36,16 @@ in vec2 texcoord0;
out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
+out vec3 vary_position;
void main()
{
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vary_normal = normalize(normal_matrix * normal);
+ //transform vertex
+ vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+ vary_normal = normalize(normal_matrix * normal);
- vertex_color = diffuse_color;
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 63d8e12e62..db7597dd74 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -1,31 +1,31 @@
-/**
+/**
* @file avatarF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
/*[EXTRA_CODE_HERE]*/
-out vec4 frag_data[3];
+out vec4 frag_data[4];
uniform sampler2D diffuseMap;
@@ -33,21 +33,25 @@ uniform float minimum_alpha;
in vec3 vary_normal;
in vec2 vary_texcoord0;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 pos);
-void main()
+void main()
{
- vec4 diff = texture(diffuseMap, vary_texcoord0.xy);
-
- if (diff.a < minimum_alpha)
- {
- discard;
- }
-
- frag_data[0] = vec4(diff.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0);
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ mirrorClip(vary_position);
+
+ vec4 diff = texture(diffuseMap, vary_texcoord0.xy);
+
+ if (diff.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_data[0] = vec4(diff.rgb, 0.0);
+ frag_data[1] = vec4(0,0,0,0);
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
index 74d16592de..5cc2846156 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file avatarV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
uniform mat4 projection_matrix;
in vec3 position;
@@ -35,29 +35,31 @@ in vec4 weight;
out vec3 vary_normal;
out vec2 vary_texcoord0;
+out vec3 vary_position;
void main()
{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- vec4 pos_in = vec4(position.xyz, 1.0);
- mat4 trans = getSkinnedTransform();
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- vary_normal = norm;
-
- gl_Position = projection_matrix * pos;
+ vary_texcoord0 = texcoord0;
+
+ vec4 pos;
+ vec3 norm;
+
+ vec4 pos_in = vec4(position.xyz, 1.0);
+ mat4 trans = getSkinnedTransform();
+ pos.x = dot(trans[0], pos_in);
+ pos.y = dot(trans[1], pos_in);
+ pos.z = dot(trans[2], pos_in);
+ pos.w = 1.0;
+
+ norm.x = dot(trans[0].xyz, normal);
+ norm.y = dot(trans[1].xyz, normal);
+ norm.z = dot(trans[2].xyz, normal);
+ norm = normalize(norm);
+
+ vary_normal = norm;
+
+ vary_position = pos.xyz;
+ gl_Position = projection_matrix * pos;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 19fc660c2d..8627ab1852 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file blurLightF.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$
*/
@@ -40,18 +40,18 @@ uniform float kern_scale;
in vec2 vary_fragcoord;
vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec4 getNorm(vec2 pos_screen);
-void main()
+void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 norm = getNorm(tc);
+ vec4 norm = getNorm(tc);
vec3 pos = getPosition(tc).xyz;
vec4 ccol = texture(lightMap, tc).rgba;
-
+
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
-
+
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
vec4 col = defined_weight.xyxx * ccol;
@@ -75,15 +75,15 @@ void main()
k[1] = (k[0]+k[2])*0.5f;
k[3] = (k[2]+k[4])*0.5f;
k[5] = (k[4]+k[6])*0.5f;
-
+
for (int i = 1; i < 7; i++)
{
vec2 samptc = tc + k[i].z*dlt*2.0;
samptc /= screen_res;
- vec3 samppos = getPosition(samptc).xyz;
+ vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-
+
if (d*d <= pointplanedist_tolerance_pow2)
{
col += texture(lightMap, samptc)*k[i].xyxx;
@@ -95,10 +95,10 @@ void main()
{
vec2 samptc = tc - k[i].z*dlt*2.0;
samptc /= screen_res;
- vec3 samppos = getPosition(samptc).xyz;
+ vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-
+
if (d*d <= pointplanedist_tolerance_pow2)
{
col += texture(lightMap, samptc)*k[i].xyxx;
@@ -108,7 +108,7 @@ void main()
col /= defined_weight.xyxx;
//col.y *= col.y;
-
+
frag_color = max(col, vec4(0));
#ifdef IS_AMD_CARD
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 11deecafbb..8483f257fa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -1,30 +1,30 @@
-/**
+/**
* @file bumpF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
/*[EXTRA_CODE_HERE]*/
-
+
out vec4 frag_data[4];
uniform float minimum_alpha;
@@ -37,29 +37,31 @@ in vec3 vary_mat2;
in vec4 vertex_color;
in vec2 vary_texcoord0;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
-
-void main()
+void mirrorClip(vec3 pos);
+void main()
{
- vec4 col = texture(diffuseMap, vary_texcoord0.xy);
-
- if(col.a < minimum_alpha)
- {
- discard;
- }
- col *= vertex_color;
-
- vec3 norm = texture(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
+ mirrorClip(vary_position);
- vec3 tnorm = vec3(dot(norm,vary_mat0),
- dot(norm,vary_mat1),
- dot(norm,vary_mat2));
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
+
+ if(col.a < minimum_alpha)
+ {
+ discard;
+ }
+ col *= vertex_color;
+
+ vec3 norm = texture(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
- frag_data[0] = vec4(col.rgb, 0.0);
- frag_data[1] = vertex_color.aaaa; // spec
- //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
- vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
- frag_data[3] = vec4(0);
+ vec3 tnorm = vec3(dot(norm,vary_mat0),
+ dot(norm,vary_mat1),
+ dot(norm,vary_mat2));
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = vertex_color.aaaa; // spec
+ //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
+ vec3 nvn = normalize(tnorm);
+ frag_data[2] = vec4(nvn, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index 4ac757be65..74319349f6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -1,28 +1,29 @@
-/**
+/**
* @file bumpV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+uniform mat4 modelview_matrix;
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
@@ -38,36 +39,38 @@ out vec3 vary_mat1;
out vec3 vary_mat2;
out vec4 vertex_color;
out vec2 vary_texcoord0;
+out vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
#endif
void main()
{
- //transform vertex
+ //transform vertex
#ifdef HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
- gl_Position = projection_matrix*vec4(pos, 1.0);
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+ vary_position = pos;
+ gl_Position = projection_matrix*vec4(pos, 1.0);
- vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+ vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+ vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
#else
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vec3 n = normalize(normal_matrix * normal);
- vec3 t = normalize(normal_matrix * tangent.xyz);
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec3 n = normalize(normal_matrix * normal);
+ vec3 t = normalize(normal_matrix * tangent.xyz);
#endif
- vec3 b = cross(n, t) * tangent.w;
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vary_mat0 = vec3(t.x, b.x, n.x);
- vary_mat1 = vec3(t.y, b.y, n.y);
- vary_mat2 = vec3(t.z, b.z, n.z);
+ vec3 b = cross(n, t) * tangent.w;
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 5ef3d63eb2..f6696e270c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file class1/deferred/deferredUtil.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -50,6 +50,7 @@ SOFTWARE.
uniform sampler2D normalMap;
uniform sampler2D depthMap;
+uniform sampler2D emissiveRect;
uniform sampler2D projectionMap; // rgba
uniform sampler2D brdfLut;
@@ -140,40 +141,20 @@ vec2 getScreenCoordinate(vec2 screenpos)
return sc - vec2(1.0, 1.0);
}
-// See: https://aras-p.info/texts/CompactNormalStorage.html
-// Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection
-vec3 getNorm(vec2 screenpos)
-{
- vec2 enc = texture(normalMap, screenpos.xy).xy;
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags)
+vec4 getNorm(vec2 screenpos)
{
- vec2 enc = packedNormalEnvIntensityFlags.xy;
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return normalize(n); // TODO: Is this normalize redundant?
+ return texture(normalMap, screenpos.xy);
}
// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w
// See: C++: addDeferredAttachments(), GLSL: softenLightF
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)
{
- vec4 packedNormalEnvIntensityFlags = texture(normalMap, screenpos.xy);
- n = getNormalFromPacked( packedNormalEnvIntensityFlags );
- envIntensity = packedNormalEnvIntensityFlags.z;
- return packedNormalEnvIntensityFlags;
+ vec4 norm = texture(normalMap, screenpos.xy);
+ n = norm.xyz;
+ envIntensity = texture(emissiveRect, screenpos.xy).r;
+
+ return norm;
}
// get linear depth value given a depth buffer sample d and znear and zfar values
@@ -385,14 +366,14 @@ vec3 pbrIbl(vec3 diffuseColor,
float perceptualRough)
{
// retrieve a scale and bias to F0. See [1], Figure 3
- vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
- vec3 diffuseLight = irradiance;
- vec3 specularLight = radiance;
-
- vec3 diffuse = diffuseLight * diffuseColor;
- vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec3 diffuseLight = irradiance;
+ vec3 specularLight = radiance;
+
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
- return (diffuse + specular) * ao;
+ return (diffuse + specular) * ao;
}
@@ -401,18 +382,18 @@ vec3 pbrIbl(vec3 diffuseColor,
// of the shading terms, outlined in the Readme.MD Appendix.
struct PBRInfo
{
- float NdotL; // cos angle between normal and light direction
- float NdotV; // cos angle between normal and view direction
- float NdotH; // cos angle between normal and half vector
- float LdotH; // cos angle between light direction and half vector
- float VdotH; // cos angle between view direction and half vector
- float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
- float metalness; // metallic value at the surface
- vec3 reflectance0; // full reflectance color (normal incidence angle)
- vec3 reflectance90; // reflectance color at grazing angle
- float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
- vec3 diffuseColor; // color contribution from diffuse lighting
- vec3 specularColor; // color contribution from specular lighting
+ float NdotL; // cos angle between normal and light direction
+ float NdotV; // cos angle between normal and view direction
+ float NdotH; // cos angle between normal and half vector
+ float LdotH; // cos angle between light direction and half vector
+ float VdotH; // cos angle between view direction and half vector
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
+ float metalness; // metallic value at the surface
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
+ vec3 reflectance90; // reflectance color at grazing angle
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
+ vec3 diffuseColor; // color contribution from diffuse lighting
+ vec3 specularColor; // color contribution from specular lighting
};
// Basic Lambertian diffuse
@@ -420,14 +401,14 @@ struct PBRInfo
// See also [1], Equation 1
vec3 diffuse(PBRInfo pbrInputs)
{
- return pbrInputs.diffuseColor / M_PI;
+ return pbrInputs.diffuseColor / M_PI;
}
// The following equation models the Fresnel reflectance term of the spec equation (aka F())
// Implementation of fresnel from [4], Equation 15
vec3 specularReflection(PBRInfo pbrInputs)
{
- return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
+ return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
}
// This calculates the specular geometric attenuation (aka G()),
@@ -436,13 +417,13 @@ vec3 specularReflection(PBRInfo pbrInputs)
// alphaRoughness as input as originally proposed in [2].
float geometricOcclusion(PBRInfo pbrInputs)
{
- float NdotL = pbrInputs.NdotL;
- float NdotV = pbrInputs.NdotV;
- float r = pbrInputs.alphaRoughness;
+ float NdotL = pbrInputs.NdotL;
+ float NdotV = pbrInputs.NdotV;
+ float r = pbrInputs.alphaRoughness;
- float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
- float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
- return attenuationL * attenuationV;
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ return attenuationL * attenuationV;
}
// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
@@ -450,13 +431,13 @@ float geometricOcclusion(PBRInfo pbrInputs)
// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
float microfacetDistribution(PBRInfo pbrInputs)
{
- float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
- float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
- return roughnessSq / (M_PI * f * f);
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
+ return roughnessSq / (M_PI * f * f);
}
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
@@ -464,53 +445,53 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
{
// make sure specular highlights from punctual lights don't fall off of polished surfaces
perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
-
- float alphaRoughness = perceptualRoughness * perceptualRoughness;
-
- // Compute reflectance.
- float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
-
- // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
- // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
- float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
- vec3 specularEnvironmentR0 = specularColor.rgb;
- vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
-
- vec3 h = normalize(l+v); // Half vector between both l and v
- vec3 reflection = -normalize(reflect(v, n));
- reflection.y *= -1.0f;
-
- float NdotL = clamp(dot(n, l), 0.001, 1.0);
- float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
- float NdotH = clamp(dot(n, h), 0.0, 1.0);
- float LdotH = clamp(dot(l, h), 0.0, 1.0);
- float VdotH = clamp(dot(v, h), 0.0, 1.0);
-
- PBRInfo pbrInputs = PBRInfo(
- NdotL,
- NdotV,
- NdotH,
- LdotH,
- VdotH,
- perceptualRoughness,
- metallic,
- specularEnvironmentR0,
- specularEnvironmentR90,
- alphaRoughness,
- diffuseColor,
- specularColor
- );
-
- // Calculate the shading terms for the microfacet specular shading model
- vec3 F = specularReflection(pbrInputs);
- float G = geometricOcclusion(pbrInputs);
- float D = microfacetDistribution(pbrInputs);
-
- // Calculation of analytical lighting contribution
- vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
- vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
- // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
- vec3 color = NdotL * (diffuseContrib + specContrib);
+
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
+
+ // Compute reflectance.
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+
+ // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
+ // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
+ vec3 specularEnvironmentR0 = specularColor.rgb;
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
+
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
+
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
+
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
+
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * (diffuseContrib + specContrib);
return clamp(color, vec3(0), vec3(10));
}
@@ -528,9 +509,9 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v,
vec3 color = vec3(0);
float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
-
+
color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
-
+
color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 3.0 * scol; //magic number to balance with legacy materials
color += colorEmissive;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index c2fb3201f4..82d5d363d2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file diffuseAlphaMaskF.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$
*/
@@ -31,25 +31,29 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
+in vec3 vary_position;
+
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 pos);
-void main()
+void main()
{
- vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;
-
- if (col.a < minimum_alpha)
- {
- discard;
- }
-
- frag_data[0] = vec4(col.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0); // spec
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ mirrorClip(vary_position);
+
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;
+
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = vec4(0,0,0,0); // spec
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index dce1f91bc3..788ea633fc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file diffuseAlphaMaskIndexedF.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$
*/
@@ -28,26 +28,29 @@
out vec4 frag_data[4];
in vec3 vary_normal;
+in vec3 vary_position;
uniform float minimum_alpha;
in vec4 vertex_color;
in vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 pos);
-void main()
+void main()
{
- vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
-
- if (col.a < minimum_alpha)
- {
- discard;
- }
-
- frag_data[0] = vec4(col.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0);
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ mirrorClip(vary_position);
+
+ vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = vec4(0,0,0,0);
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 1fc719dde5..22e6d60419 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file diffuseAlphaMaskNoColorF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_data[4];
@@ -34,21 +34,19 @@ uniform sampler2D diffuseMap;
in vec3 vary_normal;
in vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n);
-
-void main()
+void main()
{
- vec4 col = texture(diffuseMap, vary_texcoord0.xy);
-
- if (col.a < minimum_alpha)
- {
- discard;
- }
-
- frag_data[0] = vec4(col.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0); // spec
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
+
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = vec4(0,0,0,0); // spec
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index d3d375b20a..799fc62a42 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -1,30 +1,30 @@
-/**
+/**
* @file diffuseF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
/*[EXTRA_CODE_HERE]*/
-
+
out vec4 frag_data[4];
uniform sampler2D diffuseMap;
@@ -32,17 +32,19 @@ uniform sampler2D diffuseMap;
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 pos);
-void main()
+void main()
{
- vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;
- frag_data[0] = vec4(col, 0.0);
- frag_data[1] = vertex_color.aaaa; // spec
- //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
- frag_data[3] = vec4(0);
+ mirrorClip(vary_position);
+ vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;
+ frag_data[0] = vec4(col, 0.0);
+ frag_data[1] = vertex_color.aaaa; // spec
+ //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index afdd043c7c..3362a180c6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file diffuseIndexedF.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$
*/
@@ -30,20 +30,22 @@ out vec4 frag_data[4];
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 pos);
vec3 linear_to_srgb(vec3 c);
-void main()
+void main()
{
- vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+ mirrorClip(vary_position);
+ vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
- vec3 spec;
- spec.rgb = vec3(vertex_color.a);
+ vec3 spec;
+ spec.rgb = vec3(vertex_color.a);
- frag_data[0] = vec4(col, 0.0);
- frag_data[1] = vec4(spec, vertex_color.a); // spec
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
- frag_data[3] = vec4(0);
+ frag_data[0] = vec4(col, 0.0);
+ frag_data[1] = vec4(spec, vertex_color.a); // spec
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(vertex_color.a, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 304c01ecc3..64230dc680 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file diffuseV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,13 +36,16 @@ out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
+out vec3 vary_position;
void passTextureIndex();
+uniform mat4 modelview_matrix;
+
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
+
#endif
void main()
@@ -51,16 +54,18 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
+ vary_position = pos.xyz;
gl_Position = projection_matrix * pos;
vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#else
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_normal = normalize(normal_matrix * normal);
#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+ passTextureIndex();
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- passTextureIndex();
-
- vertex_color = diffuse_color;
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 709b47dcbd..eff7221ae7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -1,34 +1,36 @@
-/**
+/**
* @file exposureF.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
uniform sampler2D emissiveRect;
+#ifdef USE_LAST_EXPOSURE
uniform sampler2D exposureMap;
+#endif
uniform float dt;
uniform vec2 noiseVec;
@@ -41,7 +43,7 @@ float lum(vec3 col)
return dot(l, col);
}
-void main()
+void main()
{
vec2 tc = vec2(0.5,0.5);
@@ -51,11 +53,13 @@ void main()
L /= max_L;
L = pow(L, 2.0);
float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L);
-
+
+#ifdef USE_LAST_EXPOSURE
float prev = texture(exposureMap, vec2(0.5,0.5)).r;
s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
-
+#endif
+
frag_color = max(vec4(s, s, s, dt), vec4(0.0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index ec6a4a502f..52dfed06ae 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file deferred/fullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -50,9 +50,11 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
#endif
-void main()
-{
+void mirrorClip(vec3 pos);
+void main()
+{
+ mirrorClip(vary_position);
#ifdef IS_ALPHA
waterClip(vary_position.xyz);
#endif
@@ -88,7 +90,7 @@ void main()
calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
color.rgb = applySkyAndWaterFog(pos, additive, atten, color).rgb;
-
+
#endif
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl
new file mode 100644
index 0000000000..7e3e7d9271
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl
@@ -0,0 +1,45 @@
+/**
+ * @file class1/deferred/globalF.glsl
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+ // Global helper functions included in every fragment shader
+ // DO NOT declare sampler uniforms here as OS X doesn't compile
+ // them out
+
+uniform float mirror_flag;
+uniform vec4 clipPlane;
+uniform float clipSign;
+
+void mirrorClip(vec3 pos)
+{
+ if (mirror_flag > 0)
+ {
+ if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0)
+ {
+ discard;
+ }
+ }
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index 5561a3d488..c64f65e32c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file impostorF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -37,22 +37,21 @@ uniform sampler2D specularMap;
in vec2 vary_texcoord0;
vec3 linear_to_srgb(vec3 c);
-vec2 encode_normal (vec3 n);
-void main()
+void main()
{
- vec4 col = texture(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
- if (col.a < minimum_alpha)
- {
- discard;
- }
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
- vec4 norm = texture(normalMap, vary_texcoord0.xy);
- vec4 spec = texture(specularMap, vary_texcoord0.xy);
+ vec4 norm = texture(normalMap, vary_texcoord0.xy);
+ vec4 spec = texture(specularMap, vary_texcoord0.xy);
- frag_data[0] = vec4(col.rgb, 0.0);
- frag_data[1] = spec;
- frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = spec;
+ frag_data[2] = vec4(norm.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index b9337a357f..95b2f80e06 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -1,32 +1,32 @@
-/**
+/**
* @file luminanceF.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
-// take a luminance sample of diffuseRect and emissiveRect
+// take a luminance sample of diffuseRect and emissiveRect
out vec4 frag_color;
@@ -34,6 +34,8 @@ in vec2 vary_fragcoord;
uniform sampler2D diffuseRect;
uniform sampler2D emissiveRect;
+uniform sampler2D normalMap;
+uniform float diffuse_luminance_scale;
float lum(vec3 col)
{
@@ -41,11 +43,25 @@ float lum(vec3 col)
return dot(l, col);
}
-void main()
+void main()
{
vec2 tc = vary_fragcoord*0.6+0.2;
tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky
- vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
+ vec3 c = texture(diffuseRect, tc).rgb;
+
+ vec4 norm = texture(normalMap, tc);
+
+ if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI) &&
+ !GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))
+ {
+ // Apply the diffuse luminance scale to objects but not the sky
+ // Prevents underexposing when looking at bright environments
+ // while still allowing for realistically bright skies.
+ c *= diffuse_luminance_scale;
+ }
+
+ c += texture(emissiveRect, tc).rgb;
+
float L = lum(c);
frag_color = vec4(max(L, 0.0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 5e48ff709f..ddf878ae60 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file materialV.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$
*/
@@ -28,25 +28,18 @@
#define DIFFUSE_ALPHA_MODE_MASK 2
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
+uniform mat4 modelview_projection_matrix;
+
+#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
#else
uniform mat3 normal_matrix;
-uniform mat4 modelview_projection_matrix;
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#if !defined(HAS_SKIN)
-uniform mat4 modelview_matrix;
#endif
out vec3 vary_position;
-#endif
-
uniform mat4 texture_matrix0;
in vec3 position;
@@ -72,71 +65,67 @@ out vec3 vary_normal;
in vec2 texcoord2;
out vec2 vary_texcoord2;
#endif
-
+
out vec4 vertex_color;
out vec2 vary_texcoord0;
void main()
{
#ifdef HAS_SKIN
- mat4 mat = getObjectSkinnedTransform();
+ mat4 mat = getObjectSkinnedTransform();
- mat = modelview_matrix * mat;
+ mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vary_position = pos;
-#endif
+ vary_position = pos;
- gl_Position = projection_matrix*vec4(pos,1.0);
+ gl_Position = projection_matrix*vec4(pos,1.0);
#else
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
#ifdef HAS_NORMAL_MAP
- vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
#endif
#ifdef HAS_SPECULAR_MAP
- vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
#endif
#ifdef HAS_SKIN
- vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#ifdef HAS_NORMAL_MAP
- vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
vary_tangent = t;
vary_sign = tangent.w;
vary_normal = n;
#else //HAS_NORMAL_MAP
- vary_normal = n;
+ vary_normal = n;
#endif //HAS_NORMAL_MAP
#else //HAS_SKIN
- vec3 n = normalize(normal_matrix * normal);
+ vec3 n = normalize(normal_matrix * normal);
#ifdef HAS_NORMAL_MAP
- vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 t = normalize(normal_matrix * tangent.xyz);
vary_tangent = t;
vary_sign = tangent.w;
vary_normal = n;
#else //HAS_NORMAL_MAP
- vary_normal = n;
+ vary_normal = n;
#endif //HAS_NORMAL_MAP
#endif //HAS_SKIN
+
+ vertex_color = diffuse_color;
- vertex_color = diffuse_color;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
#if !defined(HAS_SKIN)
- vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
-#endif
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 03a8518c36..6ef556d7e8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file class1\deferred\moonF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 2020 Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_data[4];
@@ -34,7 +34,7 @@ uniform sampler2D diffuseMap;
in vec2 vary_texcoord0;
-void main()
+void main()
{
// Restore Pre-EEP alpha fade moon near horizon
float fade = 1.0;
@@ -55,7 +55,7 @@ void main()
frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
frag_data[3] = vec4(c.rgb, c.a);
// Added and commented out for a ground truth. Do not uncomment - Geenz
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
index ed19fba228..1d5f810cf3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file pbropaqueF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -28,7 +28,7 @@
#ifndef IS_HUD
-// deferred opaque implementation
+// deferred opaque implementation
uniform sampler2D diffuseMap; //always in sRGB space
@@ -54,14 +54,20 @@ in vec2 emissive_texcoord;
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
-vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
vec3 srgb_to_linear(vec3 c);
+uniform vec4 clipPlane;
+uniform float clipSign;
+
+void mirrorClip(vec3 pos);
+
uniform mat3 normal_matrix;
void main()
{
+ mirrorClip(vary_position);
+
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
if (basecolor.a < minimum_alpha)
{
@@ -75,7 +81,7 @@ void main()
float sign = vary_sign;
vec3 vN = vary_normal;
vec3 vT = vary_tangent.xyz;
-
+
vec3 vB = sign * cross(vN, vT);
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
@@ -85,7 +91,7 @@ void main()
// roughness 0.0
// metal 0.0
vec3 spec = texture(specularMap, metallic_roughness_texcoord.xy).rgb;
-
+
spec.g *= roughnessFactor;
spec.b *= metallicFactor;
@@ -103,7 +109,7 @@ void main()
// See: C++: addDeferredAttachments(), GLSL: softenLightF
frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse
frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
- frag_data[2] = max(vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
+ frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
index 53e4b732df..5e0141910b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file pbropaqueV.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -28,8 +28,9 @@
//deferred opaque implementation
-#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
+
+#ifdef HAS_SKIN
uniform mat4 projection_matrix;
mat4 getObjectSkinnedTransform();
#else
@@ -53,12 +54,13 @@ out vec2 base_color_texcoord;
out vec2 normal_texcoord;
out vec2 metallic_roughness_texcoord;
out vec2 emissive_texcoord;
-
+
out vec4 vertex_color;
out vec3 vary_tangent;
flat out float vary_sign;
out vec3 vary_normal;
+out vec3 vary_position;
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
@@ -66,17 +68,18 @@ vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] kh
void main()
{
#ifdef HAS_SKIN
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
+ mat4 mat = getObjectSkinnedTransform();
- vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+ mat = modelview_matrix * mat;
- gl_Position = projection_matrix*vec4(pos,1.0);
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+ vary_position = pos;
+ gl_Position = projection_matrix*vec4(pos,1.0);
#else
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
@@ -85,11 +88,11 @@ void main()
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
#ifdef HAS_SKIN
- vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
- vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
#else //HAS_SKIN
- vec3 n = normal_matrix * normal;
- vec3 t = normal_matrix * tangent.xyz;
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
#endif
n = normalize(n);
@@ -97,11 +100,11 @@ void main()
vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_normal_transform, texture_matrix0));
vary_sign = tangent.w;
vary_normal = n;
-
- vertex_color = diffuse_color;
+
+ vertex_color = diffuse_color;
}
-#else
+#else
// fullbright HUD implementation
@@ -118,7 +121,7 @@ in vec2 texcoord0;
out vec2 base_color_texcoord;
out vec2 emissive_texcoord;
-
+
out vec4 vertex_color;
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
@@ -126,7 +129,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl
void main()
{
//transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
new file mode 100644
index 0000000000..de4745c1c4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -0,0 +1,347 @@
+/**
+ * @file class1\deferred\terrainF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#define TERRAIN_PBR_DETAIL_EMISSIVE 0
+#define TERRAIN_PBR_DETAIL_OCCLUSION -1
+#define TERRAIN_PBR_DETAIL_NORMAL -2
+#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+#define TerrainCoord vec4[2]
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+#define TerrainCoord vec2
+#endif
+
+#define MIX_X 1 << 3
+#define MIX_Y 1 << 4
+#define MIX_Z 1 << 5
+#define MIX_W 1 << 6
+
+struct TerrainMix
+{
+ vec4 weight;
+ int type;
+};
+
+TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal);
+
+struct PBRMix
+{
+ vec4 col; // RGB color with alpha, linear space
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ vec3 orm; // Occlusion, roughness, metallic
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ vec2 rm; // Roughness, metallic
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ vec3 vNt; // Unpacked normal texture sample, vector
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ vec3 emissive; // RGB emissive color, linear space
+#endif
+};
+
+PBRMix init_pbr_mix();
+
+PBRMix terrain_sample_and_multiply_pbr(
+ TerrainCoord terrain_coord
+ , sampler2D tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , sampler2D tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , sampler2D tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , sampler2D tex_emissive
+#endif
+ , vec4 factor_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , vec3 factor_orm
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , vec2 factor_rm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , vec3 factor_emissive
+#endif
+ );
+
+PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight);
+
+out vec4 frag_data[4];
+
+uniform sampler2D alpha_ramp;
+
+// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
+uniform sampler2D detail_0_base_color;
+uniform sampler2D detail_1_base_color;
+uniform sampler2D detail_2_base_color;
+uniform sampler2D detail_3_base_color;
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+uniform sampler2D detail_0_normal;
+uniform sampler2D detail_1_normal;
+uniform sampler2D detail_2_normal;
+uniform sampler2D detail_3_normal;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+uniform sampler2D detail_0_metallic_roughness;
+uniform sampler2D detail_1_metallic_roughness;
+uniform sampler2D detail_2_metallic_roughness;
+uniform sampler2D detail_3_metallic_roughness;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+uniform sampler2D detail_0_emissive;
+uniform sampler2D detail_1_emissive;
+uniform sampler2D detail_2_emissive;
+uniform sampler2D detail_3_emissive;
+#endif
+
+uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+uniform vec4 metallicFactors;
+uniform vec4 roughnessFactors;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+uniform vec3[4] emissiveColors;
+#endif
+uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+in vec4[2] vary_coords;
+#endif
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+flat in float vary_sign;
+in vec4 vary_texcoord0;
+in vec4 vary_texcoord1;
+
+void mirrorClip(vec3 position);
+
+float terrain_mix(TerrainMix tm, vec4 tms4);
+
+void main()
+{
+ // Make sure we clip the terrain if we're in a mirror.
+ mirrorClip(vary_position);
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+ TerrainCoord terrain_texcoord = vary_coords;
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+ TerrainCoord terrain_texcoord = vary_texcoord0.xy;
+#endif
+
+ float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a;
+ float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a;
+ float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a;
+
+ TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal);
+
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerTexture::sDefaultPBRORMImagep
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+ vec3[4] orm_factors;
+ orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x);
+ orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y);
+ orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z);
+ orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w);
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ vec2[4] rm_factors;
+ rm_factors[0] = vec2(roughnessFactors.x, metallicFactors.x);
+ rm_factors[1] = vec2(roughnessFactors.y, metallicFactors.y);
+ rm_factors[2] = vec2(roughnessFactors.z, metallicFactors.z);
+ rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w);
+#endif
+
+ PBRMix mix = init_pbr_mix();
+ PBRMix mix2;
+ switch (tm.type & MIX_X)
+ {
+ case MIX_X:
+ mix2 = terrain_sample_and_multiply_pbr(
+ terrain_texcoord
+ , detail_0_base_color
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , detail_0_metallic_roughness
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , detail_0_normal
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , detail_0_emissive
+#endif
+ , baseColorFactors[0]
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , orm_factors[0]
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , rm_factors[0]
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , emissiveColors[0]
+#endif
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.x);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_Y)
+ {
+ case MIX_Y:
+ mix2 = terrain_sample_and_multiply_pbr(
+ terrain_texcoord
+ , detail_1_base_color
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , detail_1_metallic_roughness
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , detail_1_normal
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , detail_1_emissive
+#endif
+ , baseColorFactors[1]
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , orm_factors[1]
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , rm_factors[1]
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , emissiveColors[1]
+#endif
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.y);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_Z)
+ {
+ case MIX_Z:
+ mix2 = terrain_sample_and_multiply_pbr(
+ terrain_texcoord
+ , detail_2_base_color
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , detail_2_metallic_roughness
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , detail_2_normal
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , detail_2_emissive
+#endif
+ , baseColorFactors[2]
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , orm_factors[2]
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , rm_factors[2]
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , emissiveColors[2]
+#endif
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.z);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_W)
+ {
+ case MIX_W:
+ mix2 = terrain_sample_and_multiply_pbr(
+ terrain_texcoord
+ , detail_3_base_color
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , detail_3_metallic_roughness
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , detail_3_normal
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , detail_3_emissive
+#endif
+ , baseColorFactors[3]
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , orm_factors[3]
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , rm_factors[3]
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , emissiveColors[3]
+#endif
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.w);
+ break;
+ default:
+ break;
+ }
+
+ float minimum_alpha = terrain_mix(tm, minimum_alphas);
+ if (mix.col.a < minimum_alpha)
+ {
+ discard;
+ }
+ float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z));
+
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ // from mikktspace.com
+ vec3 vNt = mix.vNt;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = vary_sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+#else
+ vec3 tnorm = vary_normal;
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+#endif
+
+
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+#define emissive mix.emissive
+#else
+#define emissive vec3(0)
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+#define orm mix.orm
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+#define orm vec3(1.0, mix.rm)
+#else
+// Matte plastic potato terrain
+#define orm vec3(1.0, 1.0, 0.0)
+#endif
+ frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse
+ frag_data[1] = max(vec4(orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
+ frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, flags
+ frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
new file mode 100644
index 0000000000..935c3f9301
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
@@ -0,0 +1,473 @@
+/**
+ * @file class1\deferred\pbrterrainUtilF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+/**
+ * Triplanar mapping implementation adapted from Inigo Quilez' example shader,
+ * MIT license.
+ * https://www.shadertoy.com/view/MtsGWH
+ * Copyright © 2015 Inigo Quilez
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions: The above copyright
+ * notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define TERRAIN_PBR_DETAIL_EMISSIVE 0
+#define TERRAIN_PBR_DETAIL_OCCLUSION -1
+#define TERRAIN_PBR_DETAIL_NORMAL -2
+#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
+
+in vec3 vary_vertex_normal;
+
+vec3 srgb_to_linear(vec3 c);
+
+// A relatively agressive threshold for terrain material mixing sampling
+// cutoff. This ensures that only one or two materials are used in most places,
+// making PBR terrain blending more performant. Should be greater than 0 to work.
+#define TERRAIN_RAMP_MIX_THRESHOLD 0.1
+// A small threshold for triplanar mapping sampling cutoff. This and
+// TERRAIN_TRIPLANAR_BLEND_FACTOR together ensures that only one or two samples
+// per texture are used in most places, making triplanar mapping more
+// performant. Should be greater than 0 to work.
+// There's also an artistic design choice in the use of these factors, and the
+// use of triplanar generally. Don't take these triplanar constants for granted.
+#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01
+
+#define SAMPLE_X 1 << 0
+#define SAMPLE_Y 1 << 1
+#define SAMPLE_Z 1 << 2
+#define MIX_X 1 << 3
+#define MIX_Y 1 << 4
+#define MIX_Z 1 << 5
+#define MIX_W 1 << 6
+
+struct PBRMix
+{
+ vec4 col; // RGB color with alpha, linear space
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ vec3 orm; // Occlusion, roughness, metallic
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ vec2 rm; // Roughness, metallic
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ vec3 vNt; // Unpacked normal texture sample, vector
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ vec3 emissive; // RGB emissive color, linear space
+#endif
+};
+
+PBRMix init_pbr_mix()
+{
+ PBRMix mix;
+ mix.col = vec4(0);
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ mix.orm = vec3(0);
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ mix.rm = vec2(0);
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ mix.vNt = vec3(0);
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ mix.emissive = vec3(0);
+#endif
+ return mix;
+}
+
+// Usage example, for two weights:
+// vec2 weights = ... // Weights must add up to 1
+// PBRMix mix = init_pbr_mix();
+// PBRMix mix1 = ...
+// mix = mix_pbr(mix, mix1, weights.x);
+// PBRMix mix2 = ...
+// mix = mix_pbr(mix, mix2, weights.y);
+PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight)
+{
+ PBRMix mix;
+ mix.col = mix1.col + (mix2.col * mix2_weight);
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ mix.orm = mix1.orm + (mix2.orm * mix2_weight);
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ mix.rm = mix1.rm + (mix2.rm * mix2_weight);
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight);
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight);
+#endif
+ return mix;
+}
+
+PBRMix sample_pbr(
+ vec2 uv
+ , sampler2D tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , sampler2D tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , sampler2D tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , sampler2D tex_emissive
+#endif
+ )
+{
+ PBRMix mix;
+ mix.col = texture(tex_col, uv);
+ mix.col.rgb = srgb_to_linear(mix.col.rgb);
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ mix.orm = texture(tex_orm, uv).xyz;
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ mix.rm = texture(tex_orm, uv).yz;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz);
+#endif
+ return mix;
+}
+
+struct TerrainTriplanar
+{
+ vec3 weight;
+ int type;
+};
+
+struct TerrainMix
+{
+ vec4 weight;
+ int type;
+};
+
+#define TerrainMixSample vec4[4]
+#define TerrainMixSample3 vec3[4]
+
+TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal)
+{
+ TerrainMix tm;
+ vec4 sample_x = vec4(1,0,0,0);
+ vec4 sample_y = vec4(0,1,0,0);
+ vec4 sample_z = vec4(0,0,1,0);
+ vec4 sample_w = vec4(0,0,0,1);
+
+ tm.weight = mix( mix(sample_w, sample_z, alpha2), mix(sample_y, sample_x, alpha1), alphaFinal );
+ tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD;
+ ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight)));
+ // Prevent negative weights and keep weights balanced
+ tm.weight = tm.weight*vec4(usage);
+ tm.weight /= (tm.weight.x + tm.weight.y + tm.weight.z + tm.weight.w);
+
+ tm.type = (usage.x * MIX_X) |
+ (usage.y * MIX_Y) |
+ (usage.z * MIX_Z) |
+ (usage.w * MIX_W);
+ return tm;
+}
+
+TerrainTriplanar _t_triplanar()
+{
+ float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR;
+ float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD;
+ vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness));
+ weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z);
+ weight_signed -= vec3(threshold);
+ TerrainTriplanar tw;
+ // *NOTE: Make sure the threshold doesn't affect the materials
+ tw.weight = max(vec3(0), weight_signed);
+ tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z);
+ ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed))));
+ tw.type = ((usage.x) * SAMPLE_X) |
+ ((usage.y) * SAMPLE_Y) |
+ ((usage.z) * SAMPLE_Z);
+ return tw;
+}
+
+// Assume weights add to 1
+float terrain_mix(TerrainMix tm, vec4 tms4)
+{
+ return (tm.weight.x * tms4[0]) +
+ (tm.weight.y * tms4[1]) +
+ (tm.weight.z * tms4[2]) +
+ (tm.weight.w * tms4[3]);
+}
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+// Triplanar mapping
+
+// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused)
+#define TerrainCoord vec4[2]
+
+vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero)
+{
+ // Handle case where sign is 0
+ float sign = (2.0*sign_or_zero) + 1.0;
+ sign /= abs(sign);
+ // If the vertex normal is negative, flip the texture back
+ // right-side up.
+ vec2 uv = uv_unflipped * vec2(sign, 1);
+ return uv;
+}
+
+vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero)
+{
+ // Assume normal is unpacked
+ vec3 vNt1 = vNt0;
+ // Get sign
+ float sign = sign_or_zero;
+ // Handle case where sign is 0
+ sign = (2.0*sign) + 1.0;
+ sign /= abs(sign);
+ // If the sign is negative, rotate normal by 180 degrees
+ vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy);
+ return vNt1;
+}
+
+// Triplanar-specific normal texture fixes
+vec3 _t_normal_post_x(vec3 vNt0)
+{
+ vec3 vNt_x = _t_normal_post_1(vNt0, sign(vary_vertex_normal.x));
+ // *HACK: Transform normals according to orientation of the UVs
+ vNt_x.xy = vec2(-vNt_x.y, vNt_x.x);
+ return vNt_x;
+}
+vec3 _t_normal_post_y(vec3 vNt0)
+{
+ vec3 vNt_y = _t_normal_post_1(vNt0, sign(vary_vertex_normal.y));
+ // *HACK: Transform normals according to orientation of the UVs
+ vNt_y.xy = -vNt_y.xy;
+ return vNt_y;
+}
+vec3 _t_normal_post_z(vec3 vNt0)
+{
+ vec3 vNt_z = _t_normal_post_1(vNt0, sign(vary_vertex_normal.z));
+ return vNt_z;
+}
+
+PBRMix terrain_sample_pbr(
+ TerrainCoord terrain_coord
+ , TerrainTriplanar tw
+ , sampler2D tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , sampler2D tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , sampler2D tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , sampler2D tex_emissive
+#endif
+ )
+{
+ PBRMix mix = init_pbr_mix();
+
+#define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x))
+#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y))
+#define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z))
+ switch (tw.type & SAMPLE_X)
+ {
+ case SAMPLE_X:
+ PBRMix mix_x = sample_pbr(
+ get_uv_x()
+ , tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , tex_emissive
+#endif
+ );
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ // Triplanar-specific normal texture fix
+ mix_x.vNt = _t_normal_post_x(mix_x.vNt);
+#endif
+ mix = mix_pbr(mix, mix_x, tw.weight.x);
+ break;
+ default:
+ break;
+ }
+
+ switch (tw.type & SAMPLE_Y)
+ {
+ case SAMPLE_Y:
+ PBRMix mix_y = sample_pbr(
+ get_uv_y()
+ , tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , tex_emissive
+#endif
+ );
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ // Triplanar-specific normal texture fix
+ mix_y.vNt = _t_normal_post_y(mix_y.vNt);
+#endif
+ mix = mix_pbr(mix, mix_y, tw.weight.y);
+ break;
+ default:
+ break;
+ }
+
+ switch (tw.type & SAMPLE_Z)
+ {
+ case SAMPLE_Z:
+ PBRMix mix_z = sample_pbr(
+ get_uv_z()
+ , tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , tex_emissive
+#endif
+ );
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ // Triplanar-specific normal texture fix
+ // *NOTE: Bottom face has not been tested
+ mix_z.vNt = _t_normal_post_z(mix_z.vNt);
+#endif
+ mix = mix_pbr(mix, mix_z, tw.weight.z);
+ break;
+ default:
+ break;
+ }
+
+ return mix;
+}
+
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+
+#define TerrainCoord vec2
+
+#define terrain_sample_pbr sample_pbr
+
+#endif
+
+PBRMix multiply_factors_pbr(
+ PBRMix mix_in
+ , vec4 factor_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , vec3 factor_orm
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , vec2 factor_rm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , vec3 factor_emissive
+#endif
+ )
+{
+ PBRMix mix = mix_in;
+ mix.col *= factor_col;
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ mix.orm *= factor_orm;
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ mix.rm *= factor_rm;
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ mix.emissive *= factor_emissive;
+#endif
+ return mix;
+}
+
+PBRMix terrain_sample_and_multiply_pbr(
+ TerrainCoord terrain_coord
+ , sampler2D tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , sampler2D tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , sampler2D tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , sampler2D tex_emissive
+#endif
+ , vec4 factor_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , vec3 factor_orm
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , vec2 factor_rm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , vec3 factor_emissive
+#endif
+ )
+{
+ PBRMix mix = terrain_sample_pbr(
+ terrain_coord
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+ , _t_triplanar()
+#endif
+ , tex_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , tex_orm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
+ , tex_vNt
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , tex_emissive
+#endif
+ );
+
+ mix = multiply_factors_pbr(mix
+ , factor_col
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
+ , factor_orm
+#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ , factor_rm
+#endif
+#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ , factor_emissive
+#endif
+ );
+
+ return mix;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
new file mode 100644
index 0000000000..489fc26e3f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
@@ -0,0 +1,96 @@
+/**
+ * @file class1\environment\pbrterrainV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+in vec3 position;
+in vec3 normal;
+in vec4 tangent;
+in vec4 diffuse_color;
+in vec2 texcoord1;
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+out vec4[2] vary_coords;
+#endif
+out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl
+out vec3 vary_normal;
+out vec3 vary_tangent;
+flat out float vary_sign;
+out vec4 vary_texcoord0;
+out vec4 vary_texcoord1;
+out vec3 vary_position;
+
+// *HACK: tangent_space_transform should use texture_normal_transform, or maybe
+// we shouldn't use tangent_space_transform at all. See the call to
+// tangent_space_transform below.
+uniform vec4[2] texture_base_color_transform;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+
+ vec3 n = normal_matrix * normal;
+ vary_vertex_normal = normal;
+ vec3 t = normal_matrix * tangent.xyz;
+
+ vary_tangent = normalize(t);
+ // *TODO: Decide if we want this. It may be better to just calculate the
+ // tangents on-the-fly in the fragment shader, due to the subtleties of the
+ // effect of triplanar mapping on UVs.
+ // *HACK: Should be using texture_normal_transform here. The KHR texture
+ // transform spec requires handling texture transforms separately for each
+ // individual texture.
+ vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_base_color_transform, texture_matrix0));
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ // Transform and pass tex coords
+ // *HACK: texture_base_color_transform is used for all of these here, but
+ // the KHR texture transform spec requires handling texture transforms
+ // separately for each individual texture.
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+ // xy
+ vary_coords[0].xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0);
+ // yz
+ vary_coords[0].zw = texture_transform(position.yz, texture_base_color_transform, texture_matrix0);
+ // (-x)z
+ vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0);
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+ vary_texcoord0.xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0);
+#endif
+
+ vec4 tc = vec4(texcoord1,0,1);
+ vary_texcoord0.zw = tc.xy;
+ vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 7a25f63260..1629ed91c8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file postDeferredGammaCorrect.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -79,7 +79,7 @@ vec3 RRTAndODTFit(vec3 color)
}
-// tone mapping
+// tone mapping
vec3 toneMapACES_Hill(vec3 color)
{
color = ACESInputMat * color;
@@ -97,16 +97,17 @@ vec3 toneMapACES_Hill(vec3 color)
uniform float exposure;
uniform float gamma;
+uniform float aces_mix;
vec3 toneMap(vec3 color)
{
#ifndef NO_POST
float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
-
+
color *= exposure * exp_scale;
// mix ACES and Linear here as a compromise to avoid over-darkening legacy content
- color = mix(toneMapACES_Hill(color), color, 0.3);
+ color = mix(toneMapACES_Hill(color), color, aces_mix);
#endif
return color;
@@ -116,42 +117,51 @@ vec3 toneMap(vec3 color)
//=================================
// borrowed noise from:
-// <https://www.shadertoy.com/view/4dS3Wd>
-// By Morgan McGuire @morgan3d, http://graphicscodex.com
+// <https://www.shadertoy.com/view/4dS3Wd>
+// By Morgan McGuire @morgan3d, http://graphicscodex.com
//
float hash(float n) { return fract(sin(n) * 1e4); }
float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }
float noise(float x) {
- float i = floor(x);
- float f = fract(x);
- float u = f * f * (3.0 - 2.0 * f);
- return mix(hash(i), hash(i + 1.0), u);
+ float i = floor(x);
+ float f = fract(x);
+ float u = f * f * (3.0 - 2.0 * f);
+ return mix(hash(i), hash(i + 1.0), u);
}
float noise(vec2 x) {
- vec2 i = floor(x);
- vec2 f = fract(x);
-
- // Four corners in 2D of a tile
- float a = hash(i);
- float b = hash(i + vec2(1.0, 0.0));
- float c = hash(i + vec2(0.0, 1.0));
- float d = hash(i + vec2(1.0, 1.0));
-
- // Simple 2D lerp using smoothstep envelope between the values.
- // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
- // mix(c, d, smoothstep(0.0, 1.0, f.x)),
- // smoothstep(0.0, 1.0, f.y)));
-
- // Same code, with the clamps in smoothstep and common subexpressions
- // optimized away.
- vec2 u = f * f * (3.0 - 2.0 * f);
- return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
+ vec2 i = floor(x);
+ vec2 f = fract(x);
+
+ // Four corners in 2D of a tile
+ float a = hash(i);
+ float b = hash(i + vec2(1.0, 0.0));
+ float c = hash(i + vec2(0.0, 1.0));
+ float d = hash(i + vec2(1.0, 1.0));
+
+ // Simple 2D lerp using smoothstep envelope between the values.
+ // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
+ // mix(c, d, smoothstep(0.0, 1.0, f.x)),
+ // smoothstep(0.0, 1.0, f.y)));
+
+ // Same code, with the clamps in smoothstep and common subexpressions
+ // optimized away.
+ vec2 u = f * f * (3.0 - 2.0 * f);
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}
//=============================
+void debugExposure(inout vec3 color)
+{
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+ exp_scale *= 0.5;
+ if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
+ {
+ color = vec3(1,0,0);
+ }
+}
vec3 legacyGamma(vec3 color)
{
@@ -161,7 +171,7 @@ vec3 legacyGamma(vec3 color)
return c;
}
-void main()
+void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
vec4 diff = texture(diffuseRect, vary_fragcoord);
@@ -181,6 +191,7 @@ void main()
vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
diff.rgb += nz*0.003;
+ //debugExposure(diff.rgb);
frag_color = max(diff, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index a07a4301bc..785c748234 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file class1/deferred/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -27,6 +27,15 @@
in vec3 vary_HazeColor;
in float vary_LightNormPosDot;
+#ifdef HAS_HDRI
+in vec4 vary_position;
+in vec3 vary_rel_pos;
+uniform float sky_hdr_scale;
+uniform float hdri_split_screen;
+uniform mat3 env_mat;
+uniform sampler2D environmentMap;
+#endif
+
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
@@ -37,6 +46,9 @@ uniform float ice_level;
out vec4 frag_data[4];
vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+#define PI 3.14159265
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
@@ -71,24 +83,42 @@ vec3 halo22(float d)
void main()
{
- // Potential Fill-rate optimization. Add cloud calculation
- // back in and output alpha of 0 (so that alpha culling kills
- // the fragment) if the sky wouldn't show up because the clouds
- // are fully opaque.
-
- vec3 color = vary_HazeColor;
-
- float rel_pos_lightnorm = vary_LightNormPosDot;
- float optic_d = rel_pos_lightnorm;
- vec3 halo_22 = halo22(optic_d);
- color.rgb += rainbow(optic_d);
- color.rgb += halo_22;
- color.rgb *= 2.;
- color.rgb = clamp(color.rgb, vec3(0), vec3(5));
+ vec3 color;
+#ifdef HAS_HDRI
+ vec3 frag_coord = vary_position.xyz/vary_position.w;
+ if (-frag_coord.x > ((1.0-hdri_split_screen)*2.0-1.0))
+ {
+ vec3 pos = normalize(vary_rel_pos);
+ pos = env_mat * pos;
+ vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI);
+ color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale;
+ color = min(color, vec3(8192*8192*16)); // stupidly large value arrived at by binary search -- avoids framebuffer corruption from some HDRIs
+
+ frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_HAS_HDRI);
+ }
+ else
+#endif
+ {
+ // Potential Fill-rate optimization. Add cloud calculation
+ // back in and output alpha of 0 (so that alpha culling kills
+ // the fragment) if the sky wouldn't show up because the clouds
+ // are fully opaque.
+
+ color = vary_HazeColor;
+
+ float rel_pos_lightnorm = vary_LightNormPosDot;
+ float optic_d = rel_pos_lightnorm;
+ vec3 halo_22 = halo22(optic_d);
+ color.rgb += rainbow(optic_d);
+ color.rgb += halo_22;
+ color.rgb *= 2.;
+ color.rgb = clamp(color.rgb, vec3(0), vec3(5));
+
+ frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS);
+ }
frag_data[0] = vec4(0);
frag_data[1] = vec4(0);
- frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
frag_data[3] = vec4(color.rgb, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 6110b6ade0..24d2db2183 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -35,6 +35,11 @@ in vec3 position;
out vec3 vary_HazeColor;
out float vary_LightNormPosDot;
+#ifdef HAS_HDRI
+out vec4 vary_position;
+out vec3 vary_rel_pos;
+#endif
+
// Inputs
uniform vec3 camPosLocal;
@@ -72,6 +77,11 @@ void main()
// Get relative position
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+#ifdef HAS_HDRI
+ vary_rel_pos = rel_pos;
+ vary_position = pos;
+#endif
+
// Adj position vector to clamp altitude
if (rel_pos.y > 0.)
{
@@ -92,13 +102,13 @@ void main()
// Initialize temp variables
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color * 0.7; //magic 0.7 to match legacy color
-
+
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));
vec3 blue_weight = blue_density / combined_haze;
vec3 haze_weight = haze_density / combined_haze;
@@ -142,7 +152,7 @@ void main()
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index bee9e6d2fe..5f598f84a7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file class1\deferred\terrainF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_data[4];
@@ -38,12 +38,13 @@ in vec3 vary_normal;
in vec4 vary_texcoord0;
in vec4 vary_texcoord1;
-vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 position);
void main()
{
+ mirrorClip(pos);
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
-
+
vec4 color0 = texture(detail_0, vary_texcoord0.xy);
vec4 color1 = texture(detail_1, vary_texcoord0.xy);
vec4 color2 = texture(detail_2, vary_texcoord0.xy);
@@ -53,13 +54,13 @@ void main()
float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a;
float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a;
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- outColor.a = 0.0; // yes, downstream atmospherics
-
+
+ outColor.a = 0.0; // yes, downstream atmospherics
+
frag_data[0] = outColor;
frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index aab2abff1e..8e1e4b54d5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
@@ -1,36 +1,36 @@
-/**
+/**
* @file class1\environment\terrainV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
in vec3 position;
in vec3 normal;
in vec4 diffuse_color;
-in vec2 texcoord0;
in vec2 texcoord1;
out vec3 pos;
@@ -41,18 +41,16 @@ out vec4 vary_texcoord1;
uniform vec4 object_plane_s;
uniform vec4 object_plane_t;
-vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
+vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1)
{
vec4 tcoord;
-
+
tcoord.x = dot(vpos, tp0);
tcoord.y = dot(vpos, tp1);
- tcoord.z = tc.z;
- tcoord.w = tc.w;
-
- tcoord = mat * tcoord;
-
- return tcoord;
+
+ tcoord = mat * tcoord;
+
+ return tcoord.xy;
}
void main()
@@ -62,15 +60,15 @@ void main()
vec4 t_pos = modelview_projection_matrix * pre_pos;
gl_Position = t_pos;
- pos = t_pos.xyz;
+ pos = (modelview_matrix*pre_pos).xyz;
vary_normal = normalize(normal_matrix * normal);
-
+
// Transform and pass tex coords
- vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
+ vary_texcoord0.xy = texgen_object(vec4(position, 1.0), texture_matrix0, object_plane_s, object_plane_t);
+
vec4 t = vec4(texcoord1,0,1);
-
+
vary_texcoord0.zw = t.xy;
vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
index 8e641522e3..732333311c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file class1/deferred/textureUtilV.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -65,7 +65,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl
// Apply texture animation first to avoid shearing and other artifacts
texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy;
// Convert to left-handed coordinate system. The offset of 1 is necessary
- // for rotations to be applied correctly.
+ // for rotation and scale to be applied correctly.
texcoord.y = 1.0 - texcoord.y;
texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
// Convert back to right-handed coordinate system
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index db6070f328..708acd0194 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file treeF.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$
*/
@@ -32,22 +32,23 @@ uniform sampler2D diffuseMap;
in vec4 vertex_color;
in vec3 vary_normal;
in vec2 vary_texcoord0;
+in vec3 vary_position;
uniform float minimum_alpha;
-vec2 encode_normal(vec3 n);
-
-void main()
+void mirrorClip(vec3 pos);
+void main()
{
- vec4 col = texture(diffuseMap, vary_texcoord0.xy);
- if (col.a < minimum_alpha)
- {
- discard;
- }
-
- frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0);
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ mirrorClip(vary_position);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
+ frag_data[1] = vec4(0,0,0,0);
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);
frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
index 81900fba70..c84fccd4c6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
@@ -1,29 +1,30 @@
-/**
+/**
* @file treeV.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;
uniform mat3 normal_matrix;
@@ -34,14 +35,17 @@ in vec2 texcoord0;
out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
+out vec3 vary_position;
void main()
{
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
- vary_normal = normalize(normal_matrix * normal);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+ vary_normal = normalize(normal_matrix * normal);
- vertex_color = vec4(1,1,1,1);
+ vertex_color = vec4(1,1,1,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl
index ca3e4f6718..388042e7e0 100644
--- a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl
@@ -1,34 +1,33 @@
-/**
- * @file encodeNormF.glsl
+/**
+ * @file normaldebugF.glsl
*
- * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2018, Linden Research, Inc.
- *
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-// Lambert Azimuthal Equal-Area projection
-// See: https://aras-p.info/texts/CompactNormalStorage.html
-// Also see: A_bit_more_deferred_-_CryEngine3.ppt
-vec2 encode_normal(vec3 n)
+out vec4 frag_color;
+
+in vec4 vertex_color;
+
+void main()
{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
+ frag_color = max(vertex_color, vec4(0));
}
-
diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl
new file mode 100644
index 0000000000..51d05cd507
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl
@@ -0,0 +1,76 @@
+/**
+ * @file normaldebugG.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// *NOTE: Geometry shaders have a reputation for being slow. Consider using
+// compute shaders instead, which have a reputation for being fast. This
+// geometry shader in particular seems to run fine on my machine, but I won't
+// vouch for this in performance-critical areas.
+// -Cosmic,2023-09-28
+
+out vec4 vertex_color;
+
+in vec4 normal_g[];
+#ifdef HAS_ATTRIBUTE_TANGENT
+in vec4 tangent_g[];
+#endif
+
+layout(triangles) in;
+#ifdef HAS_ATTRIBUTE_TANGENT
+layout(line_strip, max_vertices = 12) out;
+#else
+layout(line_strip, max_vertices = 6) out;
+#endif
+
+void triangle_normal_debug(int i)
+{
+ // Normal
+ vec4 normal_color = vec4(1.0, 1.0, 0.0, 1.0);
+ gl_Position = gl_in[i].gl_Position;
+ vertex_color = normal_color;
+ EmitVertex();
+ gl_Position = normal_g[i];
+ vertex_color = normal_color;
+ EmitVertex();
+ EndPrimitive();
+
+#ifdef HAS_ATTRIBUTE_TANGENT
+ // Tangent
+ vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0);
+ gl_Position = gl_in[i].gl_Position;
+ vertex_color = tangent_color;
+ EmitVertex();
+ gl_Position = tangent_g[i];
+ vertex_color = tangent_color;
+ EmitVertex();
+ EndPrimitive();
+#endif
+}
+
+void main()
+{
+ triangle_normal_debug(0);
+ triangle_normal_debug(1);
+ triangle_normal_debug(2);
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl
new file mode 100644
index 0000000000..b198bc2485
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl
@@ -0,0 +1,74 @@
+/**
+ * @file normaldebugV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+in vec3 position;
+in vec3 normal;
+out vec4 normal_g;
+#ifdef HAS_ATTRIBUTE_TANGENT
+in vec4 tangent;
+out vec4 tangent_g;
+#endif
+
+uniform float debug_normal_draw_length;
+
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+#endif
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+
+// *NOTE: Should use the modelview_projection_matrix here in the non-skinned
+// case for efficiency, but opting for the simplier implementation for now as
+// this is debug code. Also, the skinned version hasn't beeen tested yet.
+// world_pos = mat * vec4(position.xyz, 1.0)
+vec4 get_screen_normal(vec3 position, vec4 world_pos, vec3 normal, mat4 mat)
+{
+ vec4 world_norm = mat * vec4((position + normal), 1.0);
+ world_norm.xyz -= world_pos.xyz;
+ world_norm.xyz = debug_normal_draw_length * normalize(world_norm.xyz);
+ world_norm.xyz += world_pos.xyz;
+ return projection_matrix * world_norm;
+}
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+#else
+#define mat modelview_matrix
+#endif
+
+ vec4 world_pos = mat * vec4(position.xyz,1.0);
+
+ gl_Position = projection_matrix * world_pos;
+ normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat);
+#ifdef HAS_ATTRIBUTE_TANGENT
+ tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat);
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index eb0f7297ad..c1ed1bfe6e 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file radianceGenF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
@@ -36,8 +36,9 @@ in vec3 vary_dir;
//uniform float roughness;
uniform float mipLevel;
-uniform int u_width;
+uniform int u_width;
uniform float max_probe_lod;
+uniform float probe_strength;
// =============================================================================================================
@@ -73,95 +74,96 @@ const float PI = 3.1415926536;
// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
float random(vec2 co)
{
- float a = 12.9898;
- float b = 78.233;
- float c = 43758.5453;
- float dt= dot(co.xy ,vec2(a,b));
- float sn= mod(dt,3.14);
- return fract(sin(sn) * c);
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
}
-vec2 hammersley2d(uint i, uint N)
+vec2 hammersley2d(uint i, uint N)
{
- // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
- uint bits = (i << 16u) | (i >> 16u);
- bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
- bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
- bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
- bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
- float rdi = float(bits) * 2.3283064365386963e-10;
- return vec2(float(i) /float(N), rdi);
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
}
// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
-vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
{
- // Maps a 2D point to a hemisphere with spread based on roughness
- float alpha = roughness * roughness;
- float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
- float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
- float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
- vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
-
- // Tangent space
- vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- vec3 tangentX = normalize(cross(up, normal));
- vec3 tangentY = normalize(cross(normal, tangentX));
-
- // Convert to world Space
- return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
}
// Normal Distribution function
float D_GGX(float dotNH, float roughness)
{
- float alpha = roughness * roughness;
- float alpha2 = alpha * alpha;
- float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
- return (alpha2)/(PI * denom*denom);
+ float alpha = roughness * roughness;
+ float alpha2 = alpha * alpha;
+ float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
+ return (alpha2)/(PI * denom*denom);
}
vec4 prefilterEnvMap(vec3 R)
{
- vec3 N = R;
- vec3 V = R;
- vec4 color = vec4(0.0);
- float totalWeight = 0.0;
- float envMapDim = float(textureSize(reflectionProbes, 0).s);
+ vec3 N = R;
+ vec3 V = R;
+ vec4 color = vec4(0.0);
+ float totalWeight = 0.0;
+ float envMapDim = float(textureSize(reflectionProbes, 0).s);
float roughness = mipLevel/max_probe_lod;
- int numSamples = max(int(32*roughness), 1);
+ int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1);
float numMips = max_probe_lod+1;
- for(uint i = 0u; i < numSamples; i++) {
- vec2 Xi = hammersley2d(i, numSamples);
- vec3 H = importanceSample_GGX(Xi, roughness, N);
- vec3 L = 2.0 * dot(V, H) * H - V;
- float dotNL = clamp(dot(N, L), 0.0, 1.0);
- if(dotNL > 0.0) {
- // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
-
- float dotNH = clamp(dot(N, H), 0.0, 1.0);
- float dotVH = clamp(dot(V, H), 0.0, 1.0);
-
- // Probability Distribution Function
- float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
- // Slid angle of current smple
- float omegaS = 1.0 / (float(numSamples) * pdf);
- // Solid angle of 1 pixel across all cube faces
- float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
- // Biased (+1.0) mip level for better result
- float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod);
- color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL;
- totalWeight += dotNL;
- }
- }
- return (color / totalWeight);
+ for(uint i = 0u; i < numSamples; i++) {
+ vec2 Xi = hammersley2d(i, numSamples);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+ float dotNL = clamp(dot(N, L), 0.0, 1.0);
+ if(dotNL > 0.0) {
+ // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
+
+ float dotNH = clamp(dot(N, H), 0.0, 1.0);
+ float dotVH = clamp(dot(V, H), 0.0, 1.0);
+
+ // Probability Distribution Function
+ float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
+ // Slid angle of current smple
+ float omegaS = 1.0 / (float(numSamples) * pdf);
+ // Solid angle of 1 pixel across all cube faces
+ float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
+ // Biased (+1.0) mip level for better result
+ float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod);
+ color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL;
+ totalWeight += dotNL;
+ }
+ }
+ return (color / totalWeight);
}
void main()
-{
- vec3 N = normalize(vary_dir);
- frag_color = max(prefilterEnvMap(N), vec4(0));
+{
+ vec3 N = normalize(vary_dir);
+ frag_color = max(prefilterEnvMap(N), vec4(0));
+ frag_color.a *= probe_strength;
}
// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
index db26e64f17..142f2a5d71 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file bumpF.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$
*/
@@ -30,11 +30,15 @@ uniform sampler2D texture1;
in vec2 vary_texcoord0;
in vec2 vary_texcoord1;
+in vec3 vary_position;
+
+void mirrorClip(vec3 pos);
-void main()
+void main()
{
- float tex0 = texture(texture0, vary_texcoord0.xy).a;
- float tex1 = texture(texture1, vary_texcoord1.xy).a;
+ mirrorClip(vary_position);
+ float tex0 = texture(texture0, vary_texcoord0.xy).a;
+ float tex1 = texture(texture1, vary_texcoord1.xy).a;
- frag_color = max(vec4(tex0+(1.0-tex1)-0.5), vec4(0));
+ frag_color = max(vec4(tex0+(1.0-tex1)-0.5), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
index 834c20e14d..b8a02fbdec 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
@@ -1,28 +1,29 @@
-/**
+/**
* @file bumpV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+uniform mat4 modelview_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
@@ -32,24 +33,26 @@ in vec2 texcoord1;
out vec2 vary_texcoord0;
out vec2 vary_texcoord1;
+out vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
#endif
void main()
{
- //transform vertex
+ //transform vertex
#ifdef HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
+ vary_position = pos.xyz;
gl_Position = projection_matrix * pos;
#else
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
#endif
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index b7cd3f0589..40b7f9cf0e 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -57,16 +57,16 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
-
+
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color: moonlight_color;
-
+
// sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// I had thought blue_density and haze_density should have equal weighting,
// but attenuation due to haze_density tends to seem too strong
- vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 combined_haze = max(blue_density + vec3(haze_density), vec3(1e-6));
vec3 blue_weight = blue_density / combined_haze;
vec3 haze_weight = vec3(haze_density) / combined_haze;
@@ -98,7 +98,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
haze_glow *= glow.x;
// higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
+ haze_glow = clamp(pow(haze_glow, glow.z), -10, 10);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
// add "minimum anti-solar illumination"
@@ -119,7 +119,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
// brightness of surface both sunlight and ambient
-
+
sunlit = sunlight.rgb;
amblit = tmpAmbient;
@@ -128,7 +128,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
vec3 srgb_to_linear(vec3 col);
-// provide a touch of lighting in the opposite direction of the sun light
+// provide a touch of lighting in the opposite direction of the sun light
// so areas in shadow don't lose all detail
float ambientLighting(vec3 norm, vec3 light_dir)
{
@@ -150,7 +150,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou
// (allows for mixing of light sources other than sunlight e.g. reflection probes)
sunlit *= sky_sunlight_scale;
amblit *= sky_ambient_scale;
-
+
amblit = srgb_to_linear(amblit);
amblit *= ambientLighting(norm, light_dir);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index e6bdaf265e..7a1a54a77a 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file alphaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -60,7 +60,7 @@ uniform vec2 screen_res;
uniform int sun_up_factor;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
void waterClip(vec3 pos);
@@ -68,7 +68,6 @@ void waterClip(vec3 pos);
vec3 srgb_to_linear(vec3 c);
vec3 linear_to_srgb(vec3 c);
-vec2 encode_normal (vec3 n);
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
@@ -78,6 +77,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
float getAmbientClamp();
+void mirrorClip(vec3 pos);
+
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
@@ -90,15 +91,15 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
float falloff_factor = (12.0 * fa) - 9.0;
float inverted_la = falloff_factor / la;
// Yes, it makes me want to cry as well. DJH
-
+
vec3 col = vec3(0);
- //get light vector
- vec3 lv = lp.xyz-v;
+ //get light vector
+ vec3 lv = lp.xyz-v;
- //get distance
- float dist = length(lv);
- float da = 1.0;
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
/*if (dist > inverted_la)
{
@@ -111,23 +112,23 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
if (proj_tc.z < 0
|| proj_tc.z > 1
|| proj_tc.x < 0
- || proj_tc.x > 1
+ || proj_tc.x > 1
|| proj_tc.y < 0
|| proj_tc.y > 1)
{
return col;
}*/
- if (dist > 0.0 && inverted_la > 0.0)
- {
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
dist /= inverted_la;
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
dist_atten *= 2.0f;
if (dist_atten <= 0.0)
@@ -135,20 +136,20 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
return col;
}
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
- //angular attenuation
- da *= dot(n, lv);
+ //angular attenuation
+ da *= dot(n, lv);
da = max(0.0, da);
- float lit = 0.0f;
+ float lit = 0.0f;
float amb_da = 0.0;//ambiance;
if (da > 0)
{
- lit = max(da * dist_atten,0.0);
+ lit = max(da * dist_atten,0.0);
col = lit * light_col * diffuse;
amb_da += (da*0.5+0.5) * ambiance;
}
@@ -165,10 +166,12 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
return col;
}
-void main()
+void main()
{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ mirrorClip(vary_position);
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+
vec4 pos = vec4(vary_position, 1.0);
#ifndef IS_AVATAR_SKIN
// clip against water plane unless this is a legacy avatar skin
@@ -199,7 +202,7 @@ void main()
float final_alpha = diffuse_srgb.a * vertex_color.a;
diffuse_srgb.rgb *= vertex_color.rgb;
-
+
// Insure we don't pollute depth with invis pixels in impostor rendering
//
if (final_alpha < minimum_alpha)
@@ -222,7 +225,7 @@ void main()
final_alpha *= vertex_color.a;
if (final_alpha < minimum_alpha)
- { // TODO: figure out how to get invisible faces out of
+ { // TODO: figure out how to get invisible faces out of
// render batches without breaking glow
discard;
}
@@ -245,11 +248,11 @@ void main()
vec3 glossenv;
vec3 legacyenv;
sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, frag, pos.xyz, norm.xyz, 0.0, 0.0, true, amblit_linear);
-
+
float da = dot(norm.xyz, light_dir.xyz);
da = clamp(da, -1.0, 1.0);
-
+
float final_da = da;
final_da = clamp(final_da, 0.0f, 1.0f);
@@ -266,7 +269,7 @@ void main()
color.rgb *= diffuse_linear.rgb;
vec4 light = vec4(0,0,0,0);
-
+
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
LIGHT_LOOP(1)
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index 34d86b6147..059c2a64ce 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file class1\deferred\pbralphaF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -87,9 +87,10 @@ vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
float calcLegacyDistanceAttenuation(float distance, float falloff);
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
+void mirrorClip(vec3 pos);
void waterClip(vec3 pos);
void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
@@ -110,15 +111,15 @@ vec3 pbrBaseLight(vec3 diffuseColor,
vec3 additive,
vec3 atten);
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
vec3 l); //surface point to light
-vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 p, // pixel position
@@ -156,6 +157,8 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
void main()
{
+ mirrorClip(vary_position);
+
vec3 color = vec3(0,0,0);
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
@@ -178,7 +181,7 @@ void main()
float sign = vary_sign;
vec3 vN = vary_normal;
vec3 vT = vary_tangent.xyz;
-
+
vec3 vB = sign * cross(vN, vT);
vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
@@ -215,7 +218,7 @@ void main()
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss, true, amblit);
-
+
vec3 diffuseColor;
vec3 specularColor;
calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor);
@@ -242,7 +245,7 @@ void main()
color.rgb = applySkyAndWaterFog(pos.xyz, additive, atten, vec4(color, 1.0)).rgb;
float a = basecolor.a*vertex_color.a;
-
+
frag_color = max(vec4(color.rgb,a), vec4(0));
}
@@ -292,7 +295,7 @@ void main()
// emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
colorEmissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
-
+
float a = basecolor.a*vertex_color.a;
color += colorEmissive;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 10bfe2c5d5..1bd5f5a718 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @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$
*/
@@ -35,23 +35,23 @@ in vec2 vary_fragcoord;
uniform vec3 sun_dir;
uniform float shadow_bias;
-vec3 getNorm(vec2 pos_screen);
+vec4 getNorm(vec2 pos_screen);
vec4 getPosition(vec2 pos_screen);
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-void main()
+void main()
{
vec2 pos_screen = vary_fragcoord.xy;
vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
+ vec4 norm = getNorm(pos_screen);
vec4 col;
- col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
col.g = 1.0f;
- col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+ col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen);
+ col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);
frag_color = clamp(col, vec4(0), vec4(1));
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 2f1819bff7..e0333b6044 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -1,27 +1,27 @@
-/**
+/**
* @file class2/deferred/sunLightSSAOF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -32,23 +32,23 @@ out vec4 frag_color;
in vec2 vary_fragcoord;
vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec4 getNorm(vec2 pos_screen);
float sampleDirectionalShadow(vec3 shadow_pos, vec3 norm, vec2 pos_screen);
float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen);
float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-void main()
+void main()
{
vec2 pos_screen = vary_fragcoord.xy;
vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
+ vec4 norm = getNorm(pos_screen);
vec4 col;
- col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- col.g = calcAmbientOcclusion(pos, norm, pos_screen);
- col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+ col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+ col.g = calcAmbientOcclusion(pos, norm.xyz, pos_screen);
+ col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen);
+ col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);
frag_color = clamp(col, vec4(0), vec4(1));
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index 22408387b1..c382a9fbc0 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file fullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -53,19 +53,22 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+void mirrorClip(vec3 pos);
+
void main()
{
+ mirrorClip(vary_position);
#ifdef HAS_DIFFUSE_LOOKUP
- vec4 color = diffuseLookup(vary_texcoord0.xy);
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
- vec4 color = texture(diffuseMap, vary_texcoord0.xy);
+ vec4 color = texture(diffuseMap, vary_texcoord0.xy);
#endif
+
+ color.rgb *= vertex_color.rgb;
- color.rgb *= vertex_color.rgb;
-
- // SL-9632 HUDs are affected by Atmosphere
+ // SL-9632 HUDs are affected by Atmosphere
#ifndef IS_HUD
-
+
vec3 sunlit;
vec3 amblit;
vec3 additive;
@@ -87,8 +90,8 @@ void main()
applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
#endif
- color.a = 1.0;
+ color.a = 1.0;
- frag_color = max(color, vec4(0));
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
index 7f75b16cf0..4af57e3b80 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -33,7 +33,7 @@ uniform vec3 moon_dir;
uniform int sun_up_factor;
in vec2 vary_fragcoord;
-vec3 getNorm(vec2 pos_screen);
+vec4 getNorm(vec2 pos_screen);
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
@@ -53,8 +53,7 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = getDepth(tc.xy);
vec4 pos = getPositionWithDepth(tc, depth);
- vec4 norm = texture(normalMap, tc);
- norm.xyz = getNorm(tc);
+ vec4 norm = getNorm(tc);
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
vec3 color = vec3(0);
@@ -68,16 +67,16 @@ void main()
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
vec3 sunlit_linear = srgb_to_linear(sunlit);
-
+
// mask off atmospherics below water (when camera is under water)
bool do_atmospherics = false;
-
+
if (dot(vec3(0), waterPlane.xyz) + waterPlane.w > 0.0 ||
dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
{
do_atmospherics = true;
}
-
+
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
@@ -102,5 +101,5 @@ void main()
}
frag_color = max(vec4(color.rgb, alpha), vec4(0)); //output linear since local lights will be added to this shader's results
-
+
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 20f063fe3e..2a20eb79d2 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -45,6 +45,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cs);
+uniform mat4 modelview_matrix;
+uniform mat3 normal_matrix;
+
+in vec3 vary_position;
+
+void mirrorClip(vec3 pos);
+
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
out vec4 frag_color;
@@ -66,12 +73,12 @@ uniform vec4 morphFactor;
uniform vec3 camPosLocal;
uniform mat3 env_mat;
+uniform float is_mirror;
+
uniform vec3 sun_dir;
uniform vec3 moon_dir;
in vec2 vary_fragcoord;
-in vec3 vary_position;
-
uniform mat4 proj_mat;
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -93,7 +100,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
float falloff_factor = (12.0 * fa) - 9.0;
float inverted_la = falloff_factor / la;
// Yes, it makes me want to cry as well. DJH
-
+
vec3 col = vec3(0);
//get light vector
@@ -209,25 +216,23 @@ in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n);
-
// get the transformed normal and apply glossiness component from normal map
vec3 getNormal(inout float glossiness)
{
#ifdef HAS_NORMAL_MAP
- vec4 vNt = texture(bumpMap, vary_texcoord1.xy);
+ vec4 vNt = texture(bumpMap, vary_texcoord1.xy);
glossiness *= vNt.a;
- vNt.xyz = vNt.xyz * 2 - 1;
+ vNt.xyz = vNt.xyz * 2 - 1;
float sign = vary_sign;
vec3 vN = vary_normal;
vec3 vT = vary_tangent.xyz;
-
+
vec3 vB = sign * cross(vN, vT);
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
- return tnorm;
+ return tnorm;
#else
- return normalize(vary_normal);
+ return normalize(vary_normal);
#endif
}
@@ -264,9 +269,9 @@ void waterClip()
float getEmissive(vec4 diffcol)
{
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- return emissive_brightness;
+ return emissive_brightness;
#else
- return max(diffcol.a, emissive_brightness);
+ return max(diffcol.a, emissive_brightness);
#endif
}
@@ -285,12 +290,12 @@ float getShadow(vec3 pos, vec3 norm)
void main()
{
+ mirrorClip(vary_position);
waterClip();
// diffcol == diffuse map combined with vertex color
vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
-
+ diffcol.rgb *= vertex_color.rgb;
alphaMask(diffcol.a);
// spec == specular map combined with specular color
@@ -299,8 +304,6 @@ void main()
float glossiness = specular_color.a;
vec3 norm = getNormal(glossiness);
- vec2 abnormal = encode_normal(norm.xyz);
-
float emissive = getEmissive(diffcol);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
@@ -325,7 +328,7 @@ void main()
vec3 additive;
vec3 atten;
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
-
+
vec3 sunlit_linear = srgb_to_linear(sunlit);
vec3 amblit_linear = amblit;
@@ -333,7 +336,7 @@ void main()
vec3 glossenv;
vec3 legacyenv;
sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env, true, amblit_linear);
-
+
color = ambenv;
float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
@@ -405,12 +408,17 @@ void main()
frag_color = max(vec4(color, al), vec4(0));
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
- frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
- frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
- frag_data[3] = vec4(0);
+
+ float flag = GBUFFER_FLAG_HAS_ATMOS;
+
+ frag_data[0] = max(vec4(diffcol.rgb, emissive), vec4(0)); // gbuffer is sRGB for legacy materials
+ frag_data[1] = max(vec4(spec.rgb, glossiness), vec4(0)); // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = vec4(norm, flag); // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+ frag_data[3] = vec4(env, 0, 0, 0);
+
#endif
}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index 31aca8a745..edfd6cbced 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -48,7 +48,7 @@ in vec4 vary_fragcoord;
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
float calcLegacyDistanceAttenuation(float distance, float falloff);
vec4 getPosition(vec2 pos_screen);
-vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getNorm(vec2 screenpos);
vec2 getScreenXY(vec4 clip);
vec2 getScreenCoord(vec4 clip);
vec3 srgb_to_linear(vec3 c);
@@ -56,8 +56,8 @@ vec3 srgb_to_linear(vec3 c);
// Util
vec3 hue_to_rgb(float hue);
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
@@ -74,9 +74,8 @@ void main()
discard;
}
- float envIntensity; // not used for this shader
- vec3 n;
- vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec3 n = norm.xyz;
vec4 spec = texture(specularRect, tc);
vec3 diffuse = texture(diffuseRect, tc).rgb;
@@ -92,7 +91,7 @@ void main()
float metallic = orm.b;
vec3 f0 = vec3(0.04);
vec3 baseColor = diffuse.rgb;
-
+
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
diffuseColor *= 1.0 - metallic;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index c27310cf89..60be9f4407 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file class3\deferred\pointLightF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -52,15 +52,15 @@ uniform vec4 viewport;
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
float calcLegacyDistanceAttenuation(float distance, float falloff);
-vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getNorm(vec2 screenpos);
vec4 getPosition(vec2 pos_screen);
vec2 getScreenXY(vec4 clip);
vec2 getScreenCoord(vec4 clip);
vec3 srgb_to_linear(vec3 c);
float getDepth(vec2 tc);
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
@@ -72,9 +72,8 @@ void main()
vec2 tc = getScreenCoord(vary_fragcoord);
vec3 pos = getPosition(tc).xyz;
- float envIntensity;
- vec3 n;
- vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec3 n = norm.xyz;
vec3 diffuse = texture(diffuseRect, tc).rgb;
vec4 spec = texture(specularRect, tc);
@@ -94,13 +93,13 @@ void main()
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
vec3 orm = spec.rgb;
float perceptualRoughness = orm.g;
float metallic = orm.b;
vec3 f0 = vec3(0.04);
vec3 baseColor = diffuse.rgb;
-
+
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
diffuseColor *= 1.0 - metallic;
@@ -137,7 +136,7 @@ void main()
final_color += lit*scol*color.rgb*spec.rgb;
}
}
-
+
if (dot(final_color, final_color) <= 0.0)
{
discard;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index ae81a4b472..90c84cc428 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -31,6 +31,7 @@ float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n,
uniform samplerCubeArray reflectionProbes;
uniform samplerCubeArray irradianceProbes;
+
uniform sampler2D sceneMap;
uniform int cube_snapshot;
uniform float max_probe_lod;
@@ -47,14 +48,16 @@ layout (std140) uniform ReflectionProbes
/// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
// box[3][0..2] - plane thickness
mat4 refBox[MAX_REFMAP_COUNT];
+ mat4 heroBox;
// list of bounding spheres for reflection probes sorted by distance to camera (closest first)
vec4 refSphere[MAX_REFMAP_COUNT];
- // extra parameters
+ // extra parameters
// x - irradiance scale
// y - radiance scale
// z - fade in
// w - znear
vec4 refParams[MAX_REFMAP_COUNT];
+ vec4 heroSphere;
// index of cube map in reflectionProbes for a corresponding reflection probe
// e.g. cube map channel of refSphere[2] is stored in refIndex[2]
// refIndex.x - cubemap channel in reflectionProbes
@@ -70,6 +73,10 @@ layout (std140) uniform ReflectionProbes
// number of reflection probes present in refSphere
int refmapCount;
+
+ int heroShape;
+ int heroMipCount;
+ int heroProbeCount;
};
// Inputs
@@ -95,7 +102,7 @@ bool shouldSampleProbe(int i, vec3 pos)
if (refIndex[i].w < 0)
{
vec4 v = refBox[i] * vec4(pos, 1.0);
- if (abs(v.x) > 1 ||
+ if (abs(v.x) > 1 ||
abs(v.y) > 1 ||
abs(v.z) > 1)
{
@@ -222,7 +229,7 @@ void preProbeSample(vec3 pos)
}
}
count++;
-
+
++neighborIdx;
}
@@ -244,56 +251,56 @@ void preProbeSample(vec3 pos)
// original reference implementation:
/*
-bool intersect(const Ray &ray) const
-{
- float t0, t1; // solutions for t if the ray intersects
-#if 0
+bool intersect(const Ray &ray) const
+{
+ float t0, t1; // solutions for t if the ray intersects
+#if 0
// geometric solution
- Vec3f L = center - orig;
- float tca = L.dotProduct(dir);
+ Vec3f L = center - orig;
+ float tca = L.dotProduct(dir);
// if (tca < 0) return false;
- float d2 = L.dotProduct(L) - tca * tca;
- if (d2 > radius2) return false;
- float thc = sqrt(radius2 - d2);
- t0 = tca - thc;
- t1 = tca + thc;
-#else
+ float d2 = L.dotProduct(L) - tca * tca;
+ if (d2 > radius2) return false;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+#else
// analytic solution
- Vec3f L = orig - center;
- float a = dir.dotProduct(dir);
- float b = 2 * dir.dotProduct(L);
- float c = L.dotProduct(L) - radius2;
- if (!solveQuadratic(a, b, c, t0, t1)) return false;
-#endif
- if (t0 > t1) std::swap(t0, t1);
-
- if (t0 < 0) {
- t0 = t1; // if t0 is negative, let's use t1 instead
- if (t0 < 0) return false; // both t0 and t1 are negative
- }
-
- t = t0;
-
- return true;
+ Vec3f L = orig - center;
+ float a = dir.dotProduct(dir);
+ float b = 2 * dir.dotProduct(L);
+ float c = L.dotProduct(L) - radius2;
+ if (!solveQuadratic(a, b, c, t0, t1)) return false;
+#endif
+ if (t0 > t1) std::swap(t0, t1);
+
+ if (t0 < 0) {
+ t0 = t1; // if t0 is negative, let's use t1 instead
+ if (t0 < 0) return false; // both t0 and t1 are negative
+ }
+
+ t = t0;
+
+ return true;
} */
// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
-{
- float t0, t1; // solutions for t if the ray intersects
+{
+ float t0, t1; // solutions for t if the ray intersects
- vec3 L = center - origin;
+ vec3 L = center - origin;
float tca = dot(L,dir);
- float d2 = dot(L,L) - tca * tca;
-
- float thc = sqrt(radius2 - d2);
- t0 = tca - thc;
- t1 = tca + thc;
+ float d2 = dot(L,L) - tca * tca;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+
vec3 v = origin + dir * t1;
- return v;
-}
+ return v;
+}
void swap(inout float a, inout float b)
{
@@ -305,17 +312,17 @@ void swap(inout float a, inout float b)
// debug implementation, make no assumptions about origin
void sphereIntersectDebug(vec3 origin, vec3 dir, vec3 center, float radius2, float depth, inout vec4 col)
{
- float t[2]; // solutions for t if the ray intersects
+ float t[2]; // solutions for t if the ray intersects
// geometric solution
- vec3 L = center - origin;
+ vec3 L = center - origin;
float tca = dot(L, dir);
// if (tca < 0) return false;
- float d2 = dot(L, L) - tca * tca;
- if (d2 > radius2) return;
- float thc = sqrt(radius2 - d2);
- t[0] = tca - thc;
- t[1] = tca + thc;
+ float d2 = dot(L, L) - tca * tca;
+ if (d2 > radius2) return;
+ float thc = sqrt(radius2 - d2);
+ t[0] = tca - thc;
+ t[1] = tca + thc;
for (int i = 0; i < 2; ++i)
{
@@ -365,11 +372,11 @@ return texCUBE(envMap, ReflDirectionWS);
// i - probe index in refBox/refSphere
// d - distance to nearest wall in clip space
// scale - scale of box, default 1.0
-vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
+vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d, float scale)
{
// Intersection with OBB convert to unit box space
// Transform in local unit parallax cube space (scaled and rotated)
- mat4 clipToLocal = refBox[i];
+ mat4 clipToLocal = i;
vec3 RayLS = mat3(clipToLocal) * dir;
vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
@@ -388,7 +395,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
return IntersectPositionCS;
}
-vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
+vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d)
{
return boxIntersect(origin, dir, i, d, 1.0);
}
@@ -404,8 +411,8 @@ void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
bool behind = dot(v,v) > dot(pos,pos);
float w = 0.25;
-
- if (behind)
+
+ if (behind)
{
w *= 0.5;
w /= (length(v)-length(pos))*0.5+1.0;
@@ -419,7 +426,7 @@ void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
// cribbed from https://iquilezles.org/articles/intersectors/
// axis aligned box centered at the origin, with size boxSize
-void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
+void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
{
vec3 rd = normalize(p-ro);
@@ -443,10 +450,10 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
}
-void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
+void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col)
{
- mat4 clipToLocal = refBox[i];
-
+ mat4 clipToLocal = i;
+
// transform into unit cube space
origin = (clipToLocal * vec4(origin, 1.0)).xyz;
pos = (clipToLocal * vec4(pos, 1.0)).xyz;
@@ -462,16 +469,16 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
// r - radius of probe influence volume
// i - index of probe in refSphere
// dw - distance weight
-float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw)
+float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw)
{
- float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
+ float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
vec3 delta = pos.xyz - origin;
float d2 = max(length(delta), 0.001);
float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);
float w = 1.0 / d2;
- w *= refParams[i].z;
+ w *= i.z;
dw = w * atten * max(r, 1.0)*4;
@@ -488,7 +495,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw
// lod - which mip to sample (lower is higher res, sharper reflections)
// c - center of probe
// r2 - radius of probe squared
-// i - index of probe
+// i - index of probe
vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)
{
// parallax adjustment
@@ -497,7 +504,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
if (refIndex[i].w < 0)
{ // box probe
float d = 0;
- v = boxIntersect(pos, dir, i, d);
+ v = boxIntersect(pos, dir, refBox[i], d);
w = max(d, 0.001);
}
@@ -507,18 +514,18 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
float rr = r * r;
- v = sphereIntersect(pos, dir, c,
+ v = sphereIntersect(pos, dir, c,
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
rr);
- w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);
}
v -= c;
vec3 d = normalize(v);
v = env_mat * v;
-
+
vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;
return ret.rgb;
@@ -529,7 +536,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,
// dir - pixel normal
// w - weight of sample (distance and angular attenuation)
// dw - weight of sample (distance only)
-// i - index of probe
+// i - index of probe
vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i, vec3 amblit)
{
// parallax adjustment
@@ -537,7 +544,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
if (refIndex[i].w < 0)
{
float d = 0.0;
- v = boxIntersect(pos, dir, i, d, 3.0);
+ v = boxIntersect(pos, dir, refBox[i], d, 3.0);
w = max(d, 0.001);
}
else
@@ -547,16 +554,16 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
// pad sphere for manual probe extending into automatic probe space
float rr = r * r;
- v = sphereIntersect(pos, dir, c,
+ v = sphereIntersect(pos, dir, c,
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
rr);
- w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);
}
v -= c;
v = env_mat * v;
-
+
vec3 col = textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x;
col = mix(amblit, col, min(refParams[i].x, 1.0));
@@ -618,7 +625,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
col[1] *= 1.0/wsum[1];
col[0] = vec3(0);
}
-
+
return col[1]+col[0];
}
@@ -647,7 +654,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
{
continue;
}
-
+
{
float w = 0;
float dw = 0;
@@ -677,10 +684,53 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
col[1] *= 1.0/wsum[1];
col[0] = vec3(0);
}
-
+
return col[1]+col[0];
}
+#if defined(HERO_PROBES)
+
+uniform vec4 clipPlane;
+uniform samplerCubeArray heroProbes;
+
+void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
+{
+ float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;
+ float w = 0;
+ float dw = 0;
+ float falloffMult = 10;
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+ if (heroShape < 1)
+ {
+ float d = 0;
+ boxIntersect(pos, norm, heroBox, d, 1.0);
+
+ w = max(d, 0);
+ }
+ else
+ {
+ float r = heroSphere.w;
+
+ w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw);
+ }
+
+ clipDist = clipDist * 0.95 + 0.05;
+ clipDist = clamp(clipDist * falloffMult, 0, 1);
+ w = clamp(w * falloffMult * clipDist, 0, 1);
+ w = mix(0, w, clamp(glossiness - 0.75, 0, 1) * 4); // We only generate a quarter of the mips for the hero probes. Linearly interpolate between normal probes and hero probes based upon glossiness.
+ glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w);
+}
+
+#else
+
+void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
+{
+}
+
+#endif
+
+
+
void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)
{
@@ -712,6 +762,8 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
glossenv = mix(glossenv, ssr.rgb, ssr.a);
}
#endif
+
+ tapHeroProbe(glossenv, pos, norm, glossiness);
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
@@ -747,7 +799,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
{
if (refIndex[i].w < 0)
{
- boxIntersectDebug(origin, pos, i, col);
+ boxIntersectDebug(origin, pos, refBox[i], col);
}
else
{
@@ -799,8 +851,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
{
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
+
}
-
+
if (envIntensity > 0.0)
{
legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
@@ -826,6 +879,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
}
#endif
+ tapHeroProbe(glossenv, pos, norm, glossiness);
+ tapHeroProbe(legacyenv, pos, norm, 1.0);
+
glossenv = clamp(glossenv, vec3(0), vec3(10));
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
index 63fa4ecc55..deb276ef9d 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
@@ -40,36 +40,33 @@ uniform sampler2D specularRect;
uniform sampler2D diffuseRect;
uniform sampler2D diffuseMap;
-vec3 getNorm(vec2 screenpos);
+vec4 getNorm(vec2 screenpos);
float getDepth(vec2 pos_screen);
float linearDepth(float d, float znear, float zfar);
float linearDepth01(float d, float znear, float zfar);
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
vec4 getPosition(vec2 pos_screen);
-vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
float random (vec2 uv);
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
-void main()
+void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = linearDepth01(getDepth(tc), zNear, zFar);
- float envIntensity;
- vec3 n;
- vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()
vec3 pos = getPositionWithDepth(tc, getDepth(tc)).xyz;
vec4 spec = texture(specularRect, tc);
vec2 hitpixel;
-
+
vec4 diffuse = texture(diffuseRect, tc);
vec3 specCol = spec.rgb;
vec4 fcol = texture(diffuseMap, tc);
- if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
vec3 orm = specCol.rgb;
float perceptualRoughness = orm.g;
@@ -84,7 +81,7 @@ void main()
vec4 collectedColor = vec4(0);
- float w = tapScreenSpaceReflection(4, tc, pos, n, collectedColor, diffuseMap, 0);
+ float w = tapScreenSpaceReflection(4, tc, pos, norm.xyz, collectedColor, diffuseMap, 0);
collectedColor.rgb *= specCol.rgb;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 47b5934b84..96c32734e4 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -50,6 +50,7 @@ uniform float ssao_irradiance_max;
#endif
// Inputs
+uniform vec4 clipPlane;
uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
@@ -60,7 +61,7 @@ in vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 getNorm(vec2 pos_screen);
+vec4 getNorm(vec2 pos_screen);
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
@@ -104,8 +105,8 @@ vec3 pbrBaseLight(vec3 diffuseColor,
vec3 additive,
vec3 atten);
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
@@ -127,13 +128,13 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = getDepth(tc.xy);
vec4 pos = getPositionWithDepth(tc, depth);
- vec4 norm = texture(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
+ vec4 norm = getNorm(tc);
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ float envIntensity = colorEmissive.r;
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
vec4 baseColor = texture(diffuseRect, tc);
- vec4 spec = texture(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive
+ vec4 spec = texture(specularRect, tc); // NOTE: PBR linear Emissive
#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
vec2 scol_ambocc = texture(lightMap, vary_fragcoord.xy).rg;
@@ -168,15 +169,15 @@ void main()
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 orm = texture(specularRect, tc).rgb;
+ vec3 orm = spec.rgb;
float perceptualRoughness = orm.g;
float metallic = orm.b;
float ao = orm.r;
- vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+
// PBR IBL
float gloss = 1.0 - perceptualRoughness;
-
+
sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear);
adjustIrradiance(irradiance, ambocc);
@@ -188,10 +189,15 @@ void main()
vec3 v = -normalize(pos.xyz);
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
}
- else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI))
+ {
+ // actual HDRI sky, just copy color value
+ color = colorEmissive.rgb;
+ }
+ else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))
{
- //should only be true of WL sky, just port over base color value
- color = texture(emissiveRect, tc).rgb;
+ //should only be true of WL sky, port over base color value and scale for fake HDR
+ color = colorEmissive.rgb;
color = srgb_to_linear(color);
color *= sky_hdr_scale;
}
@@ -199,7 +205,7 @@ void main()
{
// legacy shaders are still writng sRGB to gbuffer
baseColor.rgb = srgb_to_linear(baseColor.rgb);
-
+
spec.rgb = srgb_to_linear(spec.rgb);
float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
@@ -218,7 +224,7 @@ void main()
vec3 sun_contrib = min(da, scol) * sunlit_linear;
color.rgb += sun_contrib;
color.rgb *= baseColor.rgb;
-
+
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
if (spec.a > 0.0)
@@ -244,10 +250,11 @@ void main()
// add radiance map
applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+
}
color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);
-
+
if (envIntensity > 0.0)
{ // add environment map
applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index 871c7ce812..319fa86148 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file class3\deferred\spotLightF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
out vec4 frag_color;
@@ -72,7 +72,7 @@ uniform mat4 inv_proj;
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
float calcLegacyDistanceAttenuation(float distance, float falloff);
bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
-vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getNorm(vec2 screenpos);
vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
vec2 getScreenCoord(vec4 clip);
@@ -83,8 +83,8 @@ vec4 getPosition(vec2 pos_screen);
const float M_PI = 3.14159265;
-vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
- float perceptualRoughness,
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
float metallic,
vec3 n, // normal
vec3 v, // surface point to camera
@@ -112,18 +112,17 @@ void main()
}
float shadow = 1.0;
-
+
if (proj_shadow_idx >= 0)
{
vec4 shd = texture(lightMap, tc);
shadow = (proj_shadow_idx==0)?shd.b:shd.a;
shadow += shadow_fade;
- shadow = clamp(shadow, 0.0, 1.0);
+ shadow = clamp(shadow, 0.0, 1.0);
}
- float envIntensity;
- vec3 n;
- vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity);
+ vec4 norm = getNorm(tc);
+ vec3 n = norm.xyz;
float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
@@ -145,13 +144,12 @@ void main()
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorEmissive = texture(emissiveRect, tc).rgb;
vec3 orm = spec.rgb;
float perceptualRoughness = orm.g;
float metallic = orm.b;
vec3 f0 = vec3(0.04);
vec3 baseColor = diffuse.rgb;
-
+
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
diffuseColor *= 1.0 - metallic;
@@ -169,7 +167,7 @@ void main()
if (nl > 0.0)
{
amb_da += (nl*0.5 + 0.5) * proj_ambiance;
-
+
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
vec3 intensity = dist_atten * dlit * 3.25 * shadow; // Legacy attenuation, magic number to balance with legacy materials
@@ -182,6 +180,8 @@ void main()
}
else
{
+ float envIntensity = texture(emissiveRect, tc).r;
+
diffuse = srgb_to_linear(diffuse);
spec.rgb = srgb_to_linear(spec.rgb);
@@ -205,11 +205,11 @@ void main()
// unshadowed for consistency between forward and deferred?
amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
}
-
+
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
final_color += diffuse.rgb * amb_rgb * max(dot(-normalize(lv), n), 0.0);
}
-
+
if (spec.a > 0.0)
{
dlit *= min(nl*6.0, 1.0) * dist_atten;
@@ -218,7 +218,7 @@ void main()
float gtdenom = 2 * nh;
float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
-
+
if (nh > 0.0)
{
float scol = fres*texture(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
@@ -226,26 +226,26 @@ void main()
speccol = clamp(speccol, vec3(0), vec3(1));
final_color += speccol;
}
- }
+ }
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), n);
-
+
//project from point pos in direction ref to plane proj_p, proj_n
vec3 pdelta = proj_p-pos;
float ds = dot(ref, proj_n);
-
+
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 &&
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 61059e2339..f6bef1e498 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -43,7 +43,7 @@ void main()
float depth = getDepth(tc.xy);
if (above_water > 0)
- {
+ {
// we want to depth test when the camera is above water, but some GPUs have a hard time
// with depth testing against render targets that are bound for sampling in the same shader
// so we do it manually here
@@ -56,10 +56,9 @@ void main()
}
vec4 pos = getPositionWithDepth(tc, depth);
- vec4 norm = texture(normalMap, tc);
vec4 fogged = getWaterFogView(pos.xyz);
frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results
-
+
}
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 3bf606a252..ef086fc3be 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -4,25 +4,25 @@
* $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$
*/
-
+
out vec4 frag_color;
uniform sampler2D diffuseMap;
@@ -55,27 +55,29 @@ in vec4 view;
in vec3 vary_position;
vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);
+void mirrorClip(vec3 position);
-void main()
+void main()
{
- vec4 color;
+ mirrorClip(vary_position);
+ vec4 color;
//get detail normals
- vec3 wave1 = texture(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wavef = normalize(wave1+wave2+wave3);
-
- //figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
+ vec3 wave1 = texture(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2 = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3 = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec3 wavef = normalize(wave1+wave2+wave3);
+
+ //figure out distortion vector (ripply)
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ distort = distort+wavef.xy*refScale;
#ifdef TRANSPARENT_WATER
- vec4 fb = texture(screenTex, distort);
+ vec4 fb = texture(screenTex, distort);
#else
vec4 fb = vec4(waterFogColorLinear, 0.0);
#endif
-
+
fb = applyWaterFogViewLinearNoClip(vary_position, fb);
frag_color = max(fb, vec4(0));
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 88c38c46a2..b2a81aa025 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -1,28 +1,28 @@
-/**
+/**
* @file waterF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
// class3/environment/waterF.glsl
out vec4 frag_color;
@@ -35,6 +35,8 @@ vec3 scaleSoftClipFragLinear(vec3 l);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+void mirrorClip(vec3 pos);
+
// PBR interface
vec2 BRDF(float NoV, float roughness);
@@ -127,8 +129,9 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
vec3 getPositionWithNDC(vec3 ndc);
-void main()
+void main()
{
+ mirrorClip(vary_position);
vN = vary_normal;
vT = vary_tangent;
vB = cross(vN, vT);
@@ -157,7 +160,7 @@ void main()
vec3 wave3 = BlendNormal(wave3_a, wave3_b);
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
+
//wave1 = transform_normal(wave1);
//wave2 = transform_normal(wave2);
//wave3 = transform_normal(wave3);
@@ -168,7 +171,7 @@ void main()
vec3 up = transform_normal(vec3(0,0,1));
float vdu = -dot(viewVec, up)*2;
-
+
vec3 wave_ibl = wavef;
wave_ibl.z *= 2.0;
wave_ibl = transform_normal(normalize(wave_ibl));
@@ -182,13 +185,13 @@ void main()
//wavef = vec3(0, 0, 1);
wavef = transform_normal(wavef);
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- //figure out distortion vector (ripply)
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ //figure out distortion vector (ripply)
vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0);
distort2 = clamp(distort2, vec2(0), vec2(0.999));
@@ -232,7 +235,7 @@ void main()
float metallic = 0.0;
float perceptualRoughness = 0.05;
float gloss = 1.0 - perceptualRoughness;
-
+
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
@@ -248,7 +251,7 @@ void main()
vec3 colorEmissive = vec3(0);
float ao = 1.0;
vec3 light_dir = transform_normal(lightDir);
-
+
perceptualRoughness = 0.0;
metallic = 1.0;
@@ -281,7 +284,7 @@ void main()
color = ((1.0 - f) * color) + fb.rgb;
float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
-
+
frag_color = max(vec4(color, spec), vec4(0));
}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index f92d9a2a0e..8950770172 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 59
+version 60
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -48,6 +48,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
@@ -73,6 +75,7 @@ RenderGLMultiThreadedTextures 1 0
RenderGLMultiThreadedMedia 1 1
RenderReflectionProbeResolution 1 128
RenderScreenSpaceReflections 1 1
+RenderMirrors 1 1
//
@@ -94,6 +97,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
+RenderTerrainPBRDetail 1 -4
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
@@ -103,6 +108,11 @@ WLSkyDetail 1 96
RenderFSAASamples 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 256
+RenderHeroProbeDistance 1 4
+RenderHeroProbeUpdateRate 1 4
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium Low Graphics Settings
@@ -123,6 +133,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
+RenderTerrainPBRDetail 1 -1
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
@@ -132,6 +144,11 @@ WLSkyDetail 1 96
RenderFSAASamples 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 256
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 3
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium Graphics Settings (standard)
@@ -150,6 +167,8 @@ RenderLocalLightCount 1 512
RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
RenderDeferredSSAO 1 0
@@ -161,6 +180,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 1
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 3
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium High Graphics Settings
@@ -179,6 +203,8 @@ RenderLocalLightCount 1 1024
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
RenderDeferredSSAO 1 0
@@ -190,6 +216,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 2
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 2
+RenderHeroProbeConservativeUpdateMultiplier 1 8
//
// High Graphics Settings (SSAO + sun shadows)
@@ -208,6 +239,8 @@ RenderLocalLightCount 1 2048
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
@@ -219,6 +252,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 8
+RenderHeroProbeUpdateRate 1 2
+RenderHeroProbeConservativeUpdateMultiplier 1 8
//
// High Ultra Graphics Settings (deferred + SSAO + all shadows)
@@ -236,6 +274,8 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
@@ -248,6 +288,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 1024
+RenderHeroProbeDistance 1 16
+RenderHeroProbeUpdateRate 1 1
+RenderHeroProbeConservativeUpdateMultiplier 1 4
//
// Ultra graphics (REALLY PURTY!)
@@ -264,6 +309,8 @@ RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
@@ -277,6 +324,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 2048
+RenderHeroProbeDistance 1 16
+RenderHeroProbeUpdateRate 1 1
+RenderHeroProbeConservativeUpdateMultiplier 1 4
//
// Class Unknown Hardware (unknown)
@@ -285,6 +337,7 @@ list Unknown
RenderShadowDetail 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
+RenderMirrors 1 0
//
// VRAM > 512MB
@@ -306,6 +359,7 @@ RenderTransparentWater 1 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
RenderReflectionProbeDetail 0 -1
+RenderMirrors 0 0
list Intel
RenderAnisotropic 1 0
@@ -320,4 +374,7 @@ list GL3
RenderFSAASamples 0 0
RenderReflectionsEnabled 0 0
RenderReflectionProbeDetail 0 0
+RenderMirrors 0 0
+list TexUnit16orLess
+RenderTerrainPBRDetail 1 -1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 40aaccc8cb..8c71235f37 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 56
+version 57
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -45,6 +45,8 @@ RenderObjectBump 1 1
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
@@ -72,6 +74,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderScreenSpaceReflections 1 1
RenderReflectionProbeLevel 1 3
+RenderMirrors 1 1
//
// Low Graphics Settings
@@ -89,6 +92,8 @@ RenderLocalLightCount 1 8
RenderMaxPartCount 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
+RenderTerrainPBRDetail 1 -4
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
@@ -101,6 +106,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 256
+RenderHeroProbeDistance 1 4
+RenderHeroProbeUpdateRate 1 4
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium Low Graphics Settings
@@ -118,6 +128,8 @@ RenderMaxPartCount 1 2048
RenderLocalLightCount 1 256
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
+RenderTerrainPBRDetail 1 -1
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
@@ -130,6 +142,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 256
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 3
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium Graphics Settings (standard)
@@ -147,6 +164,8 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 512
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
@@ -159,6 +178,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 3
+RenderHeroProbeConservativeUpdateMultiplier 1 16
//
// Medium High Graphics Settings
@@ -176,6 +200,8 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 1024
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
@@ -188,6 +214,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
+RenderMirrors 1 0
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 6
+RenderHeroProbeUpdateRate 1 2
+RenderHeroProbeConservativeUpdateMultiplier 1 8
//
// High Graphics Settings (SSAO + sun shadows)
@@ -205,6 +236,8 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 2048
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
@@ -217,6 +250,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 1
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 8
+RenderHeroProbeUpdateRate 1 2
+RenderHeroProbeConservativeUpdateMultiplier 1 8
//
// High Ultra Graphics Settings (SSAO + all shadows)
@@ -234,6 +272,8 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
@@ -246,6 +286,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 2
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 512
+RenderHeroProbeDistance 1 16
+RenderHeroProbeUpdateRate 1 1
+RenderHeroProbeConservativeUpdateMultiplier 1 4
//
// Ultra graphics (REALLY PURTY!)
@@ -262,6 +307,8 @@ RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
+RenderTerrainPBRDetail 1 0
+RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
@@ -275,6 +322,11 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
+RenderMirrors 1 1
+RenderHeroProbeResolution 1 1024
+RenderHeroProbeDistance 1 16
+RenderHeroProbeUpdateRate 1 1
+RenderHeroProbeConservativeUpdateMultiplier 1 4
//
// Class Unknown Hardware (unknown)
@@ -283,6 +335,7 @@ list Unknown
RenderShadowDetail 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
+RenderMirrors 1 0
//
@@ -304,10 +357,14 @@ RenderTerrainDetail 1 0
RenderDeferredSSAO 0 0
RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
+RenderMirrors 0 0
list TexUnit8orLess
RenderDeferredSSAO 0 0
+list TexUnit16orLess
+RenderTerrainPBRDetail 1 -1
+
list AMD
RenderDeferredSSAO 1 0
@@ -319,3 +376,4 @@ list GL3
RenderFSAASamples 0 0
RenderReflectionProbeDetail 0 0
RenderReflectionsEnabled 0 0
+RenderMirrors 0 0
diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp
new file mode 100644
index 0000000000..55d36b7a32
--- /dev/null
+++ b/indra/newview/gltf/accessor.cpp
@@ -0,0 +1,66 @@
+/**
+ * @file accessor.cpp
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "asset.h"
+
+using namespace LL::GLTF;
+
+const Buffer& Buffer::operator=(const tinygltf::Buffer& src)
+{
+ mData = src.data;
+ mName = src.name;
+ mUri = src.uri;
+ return *this;
+}
+
+const BufferView& BufferView::operator=(const tinygltf::BufferView& src)
+{
+ mBuffer = src.buffer;
+ mByteLength = src.byteLength;
+ mByteOffset = src.byteOffset;
+ mByteStride = src.byteStride;
+ mTarget = src.target;
+ mName = src.name;
+ return *this;
+}
+
+const Accessor& Accessor::operator=(const tinygltf::Accessor& src)
+{
+ mBufferView = src.bufferView;
+ mByteOffset = src.byteOffset;
+ mComponentType = src.componentType;
+ mCount = src.count;
+ mType = src.type;
+ mNormalized = src.normalized;
+ mName = src.name;
+ mMax = src.maxValues;
+ mMin = src.minValues;
+
+ return *this;
+}
+
diff --git a/indra/newview/gltf/accessor.h b/indra/newview/gltf/accessor.h
new file mode 100644
index 0000000000..9b8265d8da
--- /dev/null
+++ b/indra/newview/gltf/accessor.h
@@ -0,0 +1,95 @@
+#pragma once
+
+/**
+ * @file asset.h
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "../lltinygltfhelper.h"
+#include "llstrider.h"
+
+// LL GLTF Implementation
+namespace LL
+{
+ namespace GLTF
+ {
+ class Asset;
+
+ constexpr S32 INVALID_INDEX = -1;
+
+ class Buffer
+ {
+ public:
+ std::vector<U8> mData;
+ std::string mName;
+ std::string mUri;
+
+ const Buffer& operator=(const tinygltf::Buffer& src);
+ };
+
+ class BufferView
+ {
+ public:
+ S32 mBuffer = INVALID_INDEX;
+ S32 mByteLength;
+ S32 mByteOffset;
+ S32 mByteStride;
+ S32 mTarget;
+ S32 mComponentType;
+
+ std::string mName;
+
+ const BufferView& operator=(const tinygltf::BufferView& src);
+
+ };
+
+ class Accessor
+ {
+ public:
+ S32 mBufferView = INVALID_INDEX;
+ S32 mByteOffset;
+ S32 mComponentType;
+ S32 mCount;
+ std::vector<double> mMax;
+ std::vector<double> mMin;
+
+ enum class Type : S32
+ {
+ SCALAR = TINYGLTF_TYPE_SCALAR,
+ VEC2 = TINYGLTF_TYPE_VEC2,
+ VEC3 = TINYGLTF_TYPE_VEC3,
+ VEC4 = TINYGLTF_TYPE_VEC4,
+ MAT2 = TINYGLTF_TYPE_MAT2,
+ MAT3 = TINYGLTF_TYPE_MAT3,
+ MAT4 = TINYGLTF_TYPE_MAT4
+ };
+
+ S32 mType;
+ bool mNormalized;
+ std::string mName;
+
+ const Accessor& operator=(const tinygltf::Accessor& src);
+ };
+ }
+}
diff --git a/indra/newview/gltf/animation.cpp b/indra/newview/gltf/animation.cpp
new file mode 100644
index 0000000000..da6d02b356
--- /dev/null
+++ b/indra/newview/gltf/animation.cpp
@@ -0,0 +1,287 @@
+/**
+ * @file animation.cpp
+ * @brief LL GLTF Animation Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "asset.h"
+#include "buffer_util.h"
+
+using namespace LL::GLTF;
+
+void Animation::allocateGLResources(Asset& asset)
+{
+ if (!mSamplers.empty())
+ {
+ mMinTime = FLT_MAX;
+ mMaxTime = -FLT_MAX;
+ for (auto& sampler : mSamplers)
+ {
+ sampler.allocateGLResources(asset);
+ mMinTime = llmin(sampler.mMinTime, mMinTime);
+ mMaxTime = llmax(sampler.mMaxTime, mMaxTime);
+ }
+ }
+ else
+ {
+ mMinTime = mMaxTime = 0.f;
+ }
+
+ for (auto& channel : mRotationChannels)
+ {
+ channel.allocateGLResources(asset, mSamplers[channel.mSampler]);
+ }
+
+ for (auto& channel : mTranslationChannels)
+ {
+ channel.allocateGLResources(asset, mSamplers[channel.mSampler]);
+ }
+}
+
+void Animation::update(Asset& asset, F32 dt)
+{
+ mTime += dt;
+
+ apply(asset, mTime);
+}
+
+void Animation::apply(Asset& asset, float time)
+{
+ // convert time to animation loop time
+ time = fmod(time, mMaxTime - mMinTime) + mMinTime;
+
+ // apply each channel
+ for (auto& channel : mRotationChannels)
+ {
+ channel.apply(asset, mSamplers[channel.mSampler], time);
+ }
+
+ for (auto& channel : mTranslationChannels)
+ {
+ channel.apply(asset, mSamplers[channel.mSampler], time);
+ }
+};
+
+
+void Animation::Sampler::allocateGLResources(Asset& asset)
+{
+ Accessor& accessor = asset.mAccessors[mInput];
+ mMinTime = accessor.mMin[0];
+ mMaxTime = accessor.mMax[0];
+
+ mFrameTimes.resize(accessor.mCount);
+
+ LLStrider<F32> frame_times = mFrameTimes.data();
+ copy(asset, accessor, frame_times);
+}
+
+void Animation::Sampler::getFrameInfo(Asset& asset, F32 time, U32& frameIndex, F32& t)
+{
+ if (time < mMinTime)
+ {
+ frameIndex = 0;
+ t = 0.0f;
+ return;
+ }
+
+ if (mFrameTimes.size() > 1)
+ {
+ if (time > mMaxTime)
+ {
+ frameIndex = mFrameTimes.size() - 2;
+ t = 1.0f;
+ return;
+ }
+
+ frameIndex = mFrameTimes.size() - 2;
+ t = 1.f;
+
+ for (U32 i = 0; i < mFrameTimes.size() - 1; i++)
+ {
+ if (time >= mFrameTimes[i] && time < mFrameTimes[i + 1])
+ {
+ frameIndex = i;
+ t = (time - mFrameTimes[i]) / (mFrameTimes[i + 1] - mFrameTimes[i]);
+ return;
+ }
+ }
+ }
+ else
+ {
+ frameIndex = 0;
+ t = 0.0f;
+ }
+}
+
+void Animation::RotationChannel::allocateGLResources(Asset& asset, Animation::Sampler& sampler)
+{
+ Accessor& accessor = asset.mAccessors[sampler.mOutput];
+
+ copy(asset, accessor, mRotations);
+}
+
+void Animation::RotationChannel::apply(Asset& asset, Sampler& sampler, F32 time)
+{
+ U32 frameIndex;
+ F32 t;
+
+ Node& node = asset.mNodes[mTarget.mNode];
+
+ sampler.getFrameInfo(asset, time, frameIndex, t);
+
+ if (sampler.mFrameTimes.size() == 1)
+ {
+ node.setRotation(mRotations[0]);
+ }
+ else
+ {
+ // interpolate
+ LLQuaternion q0(mRotations[frameIndex].get_value());
+ LLQuaternion q1(mRotations[frameIndex + 1].get_value());
+
+ LLQuaternion qf = slerp(t, q0, q1);
+
+ qf.normalize();
+ node.setRotation(glh::quaternionf(qf.mQ));
+ }
+}
+
+void Animation::TranslationChannel::allocateGLResources(Asset& asset, Animation::Sampler& sampler)
+{
+ Accessor& accessor = asset.mAccessors[sampler.mOutput];
+
+ copy(asset, accessor, mTranslations);
+}
+
+void Animation::TranslationChannel::apply(Asset& asset, Sampler& sampler, F32 time)
+{
+ U32 frameIndex;
+ F32 t;
+
+ Node& node = asset.mNodes[mTarget.mNode];
+
+ sampler.getFrameInfo(asset, time, frameIndex, t);
+
+ if (sampler.mFrameTimes.size() == 1)
+ {
+ node.setTranslation(mTranslations[0]);
+ }
+ else
+ {
+ // interpolate
+ const glh::vec3f& v0 = mTranslations[frameIndex];
+ const glh::vec3f& v1 = mTranslations[frameIndex + 1];
+
+ glh::vec3f vf = v0 + t * (v1 - v0);
+
+ node.setTranslation(vf);
+ }
+}
+
+void Animation::ScaleChannel::allocateGLResources(Asset& asset, Animation::Sampler& sampler)
+{
+ Accessor& accessor = asset.mAccessors[sampler.mOutput];
+
+ copy(asset, accessor, mScales);
+}
+
+void Animation::ScaleChannel::apply(Asset& asset, Sampler& sampler, F32 time)
+{
+ U32 frameIndex;
+ F32 t;
+
+ Node& node = asset.mNodes[mTarget.mNode];
+
+ sampler.getFrameInfo(asset, time, frameIndex, t);
+
+ if (sampler.mFrameTimes.size() == 1)
+ {
+ node.setScale(mScales[0]);
+ }
+ else
+ {
+ // interpolate
+ const glh::vec3f& v0 = mScales[frameIndex];
+ const glh::vec3f& v1 = mScales[frameIndex + 1];
+
+ glh::vec3f vf = v0 + t * (v1 - v0);
+
+ node.setScale(vf);
+ }
+}
+
+const Animation& Animation::operator=(const tinygltf::Animation& src)
+{
+ mName = src.name;
+
+ mSamplers.resize(src.samplers.size());
+ for (U32 i = 0; i < src.samplers.size(); ++i)
+ {
+ mSamplers[i] = src.samplers[i];
+ }
+
+ for (U32 i = 0; i < src.channels.size(); ++i)
+ {
+ if (src.channels[i].target_path == "rotation")
+ {
+ mRotationChannels.push_back(RotationChannel());
+ mRotationChannels.back() = src.channels[i];
+ }
+
+ if (src.channels[i].target_path == "translation")
+ {
+ mTranslationChannels.push_back(TranslationChannel());
+ mTranslationChannels.back() = src.channels[i];
+ }
+
+ if (src.channels[i].target_path == "scale")
+ {
+ mScaleChannels.push_back(ScaleChannel());
+ mScaleChannels.back() = src.channels[i];
+ }
+ }
+
+ return *this;
+}
+
+void Skin::allocateGLResources(Asset& asset)
+{
+ if (mInverseBindMatrices != INVALID_INDEX)
+ {
+ Accessor& accessor = asset.mAccessors[mInverseBindMatrices];
+ copy(asset, accessor, mInverseBindMatricesData);
+ }
+}
+
+const Skin& Skin::operator=(const tinygltf::Skin& src)
+{
+ mName = src.name;
+ mSkeleton = src.skeleton;
+ mInverseBindMatrices = src.inverseBindMatrices;
+ mJoints = src.joints;
+
+ return *this;
+}
+
diff --git a/indra/newview/gltf/animation.h b/indra/newview/gltf/animation.h
new file mode 100644
index 0000000000..869eae963a
--- /dev/null
+++ b/indra/newview/gltf/animation.h
@@ -0,0 +1,181 @@
+#pragma once
+
+/**
+ * @file animation.h
+ * @brief LL GLTF Animation Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "accessor.h"
+
+// LL GLTF Implementation
+namespace LL
+{
+ namespace GLTF
+ {
+ class Asset;
+
+ class Animation
+ {
+ public:
+ class Sampler
+ {
+ public:
+ std::vector<F32> mFrameTimes;
+
+ F32 mMinTime = -FLT_MAX;
+ F32 mMaxTime = FLT_MAX;
+
+ S32 mInput = INVALID_INDEX;
+ S32 mOutput = INVALID_INDEX;
+ std::string mInterpolation;
+
+ void allocateGLResources(Asset& asset);
+
+ const Sampler& operator=(const tinygltf::AnimationSampler& src)
+ {
+ mInput = src.input;
+ mOutput = src.output;
+ mInterpolation = src.interpolation;
+
+ return *this;
+ }
+
+ // get the frame index and time for the specified time
+ // asset -- the asset to reference for Accessors
+ // time -- the animation time to get the frame info for
+ // frameIndex -- index of the closest frame that precedes the specified time
+ // t - interpolant value between the frameIndex and the next frame
+ void getFrameInfo(Asset& asset, F32 time, U32& frameIndex, F32& t);
+ };
+
+ class Channel
+ {
+ public:
+ class Target
+ {
+ public:
+ S32 mNode = INVALID_INDEX;
+ std::string mPath;
+ };
+
+ S32 mSampler = INVALID_INDEX;
+ Target mTarget;
+ std::string mTargetPath;
+ std::string mName;
+
+ const Channel& operator=(const tinygltf::AnimationChannel& src)
+ {
+ mSampler = src.sampler;
+
+ mTarget.mNode = src.target_node;
+ mTarget.mPath = src.target_path;
+
+ return *this;
+ }
+
+ };
+
+ class RotationChannel : public Channel
+ {
+ public:
+ std::vector<glh::quaternionf> mRotations;
+
+ const RotationChannel& operator=(const tinygltf::AnimationChannel& src)
+ {
+ Channel::operator=(src);
+ return *this;
+ }
+
+ // prepare data needed for rendering
+ // asset -- asset to reference for Accessors
+ // sampler -- Sampler associated with this channel
+ void allocateGLResources(Asset& asset, Sampler& sampler);
+
+ void apply(Asset& asset, Sampler& sampler, F32 time);
+ };
+
+ class TranslationChannel : public Channel
+ {
+ public:
+ std::vector<glh::vec3f> mTranslations;
+
+ const TranslationChannel& operator=(const tinygltf::AnimationChannel& src)
+ {
+ Channel::operator=(src);
+ return *this;
+ }
+
+ // prepare data needed for rendering
+ // asset -- asset to reference for Accessors
+ // sampler -- Sampler associated with this channel
+ void allocateGLResources(Asset& asset, Sampler& sampler);
+
+ void apply(Asset& asset, Sampler& sampler, F32 time);
+ };
+
+ class ScaleChannel : public Channel
+ {
+ public:
+ std::vector<glh::vec3f> mScales;
+
+ const ScaleChannel& operator=(const tinygltf::AnimationChannel& src)
+ {
+ Channel::operator=(src);
+ return *this;
+ }
+
+ // prepare data needed for rendering
+ // asset -- asset to reference for Accessors
+ // sampler -- Sampler associated with this channel
+ void allocateGLResources(Asset& asset, Sampler& sampler);
+
+ void apply(Asset& asset, Sampler& sampler, F32 time);
+ };
+
+ std::string mName;
+ std::vector<Sampler> mSamplers;
+
+ // min/max time values for all samplers combined
+ F32 mMinTime = 0.f;
+ F32 mMaxTime = 0.f;
+
+ // current time of the animation
+ F32 mTime = 0.f;
+
+ std::vector<RotationChannel> mRotationChannels;
+ std::vector<TranslationChannel> mTranslationChannels;
+ std::vector<ScaleChannel> mScaleChannels;
+
+ const Animation& operator=(const tinygltf::Animation& src);
+
+ void allocateGLResources(Asset& asset);
+
+ void update(Asset& asset, float dt);
+
+ // apply this animation at the specified time
+ void apply(Asset& asset, F32 time);
+ };
+
+ }
+}
diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp
new file mode 100644
index 0000000000..313e82bf01
--- /dev/null
+++ b/indra/newview/gltf/asset.cpp
@@ -0,0 +1,664 @@
+/**
+ * @file asset.cpp
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "asset.h"
+#include "llvolumeoctree.h"
+#include "../llviewershadermgr.h"
+#include "../llviewercontrol.h"
+
+using namespace LL::GLTF;
+
+void Scene::updateTransforms(Asset& asset)
+{
+ LLMatrix4a identity;
+ identity.setIdentity();
+ for (auto& nodeIndex : mNodes)
+ {
+ Node& node = asset.mNodes[nodeIndex];
+ node.updateTransforms(asset, identity);
+ }
+}
+
+void Scene::updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview)
+{
+ for (auto& nodeIndex : mNodes)
+ {
+ Node& node = asset.mNodes[nodeIndex];
+ node.updateRenderTransforms(asset, modelview);
+ }
+}
+
+void Node::updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview)
+{
+ matMul(mMatrix, modelview, mRenderMatrix);
+
+ for (auto& childIndex : mChildren)
+ {
+ Node& child = asset.mNodes[childIndex];
+ child.updateRenderTransforms(asset, mRenderMatrix);
+ }
+}
+
+LLMatrix4a inverse(const LLMatrix4a& mat);
+
+void Node::updateTransforms(Asset& asset, const LLMatrix4a& parentMatrix)
+{
+ makeMatrixValid();
+ matMul(mMatrix, parentMatrix, mAssetMatrix);
+ mAssetMatrixInv = inverse(mAssetMatrix);
+
+ S32 my_index = this - &asset.mNodes[0];
+
+ for (auto& childIndex : mChildren)
+ {
+ Node& child = asset.mNodes[childIndex];
+ child.mParent = my_index;
+ child.updateTransforms(asset, mAssetMatrix);
+ }
+}
+
+void Asset::updateTransforms()
+{
+ for (auto& scene : mScenes)
+ {
+ scene.updateTransforms(*this);
+ }
+}
+
+void Asset::updateRenderTransforms(const LLMatrix4a& modelview)
+{
+#if 0
+ // traverse hierarchy and update render transforms from scratch
+ for (auto& scene : mScenes)
+ {
+ scene.updateRenderTransforms(*this, modelview);
+ }
+#else
+ // use mAssetMatrix to update render transforms from node list
+ for (auto& node : mNodes)
+ {
+ //if (node.mMesh != INVALID_INDEX)
+ {
+ matMul(node.mAssetMatrix, modelview, node.mRenderMatrix);
+ }
+ }
+
+#endif
+
+}
+
+S32 Asset::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent, // return the surface tangent at the intersection point
+ S32* primitive_hitp
+)
+{
+ S32 node_hit = -1;
+ S32 primitive_hit = -1;
+
+ LLVector4a local_start;
+ LLVector4a asset_end = end;
+ LLVector4a local_end;
+ LLVector4a p;
+
+
+ for (auto& node : mNodes)
+ {
+ if (node.mMesh != INVALID_INDEX)
+ {
+
+ bool newHit = false;
+
+ // transform start and end to this node's local space
+ node.mAssetMatrixInv.affineTransform(start, local_start);
+ node.mAssetMatrixInv.affineTransform(asset_end, local_end);
+
+ Mesh& mesh = mMeshes[node.mMesh];
+ for (auto& primitive : mesh.mPrimitives)
+ {
+ const LLVolumeTriangle* tri = primitive.lineSegmentIntersect(local_start, local_end, &p, tex_coord, normal, tangent);
+ if (tri)
+ {
+ newHit = true;
+ local_end = p;
+
+ // pointer math to get the node index
+ node_hit = &node - &mNodes[0];
+ llassert(&mNodes[node_hit] == &node);
+
+ //pointer math to get the primitive index
+ primitive_hit = &primitive - &mesh.mPrimitives[0];
+ llassert(&mesh.mPrimitives[primitive_hit] == &primitive);
+ }
+ }
+
+ if (newHit)
+ {
+ // shorten line segment on hit
+ node.mAssetMatrix.affineTransform(p, asset_end);
+
+ // transform results back to asset space
+ if (intersection)
+ {
+ *intersection = asset_end;
+ }
+
+ if (normal || tangent)
+ {
+ LLMatrix4 normalMatrix(node.mAssetMatrixInv.getF32ptr());
+
+ normalMatrix.transpose();
+
+ LLMatrix4a norm_mat;
+ norm_mat.loadu((F32*)normalMatrix.mMatrix);
+
+ if (normal)
+ {
+ LLVector4a n = *normal;
+ F32 w = n.getF32ptr()[3];
+ n.getF32ptr()[3] = 0.0f;
+
+ norm_mat.affineTransform(n, *normal);
+ normal->getF32ptr()[3] = w;
+ }
+
+ if (tangent)
+ {
+ LLVector4a t = *tangent;
+ F32 w = t.getF32ptr()[3];
+ t.getF32ptr()[3] = 0.0f;
+
+ norm_mat.affineTransform(t, *tangent);
+ tangent->getF32ptr()[3] = w;
+ }
+ }
+ }
+ }
+ }
+
+ if (node_hit != -1)
+ {
+ if (primitive_hitp)
+ {
+ *primitive_hitp = primitive_hit;
+ }
+ }
+
+ return node_hit;
+}
+
+
+void Node::makeMatrixValid()
+{
+ if (!mMatrixValid && mTRSValid)
+ {
+ glh::matrix4f rot;
+ mRotation.get_value(rot);
+
+ glh::matrix4f trans;
+ trans.set_translate(mTranslation);
+
+ glh::matrix4f sc;
+ sc.set_scale(mScale);
+
+ glh::matrix4f t;
+ //t = sc * rot * trans;
+ //t = trans * rot * sc; // best so far, still wrong on negative scale
+ //t = sc * trans * rot;
+ t = trans * sc * rot;
+
+ mMatrix.loadu(t.m);
+ mMatrixValid = true;
+ }
+}
+
+void Node::makeTRSValid()
+{
+ if (!mTRSValid && mMatrixValid)
+ {
+ glh::matrix4f t(mMatrix.getF32ptr());
+
+ glh::vec4f p = t.get_column(3);
+ mTranslation.set_value(p.v[0], p.v[1], p.v[2]);
+
+ mScale.set_value(t.get_column(0).length(), t.get_column(1).length(), t.get_column(2).length());
+ mRotation.set_value(t);
+ mTRSValid = true;
+ }
+}
+
+void Node::setRotation(const glh::quaternionf& q)
+{
+ makeTRSValid();
+ mRotation = q;
+ mMatrixValid = false;
+}
+
+void Node::setTranslation(const glh::vec3f& t)
+{
+ makeTRSValid();
+ mTranslation = t;
+ mMatrixValid = false;
+}
+
+void Node::setScale(const glh::vec3f& s)
+{
+ makeTRSValid();
+ mScale = s;
+ mMatrixValid = false;
+}
+
+const Node& Node::operator=(const tinygltf::Node& src)
+{
+ F32* dstMatrix = mMatrix.getF32ptr();
+
+ if (src.matrix.size() == 16)
+ {
+ // Node has a transformation matrix, just copy it
+ for (U32 i = 0; i < 16; ++i)
+ {
+ dstMatrix[i] = (F32)src.matrix[i];
+ }
+
+ mMatrixValid = true;
+ }
+ else if (!src.rotation.empty() || !src.translation.empty() || !src.scale.empty())
+ {
+ // node has rotation/translation/scale, convert to matrix
+ if (src.rotation.size() == 4)
+ {
+ mRotation = glh::quaternionf((F32)src.rotation[0], (F32)src.rotation[1], (F32)src.rotation[2], (F32)src.rotation[3]);
+ }
+
+ if (src.translation.size() == 3)
+ {
+ mTranslation = glh::vec3f((F32)src.translation[0], (F32)src.translation[1], (F32)src.translation[2]);
+ }
+
+ glh::vec3f scale;
+ if (src.scale.size() == 3)
+ {
+ mScale = glh::vec3f((F32)src.scale[0], (F32)src.scale[1], (F32)src.scale[2]);
+ }
+ else
+ {
+ mScale.set_value(1.f, 1.f, 1.f);
+ }
+
+ mTRSValid = true;
+ }
+ else
+ {
+ // node specifies no transformation, set to identity
+ mMatrix.setIdentity();
+ }
+
+ mChildren = src.children;
+ mMesh = src.mesh;
+ mSkin = src.skin;
+ mName = src.name;
+
+ return *this;
+}
+
+void Asset::render(bool opaque, bool rigged)
+{
+ if (rigged)
+ {
+ gGL.loadIdentity();
+ }
+
+ for (auto& node : mNodes)
+ {
+ if (node.mSkin != INVALID_INDEX)
+ {
+ if (rigged)
+ {
+ Skin& skin = mSkins[node.mSkin];
+ skin.uploadMatrixPalette(*this, node);
+ }
+ else
+ {
+ //skip static nodes if we're rendering rigged
+ continue;
+ }
+ }
+ else if (rigged)
+ {
+ // skip rigged nodes if we're not rendering rigged
+ continue;
+ }
+
+
+ if (node.mMesh != INVALID_INDEX)
+ {
+ Mesh& mesh = mMeshes[node.mMesh];
+ for (auto& primitive : mesh.mPrimitives)
+ {
+ if (!rigged)
+ {
+ gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix);
+ }
+ bool cull = true;
+ if (primitive.mMaterial != INVALID_INDEX)
+ {
+ Material& material = mMaterials[primitive.mMaterial];
+
+ if ((material.mMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND) == opaque)
+ {
+ continue;
+ }
+ material.mMaterial->bind();
+ cull = !material.mMaterial->mDoubleSided;
+ }
+ else
+ {
+ if (!opaque)
+ {
+ continue;
+ }
+ LLFetchedGLTFMaterial::sDefault.bind();
+ }
+
+ LLGLDisable cull_face(!cull ? GL_CULL_FACE : 0);
+
+ primitive.mVertexBuffer->setBuffer();
+ if (primitive.mVertexBuffer->getNumIndices() > 0)
+ {
+ primitive.mVertexBuffer->draw(primitive.mGLMode, primitive.mVertexBuffer->getNumIndices(), 0);
+ }
+ else
+ {
+ primitive.mVertexBuffer->drawArrays(primitive.mGLMode, 0, primitive.mVertexBuffer->getNumVerts());
+ }
+
+ }
+ }
+ }
+}
+
+void Asset::renderOpaque()
+{
+ render(true);
+}
+
+void Asset::renderTransparent()
+{
+ render(false);
+}
+
+void Asset::update()
+{
+ F32 dt = gFrameTimeSeconds - mLastUpdateTime;
+
+ if (dt > 0.f)
+ {
+ mLastUpdateTime = gFrameTimeSeconds;
+ if (mAnimations.size() > 0)
+ {
+ static LLCachedControl<U32> anim_idx(gSavedSettings, "GLTFAnimationIndex", 0);
+ static LLCachedControl<F32> anim_speed(gSavedSettings, "GLTFAnimationSpeed", 1.f);
+
+ U32 idx = llclamp(anim_idx(), 0U, mAnimations.size() - 1);
+ mAnimations[idx].update(*this, dt*anim_speed);
+ }
+
+ updateTransforms();
+ }
+}
+
+void Asset::allocateGLResources(const std::string& filename, const tinygltf::Model& model)
+{
+ // do images first as materials may depend on images
+ for (auto& image : mImages)
+ {
+ image.allocateGLResources();
+ }
+
+ // do materials before meshes as meshes may depend on materials
+ for (U32 i = 0; i < mMaterials.size(); ++i)
+ {
+ mMaterials[i].allocateGLResources(*this);
+ LLTinyGLTFHelper::getMaterialFromModel(filename, model, i, mMaterials[i].mMaterial, mMaterials[i].mName, true);
+ }
+
+ for (auto& mesh : mMeshes)
+ {
+ mesh.allocateGLResources(*this);
+ }
+
+ for (auto& animation : mAnimations)
+ {
+ animation.allocateGLResources(*this);
+ }
+
+ for (auto& skin : mSkins)
+ {
+ skin.allocateGLResources(*this);
+ }
+}
+
+const Asset& Asset::operator=(const tinygltf::Model& src)
+{
+ mScenes.resize(src.scenes.size());
+ for (U32 i = 0; i < src.scenes.size(); ++i)
+ {
+ mScenes[i] = src.scenes[i];
+ }
+
+ mNodes.resize(src.nodes.size());
+ for (U32 i = 0; i < src.nodes.size(); ++i)
+ {
+ mNodes[i] = src.nodes[i];
+ }
+
+ mMeshes.resize(src.meshes.size());
+ for (U32 i = 0; i < src.meshes.size(); ++i)
+ {
+ mMeshes[i] = src.meshes[i];
+ }
+
+ mMaterials.resize(src.materials.size());
+ for (U32 i = 0; i < src.materials.size(); ++i)
+ {
+ mMaterials[i] = src.materials[i];
+ }
+
+ mBuffers.resize(src.buffers.size());
+ for (U32 i = 0; i < src.buffers.size(); ++i)
+ {
+ mBuffers[i] = src.buffers[i];
+ }
+
+ mBufferViews.resize(src.bufferViews.size());
+ for (U32 i = 0; i < src.bufferViews.size(); ++i)
+ {
+ mBufferViews[i] = src.bufferViews[i];
+ }
+
+ mTextures.resize(src.textures.size());
+ for (U32 i = 0; i < src.textures.size(); ++i)
+ {
+ mTextures[i] = src.textures[i];
+ }
+
+ mSamplers.resize(src.samplers.size());
+ for (U32 i = 0; i < src.samplers.size(); ++i)
+ {
+ mSamplers[i] = src.samplers[i];
+ }
+
+ mImages.resize(src.images.size());
+ for (U32 i = 0; i < src.images.size(); ++i)
+ {
+ mImages[i] = src.images[i];
+ }
+
+ mAccessors.resize(src.accessors.size());
+ for (U32 i = 0; i < src.accessors.size(); ++i)
+ {
+ mAccessors[i] = src.accessors[i];
+ }
+
+ mAnimations.resize(src.animations.size());
+ for (U32 i = 0; i < src.animations.size(); ++i)
+ {
+ mAnimations[i] = src.animations[i];
+ }
+
+ mSkins.resize(src.skins.size());
+ for (U32 i = 0; i < src.skins.size(); ++i)
+ {
+ mSkins[i] = src.skins[i];
+ }
+
+ return *this;
+}
+
+const Material& Material::operator=(const tinygltf::Material& src)
+{
+ mName = src.name;
+ return *this;
+}
+
+void Material::allocateGLResources(Asset& asset)
+{
+ // allocate material
+ mMaterial = new LLFetchedGLTFMaterial();
+}
+
+const Mesh& Mesh::operator=(const tinygltf::Mesh& src)
+{
+ mPrimitives.resize(src.primitives.size());
+ for (U32 i = 0; i < src.primitives.size(); ++i)
+ {
+ mPrimitives[i] = src.primitives[i];
+ }
+
+ mWeights = src.weights;
+ mName = src.name;
+
+ return *this;
+}
+
+void Mesh::allocateGLResources(Asset& asset)
+{
+ for (auto& primitive : mPrimitives)
+ {
+ primitive.allocateGLResources(asset);
+ }
+}
+
+const Scene& Scene::operator=(const tinygltf::Scene& src)
+{
+ mNodes = src.nodes;
+ mName = src.name;
+
+ return *this;
+}
+
+const Texture& Texture::operator=(const tinygltf::Texture& src)
+{
+ mSampler = src.sampler;
+ mSource = src.source;
+ mName = src.name;
+
+ return *this;
+}
+
+const Sampler& Sampler::operator=(const tinygltf::Sampler& src)
+{
+ mMagFilter = src.magFilter;
+ mMinFilter = src.minFilter;
+ mWrapS = src.wrapS;
+ mWrapT = src.wrapT;
+ mName = src.name;
+
+ return *this;
+}
+
+void Skin::uploadMatrixPalette(Asset& asset, Node& node)
+{
+ // prepare matrix palette
+
+ // modelview will be applied by the shader, so assume matrix palette is in asset space
+ std::vector<glh::matrix4f> t_mp;
+
+ t_mp.resize(mJoints.size());
+
+ for (U32 i = 0; i < mJoints.size(); ++i)
+ {
+ Node& joint = asset.mNodes[mJoints[i]];
+
+ //t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
+ //t_mp[i] = t_mp[i] * mInverseBindMatricesData[i];
+
+ //t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
+ //t_mp[i] = mInverseBindMatricesData[i] * t_mp[i];
+
+ t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
+ t_mp[i] = t_mp[i] * mInverseBindMatricesData[i];
+
+ }
+
+ std::vector<F32> glmp;
+
+ glmp.resize(mJoints.size() * 12);
+
+ F32* mp = glmp.data();
+
+ for (U32 i = 0; i < mJoints.size(); ++i)
+ {
+ F32* m = (F32*)t_mp[i].m;
+
+ U32 idx = i * 12;
+
+ mp[idx + 0] = m[0];
+ mp[idx + 1] = m[1];
+ mp[idx + 2] = m[2];
+ mp[idx + 3] = m[12];
+
+ mp[idx + 4] = m[4];
+ mp[idx + 5] = m[5];
+ mp[idx + 6] = m[6];
+ mp[idx + 7] = m[13];
+
+ mp[idx + 8] = m[8];
+ mp[idx + 9] = m[9];
+ mp[idx + 10] = m[10];
+ mp[idx + 11] = m[14];
+ }
+
+ LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ mJoints.size(),
+ FALSE,
+ (GLfloat*)glmp.data());
+}
+
diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h
new file mode 100644
index 0000000000..6e576a1ffe
--- /dev/null
+++ b/indra/newview/gltf/asset.h
@@ -0,0 +1,264 @@
+#pragma once
+
+/**
+ * @file asset.h
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "llvertexbuffer.h"
+#include "llvolumeoctree.h"
+#include "../lltinygltfhelper.h"
+#include "accessor.h"
+#include "primitive.h"
+#include "animation.h"
+
+extern F32SecondsImplicit gFrameTimeSeconds;
+
+// LL GLTF Implementation
+namespace LL
+{
+ namespace GLTF
+ {
+ class Asset;
+
+ class Material
+ {
+ public:
+ // use LLFetchedGLTFMaterial for now, but eventually we'll want to use
+ // a more flexible GLTF material implementation instead of the fixed packing
+ // version we use for sharable GLTF material assets
+ LLPointer<LLFetchedGLTFMaterial> mMaterial;
+ std::string mName;
+
+ const Material& operator=(const tinygltf::Material& src);
+
+ void allocateGLResources(Asset& asset);
+ };
+
+ class Mesh
+ {
+ public:
+ std::vector<Primitive> mPrimitives;
+ std::vector<double> mWeights;
+ std::string mName;
+
+ const Mesh& operator=(const tinygltf::Mesh& src);
+
+ void allocateGLResources(Asset& asset);
+ };
+
+ class Node
+ {
+ public:
+ LLMatrix4a mMatrix; //local transform
+ LLMatrix4a mRenderMatrix; //transform for rendering
+ LLMatrix4a mAssetMatrix; //transform from local to asset space
+ LLMatrix4a mAssetMatrixInv; //transform from asset to local space
+
+ glh::vec3f mTranslation;
+ glh::quaternionf mRotation;
+ glh::vec3f mScale;
+
+ // if true, mMatrix is valid and up to date
+ bool mMatrixValid = false;
+
+ // if true, translation/rotation/scale are valid and up to date
+ bool mTRSValid = false;
+
+ bool mNeedsApplyMatrix = false;
+
+ std::vector<S32> mChildren;
+ S32 mParent = INVALID_INDEX;
+
+ S32 mMesh = INVALID_INDEX;
+ S32 mSkin = INVALID_INDEX;
+
+ std::string mName;
+
+ const Node& operator=(const tinygltf::Node& src);
+
+ // Set mRenderMatrix to a transform that can be used for the current render pass
+ // modelview -- parent's render matrix
+ void updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview);
+
+ // update mAssetMatrix and mAssetMatrixInv
+ void updateTransforms(Asset& asset, const LLMatrix4a& parentMatrix);
+
+ // ensure mMatrix is valid -- if mMatrixValid is false and mTRSValid is true, will update mMatrix to match Translation/Rotation/Scale
+ void makeMatrixValid();
+
+ // ensure Translation/Rotation/Scale are valid -- if mTRSValid is false and mMatrixValid is true, will update Translation/Rotation/Scale to match mMatrix
+ void makeTRSValid();
+
+ // Set rotation of this node
+ // SIDE EFFECT: invalidates mMatrix
+ void setRotation(const glh::quaternionf& rotation);
+
+ // Set translation of this node
+ // SIDE EFFECT: invalidates mMatrix
+ void setTranslation(const glh::vec3f& translation);
+
+ // Set scale of this node
+ // SIDE EFFECT: invalidates mMatrix
+ void setScale(const glh::vec3f& scale);
+ };
+
+ class Skin
+ {
+ public:
+ S32 mInverseBindMatrices = INVALID_INDEX;
+ S32 mSkeleton = INVALID_INDEX;
+ std::vector<S32> mJoints;
+ std::string mName;
+ std::vector<glh::matrix4f> mInverseBindMatricesData;
+
+ void allocateGLResources(Asset& asset);
+ void uploadMatrixPalette(Asset& asset, Node& node);
+
+ const Skin& operator=(const tinygltf::Skin& src);
+ };
+
+ class Scene
+ {
+ public:
+ std::vector<S32> mNodes;
+ std::string mName;
+
+ const Scene& operator=(const tinygltf::Scene& src);
+
+ void updateTransforms(Asset& asset);
+ void updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview);
+ };
+
+ class Texture
+ {
+ public:
+ S32 mSampler = INVALID_INDEX;
+ S32 mSource = INVALID_INDEX;
+ std::string mName;
+
+ const Texture& operator=(const tinygltf::Texture& src);
+ };
+
+ class Sampler
+ {
+ public:
+ S32 mMagFilter;
+ S32 mMinFilter;
+ S32 mWrapS;
+ S32 mWrapT;
+ std::string mName;
+
+ const Sampler& operator=(const tinygltf::Sampler& src);
+ };
+
+ class Image
+ {
+ public:
+ std::string mName;
+ std::string mUri;
+ std::string mMimeType;
+ std::vector<U8> mData;
+ S32 mWidth;
+ S32 mHeight;
+ S32 mComponent;
+ S32 mBits;
+ LLPointer<LLViewerFetchedTexture> mTexture;
+
+ const Image& operator=(const tinygltf::Image& src)
+ {
+ mName = src.name;
+ mUri = src.uri;
+ mMimeType = src.mimeType;
+ mData = src.image;
+ mWidth = src.width;
+ mHeight = src.height;
+ mComponent = src.component;
+ mBits = src.bits;
+
+ return *this;
+ }
+
+ void allocateGLResources()
+ {
+ // allocate texture
+
+ }
+ };
+
+ // C++ representation of a GLTF Asset
+ class Asset : public LLRefCount
+ {
+ public:
+ std::vector<Scene> mScenes;
+ std::vector<Node> mNodes;
+ std::vector<Mesh> mMeshes;
+ std::vector<Material> mMaterials;
+ std::vector<Buffer> mBuffers;
+ std::vector<BufferView> mBufferViews;
+ std::vector<Texture> mTextures;
+ std::vector<Sampler> mSamplers;
+ std::vector<Image> mImages;
+ std::vector<Accessor> mAccessors;
+ std::vector<Animation> mAnimations;
+ std::vector<Skin> mSkins;
+
+ // the last time update() was called according to gFrameTimeSeconds
+ F32 mLastUpdateTime = gFrameTimeSeconds;
+
+ // prepare the asset for rendering
+ void allocateGLResources(const std::string& filename, const tinygltf::Model& model);
+
+ // Called periodically (typically once per frame)
+ // Any ongoing work (such as animations) should be handled here
+ // NOT guaranteed to be called every frame
+ // MAY be called more than once per frame
+ // Upon return, all Node Matrix transforms should be up to date
+ void update();
+
+ // update asset-to-node and node-to-asset transforms
+ void updateTransforms();
+
+ // update node render transforms
+ void updateRenderTransforms(const LLMatrix4a& modelview);
+
+ void render(bool opaque, bool rigged = false);
+ void renderOpaque();
+ void renderTransparent();
+
+ // return the index of the node that the line segment intersects with, or -1 if no hit
+ // input and output values must be in this asset's local coordinate frame
+ S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ LLVector4a* intersection = nullptr, // return the intersection point
+ LLVector2* tex_coord = nullptr, // return the texture coordinates of the intersection point
+ LLVector4a* normal = nullptr, // return the surface normal at the intersection point
+ LLVector4a* tangent = nullptr, // return the surface tangent at the intersection point
+ S32* primitive_hitp = nullptr // return the index of the primitive that was hit
+ );
+
+ const Asset& operator=(const tinygltf::Model& src);
+
+ };
+ }
+}
diff --git a/indra/newview/gltf/buffer_util.h b/indra/newview/gltf/buffer_util.h
new file mode 100644
index 0000000000..4e6f5901e7
--- /dev/null
+++ b/indra/newview/gltf/buffer_util.h
@@ -0,0 +1,402 @@
+#pragma once
+
+/**
+ * @file buffer_util.inl
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// inline template implementations for copying data out of GLTF buffers
+// DO NOT include from header files to avoid the need to rebuild the whole project
+// whenever we add support for more types
+
+#ifdef _MSC_VER
+#define LL_FUNCSIG __FUNCSIG__
+#else
+#define LL_FUNCSIG __PRETTY_FUNCTION__
+#endif
+
+namespace LL
+{
+ namespace GLTF
+ {
+ // copy one Scalar from src to dst
+ template<class S, class T>
+ static void copyScalar(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec2 from src to dst
+ template<class S, class T>
+ static void copyVec2(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec3 from src to dst
+ template<class S, class T>
+ static void copyVec3(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec4 from src to dst
+ template<class S, class T>
+ static void copyVec4(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec2 from src to dst
+ template<class S, class T>
+ static void copyMat2(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec3 from src to dst
+ template<class S, class T>
+ static void copyMat3(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ // copy one vec4 from src to dst
+ template<class S, class T>
+ static void copyMat4(S* src, T& dst)
+ {
+ LL_ERRS() << "TODO: implement " << LL_FUNCSIG << LL_ENDL;
+ }
+
+ //=========================================================================================================
+ // concrete implementations for different types of source and destination
+ //=========================================================================================================
+
+// suppress unused function warning -- clang complains here but these specializations are definitely used
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+ template<>
+ void copyScalar<F32, F32>(F32* src, F32& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U32, U32>(U32* src, U32& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U32, U16>(U32* src, U16& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U16, U16>(U16* src, U16& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U16, U32>(U16* src, U32& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U8, U16>(U8* src, U16& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyScalar<U8, U32>(U8* src, U32& dst)
+ {
+ dst = *src;
+ }
+
+ template<>
+ void copyVec2<F32, LLVector2>(F32* src, LLVector2& dst)
+ {
+ dst.set(src[0], src[1]);
+ }
+
+ template<>
+ void copyVec3<F32, glh::vec3f>(F32* src, glh::vec3f& dst)
+ {
+ dst.set_value(src[0], src[1], src[2]);
+ }
+
+ template<>
+ void copyVec3<F32, LLVector4a>(F32* src, LLVector4a& dst)
+ {
+ dst.load3(src);
+ }
+
+ template<>
+ void copyVec3<U16, LLColor4U>(U16* src, LLColor4U& dst)
+ {
+ dst.set(src[0], src[1], src[2], 255);
+ }
+
+ template<>
+ void copyVec4<U8, LLColor4U>(U8* src, LLColor4U& dst)
+ {
+ dst.set(src[0], src[1], src[2], src[3]);
+ }
+
+ template<>
+ void copyVec4<U16, LLColor4U>(U16* src, LLColor4U& dst)
+ {
+ dst.set(src[0], src[1], src[2], src[3]);
+ }
+
+ template<>
+ void copyVec4<F32, LLColor4U>(F32* src, LLColor4U& dst)
+ {
+ dst.set(src[0]*255, src[1]*255, src[2]*255, src[3]*255);
+ }
+
+ template<>
+ void copyVec4<F32, LLVector4a>(F32* src, LLVector4a& dst)
+ {
+ dst.loadua(src);
+ }
+
+ template<>
+ void copyVec4<U16, LLVector4a>(U16* src, LLVector4a& dst)
+ {
+ dst.set(src[0], src[1], src[2], src[3]);
+ }
+
+ template<>
+ void copyVec4<U8, LLVector4a>(U8* src, LLVector4a& dst)
+ {
+ dst.set(src[0], src[1], src[2], src[3]);
+ }
+
+ template<>
+ void copyVec4<F32, glh::quaternionf>(F32* src, glh::quaternionf& dst)
+ {
+ dst.set_value(src);
+ }
+
+ template<>
+ void copyMat4<F32, glh::matrix4f>(F32* src, glh::matrix4f& dst)
+ {
+ dst.set_value(src);
+ }
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+ //=========================================================================================================
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyScalar(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyScalar(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyVec2(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyVec2(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyVec3(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyVec3(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyVec4(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyVec4(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyMat2(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyMat2(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyMat3(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyMat3(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ // copy from src to dst, stride is the number of bytes between each element in src, count is number of elements to copy
+ template<class S, class T>
+ static void copyMat4(S* src, LLStrider<T> dst, S32 stride, S32 count)
+ {
+ for (S32 i = 0; i < count; ++i)
+ {
+ copyMat4(src, *dst);
+ dst++;
+ src = (S*)((U8*)src + stride);
+ }
+ }
+
+ template<class S, class T>
+ static void copy(Asset& asset, Accessor& accessor, const S* src, LLStrider<T>& dst, S32 byteStride)
+ {
+ if (accessor.mType == (S32)Accessor::Type::SCALAR)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 1 : byteStride;
+ copyScalar((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::VEC2)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 2 : byteStride;
+ copyVec2((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::VEC3)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 3 : byteStride;
+ copyVec3((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::VEC4)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 4 : byteStride;
+ copyVec4((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::MAT2)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 4 : byteStride;
+ copyMat2((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::MAT3)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 9 : byteStride;
+ copyMat3((S*)src, dst, stride, accessor.mCount);
+ }
+ else if (accessor.mType == (S32)Accessor::Type::MAT4)
+ {
+ S32 stride = byteStride == 0 ? sizeof(S) * 16 : byteStride;
+ copyMat4((S*)src, dst, stride, accessor.mCount);
+ }
+ else
+ {
+ LL_ERRS("GLTF") << "Unsupported accessor type" << LL_ENDL;
+ }
+ }
+
+ // copy data from accessor to strider
+ template<class T>
+ static void copy(Asset& asset, Accessor& accessor, LLStrider<T>& dst)
+ {
+ const BufferView& bufferView = asset.mBufferViews[accessor.mBufferView];
+ const Buffer& buffer = asset.mBuffers[bufferView.mBuffer];
+ const U8* src = buffer.mData.data() + bufferView.mByteOffset + accessor.mByteOffset;
+
+ if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
+ {
+ LL::GLTF::copy(asset, accessor, (const F32*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
+ {
+ LL::GLTF::copy(asset, accessor, (const U16*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
+ {
+ LL::GLTF::copy(asset, accessor, (const U32*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
+ {
+ LL::GLTF::copy(asset, accessor, (const U8*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_SHORT)
+ {
+ LL::GLTF::copy(asset, accessor, (const S16*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_BYTE)
+ {
+ LL::GLTF::copy(asset, accessor, (const S8*)src, dst, bufferView.mByteStride);
+ }
+ else if (accessor.mComponentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)
+ {
+ LL::GLTF::copy(asset, accessor, (const F64*)src, dst, bufferView.mByteStride);
+ }
+ else
+ {
+ LL_ERRS("GLTF") << "Unsupported component type" << LL_ENDL;
+ }
+ }
+
+ // copy data from accessor to vector
+ template<class T>
+ static void copy(Asset& asset, Accessor& accessor, std::vector<T>& dst)
+ {
+ dst.resize(accessor.mCount);
+ LLStrider<T> strider = dst.data();
+ copy(asset, accessor, strider);
+ }
+ }
+}
+
diff --git a/indra/newview/gltf/primitive.cpp b/indra/newview/gltf/primitive.cpp
new file mode 100644
index 0000000000..b57a0af18d
--- /dev/null
+++ b/indra/newview/gltf/primitive.cpp
@@ -0,0 +1,400 @@
+/**
+ * @file primitive.cpp
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "asset.h"
+#include "buffer_util.h"
+
+#include "../lltinygltfhelper.h"
+
+using namespace LL::GLTF;
+
+void Primitive::allocateGLResources(Asset& asset)
+{
+ // allocate vertex buffer
+ // We diverge from the intent of the GLTF format here to work with our existing render pipeline
+ // GLTF wants us to copy the buffer views into GPU storage as is and build render commands that source that data.
+ // For our engine, though, it's better to rearrange the buffers at load time into a layout that's more consistent.
+ // The GLTF native approach undoubtedly works well if you can count on VAOs, but VAOs perform much worse with our scenes.
+
+ // load vertex data
+ for (auto& it : mAttributes)
+ {
+ const std::string& attribName = it.first;
+ Accessor& accessor = asset.mAccessors[it.second];
+
+ // load vertex data
+ if (attribName == "POSITION")
+ {
+ copy(asset, accessor, mPositions);
+ }
+ else if (attribName == "NORMAL")
+ {
+ copy(asset, accessor, mNormals);
+ }
+ else if (attribName == "TANGENT")
+ {
+ copy(asset, accessor, mTangents);
+ }
+ else if (attribName == "COLOR_0")
+ {
+ copy(asset, accessor, mColors);
+ }
+ else if (attribName == "TEXCOORD_0")
+ {
+ copy(asset, accessor, mTexCoords);
+ }
+ else if (attribName == "JOINTS_0")
+ {
+ copy(asset, accessor, mJoints);
+ }
+ else if (attribName == "WEIGHTS_0")
+ {
+ copy(asset, accessor, mWeights);
+ }
+ }
+
+ // copy index buffer
+ if (mIndices != INVALID_INDEX)
+ {
+ Accessor& accessor = asset.mAccessors[mIndices];
+ copy(asset, accessor, mIndexArray);
+ }
+
+ U32 mask = ATTRIBUTE_MASK;
+
+ if (!mWeights.empty())
+ {
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ mVertexBuffer = new LLVertexBuffer(mask);
+ mVertexBuffer->allocateBuffer(mPositions.size(), mIndexArray.size()*2); // double the size of the index buffer for 32-bit indices
+
+ mVertexBuffer->setBuffer();
+ mVertexBuffer->setPositionData(mPositions.data());
+
+ if (!mIndexArray.empty())
+ {
+ mVertexBuffer->setIndexData(mIndexArray.data());
+ }
+
+ if (mTexCoords.empty())
+ {
+ mTexCoords.resize(mPositions.size());
+ }
+
+ // flip texcoord y, upload, then flip back (keep the off-spec data in vram only)
+ for (auto& tc : mTexCoords)
+ {
+ tc[1] = 1.f - tc[1];
+ }
+ mVertexBuffer->setTexCoordData(mTexCoords.data());
+
+ for (auto& tc : mTexCoords)
+ {
+ tc[1] = 1.f - tc[1];
+ }
+
+ if (mColors.empty())
+ {
+ mColors.resize(mPositions.size(), LLColor4U::white);
+ }
+
+ // bake material basecolor into color array
+ if (mMaterial != INVALID_INDEX)
+ {
+ const Material& material = asset.mMaterials[mMaterial];
+ LLColor4 baseColor = material.mMaterial->mBaseColor;
+ for (auto& dst : mColors)
+ {
+ dst = LLColor4U(baseColor * LLColor4(dst));
+ }
+ }
+
+ mVertexBuffer->setColorData(mColors.data());
+
+ if (mNormals.empty())
+ {
+ mNormals.resize(mPositions.size(), LLVector4a(0, 0, 1, 0));
+ }
+
+ mVertexBuffer->setNormalData(mNormals.data());
+
+ if (mTangents.empty())
+ {
+ // TODO: generate tangents if needed
+ mTangents.resize(mPositions.size(), LLVector4a(1, 0, 0, 1));
+ }
+
+ mVertexBuffer->setTangentData(mTangents.data());
+
+ if (!mWeights.empty())
+ {
+ std::vector<LLVector4a> weight_data;
+ weight_data.resize(mWeights.size());
+
+ F32 max_weight = 1.f - FLT_EPSILON*100.f;
+ LLVector4a maxw(max_weight, max_weight, max_weight, max_weight);
+ for (U32 i = 0; i < mWeights.size(); ++i)
+ {
+ LLVector4a& w = weight_data[i];
+ w.setMin(mWeights[i], maxw);
+ w.add(mJoints[i]);
+ };
+
+ mVertexBuffer->setWeight4Data(weight_data.data());
+ }
+
+ createOctree();
+
+ mVertexBuffer->unbind();
+}
+
+void initOctreeTriangle(LLVolumeTriangle* tri, F32 scaler, S32 i0, S32 i1, S32 i2, const LLVector4a& v0, const LLVector4a& v1, const LLVector4a& v2)
+{
+ //store pointers to vertex data
+ tri->mV[0] = &v0;
+ tri->mV[1] = &v1;
+ tri->mV[2] = &v2;
+
+ //store indices
+ tri->mIndex[0] = i0;
+ tri->mIndex[1] = i1;
+ tri->mIndex[2] = i2;
+
+ //get minimum point
+ LLVector4a min = v0;
+ min.setMin(min, v1);
+ min.setMin(min, v2);
+
+ //get maximum point
+ LLVector4a max = v0;
+ max.setMax(max, v1);
+ max.setMax(max, v2);
+
+ //compute center
+ LLVector4a center;
+ center.setAdd(min, max);
+ center.mul(0.5f);
+
+ tri->mPositionGroup = center;
+
+ //compute "radius"
+ LLVector4a size;
+ size.setSub(max, min);
+
+ tri->mRadius = size.getLength3().getF32() * scaler;
+}
+
+void Primitive::createOctree()
+{
+ // create octree
+ mOctree = new LLVolumeOctree();
+
+ F32 scaler = 0.25f;
+
+ if (mMode == TINYGLTF_MODE_TRIANGLES)
+ {
+ const U32 num_triangles = mVertexBuffer->getNumIndices() / 3;
+ // Initialize all the triangles we need
+ mOctreeTriangles.resize(num_triangles);
+
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
+ { //for each triangle
+ const U32 index = triangle_index * 3;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
+ S32 i0 = mIndexArray[index];
+ S32 i1 = mIndexArray[index + 1];
+ S32 i2 = mIndexArray[index + 2];
+
+ const LLVector4a& v0 = mPositions[i0];
+ const LLVector4a& v1 = mPositions[i1];
+ const LLVector4a& v2 = mPositions[i2];
+
+ initOctreeTriangle(tri, scaler, i0, i1, i2, v0, v1, v2);
+
+ //insert
+ mOctree->insert(tri);
+ }
+ }
+ else if (mMode == TINYGLTF_MODE_TRIANGLE_STRIP)
+ {
+ const U32 num_triangles = mVertexBuffer->getNumIndices() - 2;
+ // Initialize all the triangles we need
+ mOctreeTriangles.resize(num_triangles);
+
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
+ { //for each triangle
+ const U32 index = triangle_index + 2;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
+ S32 i0 = mIndexArray[index];
+ S32 i1 = mIndexArray[index - 1];
+ S32 i2 = mIndexArray[index - 2];
+
+ const LLVector4a& v0 = mPositions[i0];
+ const LLVector4a& v1 = mPositions[i1];
+ const LLVector4a& v2 = mPositions[i2];
+
+ initOctreeTriangle(tri, scaler, i0, i1, i2, v0, v1, v2);
+
+ //insert
+ mOctree->insert(tri);
+ }
+ }
+ else if (mMode == TINYGLTF_MODE_TRIANGLE_FAN)
+ {
+ const U32 num_triangles = mVertexBuffer->getNumIndices() - 2;
+ // Initialize all the triangles we need
+ mOctreeTriangles.resize(num_triangles);
+
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
+ { //for each triangle
+ const U32 index = triangle_index + 2;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
+ S32 i0 = mIndexArray[0];
+ S32 i1 = mIndexArray[index - 1];
+ S32 i2 = mIndexArray[index - 2];
+
+ const LLVector4a& v0 = mPositions[i0];
+ const LLVector4a& v1 = mPositions[i1];
+ const LLVector4a& v2 = mPositions[i2];
+
+ initOctreeTriangle(tri, scaler, i0, i1, i2, v0, v1, v2);
+
+ //insert
+ mOctree->insert(tri);
+ }
+ }
+ else if (mMode == TINYGLTF_MODE_POINTS ||
+ mMode == TINYGLTF_MODE_LINE ||
+ mMode == TINYGLTF_MODE_LINE_LOOP ||
+ mMode == TINYGLTF_MODE_LINE_STRIP)
+ {
+ // nothing to do, no volume... maybe add some collision geometry around these primitive types?
+ }
+
+ else
+ {
+ LL_ERRS() << "Unsupported Primitive mode" << LL_ENDL;
+ }
+
+ //remove unneeded octree layers
+ while (!mOctree->balance()) {}
+
+ //calculate AABB for each node
+ LLVolumeOctreeRebound rebound;
+ rebound.traverse(mOctree);
+}
+
+const LLVolumeTriangle* Primitive::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
+{
+ if (mOctree.isNull())
+ {
+ return nullptr;
+ }
+
+ LLVector4a dir;
+ dir.setSub(end, start);
+
+ F32 closest_t = 2.f; // must be larger than 1
+
+ //create a proxy LLVolumeFace for the raycast
+ LLVolumeFace face;
+ face.mPositions = mPositions.data();
+ face.mTexCoords = mTexCoords.data();
+ face.mNormals = mNormals.data();
+ face.mTangents = mTangents.data();
+ face.mIndices = nullptr; // unreferenced
+
+ face.mNumIndices = mIndexArray.size();
+ face.mNumVertices = mPositions.size();
+
+ LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
+ intersect.traverse(mOctree);
+
+ // null out proxy data so it doesn't get freed
+ face.mPositions = face.mNormals = face.mTangents = nullptr;
+ face.mIndices = nullptr;
+ face.mTexCoords = nullptr;
+
+ return intersect.mHitTriangle;
+}
+
+Primitive::~Primitive()
+{
+ mOctree = nullptr;
+}
+
+
+const Primitive& Primitive::operator=(const tinygltf::Primitive& src)
+{
+ // load material
+ mMaterial = src.material;
+
+ // load mode
+ mMode = src.mode;
+
+ // load indices
+ mIndices = src.indices;
+
+ // load attributes
+ for (auto& it : src.attributes)
+ {
+ mAttributes[it.first] = it.second;
+ }
+
+ switch (mMode)
+ {
+ case TINYGLTF_MODE_POINTS:
+ mGLMode = LLRender::POINTS;
+ break;
+ case TINYGLTF_MODE_LINE:
+ mGLMode = LLRender::LINES;
+ break;
+ case TINYGLTF_MODE_LINE_LOOP:
+ mGLMode = LLRender::LINE_LOOP;
+ break;
+ case TINYGLTF_MODE_LINE_STRIP:
+ mGLMode = LLRender::LINE_STRIP;
+ break;
+ case TINYGLTF_MODE_TRIANGLES:
+ mGLMode = LLRender::TRIANGLES;
+ break;
+ case TINYGLTF_MODE_TRIANGLE_STRIP:
+ mGLMode = LLRender::TRIANGLE_STRIP;
+ break;
+ case TINYGLTF_MODE_TRIANGLE_FAN:
+ mGLMode = LLRender::TRIANGLE_FAN;
+ break;
+ default:
+ mGLMode = GL_TRIANGLES;
+ }
+
+ return *this;
+}
diff --git a/indra/newview/gltf/primitive.h b/indra/newview/gltf/primitive.h
new file mode 100644
index 0000000000..07e8e7deb2
--- /dev/null
+++ b/indra/newview/gltf/primitive.h
@@ -0,0 +1,93 @@
+#pragma once
+
+/**
+ * @file primitive.h
+ * @brief LL GLTF Implementation
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "llvertexbuffer.h"
+#include "llvolumeoctree.h"
+
+// LL GLTF Implementation
+namespace LL
+{
+ namespace GLTF
+ {
+ class Asset;
+
+ constexpr U32 ATTRIBUTE_MASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TANGENT |
+ LLVertexBuffer::MAP_COLOR;
+
+ class Primitive
+ {
+ public:
+ ~Primitive();
+
+ // GPU copy of mesh data
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+
+ // CPU copy of mesh data
+ std::vector<LLVector2> mTexCoords;
+ std::vector<LLVector4a> mNormals;
+ std::vector<LLVector4a> mTangents;
+ std::vector<LLVector4a> mPositions;
+ std::vector<LLVector4a> mJoints;
+ std::vector<LLVector4a> mWeights;
+ std::vector<LLColor4U> mColors;
+ std::vector<U32> mIndexArray;
+
+ // raycast acceleration structure
+ LLPointer<LLVolumeOctree> mOctree;
+ std::vector<LLVolumeTriangle> mOctreeTriangles;
+
+ S32 mMaterial = -1;
+ U32 mMode = TINYGLTF_MODE_TRIANGLES; // default to triangles
+ U32 mGLMode = LLRender::TRIANGLES;
+ S32 mIndices = -1;
+ std::unordered_map<std::string, int> mAttributes;
+
+ // create octree based on vertex buffer
+ // must be called before buffer is unmapped and after buffer is populated with good data
+ void createOctree();
+
+ //get the LLVolumeTriangle that intersects with the given line segment at the point
+ //closest to start. Moves end to the point of intersection. Returns nullptr if no intersection.
+ //Line segment must be in the same coordinate frame as this Primitive
+ const LLVolumeTriangle* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+ const Primitive& operator=(const tinygltf::Primitive& src);
+
+ void allocateGLResources(Asset& asset);
+ };
+ }
+}
diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp
new file mode 100644
index 0000000000..4e3439ea5c
--- /dev/null
+++ b/indra/newview/gltfscenemanager.cpp
@@ -0,0 +1,564 @@
+/**
+ * @file gltfscenemanager.cpp
+ * @brief Builds menus out of items.
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "gltfscenemanager.h"
+#include "llviewermenufile.h"
+#include "llappviewer.h"
+#include "lltinygltfhelper.h"
+#include "llvertexbuffer.h"
+#include "llselectmgr.h"
+#include "llagent.h"
+#include "llnotificationsutil.h"
+#include "llvoavatarself.h"
+#include "llvolumeoctree.h"
+#include "gltf/asset.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+
+
+using namespace LL;
+
+// temporary location of LL GLTF Implementation
+using namespace LL::GLTF;
+
+void GLTFSceneManager::load()
+{
+ LLViewerObject* obj = LLSelectMgr::instance().getSelection()->getFirstRootObject();
+
+ if (obj)
+ {
+ // Load a scene from disk
+ LLFilePickerReplyThread::startPicker(
+ [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)
+ {
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+ if (filenames.size() > 0)
+ {
+ GLTFSceneManager::instance().load(filenames[0]);
+ }
+ },
+ LLFilePicker::FFLOAD_GLTF,
+ true);
+ }
+ else
+ {
+ LLNotificationsUtil::add("GLTFPreviewSelection");
+ }
+}
+
+void GLTFSceneManager::load(const std::string& filename)
+{
+ tinygltf::Model model;
+ LLTinyGLTFHelper::loadModel(filename, model);
+
+ LLPointer<Asset> asset = new Asset();
+ *asset = model;
+
+ gDebugProgram.bind(); // bind a shader to satisfy LLVertexBuffer assertions
+ asset->allocateGLResources(filename, model);
+ asset->updateTransforms();
+
+ // hang the asset off the currently selected object, or off of the avatar if no object is selected
+ LLViewerObject* obj = LLSelectMgr::instance().getSelection()->getFirstRootObject();
+
+ if (obj)
+ { // assign to self avatar
+ obj->mGLTFAsset = asset;
+
+ if (std::find(mObjects.begin(), mObjects.end(), obj) == mObjects.end())
+ {
+ mObjects.push_back(obj);
+ }
+ }
+}
+
+GLTFSceneManager::~GLTFSceneManager()
+{
+ mObjects.clear();
+}
+
+void GLTFSceneManager::renderOpaque()
+{
+ render(true);
+}
+
+void GLTFSceneManager::renderAlpha()
+{
+ render(false);
+}
+
+void GLTFSceneManager::update()
+{
+ for (U32 i = 0; i < mObjects.size(); ++i)
+ {
+ if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr)
+ {
+ mObjects.erase(mObjects.begin() + i);
+ --i;
+ continue;
+ }
+
+ Asset* asset = mObjects[i]->mGLTFAsset;
+
+ asset->update();
+
+ }
+}
+
+void GLTFSceneManager::render(bool opaque, bool rigged)
+{
+ // for debugging, just render the whole scene as opaque
+ // by traversing the whole scenegraph
+ // Assumes camera transform is already set and
+ // appropriate shader is already bound
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ for (U32 i = 0; i < mObjects.size(); ++i)
+ {
+ if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr)
+ {
+ mObjects.erase(mObjects.begin() + i);
+ --i;
+ continue;
+ }
+
+ Asset* asset = mObjects[i]->mGLTFAsset;
+
+ gGL.pushMatrix();
+
+ LLMatrix4a mat = mObjects[i]->getGLTFAssetToAgentTransform();
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+
+ matMul(mat, modelview, modelview);
+
+ asset->updateRenderTransforms(modelview);
+ asset->render(opaque, rigged);
+
+ gGL.popMatrix();
+ }
+}
+
+LLMatrix4a inverse(const LLMatrix4a& mat)
+{
+ glh::matrix4f m((F32*)mat.mMatrix);
+ m = m.inverse();
+ LLMatrix4a ret;
+ ret.loadu(m.m);
+ return ret;
+}
+
+bool GLTFSceneManager::lineSegmentIntersect(LLVOVolume* obj, Asset* asset, const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32* node_hit, S32* primitive_hit,
+ LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
+
+{
+ // line segment intersection test
+ // start and end should be in agent space
+ // volume space and asset space should be the same coordinate frame
+ // results should be transformed back to agent space
+
+ bool ret = false;
+
+ LLVector4a local_start;
+ LLVector4a local_end;
+
+ LLMatrix4a asset_to_agent = obj->getGLTFAssetToAgentTransform();
+ LLMatrix4a agent_to_asset = inverse(asset_to_agent);
+
+ agent_to_asset.affineTransform(start, local_start);
+ agent_to_asset.affineTransform(end, local_end);
+
+ LLVector4a p;
+ LLVector4a n;
+ LLVector2 tc;
+ LLVector4a tn;
+
+ if (intersection != NULL)
+ {
+ p = *intersection;
+ }
+
+ if (tex_coord != NULL)
+ {
+ tc = *tex_coord;
+ }
+
+ if (normal != NULL)
+ {
+ n = *normal;
+ }
+
+ if (tangent != NULL)
+ {
+ tn = *tangent;
+ }
+
+ S32 hit_node_index = asset->lineSegmentIntersect(local_start, local_end, &p, &tc, &n, &tn, primitive_hit);
+
+ if (hit_node_index >= 0)
+ {
+ local_end = p;
+ if (node_hit != NULL)
+ {
+ *node_hit = hit_node_index;
+ }
+
+ if (intersection != NULL)
+ {
+ asset_to_agent.affineTransform(p, *intersection);
+ }
+
+ if (normal != NULL)
+ {
+ LLVector3 v_n(n.getF32ptr());
+ normal->load3(obj->volumeDirectionToAgent(v_n).mV);
+ (*normal).normalize3fast();
+ }
+
+ if (tangent != NULL)
+ {
+ LLVector3 v_tn(tn.getF32ptr());
+
+ LLVector4a trans_tangent;
+ trans_tangent.load3(obj->volumeDirectionToAgent(v_tn).mV);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ tangent->setSelectWithMask(mask, tn, trans_tangent);
+ (*tangent).normalize3fast();
+ }
+
+ if (tex_coord != NULL)
+ {
+ *tex_coord = tc;
+ }
+
+ ret = true;
+ }
+
+ return ret;
+}
+
+LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
+ S32* node_hit, // return the index of the node that was hit
+ S32* primitive_hit, // return the index of the primitive that was hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent) // return the surface tangent at the intersection point
+{
+ LLDrawable* drawable = nullptr;
+
+ LLVector4a local_end = end;
+ LLVector4a position;
+
+ for (U32 i = 0; i < mObjects.size(); ++i)
+ {
+ if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr || !mObjects[i]->getVolume())
+ {
+ mObjects.erase(mObjects.begin() + i);
+ --i;
+ continue;
+ }
+
+ // temporary debug -- always double check objects that have GLTF scenes hanging off of them even if the ray doesn't intersect the object bounds
+ if (lineSegmentIntersect((LLVOVolume*) mObjects[i].get(), mObjects[i]->mGLTFAsset, start, local_end, -1, pick_transparent, pick_rigged, pick_unselectable, node_hit, primitive_hit, &position, tex_coord, normal, tangent))
+ {
+ local_end = position;
+ if (intersection)
+ {
+ *intersection = position;
+ }
+ drawable = mObjects[i]->mDrawable;
+ }
+ }
+
+ return drawable;
+}
+
+void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size);
+
+extern LLVector4a gDebugRaycastStart;
+extern LLVector4a gDebugRaycastEnd;
+
+void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree);
+
+void renderAssetDebug(LLViewerObject* obj, Asset* asset)
+{
+ // render debug
+ // assumes appropriate shader is already bound
+ // assumes modelview matrix is already set
+
+ gGL.pushMatrix();
+
+ // get raycast in asset space
+ LLMatrix4a agent_to_asset = obj->getAgentToGLTFAssetTransform();
+
+ LLVector4a start;
+ LLVector4a end;
+
+ agent_to_asset.affineTransform(gDebugRaycastStart, start);
+ agent_to_asset.affineTransform(gDebugRaycastEnd, end);
+
+
+ for (auto& node : asset->mNodes)
+ {
+ Mesh& mesh = asset->mMeshes[node.mMesh];
+
+ if (node.mMesh != INVALID_INDEX)
+ {
+ gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix);
+
+ // draw bounding box of mesh primitives
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
+ {
+ gGL.color3f(0.f, 1.f, 1.f);
+
+ for (auto& primitive : mesh.mPrimitives)
+ {
+ auto* listener = (LLVolumeOctreeListener*) primitive.mOctree->getListener(0);
+
+ LLVector4a center = listener->mBounds[0];
+ LLVector4a size = listener->mBounds[1];
+
+ drawBoxOutline(center, size);
+ }
+ }
+
+#if 0
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
+ {
+ gGL.flush();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ // convert raycast to node local space
+ LLVector4a local_start;
+ LLVector4a local_end;
+
+ node.mAssetMatrixInv.affineTransform(start, local_start);
+ node.mAssetMatrixInv.affineTransform(end, local_end);
+
+ for (auto& primitive : mesh.mPrimitives)
+ {
+ if (primitive.mOctree.notNull())
+ {
+ renderOctreeRaycast(local_start, local_end, primitive.mOctree);
+ }
+ }
+
+ gGL.flush();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+#endif
+ }
+ }
+
+ gGL.popMatrix();
+}
+
+void GLTFSceneManager::renderDebug()
+{
+ if (!gPipeline.hasRenderDebugMask(
+ LLPipeline::RENDER_DEBUG_BBOXES |
+ LLPipeline::RENDER_DEBUG_RAYCAST |
+ LLPipeline::RENDER_DEBUG_NODES))
+ {
+ return;
+ }
+
+ gDebugProgram.bind();
+
+ LLGLDisable cullface(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gPipeline.disableLights();
+
+ // force update all mRenderMatrix, not just nodes with meshes
+ for (auto& obj : mObjects)
+ {
+ if (obj->isDead() || obj->mGLTFAsset == nullptr)
+ {
+ continue;
+ }
+
+ LLMatrix4a mat = obj->getGLTFAssetToAgentTransform();
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+
+ matMul(mat, modelview, modelview);
+
+ Asset* asset = obj->mGLTFAsset;
+
+ for (auto& node : asset->mNodes)
+ {
+ matMul(node.mAssetMatrix, modelview, node.mRenderMatrix);
+ }
+ }
+
+ for (auto& obj : mObjects)
+ {
+ if (obj->isDead() || obj->mGLTFAsset == nullptr)
+ {
+ continue;
+ }
+
+ Asset* asset = obj->mGLTFAsset;
+
+ LLMatrix4a mat = obj->getGLTFAssetToAgentTransform();
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+
+ matMul(mat, modelview, modelview);
+
+ renderAssetDebug(obj, asset);
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NODES))
+ { //render node hierarchy
+
+ for (U32 i = 0; i < 2; ++i)
+ {
+ LLGLDepthTest depth(GL_TRUE, i == 0 ? GL_FALSE : GL_TRUE, i == 0 ? GL_GREATER : GL_LEQUAL);
+ LLGLState blend(GL_BLEND, i == 0 ? TRUE : FALSE);
+
+
+ gGL.pushMatrix();
+
+ for (auto& obj : mObjects)
+ {
+ if (obj->isDead() || obj->mGLTFAsset == nullptr)
+ {
+ continue;
+ }
+
+ LLMatrix4a mat = obj->getGLTFAssetToAgentTransform();
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+
+ matMul(mat, modelview, modelview);
+
+ Asset* asset = obj->mGLTFAsset;
+
+ for (auto& node : asset->mNodes)
+ {
+ // force update all mRenderMatrix, not just nodes with meshes
+ matMul(node.mAssetMatrix, modelview, node.mRenderMatrix);
+
+ gGL.loadMatrix(node.mRenderMatrix.getF32ptr());
+ // render x-axis red, y-axis green, z-axis blue
+ gGL.color4f(1.f, 0.f, 0.f, 0.5f);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3f(0.f, 0.f, 0.f);
+ gGL.vertex3f(1.f, 0.f, 0.f);
+ gGL.end();
+ gGL.flush();
+
+ gGL.color4f(0.f, 1.f, 0.f, 0.5f);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3f(0.f, 0.f, 0.f);
+ gGL.vertex3f(0.f, 1.f, 0.f);
+ gGL.end();
+ gGL.flush();
+
+ gGL.begin(LLRender::LINES);
+ gGL.color4f(0.f, 0.f, 1.f, 0.5f);
+ gGL.vertex3f(0.f, 0.f, 0.f);
+ gGL.vertex3f(0.f, 0.f, 1.f);
+ gGL.end();
+ gGL.flush();
+
+ // render path to child nodes cyan
+ gGL.color4f(0.f, 1.f, 1.f, 0.5f);
+ gGL.begin(LLRender::LINES);
+ for (auto& child_idx : node.mChildren)
+ {
+ Node& child = asset->mNodes[child_idx];
+ gGL.vertex3f(0.f, 0.f, 0.f);
+ gGL.vertex3fv(child.mMatrix.getTranslation().getF32ptr());
+ }
+ gGL.end();
+ gGL.flush();
+ }
+ }
+
+ gGL.popMatrix();
+ }
+
+ }
+
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
+ {
+ S32 node_hit = -1;
+ S32 primitive_hit = -1;
+ LLVector4a intersection;
+
+ LLDrawable* drawable = lineSegmentIntersect(gDebugRaycastStart, gDebugRaycastEnd, TRUE, TRUE, TRUE, TRUE, &node_hit, &primitive_hit, &intersection, nullptr, nullptr, nullptr);
+
+ if (drawable)
+ {
+ gGL.pushMatrix();
+ Asset* asset = drawable->getVObj()->mGLTFAsset;
+ Node* node = &asset->mNodes[node_hit];
+ Primitive* primitive = &asset->mMeshes[node->mMesh].mPrimitives[primitive_hit];
+
+ gGL.flush();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.color3f(1, 0, 1);
+ drawBoxOutline(intersection, LLVector4a(0.1f, 0.1f, 0.1f, 0.f));
+
+ gGL.loadMatrix((F32*) node->mRenderMatrix.mMatrix);
+
+
+
+ auto* listener = (LLVolumeOctreeListener*) primitive->mOctree->getListener(0);
+ drawBoxOutline(listener->mBounds[0], listener->mBounds[1]);
+
+ gGL.flush();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gGL.popMatrix();
+ }
+ }
+ gDebugProgram.unbind();
+}
+
diff --git a/indra/newview/gltfscenemanager.h b/indra/newview/gltfscenemanager.h
new file mode 100644
index 0000000000..d286f335e4
--- /dev/null
+++ b/indra/newview/gltfscenemanager.h
@@ -0,0 +1,69 @@
+#pragma once
+
+/**
+ * @file gltfscenemanager.h
+ * @brief Builds menus out of items.
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "llsingleton.h"
+#include "llviewerobject.h"
+
+namespace LL
+{
+ class GLTFSceneManager : public LLSimpleton<GLTFSceneManager>
+ {
+ public:
+ ~GLTFSceneManager();
+ // load GLTF file from disk
+
+ void load(); // open filepicker to choose asset
+ void load(const std::string& filename); // load asset from filename
+
+ void update();
+ void render(bool opaque, bool rigged = false);
+ void renderOpaque();
+ void renderAlpha();
+
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
+ S32* node_hit, // return the index of the node that was hit
+ S32* primitive_hit, // return the index of the primitive that was hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent); // return the surface tangent at the intersection point
+
+ bool lineSegmentIntersect(LLVOVolume* obj, GLTF::Asset* asset, const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32* face_hitp, S32* primitive_hitp,
+ LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
+
+ void renderDebug();
+
+ std::vector<LLPointer<LLViewerObject>> mObjects;
+ };
+}
+
+
diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp
index c2a1589682..0717d92ea7 100644
--- a/indra/newview/llagentbenefits.cpp
+++ b/indra/newview/llagentbenefits.cpp
@@ -25,16 +25,17 @@
#include "llviewerprecompiledheaders.h"
#include "llagentbenefits.h"
+#include "llviewertexture.h"
LLAgentBenefits::LLAgentBenefits():
- m_initalized(false),
- m_animated_object_limit(-1),
- m_animation_upload_cost(-1),
- m_attachment_limit(-1),
- m_group_membership_limit(-1),
- m_picks_limit(-1),
- m_sound_upload_cost(-1),
- m_texture_upload_cost(-1)
+ m_initalized(false),
+ m_animated_object_limit(-1),
+ m_animation_upload_cost(-1),
+ m_attachment_limit(-1),
+ m_group_membership_limit(-1),
+ m_picks_limit(-1),
+ m_sound_upload_cost(-1),
+ m_texture_upload_cost(-1)
{
}
@@ -47,118 +48,181 @@ LLAgentBenefits::~LLAgentBenefits()
// the viewer cares about are integer.
bool get_required_S32(const LLSD& sd, const LLSD::String& key, S32& value)
{
- value = -1;
- if (sd.has(key))
- {
- value = sd[key].asInteger();
- return true;
- }
+ value = -1;
+ if (sd.has(key))
+ {
+ value = sd[key].asInteger();
+ return true;
+ }
- LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL;
- return false;
+ LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL;
+ return false;
}
bool LLAgentBenefits::init(const LLSD& benefits_sd)
{
- LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL;
+ LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL;
- if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit))
- {
- return false;
- }
- if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost))
+ if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost))
+ {
+ return false;
+ }
+
+ if (benefits_sd.has("large_texture_upload_cost"))
{
- return false;
+ LLSD large_texture_cost = benefits_sd.get("large_texture_upload_cost");
+ if (large_texture_cost.isArray())
+ {
+ LLSD::array_const_iterator end = large_texture_cost.endArray();
+ LLSD::array_const_iterator it = large_texture_cost.beginArray();
+ for (; it != end; ++it)
+ {
+ m_2k_texture_upload_cost.push_back(it->asInteger());
+ }
+ std::sort(m_2k_texture_upload_cost.begin(), m_2k_texture_upload_cost.end());
+ }
}
- if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost))
+
+ if (m_2k_texture_upload_cost.empty())
{
- return false;
+ m_2k_texture_upload_cost.push_back(m_texture_upload_cost);
}
- // FIXME PREMIUM - either use this field or get rid of it
- m_initalized = true;
- return true;
+ // FIXME PREMIUM - either use this field or get rid of it
+ m_initalized = true;
+ return true;
}
S32 LLAgentBenefits::getAnimatedObjectLimit() const
{
- return m_animated_object_limit;
+ return m_animated_object_limit;
}
S32 LLAgentBenefits::getAnimationUploadCost() const
{
- return m_animation_upload_cost;
+ return m_animation_upload_cost;
}
S32 LLAgentBenefits::getAttachmentLimit() const
{
- return m_attachment_limit;
+ return m_attachment_limit;
}
S32 LLAgentBenefits::getCreateGroupCost() const
{
- return m_create_group_cost;
+ return m_create_group_cost;
}
S32 LLAgentBenefits::getGroupMembershipLimit() const
{
- return m_group_membership_limit;
+ return m_group_membership_limit;
}
S32 LLAgentBenefits::getPicksLimit() const
{
- return m_picks_limit;
+ return m_picks_limit;
}
S32 LLAgentBenefits::getSoundUploadCost() const
{
- return m_sound_upload_cost;
+ return m_sound_upload_cost;
}
S32 LLAgentBenefits::getTextureUploadCost() const
{
- return m_texture_upload_cost;
+ return m_texture_upload_cost;
}
-bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const
+S32 LLAgentBenefits::getTextureUploadCost(const LLViewerTexture* tex) const
{
- bool succ = false;
- if (asset_type == LLAssetType::AT_TEXTURE)
+ if (tex)
{
- cost = getTextureUploadCost();
- succ = true;
+ S32 area = tex->getFullHeight() * tex->getFullWidth();
+ if (area >= MIN_2K_TEXTURE_AREA)
+ {
+ return get2KTextureUploadCost(area);
+ }
+ else
+ {
+ return getTextureUploadCost();
+ }
}
- else if (asset_type == LLAssetType::AT_SOUND)
+ return getTextureUploadCost();
+}
+
+S32 LLAgentBenefits::getTextureUploadCost(const LLImageBase* tex) const
+{
+ if (tex)
{
- cost = getSoundUploadCost();
- succ = true;
+ S32 area = tex->getHeight() * tex->getWidth();
+ if (area >= MIN_2K_TEXTURE_AREA)
+ {
+ return get2KTextureUploadCost(area);
+ }
+ else
+ {
+ return getTextureUploadCost();
+ }
}
- else if (asset_type == LLAssetType::AT_ANIMATION)
+ return getTextureUploadCost();
+}
+
+S32 LLAgentBenefits::get2KTextureUploadCost(S32 area) const
+{
+ if (m_2k_texture_upload_cost.empty())
{
- cost = getAnimationUploadCost();
- succ = true;
+ return m_texture_upload_cost;
}
- return succ;
+ return m_2k_texture_upload_cost[0];
+}
+
+bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const
+{
+ bool succ = false;
+ if (asset_type == LLAssetType::AT_TEXTURE)
+ {
+ cost = getTextureUploadCost();
+ succ = true;
+ }
+ else if (asset_type == LLAssetType::AT_SOUND)
+ {
+ cost = getSoundUploadCost();
+ succ = true;
+ }
+ else if (asset_type == LLAssetType::AT_ANIMATION)
+ {
+ cost = getAnimationUploadCost();
+ succ = true;
+ }
+ return succ;
}
LLAgentBenefitsMgr::LLAgentBenefitsMgr()
@@ -172,65 +236,65 @@ LLAgentBenefitsMgr::~LLAgentBenefitsMgr()
// static
const LLAgentBenefits& LLAgentBenefitsMgr::current()
{
- return instance().mCurrent;
+ return instance().mCurrent;
}
// static
const LLAgentBenefits& LLAgentBenefitsMgr::get(const std::string& package)
{
- if (instance().mPackageMap.find(package) != instance().mPackageMap.end())
- {
- return instance().mPackageMap[package];
- }
- else
- {
- return instance().mDefault;
- }
+ if (instance().mPackageMap.find(package) != instance().mPackageMap.end())
+ {
+ return instance().mPackageMap[package];
+ }
+ else
+ {
+ return instance().mDefault;
+ }
}
// static
bool LLAgentBenefitsMgr::init(const std::string& package, const LLSD& benefits_sd)
{
- LLAgentBenefits benefits;
- if (!benefits.init(benefits_sd))
- {
- LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
- return false;
- }
- else
- {
- instance().mPackageMap[package] = benefits;
- }
- return true;
+ LLAgentBenefits benefits;
+ if (!benefits.init(benefits_sd))
+ {
+ LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ instance().mPackageMap[package] = benefits;
+ }
+ return true;
}
// static
bool LLAgentBenefitsMgr::initCurrent(const std::string& package, const LLSD& benefits_sd)
{
- LLAgentBenefits benefits;
- if (!benefits.init(benefits_sd))
- {
- LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
- return false;
- }
- else
- {
- instance().mCurrent = benefits;
- instance().mCurrentName = package;
- }
- return true;
+ LLAgentBenefits benefits;
+ if (!benefits.init(benefits_sd))
+ {
+ LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ instance().mCurrent = benefits;
+ instance().mCurrentName = package;
+ }
+ return true;
}
// static
bool LLAgentBenefitsMgr::has(const std::string& package)
{
- return instance().mPackageMap.find(package) != instance().mPackageMap.end();
+ return instance().mPackageMap.find(package) != instance().mPackageMap.end();
}
//static
bool LLAgentBenefitsMgr::isCurrent(const std::string& package)
{
- return instance().mCurrentName == package;
+ return instance().mCurrentName == package;
}
diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h
index 1afc80a6cc..962d0f9371 100644
--- a/indra/newview/llagentbenefits.h
+++ b/indra/newview/llagentbenefits.h
@@ -30,58 +30,67 @@
#include "llsd.h"
#include "llassettype.h"
+class LLViewerTexture;
+class LLImageBase;
+
class LLAgentBenefits
{
public:
- LLAgentBenefits();
- ~LLAgentBenefits();
- LOG_CLASS(LLAgentBenefits);
+ static constexpr S32 MIN_2K_TEXTURE_AREA = 1024 * 1024 + 1;
- bool init(const LLSD& benefits_sd);
+ LLAgentBenefits();
+ ~LLAgentBenefits();
+ LOG_CLASS(LLAgentBenefits);
- S32 getAnimatedObjectLimit() const;
- S32 getAnimationUploadCost() const;
- S32 getAttachmentLimit() const;
- S32 getCreateGroupCost() const;
- S32 getGroupMembershipLimit() const;
- S32 getPicksLimit() const;
- S32 getSoundUploadCost() const;
- S32 getTextureUploadCost() const;
+ bool init(const LLSD& benefits_sd);
- bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const;
+ S32 getAnimatedObjectLimit() const;
+ S32 getAnimationUploadCost() const;
+ S32 getAttachmentLimit() const;
+ S32 getCreateGroupCost() const;
+ S32 getGroupMembershipLimit() const;
+ S32 getPicksLimit() const;
+ S32 getSoundUploadCost() const;
+ S32 getTextureUploadCost() const;
+ S32 getTextureUploadCost(const LLViewerTexture* tex) const;
+ S32 getTextureUploadCost(const LLImageBase* tex) const;
+ S32 get2KTextureUploadCost(S32 area) const;
+ bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const;
+
private:
- S32 m_animated_object_limit;
- S32 m_animation_upload_cost;
- S32 m_attachment_limit;
- S32 m_create_group_cost;
- S32 m_group_membership_limit;
- S32 m_picks_limit;
- S32 m_sound_upload_cost;
- S32 m_texture_upload_cost;
+ S32 m_animated_object_limit;
+ S32 m_animation_upload_cost;
+ S32 m_attachment_limit;
+ S32 m_create_group_cost;
+ S32 m_group_membership_limit;
+ S32 m_picks_limit;
+ S32 m_sound_upload_cost;
+ S32 m_texture_upload_cost;
+ std::vector<S32> m_2k_texture_upload_cost;
- bool m_initalized;
+ bool m_initalized;
};
-class LLAgentBenefitsMgr: public LLSingleton<LLAgentBenefitsMgr>
+class LLAgentBenefitsMgr: public LLSingleton<LLAgentBenefitsMgr>
{
- LLSINGLETON(LLAgentBenefitsMgr);
- ~LLAgentBenefitsMgr();
- LOG_CLASS(LLAgentBenefitsMgr);
+ LLSINGLETON(LLAgentBenefitsMgr);
+ ~LLAgentBenefitsMgr();
+ LOG_CLASS(LLAgentBenefitsMgr);
public:
- static const LLAgentBenefits& current();
- static const LLAgentBenefits& get(const std::string& package);
- static bool init(const std::string& package, const LLSD& benefits_sd);
- static bool initCurrent(const std::string& package, const LLSD& benefits_sd);
- static bool has(const std::string& package);
- static bool isCurrent(const std::string& package);
+ static const LLAgentBenefits& current();
+ static const LLAgentBenefits& get(const std::string& package);
+ static bool init(const std::string& package, const LLSD& benefits_sd);
+ static bool initCurrent(const std::string& package, const LLSD& benefits_sd);
+ static bool has(const std::string& package);
+ static bool isCurrent(const std::string& package);
private:
- std::string mCurrentName;
- LLAgentBenefits mCurrent;
- LLAgentBenefits mDefault;
- std::map<std::string, LLAgentBenefits> mPackageMap;
+ std::string mCurrentName;
+ LLAgentBenefits mCurrent;
+ LLAgentBenefits mDefault;
+ std::map<std::string, LLAgentBenefits> mPackageMap;
};
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index e763e797b5..1764acfc67 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1,31 +1,31 @@
-/**
+/**
* @file llagentcamera.cpp
* @brief LLAgent 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 "llagentcamera.h"
+#include "llagentcamera.h"
#include "pipeline.h"
@@ -60,8 +60,8 @@ const F32 MIN_ZOOM_FRACTION = 0.25f;
const F32 INITIAL_ZOOM_FRACTION = 1.f;
const F32 MAX_ZOOM_FRACTION = 8.f;
-const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f; // seconds
-const F32 FOV_ZOOM_HALF_LIFE = 0.07f; // seconds
+const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f; // seconds
+const F32 FOV_ZOOM_HALF_LIFE = 0.07f; // seconds
const F32 CAMERA_FOCUS_HALF_LIFE = 0.f;//0.02f;
const F32 CAMERA_LAG_HALF_LIFE = 0.25f;
@@ -102,8 +102,8 @@ const F32 OBJECT_EXTENTS_PADDING = 0.5f;
static bool isDisableCameraConstraints()
{
- static LLCachedControl<bool> sDisableCameraConstraints(gSavedSettings, "DisableCameraConstraints", false);
- return sDisableCameraConstraints;
+ static LLCachedControl<bool> sDisableCameraConstraints(gSavedSettings, "DisableCameraConstraints", false);
+ return sDisableCameraConstraints;
}
// The agent instance.
@@ -113,84 +113,84 @@ LLAgentCamera gAgentCamera;
// LLAgentCamera()
//-----------------------------------------------------------------------------
LLAgentCamera::LLAgentCamera() :
- mInitialized(false),
-
- mDrawDistance( DEFAULT_FAR_PLANE ),
-
- mLookAt(NULL),
- mPointAt(NULL),
-
- mHUDTargetZoom(1.f),
- mHUDCurZoom(1.f),
-
- mForceMouselook(FALSE),
-
- mCameraMode( CAMERA_MODE_THIRD_PERSON ),
- mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
-
- mCameraPreset(CAMERA_PRESET_REAR_VIEW),
-
- mCameraAnimating( FALSE ),
- mAnimationCameraStartGlobal(),
- mAnimationFocusStartGlobal(),
- mAnimationTimer(),
- mAnimationDuration(0.33f),
-
- mCameraFOVZoomFactor(0.f),
- mCameraCurrentFOVZoomFactor(0.f),
- mCameraFocusOffset(),
-
- mCameraCollidePlane(),
-
- mCurrentCameraDistance(2.f), // meters, set in init()
- mTargetCameraDistance(2.f),
- mCameraZoomFraction(1.f), // deprecated
- mThirdPersonHeadOffset(0.f, 0.f, 1.f),
- mSitCameraEnabled(FALSE),
- mCameraSmoothingLastPositionGlobal(),
- mCameraSmoothingLastPositionAgent(),
- mCameraSmoothingStop(false),
-
- mCameraUpVector(LLVector3::z_axis), // default is straight up
-
- mFocusOnAvatar(TRUE),
- mAllowChangeToFollow(FALSE),
- mFocusGlobal(),
- mFocusTargetGlobal(),
- mFocusObject(NULL),
- mFocusObjectDist(0.f),
- mFocusObjectOffset(),
- mTrackFocusObject(TRUE),
-
- mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
- mWalkKey(0), // like AtKey, but causes less forward thrust
- mLeftKey(0),
- mUpKey(0),
- mYawKey(0.f),
- mPitchKey(0.f),
-
- mOrbitLeftKey(0.f),
- mOrbitRightKey(0.f),
- mOrbitUpKey(0.f),
- mOrbitDownKey(0.f),
- mOrbitInKey(0.f),
- mOrbitOutKey(0.f),
-
- mPanUpKey(0.f),
- mPanDownKey(0.f),
- mPanLeftKey(0.f),
- mPanRightKey(0.f),
- mPanInKey(0.f),
- mPanOutKey(0.f)
-{
- mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
-
- clearGeneralKeys();
- clearOrbitKeys();
- clearPanKeys();
-
- resetPanDiff();
- resetOrbitDiff();
+ mInitialized(false),
+
+ mDrawDistance( DEFAULT_FAR_PLANE ),
+
+ mLookAt(NULL),
+ mPointAt(NULL),
+
+ mHUDTargetZoom(1.f),
+ mHUDCurZoom(1.f),
+
+ mForceMouselook(FALSE),
+
+ mCameraMode( CAMERA_MODE_THIRD_PERSON ),
+ mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
+
+ mCameraPreset(CAMERA_PRESET_REAR_VIEW),
+
+ mCameraAnimating( FALSE ),
+ mAnimationCameraStartGlobal(),
+ mAnimationFocusStartGlobal(),
+ mAnimationTimer(),
+ mAnimationDuration(0.33f),
+
+ mCameraFOVZoomFactor(0.f),
+ mCameraCurrentFOVZoomFactor(0.f),
+ mCameraFocusOffset(),
+
+ mCameraCollidePlane(),
+
+ mCurrentCameraDistance(2.f), // meters, set in init()
+ mTargetCameraDistance(2.f),
+ mCameraZoomFraction(1.f), // deprecated
+ mThirdPersonHeadOffset(0.f, 0.f, 1.f),
+ mSitCameraEnabled(FALSE),
+ mCameraSmoothingLastPositionGlobal(),
+ mCameraSmoothingLastPositionAgent(),
+ mCameraSmoothingStop(false),
+
+ mCameraUpVector(LLVector3::z_axis), // default is straight up
+
+ mFocusOnAvatar(TRUE),
+ mAllowChangeToFollow(FALSE),
+ mFocusGlobal(),
+ mFocusTargetGlobal(),
+ mFocusObject(NULL),
+ mFocusObjectDist(0.f),
+ mFocusObjectOffset(),
+ mTrackFocusObject(TRUE),
+
+ mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
+ mWalkKey(0), // like AtKey, but causes less forward thrust
+ mLeftKey(0),
+ mUpKey(0),
+ mYawKey(0.f),
+ mPitchKey(0.f),
+
+ mOrbitLeftKey(0.f),
+ mOrbitRightKey(0.f),
+ mOrbitUpKey(0.f),
+ mOrbitDownKey(0.f),
+ mOrbitInKey(0.f),
+ mOrbitOutKey(0.f),
+
+ mPanUpKey(0.f),
+ mPanDownKey(0.f),
+ mPanLeftKey(0.f),
+ mPanRightKey(0.f),
+ mPanInKey(0.f),
+ mPanOutKey(0.f)
+{
+ mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
+
+ clearGeneralKeys();
+ clearOrbitKeys();
+ clearPanKeys();
+
+ resetPanDiff();
+ resetOrbitDiff();
}
// Requires gSavedSettings to be initialized.
@@ -199,28 +199,28 @@ LLAgentCamera::LLAgentCamera() :
//-----------------------------------------------------------------------------
void LLAgentCamera::init()
{
- // *Note: this is where LLViewerCamera::getInstance() used to be constructed.
-
- mDrawDistance = gSavedSettings.getF32("RenderFarClip");
+ // *Note: this is where LLViewerCamera::getInstance() used to be constructed.
- LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
- // Leave at 0.1 meters until we have real near clip management
- LLViewerCamera::getInstance()->setNear(0.1f);
- LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h
- LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape
- LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape
+ mDrawDistance = gSavedSettings.getF32("RenderFarClip");
- mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
+ LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
+ // Leave at 0.1 meters until we have real near clip management
+ LLViewerCamera::getInstance()->setNear(0.1f);
+ LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h
+ LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape
+ LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape
- mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
+ mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
+
+ mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
- mCameraCollidePlane.clearVec();
- mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
- mTargetCameraDistance = mCurrentCameraDistance;
- mCameraZoomFraction = 1.f;
- mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
+ mCameraCollidePlane.clearVec();
+ mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
+ mTargetCameraDistance = mCurrentCameraDistance;
+ mCameraZoomFraction = 1.f;
+ mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
- mInitialized = true;
+ mInitialized = true;
}
//-----------------------------------------------------------------------------
@@ -228,40 +228,40 @@ void LLAgentCamera::init()
//-----------------------------------------------------------------------------
void LLAgentCamera::cleanup()
{
- setSitCamera(LLUUID::null);
+ setSitCamera(LLUUID::null);
- if(mLookAt)
- {
- mLookAt->markDead() ;
- mLookAt = NULL;
- }
- if(mPointAt)
- {
- mPointAt->markDead() ;
- mPointAt = NULL;
- }
- setFocusObject(NULL);
+ if(mLookAt)
+ {
+ mLookAt->markDead() ;
+ mLookAt = NULL;
+ }
+ if(mPointAt)
+ {
+ mPointAt->markDead() ;
+ mPointAt = NULL;
+ }
+ setFocusObject(NULL);
}
void LLAgentCamera::setAvatarObject(LLVOAvatarSelf* avatar)
{
- if (!mLookAt)
- {
- mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
- }
- if (!mPointAt)
- {
- mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
- }
-
- if (!mLookAt.isNull())
- {
- mLookAt->setSourceObject(avatar);
- }
- if (!mPointAt.isNull())
- {
- mPointAt->setSourceObject(avatar);
- }
+ if (!mLookAt)
+ {
+ mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
+ }
+ if (!mPointAt)
+ {
+ mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
+ }
+
+ if (!mLookAt.isNull())
+ {
+ mLookAt->setSourceObject(avatar);
+ }
+ if (!mPointAt.isNull())
+ {
+ mPointAt->setSourceObject(avatar);
+ }
}
//-----------------------------------------------------------------------------
@@ -269,9 +269,9 @@ void LLAgentCamera::setAvatarObject(LLVOAvatarSelf* avatar)
//-----------------------------------------------------------------------------
LLAgentCamera::~LLAgentCamera()
{
- cleanup();
+ cleanup();
- // *Note: this is where LLViewerCamera::getInstance() used to be deleted.
+ // *Note: this is where LLViewerCamera::getInstance() used to be deleted.
}
// Change camera back to third person, stop the autopilot,
@@ -281,80 +281,80 @@ LLAgentCamera::~LLAgentCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
{
- if (gDisconnected)
- {
- return;
- }
-
- if (gAgent.getAutoPilot())
- {
- gAgent.stopAutoPilot(TRUE);
- }
-
- LLSelectMgr::getInstance()->unhighlightAll();
-
- // By popular request, keep land selection while walking around. JC
- // LLViewerParcelMgr::getInstance()->deselectLand();
-
- // force deselect when walking and attachment is selected
- // this is so people don't wig out when their avatar moves without animating
- if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
- {
- LLSelectMgr::getInstance()->deselectAll();
- }
-
- if (gMenuHolder != NULL)
- {
- // Hide all popup menus
- gMenuHolder->hideMenus();
- }
-
- if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
- {
- changeCameraToDefault();
-
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- handle_toggle_flycam();
- }
-
- // reset avatar mode from eventual residual motion
- if (LLToolMgr::getInstance()->inBuildMode())
- {
- LLViewerJoystick::getInstance()->moveAvatar(true);
- }
-
- //Camera Tool is needed for Free Camera Control Mode
- if (!LLFloaterCamera::inFreeCameraMode())
- {
- LLFloaterReg::hideInstance("build");
-
- // Switch back to basic toolset
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- }
-
- gViewerWindow->showCursor();
- }
-
-
- if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
- {
- if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
- {
- // leaving mouse-steer mode
- LLVector3 agent_at_axis = gAgent.getAtAxis();
- agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector());
- agent_at_axis.normalize();
- gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f)));
- }
-
- setFocusOnAvatar(TRUE, ANIMATE);
-
- mCameraFOVZoomFactor = 0.f;
- }
- resetPanDiff();
- resetOrbitDiff();
- mHUDTargetZoom = 1.f;
+ if (gDisconnected)
+ {
+ return;
+ }
+
+ if (gAgent.getAutoPilot())
+ {
+ gAgent.stopAutoPilot(TRUE);
+ }
+
+ LLSelectMgr::getInstance()->unhighlightAll();
+
+ // By popular request, keep land selection while walking around. JC
+ // LLViewerParcelMgr::getInstance()->deselectLand();
+
+ // force deselect when walking and attachment is selected
+ // this is so people don't wig out when their avatar moves without animating
+ if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ }
+
+ if (gMenuHolder != NULL)
+ {
+ // Hide all popup menus
+ gMenuHolder->hideMenus();
+ }
+
+ if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
+ {
+ changeCameraToDefault();
+
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ handle_toggle_flycam();
+ }
+
+ // reset avatar mode from eventual residual motion
+ if (LLToolMgr::getInstance()->inBuildMode())
+ {
+ LLViewerJoystick::getInstance()->moveAvatar(true);
+ }
+
+ //Camera Tool is needed for Free Camera Control Mode
+ if (!LLFloaterCamera::inFreeCameraMode())
+ {
+ LLFloaterReg::hideInstance("build");
+
+ // Switch back to basic toolset
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ }
+
+ gViewerWindow->showCursor();
+ }
+
+
+ if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
+ {
+ if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
+ {
+ // leaving mouse-steer mode
+ LLVector3 agent_at_axis = gAgent.getAtAxis();
+ agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector());
+ agent_at_axis.normalize();
+ gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f)));
+ }
+
+ setFocusOnAvatar(TRUE, ANIMATE);
+
+ mCameraFOVZoomFactor = 0.f;
+ }
+ resetPanDiff();
+ resetOrbitDiff();
+ mHUDTargetZoom = 1.f;
if (LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
@@ -375,14 +375,14 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
//-----------------------------------------------------------------------------
void LLAgentCamera::unlockView()
{
- if (getFocusOnAvatar())
- {
- if (isAgentAvatarValid())
- {
- setFocusGlobal(LLVector3d::zero, gAgentAvatarp->mID);
- }
- setFocusOnAvatar(FALSE, FALSE); // no animation
- }
+ if (getFocusOnAvatar())
+ {
+ if (isAgentAvatarValid())
+ {
+ setFocusGlobal(LLVector3d::zero, gAgentAvatarp->mID);
+ }
+ setFocusOnAvatar(FALSE, FALSE); // no animation
+ }
}
//-----------------------------------------------------------------------------
@@ -390,10 +390,10 @@ void LLAgentCamera::unlockView()
//-----------------------------------------------------------------------------
void LLAgentCamera::slamLookAt(const LLVector3 &look_at)
{
- LLVector3 look_at_norm = look_at;
- look_at_norm.mV[VZ] = 0.f;
- look_at_norm.normalize();
- gAgent.resetAxes(look_at_norm);
+ LLVector3 look_at_norm = look_at;
+ look_at_norm.mV[VZ] = 0.f;
+ look_at_norm.normalize();
+ gAgent.resetAxes(look_at_norm);
}
//-----------------------------------------------------------------------------
@@ -401,172 +401,172 @@ void LLAgentCamera::slamLookAt(const LLVector3 &look_at)
//-----------------------------------------------------------------------------
LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y)
{
- LLMatrix4 obj_matrix = object->getRenderMatrix();
- LLQuaternion obj_rot = object->getRenderRotation();
- LLVector3 obj_pos = object->getRenderPosition();
+ LLMatrix4 obj_matrix = object->getRenderMatrix();
+ LLQuaternion obj_rot = object->getRenderRotation();
+ LLVector3 obj_pos = object->getRenderPosition();
- // if is avatar - don't do any funk heuristics to position the focal point
- // see DEV-30589
- if ((object->isAvatar() && !object->isRoot()) || (object->isAnimatedObject() && object->getControlAvatar()))
- {
- return original_focus_point - obj_pos;
- }
+ // if is avatar - don't do any funk heuristics to position the focal point
+ // see DEV-30589
+ if ((object->isAvatar() && !object->isRoot()) || (object->isAnimatedObject() && object->getControlAvatar()))
+ {
+ return original_focus_point - obj_pos;
+ }
if (object->isAvatar())
{
LLVOAvatar* av = object->asAvatar();
return original_focus_point - av->getCharacterPosition();
}
-
- LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
- LLVector3 object_extents = object->getScale();
-
- // make sure they object extents are non-zero
- object_extents.clamp(0.001f, F32_MAX);
-
- // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
- LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin();
- obj_to_cam_ray.rotVec(inv_obj_rot);
- obj_to_cam_ray.normalize();
-
- // obj_to_cam_ray_proportions are the (positive) ratios of
- // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions.
- LLVector3 obj_to_cam_ray_proportions;
- obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]);
- obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]);
- obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]);
-
- // find the largest ratio stored in obj_to_cam_ray_proportions
- // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera
- LLVector3 longest_object_axis;
- // is x-axis longest?
- if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY]
- && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ])
- {
- // then grab it
- longest_object_axis.setVec(obj_matrix.getFwdRow4());
- }
- // is y-axis longest?
- else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ])
- {
- // then grab it
- longest_object_axis.setVec(obj_matrix.getLeftRow4());
- }
- // otherwise, use z axis
- else
- {
- longest_object_axis.setVec(obj_matrix.getUpRow4());
- }
-
- // Use this axis as the normal to project mouse click on to plane with that normal, at the object center.
- // This generates a point behind the mouse cursor that is approximately in the middle of the object in
- // terms of depth.
- // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera.
- // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable
- // eccentricity to the object orientation
- LLVector3 focus_plane_normal(longest_object_axis);
- focus_plane_normal.normalize();
-
- LLVector3d focus_pt_global;
- gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal);
- LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
-
- // find vector from camera to focus point in object space
- LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin();
- camera_to_focus_vec.rotVec(inv_obj_rot);
-
- // find vector from object origin to focus point in object coordinates
- LLVector3 focus_offset_from_object_center = focus_pt - obj_pos;
- // convert to object-local space
- focus_offset_from_object_center.rotVec(inv_obj_rot);
-
- // We need to project the focus point back into the bounding box of the focused object.
- // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis
- LLVector3 clip_fraction;
-
- // for each axis...
- for (U32 axis = VX; axis <= VZ; axis++)
- {
- //...calculate distance that focus offset sits outside of bounding box along that axis...
- //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center
- F32 dist_out_of_bounds;
- if (focus_offset_from_object_center.mV[axis] > 0.f)
- {
- dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f));
- }
- else
- {
- dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f));
- }
-
- //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis
- if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f)
- {
- // don't divide by very small number
- clip_fraction.mV[axis] = 0.f;
- }
- else
- {
- clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis];
- }
- }
-
- LLVector3 abs_clip_fraction = clip_fraction;
- abs_clip_fraction.abs();
-
- // find axis of focus offset that is *most* outside the bounding box and use that to
- // rescale focus offset to inside object extents
- if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY]
- && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
- {
- focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec;
- }
- else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
- {
- focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec;
- }
- else
- {
- focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec;
- }
-
- // convert back to world space
- focus_offset_from_object_center.rotVec(obj_rot);
-
- // now, based on distance of camera from object relative to object size
- // push the focus point towards the near surface of the object when (relatively) close to the objcet
- // or keep the focus point in the object middle when (relatively) far
- // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
- // is almost always "tumble about middle" and not "spin around surface point"
- {
- LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
-
- //now that we have the object relative position, we should bias toward the center of the object
- //based on the distance of the camera to the focus point vs. the distance of the camera to the focus
-
- F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis());
- F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin());
-
-
- LLBBox obj_bbox = object->getBoundingBoxAgent();
- F32 bias = 0.f;
-
- // virtual_camera_pos is the camera position we are simulating by backing the camera off
- // and adjusting the FOV
- LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
-
- // if the camera is inside the object (large, hollow objects, for example)
- // leave focus point all the way to destination depth, away from object center
- if(!obj_bbox.containsPointAgent(virtual_camera_pos))
- {
- // perform magic number biasing of focus point towards surface vs. planar center
- bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
- obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias);
- }
-
- focus_offset_from_object_center = obj_rel;
- }
-
- return focus_offset_from_object_center;
+
+ LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
+ LLVector3 object_extents = object->getScale();
+
+ // make sure they object extents are non-zero
+ object_extents.clamp(0.001f, F32_MAX);
+
+ // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
+ LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin();
+ obj_to_cam_ray.rotVec(inv_obj_rot);
+ obj_to_cam_ray.normalize();
+
+ // obj_to_cam_ray_proportions are the (positive) ratios of
+ // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions.
+ LLVector3 obj_to_cam_ray_proportions;
+ obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]);
+ obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]);
+ obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]);
+
+ // find the largest ratio stored in obj_to_cam_ray_proportions
+ // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera
+ LLVector3 longest_object_axis;
+ // is x-axis longest?
+ if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY]
+ && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ])
+ {
+ // then grab it
+ longest_object_axis.setVec(obj_matrix.getFwdRow4());
+ }
+ // is y-axis longest?
+ else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ])
+ {
+ // then grab it
+ longest_object_axis.setVec(obj_matrix.getLeftRow4());
+ }
+ // otherwise, use z axis
+ else
+ {
+ longest_object_axis.setVec(obj_matrix.getUpRow4());
+ }
+
+ // Use this axis as the normal to project mouse click on to plane with that normal, at the object center.
+ // This generates a point behind the mouse cursor that is approximately in the middle of the object in
+ // terms of depth.
+ // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera.
+ // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable
+ // eccentricity to the object orientation
+ LLVector3 focus_plane_normal(longest_object_axis);
+ focus_plane_normal.normalize();
+
+ LLVector3d focus_pt_global;
+ gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal);
+ LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
+
+ // find vector from camera to focus point in object space
+ LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin();
+ camera_to_focus_vec.rotVec(inv_obj_rot);
+
+ // find vector from object origin to focus point in object coordinates
+ LLVector3 focus_offset_from_object_center = focus_pt - obj_pos;
+ // convert to object-local space
+ focus_offset_from_object_center.rotVec(inv_obj_rot);
+
+ // We need to project the focus point back into the bounding box of the focused object.
+ // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis
+ LLVector3 clip_fraction;
+
+ // for each axis...
+ for (U32 axis = VX; axis <= VZ; axis++)
+ {
+ //...calculate distance that focus offset sits outside of bounding box along that axis...
+ //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center
+ F32 dist_out_of_bounds;
+ if (focus_offset_from_object_center.mV[axis] > 0.f)
+ {
+ dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f));
+ }
+ else
+ {
+ dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f));
+ }
+
+ //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis
+ if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f)
+ {
+ // don't divide by very small number
+ clip_fraction.mV[axis] = 0.f;
+ }
+ else
+ {
+ clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis];
+ }
+ }
+
+ LLVector3 abs_clip_fraction = clip_fraction;
+ abs_clip_fraction.abs();
+
+ // find axis of focus offset that is *most* outside the bounding box and use that to
+ // rescale focus offset to inside object extents
+ if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY]
+ && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
+ {
+ focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec;
+ }
+ else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
+ {
+ focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec;
+ }
+ else
+ {
+ focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec;
+ }
+
+ // convert back to world space
+ focus_offset_from_object_center.rotVec(obj_rot);
+
+ // now, based on distance of camera from object relative to object size
+ // push the focus point towards the near surface of the object when (relatively) close to the objcet
+ // or keep the focus point in the object middle when (relatively) far
+ // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
+ // is almost always "tumble about middle" and not "spin around surface point"
+ {
+ LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
+
+ //now that we have the object relative position, we should bias toward the center of the object
+ //based on the distance of the camera to the focus point vs. the distance of the camera to the focus
+
+ F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis());
+ F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin());
+
+
+ LLBBox obj_bbox = object->getBoundingBoxAgent();
+ F32 bias = 0.f;
+
+ // virtual_camera_pos is the camera position we are simulating by backing the camera off
+ // and adjusting the FOV
+ LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
+
+ // if the camera is inside the object (large, hollow objects, for example)
+ // leave focus point all the way to destination depth, away from object center
+ if(!obj_bbox.containsPointAgent(virtual_camera_pos))
+ {
+ // perform magic number biasing of focus point towards surface vs. planar center
+ bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
+ obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias);
+ }
+
+ focus_offset_from_object_center = obj_rel;
+ }
+
+ return focus_offset_from_object_center;
}
//-----------------------------------------------------------------------------
@@ -574,277 +574,277 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
//-----------------------------------------------------------------------------
BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
{
- BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
+ BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
- if (!mFocusObject || mFocusObject->isDead() ||
- mFocusObject->isMesh() ||
- isDisableCameraConstraints())
- {
- obj_min_distance = 0.f;
- return TRUE;
- }
+ if (!mFocusObject || mFocusObject->isDead() ||
+ mFocusObject->isMesh() ||
+ isDisableCameraConstraints())
+ {
+ obj_min_distance = 0.f;
+ return TRUE;
+ }
- if (mFocusObject->mDrawable.isNull())
- {
+ if (mFocusObject->mDrawable.isNull())
+ {
#ifdef LL_RELEASE_FOR_DOWNLOAD
- LL_WARNS() << "Focus object with no drawable!" << LL_ENDL;
+ LL_WARNS() << "Focus object with no drawable!" << LL_ENDL;
#else
- mFocusObject->dump();
- LL_ERRS() << "Focus object with no drawable!" << LL_ENDL;
+ mFocusObject->dump();
+ LL_ERRS() << "Focus object with no drawable!" << LL_ENDL;
#endif
- obj_min_distance = 0.f;
- return TRUE;
- }
-
- LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation();
- LLVector3 target_offset_origin = mFocusObjectOffset;
- LLVector3 camera_offset_target(getCameraPositionAgent() - gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
-
- // convert offsets into object local space
- camera_offset_target.rotVec(inv_object_rot);
- target_offset_origin.rotVec(inv_object_rot);
-
- // push around object extents based on target offset
- LLVector3 object_extents = mFocusObject->getScale();
- if (mFocusObject->isAvatar())
- {
- // fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom)
- object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR;
- object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR;
- object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR;
- soft_limit = TRUE;
- }
- LLVector3 abs_target_offset = target_offset_origin;
- abs_target_offset.abs();
-
- LLVector3 target_offset_dir = target_offset_origin;
-
- BOOL target_outside_object_extents = FALSE;
-
- for (U32 i = VX; i <= VZ; i++)
- {
- if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING)
- {
- target_outside_object_extents = TRUE;
- }
- if (camera_offset_target.mV[i] > 0.f)
- {
- object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f;
- }
- else
- {
- object_extents.mV[i] += target_offset_origin.mV[i] * 2.f;
- }
- }
-
- // don't shrink the object extents so far that the object inverts
- object_extents.clamp(0.001f, F32_MAX);
-
- // move into first octant
- LLVector3 camera_offset_target_abs_norm = camera_offset_target;
- camera_offset_target_abs_norm.abs();
- // make sure offset is non-zero
- camera_offset_target_abs_norm.clamp(0.001f, F32_MAX);
- camera_offset_target_abs_norm.normalize();
-
- // find camera position relative to normalized object extents
- LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm;
- camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX];
- camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY];
- camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ];
-
- if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] &&
- camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ])
- {
- if (camera_offset_target_abs_norm.mV[VX] < 0.001f)
- {
- obj_min_distance = object_extents.mV[VX] * 0.5f;
- }
- else
- {
- obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX];
- }
- }
- else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ])
- {
- if (camera_offset_target_abs_norm.mV[VY] < 0.001f)
- {
- obj_min_distance = object_extents.mV[VY] * 0.5f;
- }
- else
- {
- obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY];
- }
- }
- else
- {
- if (camera_offset_target_abs_norm.mV[VZ] < 0.001f)
- {
- obj_min_distance = object_extents.mV[VZ] * 0.5f;
- }
- else
- {
- obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ];
- }
- }
-
- LLVector3 object_split_axis;
- LLVector3 target_offset_scaled = target_offset_origin;
- target_offset_scaled.abs();
- target_offset_scaled.normalize();
- target_offset_scaled.mV[VX] /= object_extents.mV[VX];
- target_offset_scaled.mV[VY] /= object_extents.mV[VY];
- target_offset_scaled.mV[VZ] /= object_extents.mV[VZ];
-
- if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] &&
- target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ])
- {
- object_split_axis = LLVector3::x_axis;
- }
- else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ])
- {
- object_split_axis = LLVector3::y_axis;
- }
- else
- {
- object_split_axis = LLVector3::z_axis;
- }
-
- LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
-
-
- F32 camera_offset_clip = camera_offset_object * object_split_axis;
- F32 target_offset_clip = target_offset_dir * object_split_axis;
-
- // target has moved outside of object extents
- // check to see if camera and target are on same side
- if (target_outside_object_extents)
- {
- if (camera_offset_clip > 0.f && target_offset_clip > 0.f)
- {
- return FALSE;
- }
- else if (camera_offset_clip < 0.f && target_offset_clip < 0.f)
- {
- return FALSE;
- }
- }
-
- // clamp obj distance to diagonal of 10 by 10 cube
- obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
-
- obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f);
-
- return TRUE;
+ obj_min_distance = 0.f;
+ return TRUE;
+ }
+
+ LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation();
+ LLVector3 target_offset_origin = mFocusObjectOffset;
+ LLVector3 camera_offset_target(getCameraPositionAgent() - gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
+
+ // convert offsets into object local space
+ camera_offset_target.rotVec(inv_object_rot);
+ target_offset_origin.rotVec(inv_object_rot);
+
+ // push around object extents based on target offset
+ LLVector3 object_extents = mFocusObject->getScale();
+ if (mFocusObject->isAvatar())
+ {
+ // fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom)
+ object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR;
+ object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR;
+ object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR;
+ soft_limit = TRUE;
+ }
+ LLVector3 abs_target_offset = target_offset_origin;
+ abs_target_offset.abs();
+
+ LLVector3 target_offset_dir = target_offset_origin;
+
+ BOOL target_outside_object_extents = FALSE;
+
+ for (U32 i = VX; i <= VZ; i++)
+ {
+ if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING)
+ {
+ target_outside_object_extents = TRUE;
+ }
+ if (camera_offset_target.mV[i] > 0.f)
+ {
+ object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f;
+ }
+ else
+ {
+ object_extents.mV[i] += target_offset_origin.mV[i] * 2.f;
+ }
+ }
+
+ // don't shrink the object extents so far that the object inverts
+ object_extents.clamp(0.001f, F32_MAX);
+
+ // move into first octant
+ LLVector3 camera_offset_target_abs_norm = camera_offset_target;
+ camera_offset_target_abs_norm.abs();
+ // make sure offset is non-zero
+ camera_offset_target_abs_norm.clamp(0.001f, F32_MAX);
+ camera_offset_target_abs_norm.normalize();
+
+ // find camera position relative to normalized object extents
+ LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm;
+ camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX];
+ camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY];
+ camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ];
+
+ if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] &&
+ camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ])
+ {
+ if (camera_offset_target_abs_norm.mV[VX] < 0.001f)
+ {
+ obj_min_distance = object_extents.mV[VX] * 0.5f;
+ }
+ else
+ {
+ obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX];
+ }
+ }
+ else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ])
+ {
+ if (camera_offset_target_abs_norm.mV[VY] < 0.001f)
+ {
+ obj_min_distance = object_extents.mV[VY] * 0.5f;
+ }
+ else
+ {
+ obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY];
+ }
+ }
+ else
+ {
+ if (camera_offset_target_abs_norm.mV[VZ] < 0.001f)
+ {
+ obj_min_distance = object_extents.mV[VZ] * 0.5f;
+ }
+ else
+ {
+ obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ];
+ }
+ }
+
+ LLVector3 object_split_axis;
+ LLVector3 target_offset_scaled = target_offset_origin;
+ target_offset_scaled.abs();
+ target_offset_scaled.normalize();
+ target_offset_scaled.mV[VX] /= object_extents.mV[VX];
+ target_offset_scaled.mV[VY] /= object_extents.mV[VY];
+ target_offset_scaled.mV[VZ] /= object_extents.mV[VZ];
+
+ if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] &&
+ target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ])
+ {
+ object_split_axis = LLVector3::x_axis;
+ }
+ else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ])
+ {
+ object_split_axis = LLVector3::y_axis;
+ }
+ else
+ {
+ object_split_axis = LLVector3::z_axis;
+ }
+
+ LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
+
+
+ F32 camera_offset_clip = camera_offset_object * object_split_axis;
+ F32 target_offset_clip = target_offset_dir * object_split_axis;
+
+ // target has moved outside of object extents
+ // check to see if camera and target are on same side
+ if (target_outside_object_extents)
+ {
+ if (camera_offset_clip > 0.f && target_offset_clip > 0.f)
+ {
+ return FALSE;
+ }
+ else if (camera_offset_clip < 0.f && target_offset_clip < 0.f)
+ {
+ return FALSE;
+ }
+ }
+
+ // clamp obj distance to diagonal of 10 by 10 cube
+ obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
+
+ obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f);
+
+ return TRUE;
}
F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person)
{
- // 0.f -> camera zoomed all the way out
- // 1.f -> camera zoomed all the way in
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- // already [0,1]
- return mHUDTargetZoom;
- }
-
- if (isDisableCameraConstraints())
- {
- return mCameraZoomFraction;
- }
-
- if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
- {
- return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
- }
-
- if (cameraCustomizeAvatar())
- {
- F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
- return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
- }
-
- F32 min_zoom;
- F32 max_zoom = getCameraMaxZoomDistance();
-
- F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
- if (mFocusObject.notNull())
- {
- if (mFocusObject->isAvatar())
- {
- min_zoom = AVATAR_MIN_ZOOM;
- }
- else
- {
- min_zoom = OBJECT_MIN_ZOOM;
- }
- }
- else
- {
- min_zoom = LAND_MIN_ZOOM;
- }
-
- return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
+ // 0.f -> camera zoomed all the way out
+ // 1.f -> camera zoomed all the way in
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ // already [0,1]
+ return mHUDTargetZoom;
+ }
+
+ if (isDisableCameraConstraints())
+ {
+ return mCameraZoomFraction;
+ }
+
+ if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
+ {
+ return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
+ }
+
+ if (cameraCustomizeAvatar())
+ {
+ F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
+ return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
+ }
+
+ F32 min_zoom;
+ F32 max_zoom = getCameraMaxZoomDistance();
+
+ F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
+ if (mFocusObject.notNull())
+ {
+ if (mFocusObject->isAvatar())
+ {
+ min_zoom = AVATAR_MIN_ZOOM;
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
+ }
+ }
+ else
+ {
+ min_zoom = LAND_MIN_ZOOM;
+ }
+
+ return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
}
void LLAgentCamera::setCameraZoomFraction(F32 fraction)
{
- // 0.f -> camera zoomed all the way out
- // 1.f -> camera zoomed all the way in
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- mHUDTargetZoom = fraction;
- }
- else if (isDisableCameraConstraints())
- {
- mCameraZoomFraction = fraction;
- }
- else if (mFocusOnAvatar && cameraThirdPerson())
- {
- mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
- }
- else if (cameraCustomizeAvatar())
- {
- LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
- camera_offset_dir.normalize();
- mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM);
- }
- else
- {
- F32 min_zoom = LAND_MIN_ZOOM;
- F32 max_zoom = getCameraMaxZoomDistance();
-
- if (mFocusObject.notNull())
- {
- if (mFocusObject.notNull())
- {
- if (mFocusObject->isAvatar())
- {
- min_zoom = AVATAR_MIN_ZOOM;
- }
- else
- {
- min_zoom = OBJECT_MIN_ZOOM;
- }
- }
- }
-
- LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
- camera_offset_dir.normalize();
- mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
- }
-
- startCameraAnimation();
+ // 0.f -> camera zoomed all the way out
+ // 1.f -> camera zoomed all the way in
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ mHUDTargetZoom = fraction;
+ }
+ else if (isDisableCameraConstraints())
+ {
+ mCameraZoomFraction = fraction;
+ }
+ else if (mFocusOnAvatar && cameraThirdPerson())
+ {
+ mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
+ }
+ else if (cameraCustomizeAvatar())
+ {
+ LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
+ camera_offset_dir.normalize();
+ mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM);
+ }
+ else
+ {
+ F32 min_zoom = LAND_MIN_ZOOM;
+ F32 max_zoom = getCameraMaxZoomDistance();
+
+ if (mFocusObject.notNull())
+ {
+ if (mFocusObject.notNull())
+ {
+ if (mFocusObject->isAvatar())
+ {
+ min_zoom = AVATAR_MIN_ZOOM;
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
+ }
+ }
+ }
+
+ LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
+ camera_offset_dir.normalize();
+ mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
+ }
+
+ startCameraAnimation();
}
F32 LLAgentCamera::getAgentHUDTargetZoom()
{
- static LLCachedControl<F32> hud_scale_factor(gSavedSettings, "HUDScaleFactor");
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor;
+ static LLCachedControl<F32> hud_scale_factor(gSavedSettings, "HUDScaleFactor");
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor;
}
//-----------------------------------------------------------------------------
@@ -852,22 +852,22 @@ F32 LLAgentCamera::getAgentHUDTargetZoom()
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraOrbitAround(const F32 radians)
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- // do nothing for hud selection
- }
- else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
- {
- gAgent.yaw(radians);
- }
- else
- {
- mOrbitAroundRadians += radians;
- mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
-
- cameraZoomIn(1.f);
- }
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ // do nothing for hud selection
+ }
+ else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
+ {
+ gAgent.yaw(radians);
+ }
+ else
+ {
+ mOrbitAroundRadians += radians;
+ mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
+
+ cameraZoomIn(1.f);
+ }
}
@@ -876,51 +876,51 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians)
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraOrbitOver(const F32 angle)
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- // do nothing for hud selection
- }
- else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
- {
- gAgent.pitch(angle);
- }
- else
- {
- LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
- camera_offset_unit.normalize();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ // do nothing for hud selection
+ }
+ else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+ {
+ gAgent.pitch(angle);
+ }
+ else
+ {
+ LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
+ camera_offset_unit.normalize();
- F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() );
+ F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() );
- LLVector3d left_axis;
- left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
- F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
- mOrbitOverAngle += angle_from_up - new_angle;
- mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
+ LLVector3d left_axis;
+ left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+ F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
+ mOrbitOverAngle += angle_from_up - new_angle;
+ mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
- cameraZoomIn(1.f);
- }
+ cameraZoomIn(1.f);
+ }
}
void LLAgentCamera::resetCameraOrbit()
{
- LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
- camera_offset_unit.normalize();
-
- LLVector3d left_axis;
- left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
- mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis);
+ LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
+ camera_offset_unit.normalize();
- mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f);
+ LLVector3d left_axis;
+ left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+ mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis);
+
+ mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f);
- cameraZoomIn(1.f);
- resetOrbitDiff();
+ cameraZoomIn(1.f);
+ resetOrbitDiff();
}
void LLAgentCamera::resetOrbitDiff()
{
- mOrbitAroundRadians = 0;
- mOrbitOverAngle = 0;
+ mOrbitAroundRadians = 0;
+ mOrbitOverAngle = 0;
}
//-----------------------------------------------------------------------------
@@ -928,56 +928,56 @@ void LLAgentCamera::resetOrbitDiff()
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraZoomIn(const F32 fraction)
{
- if (gDisconnected)
- {
- return;
- }
+ if (gDisconnected)
+ {
+ return;
+ }
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- // just update hud zoom level
- mHUDTargetZoom /= fraction;
- return;
- }
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ // just update hud zoom level
+ mHUDTargetZoom /= fraction;
+ return;
+ }
- LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
- F32 current_distance = (F32)camera_offset_unit.normalize();
- F32 new_distance = current_distance * fraction;
+ LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
+ F32 current_distance = (F32)camera_offset_unit.normalize();
+ F32 new_distance = current_distance * fraction;
- // Unless camera is unlocked
- if (!isDisableCameraConstraints())
- {
- F32 min_zoom = LAND_MIN_ZOOM;
+ // Unless camera is unlocked
+ if (!isDisableCameraConstraints())
+ {
+ F32 min_zoom = LAND_MIN_ZOOM;
- // Don't move through focus point
- if (mFocusObject)
- {
- LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
-
- if (mFocusObject->isAvatar())
- {
- calcCameraMinDistance(min_zoom);
- }
- else
- {
- min_zoom = OBJECT_MIN_ZOOM;
- }
- }
+ // Don't move through focus point
+ if (mFocusObject)
+ {
+ LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
- new_distance = llmax(new_distance, min_zoom);
+ if (mFocusObject->isAvatar())
+ {
+ calcCameraMinDistance(min_zoom);
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
+ }
+ }
- F32 max_distance = getCameraMaxZoomDistance();
- max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
- new_distance = llmin(new_distance, max_distance);
+ new_distance = llmax(new_distance, min_zoom);
- if (cameraCustomizeAvatar())
- {
- new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
- }
- }
+ F32 max_distance = getCameraMaxZoomDistance();
+ max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
+ new_distance = llmin(new_distance, max_distance);
+
+ if (cameraCustomizeAvatar())
+ {
+ new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
+ }
+ }
- mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
+ mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
}
//-----------------------------------------------------------------------------
@@ -985,62 +985,62 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraOrbitIn(const F32 meters)
{
- if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
- {
- F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
-
- mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
-
- if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f)
- {
- // No need to animate, camera is already there.
- changeCameraToMouselook(FALSE);
- }
-
- if (!isDisableCameraConstraints())
- {
- mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
- }
- }
- else
- {
- LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
- F32 current_distance = (F32)camera_offset_unit.normalize();
- F32 new_distance = current_distance - meters;
-
- // Unless camera is unlocked
- if (!isDisableCameraConstraints())
- {
- F32 min_zoom = LAND_MIN_ZOOM;
-
- // Don't move through focus point
- if (mFocusObject.notNull())
- {
- if (mFocusObject->isAvatar())
- {
- min_zoom = AVATAR_MIN_ZOOM;
- }
- else
- {
- min_zoom = OBJECT_MIN_ZOOM;
- }
- }
-
- new_distance = llmax(new_distance, min_zoom);
-
- F32 max_distance = getCameraMaxZoomDistance();
- new_distance = llmin(new_distance, max_distance);
-
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
- {
- new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
- }
- }
-
- // Compute new camera offset
- mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
- cameraZoomIn(1.f);
- }
+ if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+ {
+ F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
+
+ mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
+
+ if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f)
+ {
+ // No need to animate, camera is already there.
+ changeCameraToMouselook(FALSE);
+ }
+
+ if (!isDisableCameraConstraints())
+ {
+ mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
+ }
+ }
+ else
+ {
+ LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
+ F32 current_distance = (F32)camera_offset_unit.normalize();
+ F32 new_distance = current_distance - meters;
+
+ // Unless camera is unlocked
+ if (!isDisableCameraConstraints())
+ {
+ F32 min_zoom = LAND_MIN_ZOOM;
+
+ // Don't move through focus point
+ if (mFocusObject.notNull())
+ {
+ if (mFocusObject->isAvatar())
+ {
+ min_zoom = AVATAR_MIN_ZOOM;
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
+ }
+ }
+
+ new_distance = llmax(new_distance, min_zoom);
+
+ F32 max_distance = getCameraMaxZoomDistance();
+ new_distance = llmin(new_distance, max_distance);
+
+ if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
+ {
+ new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
+ }
+ }
+
+ // Compute new camera offset
+ mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
+ cameraZoomIn(1.f);
+ }
}
//-----------------------------------------------------------------------------
@@ -1048,17 +1048,17 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraPanIn(F32 meters)
{
- LLVector3d at_axis;
- at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
+ LLVector3d at_axis;
+ at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
- mPanFocusDiff += meters * at_axis;
+ mPanFocusDiff += meters * at_axis;
- mFocusTargetGlobal += meters * at_axis;
- mFocusGlobal = mFocusTargetGlobal;
- // don't enforce zoom constraints as this is the only way for users to get past them easily
- updateFocusOffset();
- // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
- mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+ mFocusTargetGlobal += meters * at_axis;
+ mFocusGlobal = mFocusTargetGlobal;
+ // don't enforce zoom constraints as this is the only way for users to get past them easily
+ updateFocusOffset();
+ // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+ mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
}
//-----------------------------------------------------------------------------
@@ -1066,21 +1066,21 @@ void LLAgentCamera::cameraPanIn(F32 meters)
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraPanLeft(F32 meters)
{
- LLVector3d left_axis;
- left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+ LLVector3d left_axis;
+ left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
- mPanFocusDiff += meters * left_axis;
+ mPanFocusDiff += meters * left_axis;
- mFocusTargetGlobal += meters * left_axis;
- mFocusGlobal = mFocusTargetGlobal;
+ mFocusTargetGlobal += meters * left_axis;
+ mFocusGlobal = mFocusTargetGlobal;
- // disable smoothing for camera pan, which causes some residents unhappiness
- mCameraSmoothingStop = true;
-
- cameraZoomIn(1.f);
- updateFocusOffset();
- // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx
- mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+ // disable smoothing for camera pan, which causes some residents unhappiness
+ mCameraSmoothingStop = true;
+
+ cameraZoomIn(1.f);
+ updateFocusOffset();
+ // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx
+ mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
}
//-----------------------------------------------------------------------------
@@ -1088,41 +1088,41 @@ void LLAgentCamera::cameraPanLeft(F32 meters)
//-----------------------------------------------------------------------------
void LLAgentCamera::cameraPanUp(F32 meters)
{
- LLVector3d up_axis;
- up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
+ LLVector3d up_axis;
+ up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
- mPanFocusDiff += meters * up_axis;
+ mPanFocusDiff += meters * up_axis;
- mFocusTargetGlobal += meters * up_axis;
- mFocusGlobal = mFocusTargetGlobal;
+ mFocusTargetGlobal += meters * up_axis;
+ mFocusGlobal = mFocusTargetGlobal;
- // disable smoothing for camera pan, which causes some residents unhappiness
- mCameraSmoothingStop = true;
+ // disable smoothing for camera pan, which causes some residents unhappiness
+ mCameraSmoothingStop = true;
- cameraZoomIn(1.f);
- updateFocusOffset();
- // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
- mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+ cameraZoomIn(1.f);
+ updateFocusOffset();
+ // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+ mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
}
void LLAgentCamera::resetCameraPan()
{
- mFocusTargetGlobal -= mPanFocusDiff;
+ mFocusTargetGlobal -= mPanFocusDiff;
- mFocusGlobal = mFocusTargetGlobal;
- mCameraSmoothingStop = true;
+ mFocusGlobal = mFocusTargetGlobal;
+ mCameraSmoothingStop = true;
- cameraZoomIn(1.f);
- updateFocusOffset();
+ cameraZoomIn(1.f);
+ updateFocusOffset();
- mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+ mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
- resetPanDiff();
+ resetPanDiff();
}
void LLAgentCamera::resetPanDiff()
{
- mPanFocusDiff.clear();
+ mPanFocusDiff.clear();
}
//-----------------------------------------------------------------------------
@@ -1130,67 +1130,67 @@ void LLAgentCamera::resetPanDiff()
//-----------------------------------------------------------------------------
void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
{
- static LLVector3 last_at_axis;
-
- if (!isAgentAvatarValid()) return;
-
- LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
- LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
-
- if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f
- && (root_at * last_at_axis > 0.95f))
- {
- LLVector3 vel = gAgentAvatarp->getVelocity();
- if (vel.magVecSquared() > 4.f)
- {
- setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, vel * av_inv_rot);
- }
- else
- {
- // *FIX: rotate mframeagent by sit object's rotation?
- LLQuaternion look_rotation = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation
- LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
- setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, look_offset);
- }
- last_at_axis = root_at;
- return;
- }
-
- last_at_axis = root_at;
-
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
- {
- setLookAt(LOOKAT_TARGET_NONE, gAgentAvatarp, LLVector3(-2.f, 0.f, 0.f));
- }
- else
- {
- // Move head based on cursor position
- ELookAtType lookAtType = LOOKAT_TARGET_NONE;
- LLVector3 headLookAxis;
- LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
-
- if (cameraMouselook())
- {
- lookAtType = LOOKAT_TARGET_MOUSELOOK;
- }
- else if (cameraThirdPerson())
- {
- // range from -.5 to .5
- F32 x_from_center =
- ((F32) mouse_x / (F32) gViewerWindow->getWorldViewWidthScaled() ) - 0.5f;
- F32 y_from_center =
- ((F32) mouse_y / (F32) gViewerWindow->getWorldViewHeightScaled() ) - 0.5f;
-
- frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
- frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
- lookAtType = LOOKAT_TARGET_FREELOOK;
- }
-
- headLookAxis = frameCamera.getAtAxis();
- // RN: we use world-space offset for mouselook and freelook
- //headLookAxis = headLookAxis * av_inv_rot;
- setLookAt(lookAtType, gAgentAvatarp, headLookAxis);
- }
+ static LLVector3 last_at_axis;
+
+ if (!isAgentAvatarValid()) return;
+
+ LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
+ LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
+
+ if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f
+ && (root_at * last_at_axis > 0.95f))
+ {
+ LLVector3 vel = gAgentAvatarp->getVelocity();
+ if (vel.magVecSquared() > 4.f)
+ {
+ setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, vel * av_inv_rot);
+ }
+ else
+ {
+ // *FIX: rotate mframeagent by sit object's rotation?
+ LLQuaternion look_rotation = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation
+ LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
+ setLookAt(LOOKAT_TARGET_IDLE, gAgentAvatarp, look_offset);
+ }
+ last_at_axis = root_at;
+ return;
+ }
+
+ last_at_axis = root_at;
+
+ if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
+ {
+ setLookAt(LOOKAT_TARGET_NONE, gAgentAvatarp, LLVector3(-2.f, 0.f, 0.f));
+ }
+ else
+ {
+ // Move head based on cursor position
+ ELookAtType lookAtType = LOOKAT_TARGET_NONE;
+ LLVector3 headLookAxis;
+ LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+
+ if (cameraMouselook())
+ {
+ lookAtType = LOOKAT_TARGET_MOUSELOOK;
+ }
+ else if (cameraThirdPerson())
+ {
+ // range from -.5 to .5
+ F32 x_from_center =
+ ((F32) mouse_x / (F32) gViewerWindow->getWorldViewWidthScaled() ) - 0.5f;
+ F32 y_from_center =
+ ((F32) mouse_y / (F32) gViewerWindow->getWorldViewHeightScaled() ) - 0.5f;
+
+ frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
+ frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
+ lookAtType = LOOKAT_TARGET_FREELOOK;
+ }
+
+ headLookAxis = frameCamera.getAtAxis();
+ // RN: we use world-space offset for mouselook and freelook
+ //headLookAxis = headLookAxis * av_inv_rot;
+ setLookAt(lookAtType, gAgentAvatarp, headLookAxis);
+ }
}
static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera");
@@ -1202,377 +1202,377 @@ extern BOOL gCubeSnapshot;
//-----------------------------------------------------------------------------
void LLAgentCamera::updateCamera()
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
+ LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
if (gCubeSnapshot)
{
return;
}
- // - changed camera_skyward to the new global "mCameraUpVector"
- mCameraUpVector = LLVector3::z_axis;
- //LLVector3 camera_skyward(0.f, 0.f, 1.f);
-
- U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
-
- validateFocusObject();
-
- if (isAgentAvatarValid() &&
- gAgentAvatarp->isSitting() &&
- camera_mode == CAMERA_MODE_MOUSELOOK)
- {
- //changed camera_skyward to the new global "mCameraUpVector"
- mCameraUpVector = mCameraUpVector * gAgentAvatarp->getRenderRotation();
- }
-
- if (cameraThirdPerson() && (mFocusOnAvatar || mAllowChangeToFollow) && LLFollowCamMgr::getInstance()->getActiveFollowCamParams())
- {
- mAllowChangeToFollow = FALSE;
- mFocusOnAvatar = TRUE;
- changeCameraToFollow();
- }
-
- //NOTE - this needs to be integrated into a general upVector system here within llAgent.
- if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
- {
- mCameraUpVector = mFollowCam.getUpVector();
- }
-
- if (mSitCameraEnabled)
- {
- if (mSitCameraReferenceObject->isDead())
- {
- setSitCamera(LLUUID::null);
- }
- }
-
- // Update UI with our camera inputs
- LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
- if (camera_floater)
- {
- camera_floater->mRotate->setToggleState(gAgentCamera.getOrbitRightKey() > 0.f, // left
- gAgentCamera.getOrbitUpKey() > 0.f, // top
- gAgentCamera.getOrbitLeftKey() > 0.f, // right
- gAgentCamera.getOrbitDownKey() > 0.f); // bottom
-
- camera_floater->mTrack->setToggleState(gAgentCamera.getPanLeftKey() > 0.f, // left
- gAgentCamera.getPanUpKey() > 0.f, // top
- gAgentCamera.getPanRightKey() > 0.f, // right
- gAgentCamera.getPanDownKey() > 0.f); // bottom
- }
-
- // Handle camera movement based on keyboard.
- const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second
- const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second
- const F32 PAN_RATE = 5.f; // meters per second
-
- if (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey())
- {
- F32 input_rate = gAgentCamera.getOrbitUpKey() - gAgentCamera.getOrbitDownKey();
- cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped );
- }
-
- if (gAgentCamera.getOrbitLeftKey() || gAgentCamera.getOrbitRightKey())
- {
- F32 input_rate = gAgentCamera.getOrbitLeftKey() - gAgentCamera.getOrbitRightKey();
- cameraOrbitAround(input_rate * ORBIT_AROUND_RATE / gFPSClamped);
- }
-
- if (gAgentCamera.getOrbitInKey() || gAgentCamera.getOrbitOutKey())
- {
- F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey();
-
- LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal();
- F32 distance_to_focus = (F32)to_focus.magVec();
- // Move at distance (in meters) meters per second
- cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
- }
-
- if (gAgentCamera.getPanInKey() || gAgentCamera.getPanOutKey())
- {
- F32 input_rate = gAgentCamera.getPanInKey() - gAgentCamera.getPanOutKey();
- cameraPanIn(input_rate * PAN_RATE / gFPSClamped);
- }
-
- if (gAgentCamera.getPanRightKey() || gAgentCamera.getPanLeftKey())
- {
- F32 input_rate = gAgentCamera.getPanRightKey() - gAgentCamera.getPanLeftKey();
- cameraPanLeft(input_rate * -PAN_RATE / gFPSClamped );
- }
-
- if (gAgentCamera.getPanUpKey() || gAgentCamera.getPanDownKey())
- {
- F32 input_rate = gAgentCamera.getPanUpKey() - gAgentCamera.getPanDownKey();
- cameraPanUp(input_rate * PAN_RATE / gFPSClamped );
- }
-
- // Clear camera keyboard keys.
- gAgentCamera.clearOrbitKeys();
- gAgentCamera.clearPanKeys();
-
- // lerp camera focus offset
- mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
-
- if ( mCameraMode == CAMERA_MODE_FOLLOW )
- {
- if (isAgentAvatarValid())
- {
- //--------------------------------------------------------------------------------
- // this is where the avatar's position and rotation are given to followCam, and
- // where it is updated. All three of its attributes are updated: (1) position,
- // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
- //--------------------------------------------------------------------------------
- // *TODO: use combined rotation of frameagent and sit object
- LLQuaternion avatarRotationForFollowCam = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion();
-
- LLFollowCamParams* current_cam = LLFollowCamMgr::getInstance()->getActiveFollowCamParams();
- if (current_cam)
- {
- mFollowCam.copyParams(*current_cam);
- mFollowCam.setSubjectPositionAndRotation( gAgentAvatarp->getRenderPosition(), avatarRotationForFollowCam );
- mFollowCam.update();
- LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
- }
- else
- {
- changeCameraToThirdPerson(TRUE);
- }
- }
- }
-
- BOOL hit_limit;
- LLVector3d camera_pos_global;
- LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit);
- mCameraVirtualPositionAgent = gAgent.getPosAgentFromGlobal(camera_target_global);
- LLVector3d focus_target_global = calcFocusPositionTargetGlobal();
-
- // perform field of view correction
- mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
- camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
-
- gAgent.setShowAvatar(TRUE); // can see avatar by default
-
- // Adjust position for animation
- if (mCameraAnimating)
- {
- F32 time = mAnimationTimer.getElapsedTimeF32();
-
- // yet another instance of critically damped motion, hooray!
- // F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE);
-
- // linear interpolation
- F32 fraction_of_animation = time / mAnimationDuration;
-
- BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK;
- BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK;
- F32 fraction_animation_to_skip;
-
- if (mAnimationCameraStartGlobal == camera_target_global)
- {
- fraction_animation_to_skip = 0.f;
- }
- else
- {
- LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global;
- fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec();
- }
- F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f;
- F32 animation_finish_fraction = (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f;
-
- if (fraction_of_animation < animation_finish_fraction)
- {
- if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
- {
- gAgent.setShowAvatar(FALSE);
- }
-
- // ...adjust position for animation
- F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation);
- camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation);
- mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation);
- }
- else
- {
- // ...animation complete
- mCameraAnimating = FALSE;
-
- camera_pos_global = camera_target_global;
- mFocusGlobal = focus_target_global;
-
- gAgent.endAnimationUpdateUI();
- gAgent.setShowAvatar(TRUE);
- }
-
- if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK))
- {
- gAgentAvatarp->updateAttachmentVisibility(mCameraMode);
- }
- }
- else
- {
- camera_pos_global = camera_target_global;
- mFocusGlobal = focus_target_global;
- gAgent.setShowAvatar(TRUE);
- }
-
- // smoothing
- if (TRUE)
- {
- LLVector3d agent_pos = gAgent.getPositionGlobal();
- LLVector3d camera_pos_agent = camera_pos_global - agent_pos;
- // Sitting on what you're manipulating can cause camera jitter with smoothing.
- // This turns off smoothing while editing. -MG
- bool in_build_mode = LLToolMgr::getInstance()->inBuildMode();
- mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode;
-
- if (cameraThirdPerson() && !mCameraSmoothingStop)
- {
- const F32 SMOOTHING_HALF_LIFE = 0.02f;
-
- F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
-
- if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode
- {
- // for avatar-relative focus, we smooth in avatar space -
- // the avatar moves too jerkily w/r/t global space to smooth there.
-
- LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
- if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
- {
- camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
- camera_pos_global = camera_pos_agent + agent_pos;
- }
- }
- else
- {
- LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
- if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
- {
- camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
- }
- }
- }
-
- mCameraSmoothingLastPositionGlobal = camera_pos_global;
- mCameraSmoothingLastPositionAgent = camera_pos_agent;
- mCameraSmoothingStop = false;
- }
-
-
- mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE));
-
-// LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL;
-
- LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal);
-
- mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global);
-
- // Move the camera
-
- LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
- //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
-
- // Change FOV
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
-
- // follow camera when in customize mode
- if (cameraCustomizeAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
- }
-
- // update the travel distance stat
- // this isn't directly related to the camera
- // but this seemed like the best place to do this
- LLVector3d global_pos = gAgent.getPositionGlobal();
- if (!gAgent.getLastPositionGlobal().isExactlyZero())
- {
- LLVector3d delta = global_pos - gAgent.getLastPositionGlobal();
- gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec());
- }
- gAgent.setLastPositionGlobal(global_pos);
-
- if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook())
- {
- LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() +
- LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
- LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
- LLVector3 diff = mCameraPositionAgent - head_pos;
- diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
-
- LLJoint* torso_joint = gAgentAvatarp->mTorsop;
- LLJoint* chest_joint = gAgentAvatarp->mChestp;
- LLVector3 torso_scale = torso_joint->getScale();
- LLVector3 chest_scale = chest_joint->getScale();
-
- // shorten avatar skeleton to avoid foot interpenetration
- if (!gAgentAvatarp->mInAir)
- {
- LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
- F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
- F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
- torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
-
- LLJoint* neck_joint = gAgentAvatarp->mNeckp;
- LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
- scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
- chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
- diff.mV[VZ] = 0.f;
- }
-
- // SL-315
- gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
-
- gAgentAvatarp->mRoot->updateWorldMatrixChildren();
-
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = attachment_iter->get();
- if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
- {
- // clear any existing "early" movements of attachment
- attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
- gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
- attached_object->updateText();
- }
- }
- }
-
- torso_joint->setScale(torso_scale);
- chest_joint->setScale(chest_scale);
- }
+ // - changed camera_skyward to the new global "mCameraUpVector"
+ mCameraUpVector = LLVector3::z_axis;
+ //LLVector3 camera_skyward(0.f, 0.f, 1.f);
+
+ U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
+
+ validateFocusObject();
+
+ if (isAgentAvatarValid() &&
+ gAgentAvatarp->isSitting() &&
+ camera_mode == CAMERA_MODE_MOUSELOOK)
+ {
+ //changed camera_skyward to the new global "mCameraUpVector"
+ mCameraUpVector = mCameraUpVector * gAgentAvatarp->getRenderRotation();
+ }
+
+ if (cameraThirdPerson() && (mFocusOnAvatar || mAllowChangeToFollow) && LLFollowCamMgr::getInstance()->getActiveFollowCamParams())
+ {
+ mAllowChangeToFollow = FALSE;
+ mFocusOnAvatar = TRUE;
+ changeCameraToFollow();
+ }
+
+ //NOTE - this needs to be integrated into a general upVector system here within llAgent.
+ if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+ {
+ mCameraUpVector = mFollowCam.getUpVector();
+ }
+
+ if (mSitCameraEnabled)
+ {
+ if (mSitCameraReferenceObject->isDead())
+ {
+ setSitCamera(LLUUID::null);
+ }
+ }
+
+ // Update UI with our camera inputs
+ LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
+ if (camera_floater)
+ {
+ camera_floater->mRotate->setToggleState(gAgentCamera.getOrbitRightKey() > 0.f, // left
+ gAgentCamera.getOrbitUpKey() > 0.f, // top
+ gAgentCamera.getOrbitLeftKey() > 0.f, // right
+ gAgentCamera.getOrbitDownKey() > 0.f); // bottom
+
+ camera_floater->mTrack->setToggleState(gAgentCamera.getPanLeftKey() > 0.f, // left
+ gAgentCamera.getPanUpKey() > 0.f, // top
+ gAgentCamera.getPanRightKey() > 0.f, // right
+ gAgentCamera.getPanDownKey() > 0.f); // bottom
+ }
+
+ // Handle camera movement based on keyboard.
+ const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second
+ const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second
+ const F32 PAN_RATE = 5.f; // meters per second
+
+ if (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey())
+ {
+ F32 input_rate = gAgentCamera.getOrbitUpKey() - gAgentCamera.getOrbitDownKey();
+ cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped );
+ }
+
+ if (gAgentCamera.getOrbitLeftKey() || gAgentCamera.getOrbitRightKey())
+ {
+ F32 input_rate = gAgentCamera.getOrbitLeftKey() - gAgentCamera.getOrbitRightKey();
+ cameraOrbitAround(input_rate * ORBIT_AROUND_RATE / gFPSClamped);
+ }
+
+ if (gAgentCamera.getOrbitInKey() || gAgentCamera.getOrbitOutKey())
+ {
+ F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey();
+
+ LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal();
+ F32 distance_to_focus = (F32)to_focus.magVec();
+ // Move at distance (in meters) meters per second
+ cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
+ }
+
+ if (gAgentCamera.getPanInKey() || gAgentCamera.getPanOutKey())
+ {
+ F32 input_rate = gAgentCamera.getPanInKey() - gAgentCamera.getPanOutKey();
+ cameraPanIn(input_rate * PAN_RATE / gFPSClamped);
+ }
+
+ if (gAgentCamera.getPanRightKey() || gAgentCamera.getPanLeftKey())
+ {
+ F32 input_rate = gAgentCamera.getPanRightKey() - gAgentCamera.getPanLeftKey();
+ cameraPanLeft(input_rate * -PAN_RATE / gFPSClamped );
+ }
+
+ if (gAgentCamera.getPanUpKey() || gAgentCamera.getPanDownKey())
+ {
+ F32 input_rate = gAgentCamera.getPanUpKey() - gAgentCamera.getPanDownKey();
+ cameraPanUp(input_rate * PAN_RATE / gFPSClamped );
+ }
+
+ // Clear camera keyboard keys.
+ gAgentCamera.clearOrbitKeys();
+ gAgentCamera.clearPanKeys();
+
+ // lerp camera focus offset
+ mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
+
+ if ( mCameraMode == CAMERA_MODE_FOLLOW )
+ {
+ if (isAgentAvatarValid())
+ {
+ //--------------------------------------------------------------------------------
+ // this is where the avatar's position and rotation are given to followCam, and
+ // where it is updated. All three of its attributes are updated: (1) position,
+ // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
+ //--------------------------------------------------------------------------------
+ // *TODO: use combined rotation of frameagent and sit object
+ LLQuaternion avatarRotationForFollowCam = gAgentAvatarp->isSitting() ? gAgentAvatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion();
+
+ LLFollowCamParams* current_cam = LLFollowCamMgr::getInstance()->getActiveFollowCamParams();
+ if (current_cam)
+ {
+ mFollowCam.copyParams(*current_cam);
+ mFollowCam.setSubjectPositionAndRotation( gAgentAvatarp->getRenderPosition(), avatarRotationForFollowCam );
+ mFollowCam.update();
+ LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
+ }
+ else
+ {
+ changeCameraToThirdPerson(TRUE);
+ }
+ }
+ }
+
+ BOOL hit_limit;
+ LLVector3d camera_pos_global;
+ LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit);
+ mCameraVirtualPositionAgent = gAgent.getPosAgentFromGlobal(camera_target_global);
+ LLVector3d focus_target_global = calcFocusPositionTargetGlobal();
+
+ // perform field of view correction
+ mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
+ camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
+
+ gAgent.setShowAvatar(TRUE); // can see avatar by default
+
+ // Adjust position for animation
+ if (mCameraAnimating)
+ {
+ F32 time = mAnimationTimer.getElapsedTimeF32();
+
+ // yet another instance of critically damped motion, hooray!
+ // F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE);
+
+ // linear interpolation
+ F32 fraction_of_animation = time / mAnimationDuration;
+
+ BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK;
+ BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK;
+ F32 fraction_animation_to_skip;
+
+ if (mAnimationCameraStartGlobal == camera_target_global)
+ {
+ fraction_animation_to_skip = 0.f;
+ }
+ else
+ {
+ LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global;
+ fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec();
+ }
+ F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f;
+ F32 animation_finish_fraction = (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f;
+
+ if (fraction_of_animation < animation_finish_fraction)
+ {
+ if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
+ {
+ gAgent.setShowAvatar(FALSE);
+ }
+
+ // ...adjust position for animation
+ F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation);
+ camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation);
+ mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation);
+ }
+ else
+ {
+ // ...animation complete
+ mCameraAnimating = FALSE;
+
+ camera_pos_global = camera_target_global;
+ mFocusGlobal = focus_target_global;
+
+ gAgent.endAnimationUpdateUI();
+ gAgent.setShowAvatar(TRUE);
+ }
+
+ if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK))
+ {
+ gAgentAvatarp->updateAttachmentVisibility(mCameraMode);
+ }
+ }
+ else
+ {
+ camera_pos_global = camera_target_global;
+ mFocusGlobal = focus_target_global;
+ gAgent.setShowAvatar(TRUE);
+ }
+
+ // smoothing
+ if (TRUE)
+ {
+ LLVector3d agent_pos = gAgent.getPositionGlobal();
+ LLVector3d camera_pos_agent = camera_pos_global - agent_pos;
+ // Sitting on what you're manipulating can cause camera jitter with smoothing.
+ // This turns off smoothing while editing. -MG
+ bool in_build_mode = LLToolMgr::getInstance()->inBuildMode();
+ mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode;
+
+ if (cameraThirdPerson() && !mCameraSmoothingStop)
+ {
+ const F32 SMOOTHING_HALF_LIFE = 0.02f;
+
+ F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
+
+ if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode
+ {
+ // for avatar-relative focus, we smooth in avatar space -
+ // the avatar moves too jerkily w/r/t global space to smooth there.
+
+ LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
+ if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
+ {
+ camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
+ camera_pos_global = camera_pos_agent + agent_pos;
+ }
+ }
+ else
+ {
+ LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
+ if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
+ {
+ camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
+ }
+ }
+ }
+
+ mCameraSmoothingLastPositionGlobal = camera_pos_global;
+ mCameraSmoothingLastPositionAgent = camera_pos_agent;
+ mCameraSmoothingStop = false;
+ }
+
+
+ mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE));
+
+// LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL;
+
+ LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal);
+
+ mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global);
+
+ // Move the camera
+
+ LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
+ //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
+
+ // Change FOV
+ LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
+
+ // follow camera when in customize mode
+ if (cameraCustomizeAvatar())
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
+ }
+
+ // update the travel distance stat
+ // this isn't directly related to the camera
+ // but this seemed like the best place to do this
+ LLVector3d global_pos = gAgent.getPositionGlobal();
+ if (!gAgent.getLastPositionGlobal().isExactlyZero())
+ {
+ LLVector3d delta = global_pos - gAgent.getLastPositionGlobal();
+ gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec());
+ }
+ gAgent.setLastPositionGlobal(global_pos);
+
+ if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook())
+ {
+ LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() +
+ LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
+ LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
+ LLVector3 diff = mCameraPositionAgent - head_pos;
+ diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
+
+ LLJoint* torso_joint = gAgentAvatarp->mTorsop;
+ LLJoint* chest_joint = gAgentAvatarp->mChestp;
+ LLVector3 torso_scale = torso_joint->getScale();
+ LLVector3 chest_scale = chest_joint->getScale();
+
+ // shorten avatar skeleton to avoid foot interpenetration
+ if (!gAgentAvatarp->mInAir)
+ {
+ LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
+ F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
+ F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
+ torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
+
+ LLJoint* neck_joint = gAgentAvatarp->mNeckp;
+ LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
+ scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
+ chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
+ diff.mV[VZ] = 0.f;
+ }
+
+ // SL-315
+ gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
+
+ gAgentAvatarp->mRoot->updateWorldMatrixChildren();
+
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
+ {
+ // clear any existing "early" movements of attachment
+ attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
+ gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
+ attached_object->updateText();
+ }
+ }
+ }
+
+ torso_joint->setScale(torso_scale);
+ chest_joint->setScale(chest_scale);
+ }
}
void LLAgentCamera::updateLastCamera()
{
- mLastCameraMode = mCameraMode;
+ mLastCameraMode = mCameraMode;
}
void LLAgentCamera::updateFocusOffset()
{
- validateFocusObject();
- if (mFocusObject.notNull())
- {
- LLVector3d obj_pos = gAgent.getPosGlobalFromAgent(mFocusObject->getRenderPosition());
- mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
- }
+ validateFocusObject();
+ if (mFocusObject.notNull())
+ {
+ LLVector3d obj_pos = gAgent.getPosGlobalFromAgent(mFocusObject->getRenderPosition());
+ mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
+ }
}
void LLAgentCamera::validateFocusObject()
{
- if (mFocusObject.notNull() &&
- mFocusObject->isDead())
- {
- mFocusObjectOffset.clearVec();
- clearFocusObject();
- mCameraFOVZoomFactor = 0.f;
- }
+ if (mFocusObject.notNull() &&
+ mFocusObject->isDead())
+ {
+ mFocusObjectOffset.clearVec();
+ clearFocusObject();
+ mCameraFOVZoomFactor = 0.f;
+ }
}
//-----------------------------------------------------------------------------
@@ -1580,124 +1580,124 @@ void LLAgentCamera::validateFocusObject()
//-----------------------------------------------------------------------------
LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
{
- if (mFocusObject.notNull() && mFocusObject->isDead())
- {
- clearFocusObject();
- }
-
- if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
- {
- mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
- return mFocusTargetGlobal;
- }
- else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- LLVector3d at_axis(1.0, 0.0, 0.0);
- LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
- {
- LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot();
- if (!root_object->flagCameraDecoupled())
- {
- agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
- }
- }
- at_axis = at_axis * agent_rot;
- mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
- return mFocusTargetGlobal;
- }
- else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
- {
- if (mFocusOnAvatar)
- {
- LLVector3 focus_target = isAgentAvatarValid()
- ? gAgentAvatarp->mHeadp->getWorldPosition()
- : gAgent.getPositionAgent();
- LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
- mFocusTargetGlobal = focus_target_global;
- }
- return mFocusTargetGlobal;
- }
- else if (!mFocusOnAvatar)
- {
- if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
- {
- LLDrawable* drawablep = mFocusObject->mDrawable;
-
- if (mTrackFocusObject &&
- drawablep &&
- drawablep->isActive())
- {
- if (!mFocusObject->isAvatar())
- {
- if (mFocusObject->isSelected())
- {
- gPipeline.updateMoveNormalAsync(drawablep);
- }
- else
- {
- if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
- {
- gPipeline.updateMoveNormalAsync(drawablep);
- }
- else
- {
- gPipeline.updateMoveDampedAsync(drawablep);
- }
- }
- }
- }
- // if not tracking object, update offset based on new object position
- else
- {
- updateFocusOffset();
- }
- LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
- mFocusTargetGlobal.setVec(gAgent.getPosGlobalFromAgent(focus_agent));
- }
- return mFocusTargetGlobal;
- }
- else if (mSitCameraEnabled && isAgentAvatarValid() && gAgentAvatarp->isSitting() && mSitCameraReferenceObject.notNull())
- {
- // sit camera
- LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
- LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
-
- LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
- return gAgent.getPosGlobalFromAgent(target_pos);
- }
- else
- {
- return gAgent.getPositionGlobal() + calcThirdPersonFocusOffset();
- }
+ if (mFocusObject.notNull() && mFocusObject->isDead())
+ {
+ clearFocusObject();
+ }
+
+ if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
+ {
+ mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
+ return mFocusTargetGlobal;
+ }
+ else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ LLVector3d at_axis(1.0, 0.0, 0.0);
+ LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot();
+ if (!root_object->flagCameraDecoupled())
+ {
+ agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
+ }
+ }
+ at_axis = at_axis * agent_rot;
+ mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
+ return mFocusTargetGlobal;
+ }
+ else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
+ {
+ if (mFocusOnAvatar)
+ {
+ LLVector3 focus_target = isAgentAvatarValid()
+ ? gAgentAvatarp->mHeadp->getWorldPosition()
+ : gAgent.getPositionAgent();
+ LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+ mFocusTargetGlobal = focus_target_global;
+ }
+ return mFocusTargetGlobal;
+ }
+ else if (!mFocusOnAvatar)
+ {
+ if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
+ {
+ LLDrawable* drawablep = mFocusObject->mDrawable;
+
+ if (mTrackFocusObject &&
+ drawablep &&
+ drawablep->isActive())
+ {
+ if (!mFocusObject->isAvatar())
+ {
+ if (mFocusObject->isSelected())
+ {
+ gPipeline.updateMoveNormalAsync(drawablep);
+ }
+ else
+ {
+ if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
+ {
+ gPipeline.updateMoveNormalAsync(drawablep);
+ }
+ else
+ {
+ gPipeline.updateMoveDampedAsync(drawablep);
+ }
+ }
+ }
+ }
+ // if not tracking object, update offset based on new object position
+ else
+ {
+ updateFocusOffset();
+ }
+ LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
+ mFocusTargetGlobal.setVec(gAgent.getPosGlobalFromAgent(focus_agent));
+ }
+ return mFocusTargetGlobal;
+ }
+ else if (mSitCameraEnabled && isAgentAvatarValid() && gAgentAvatarp->isSitting() && mSitCameraReferenceObject.notNull())
+ {
+ // sit camera
+ LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
+ LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
+
+ LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
+ return gAgent.getPosGlobalFromAgent(target_pos);
+ }
+ else
+ {
+ return gAgent.getPositionGlobal() + calcThirdPersonFocusOffset();
+ }
}
LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
{
- // ...offset from avatar
- LLVector3d focus_offset;
- LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
- {
- agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
- }
+ // ...offset from avatar
+ LLVector3d focus_offset;
+ LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
+ }
static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d());
- return focus_offset_initial * agent_rot;
+ return focus_offset_initial * agent_rot;
}
void LLAgentCamera::setupSitCamera()
{
- // agent frame entering this function is in world coordinates
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
- {
- LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
- // slam agent coordinate frame to proper parent local version
- LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis * ~parent_rot);
- }
+ // agent frame entering this function is in world coordinates
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
+ // slam agent coordinate frame to proper parent local version
+ LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis();
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis * ~parent_rot);
+ }
}
//-----------------------------------------------------------------------------
@@ -1705,7 +1705,7 @@ void LLAgentCamera::setupSitCamera()
//-----------------------------------------------------------------------------
const LLVector3 &LLAgentCamera::getCameraPositionAgent() const
{
- return LLViewerCamera::getInstance()->getOrigin();
+ return LLViewerCamera::getInstance()->getOrigin();
}
//-----------------------------------------------------------------------------
@@ -1713,39 +1713,39 @@ const LLVector3 &LLAgentCamera::getCameraPositionAgent() const
//-----------------------------------------------------------------------------
LLVector3d LLAgentCamera::getCameraPositionGlobal() const
{
- return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
+ return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
}
//-----------------------------------------------------------------------------
// calcCameraFOVZoomFactor()
//-----------------------------------------------------------------------------
-F32 LLAgentCamera::calcCameraFOVZoomFactor()
+F32 LLAgentCamera::calcCameraFOVZoomFactor()
{
- LLVector3 camera_offset_dir;
- camera_offset_dir.setVec(mCameraFocusOffset);
+ LLVector3 camera_offset_dir;
+ camera_offset_dir.setVec(mCameraFocusOffset);
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- return 0.f;
- }
- else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
- {
- // don't FOV zoom on mostly transparent objects
- F32 obj_min_dist = 0.f;
- calcCameraMinDistance(obj_min_dist);
- F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
+ if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ return 0.f;
+ }
+ else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
+ {
+ // don't FOV zoom on mostly transparent objects
+ F32 obj_min_dist = 0.f;
+ calcCameraMinDistance(obj_min_dist);
+ F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
- mFocusObjectDist = obj_min_dist - current_distance;
+ mFocusObjectDist = obj_min_dist - current_distance;
- F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
- return new_fov_zoom;
- }
- else // focusing on land or avatar
- {
- // keep old field of view until user changes focus explicitly
- return mCameraFOVZoomFactor;
- //return 0.f;
- }
+ F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
+ return new_fov_zoom;
+ }
+ else // focusing on land or avatar
+ {
+ // keep old field of view until user changes focus explicitly
+ return mCameraFOVZoomFactor;
+ //return 0.f;
+ }
}
//-----------------------------------------------------------------------------
@@ -1753,307 +1753,307 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor()
//-----------------------------------------------------------------------------
LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
{
- // Compute base camera position and look-at points.
- F32 camera_land_height;
- LLVector3d frame_center_global = !isAgentAvatarValid() ?
- gAgent.getPositionGlobal() :
- gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
-
- BOOL isConstrained = FALSE;
- LLVector3d head_offset;
- head_offset.setVec(mThirdPersonHeadOffset);
-
- LLVector3d camera_position_global;
-
- if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
- {
- camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
- }
- else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- if (!isAgentAvatarValid() || gAgentAvatarp->mDrawable.isNull())
- {
- LL_WARNS() << "Null avatar drawable!" << LL_ENDL;
- return LLVector3d::zero;
- }
-
- head_offset.clearVec();
- F32 fixup;
+ // Compute base camera position and look-at points.
+ F32 camera_land_height;
+ LLVector3d frame_center_global = !isAgentAvatarValid() ?
+ gAgent.getPositionGlobal() :
+ gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
+
+ BOOL isConstrained = FALSE;
+ LLVector3d head_offset;
+ head_offset.setVec(mThirdPersonHeadOffset);
+
+ LLVector3d camera_position_global;
+
+ if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
+ {
+ camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
+ }
+ else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ if (!isAgentAvatarValid() || gAgentAvatarp->mDrawable.isNull())
+ {
+ LL_WARNS() << "Null avatar drawable!" << LL_ENDL;
+ return LLVector3d::zero;
+ }
+
+ head_offset.clearVec();
+ F32 fixup;
if (gAgentAvatarp->hasPelvisFixup(fixup) && !gAgentAvatarp->isSitting())
- {
- head_offset[VZ] -= fixup;
- }
- if (gAgentAvatarp->isSitting())
- {
- head_offset.mdV[VZ] += 0.1;
- }
-
- if (gAgentAvatarp->isSitting() && gAgentAvatarp->getParent())
- {
- gAgentAvatarp->updateHeadOffset();
- head_offset.mdV[VX] += gAgentAvatarp->mHeadOffset.mV[VX];
- head_offset.mdV[VY] += gAgentAvatarp->mHeadOffset.mV[VY];
- head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
- const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix();
- camera_position_global = gAgent.getPosGlobalFromAgent
- ((gAgentAvatarp->getPosition()+
- LLVector3(head_offset)*gAgentAvatarp->getRotation()) * mat);
- }
- else
- {
- head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
- camera_position_global = gAgent.getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());//frame_center_global;
- head_offset = head_offset * gAgentAvatarp->getRenderRotation();
- camera_position_global = camera_position_global + head_offset;
- }
- }
- else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
- {
- LLVector3 local_camera_offset;
- F32 camera_distance = 0.f;
-
- if (mSitCameraEnabled
- && isAgentAvatarValid()
- && gAgentAvatarp->isSitting()
- && mSitCameraReferenceObject.notNull())
- {
- // sit camera
- LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
- LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
-
- LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
-
- camera_position_global = gAgent.getPosGlobalFromAgent(target_pos);
- }
- else
- {
+ {
+ head_offset[VZ] -= fixup;
+ }
+ if (gAgentAvatarp->isSitting())
+ {
+ head_offset.mdV[VZ] += 0.1;
+ }
+
+ if (gAgentAvatarp->isSitting() && gAgentAvatarp->getParent())
+ {
+ gAgentAvatarp->updateHeadOffset();
+ head_offset.mdV[VX] += gAgentAvatarp->mHeadOffset.mV[VX];
+ head_offset.mdV[VY] += gAgentAvatarp->mHeadOffset.mV[VY];
+ head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
+ const LLMatrix4& mat = ((LLViewerObject*) gAgentAvatarp->getParent())->getRenderMatrix();
+ camera_position_global = gAgent.getPosGlobalFromAgent
+ ((gAgentAvatarp->getPosition()+
+ LLVector3(head_offset)*gAgentAvatarp->getRotation()) * mat);
+ }
+ else
+ {
+ head_offset.mdV[VZ] += gAgentAvatarp->mHeadOffset.mV[VZ];
+ camera_position_global = gAgent.getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());//frame_center_global;
+ head_offset = head_offset * gAgentAvatarp->getRenderRotation();
+ camera_position_global = camera_position_global + head_offset;
+ }
+ }
+ else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
+ {
+ LLVector3 local_camera_offset;
+ F32 camera_distance = 0.f;
+
+ if (mSitCameraEnabled
+ && isAgentAvatarValid()
+ && gAgentAvatarp->isSitting()
+ && mSitCameraReferenceObject.notNull())
+ {
+ // sit camera
+ LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
+ LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
+
+ LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
+
+ camera_position_global = gAgent.getPosGlobalFromAgent(target_pos);
+ }
+ else
+ {
static LLCachedControl<F32> camera_offset_scale(gSavedSettings, "CameraOffsetScale");
local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * camera_offset_scale;
- // are we sitting down?
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
- {
- LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
- // slam agent coordinate frame to proper parent local version
- LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot;
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis * ~parent_rot);
-
- local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot;
- }
- else
- {
- local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset );
- }
-
- if (!isDisableCameraConstraints() && !mCameraCollidePlane.isExactlyZero() &&
- (!isAgentAvatarValid() || !gAgentAvatarp->isSitting()))
- {
- LLVector3 plane_normal;
- plane_normal.setVec(mCameraCollidePlane.mV);
-
- F32 offset_dot_norm = local_camera_offset * plane_normal;
- if (llabs(offset_dot_norm) < 0.001f)
- {
- offset_dot_norm = 0.001f;
- }
-
- camera_distance = local_camera_offset.normalize();
-
- F32 pos_dot_norm = gAgent.getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
-
- // if agent is outside the colliding half-plane
- if (pos_dot_norm > mCameraCollidePlane.mV[VW])
- {
- // check to see if camera is on the opposite side (inside) the half-plane
- if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
- {
- // diminish offset by factor to push it back outside the half-plane
- camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
- }
- }
- else
- {
- if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
- {
- camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
- }
- }
- }
- else
- {
- camera_distance = local_camera_offset.normalize();
- }
-
- mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
-
- if (mTargetCameraDistance != mCurrentCameraDistance)
- {
- F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
-
- mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
- }
-
- // Make the camera distance current
- local_camera_offset *= mCurrentCameraDistance;
-
- // set the global camera position
- LLVector3d camera_offset;
-
- camera_offset.setVec( local_camera_offset );
- camera_position_global = frame_center_global + head_offset + camera_offset;
-
- if (isAgentAvatarValid())
- {
- LLVector3d camera_lag_d;
- F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE);
- LLVector3 target_lag;
- LLVector3 vel = gAgent.getVelocity();
-
- // lag by appropriate amount for flying
- F32 time_in_air = gAgentAvatarp->mTimeInAir.getElapsedTimeF32();
- if(!mCameraAnimating && gAgentAvatarp->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
- {
- LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis();
- frame_at_axis -= projected_vec(frame_at_axis, gAgent.getReferenceUpVector());
- frame_at_axis.normalize();
-
- //transition smoothly in air mode, to avoid camera pop
- F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
- u = llclamp(u, 0.f, 1.f);
-
- lag_interp *= u;
-
- if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgentAvatarp->getID())
- {
- // disable camera lag when using mouse-directed steering
- target_lag.clearVec();
- }
- else
- {
- target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
- }
-
- mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
-
- F32 lag_dist = mCameraLag.magVec();
- if (lag_dist > MAX_CAMERA_LAG)
- {
- mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
- }
-
- // clamp camera lag so that avatar is always in front
- F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
- if (dot < -(MIN_CAMERA_LAG * u))
- {
- mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
- }
- }
- else
- {
- mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f));
- }
-
- camera_lag_d.setVec(mCameraLag);
- camera_position_global = camera_position_global - camera_lag_d;
- }
- }
- }
- else
- {
- LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
- // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value
- camera_position_global = focusPosGlobal + mCameraFocusOffset;
- }
-
- if (!isDisableCameraConstraints() && !gAgent.isGodlike())
- {
- LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
- bool constrain = true;
- if(regionp && regionp->canManageEstate())
- {
- constrain = false;
- }
- if(constrain)
- {
- F32 max_dist = (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) ? APPEARANCE_MAX_ZOOM : mDrawDistance;
-
- LLVector3d camera_offset = camera_position_global - gAgent.getPositionGlobal();
- F32 camera_distance = (F32)camera_offset.magVec();
-
- if(camera_distance > max_dist)
- {
- camera_position_global = gAgent.getPositionGlobal() + (max_dist/camera_distance)*camera_offset;
- isConstrained = TRUE;
- }
- }
+ // are we sitting down?
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ LLQuaternion parent_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
+ // slam agent coordinate frame to proper parent local version
+ LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot;
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis * ~parent_rot);
+
+ local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot;
+ }
+ else
+ {
+ local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset );
+ }
+
+ if (!isDisableCameraConstraints() && !mCameraCollidePlane.isExactlyZero() &&
+ (!isAgentAvatarValid() || !gAgentAvatarp->isSitting()))
+ {
+ LLVector3 plane_normal;
+ plane_normal.setVec(mCameraCollidePlane.mV);
+
+ F32 offset_dot_norm = local_camera_offset * plane_normal;
+ if (llabs(offset_dot_norm) < 0.001f)
+ {
+ offset_dot_norm = 0.001f;
+ }
+
+ camera_distance = local_camera_offset.normalize();
+
+ F32 pos_dot_norm = gAgent.getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
+
+ // if agent is outside the colliding half-plane
+ if (pos_dot_norm > mCameraCollidePlane.mV[VW])
+ {
+ // check to see if camera is on the opposite side (inside) the half-plane
+ if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
+ {
+ // diminish offset by factor to push it back outside the half-plane
+ camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
+ }
+ }
+ else
+ {
+ if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
+ {
+ camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
+ }
+ }
+ }
+ else
+ {
+ camera_distance = local_camera_offset.normalize();
+ }
+
+ mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
+
+ if (mTargetCameraDistance != mCurrentCameraDistance)
+ {
+ F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
+
+ mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
+ }
+
+ // Make the camera distance current
+ local_camera_offset *= mCurrentCameraDistance;
+
+ // set the global camera position
+ LLVector3d camera_offset;
+
+ camera_offset.setVec( local_camera_offset );
+ camera_position_global = frame_center_global + head_offset + camera_offset;
+
+ if (isAgentAvatarValid())
+ {
+ LLVector3d camera_lag_d;
+ F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE);
+ LLVector3 target_lag;
+ LLVector3 vel = gAgent.getVelocity();
+
+ // lag by appropriate amount for flying
+ F32 time_in_air = gAgentAvatarp->mTimeInAir.getElapsedTimeF32();
+ if(!mCameraAnimating && gAgentAvatarp->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
+ {
+ LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis();
+ frame_at_axis -= projected_vec(frame_at_axis, gAgent.getReferenceUpVector());
+ frame_at_axis.normalize();
+
+ //transition smoothly in air mode, to avoid camera pop
+ F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
+ u = llclamp(u, 0.f, 1.f);
+
+ lag_interp *= u;
+
+ if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgentAvatarp->getID())
+ {
+ // disable camera lag when using mouse-directed steering
+ target_lag.clearVec();
+ }
+ else
+ {
+ target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
+ }
+
+ mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
+
+ F32 lag_dist = mCameraLag.magVec();
+ if (lag_dist > MAX_CAMERA_LAG)
+ {
+ mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
+ }
+
+ // clamp camera lag so that avatar is always in front
+ F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
+ if (dot < -(MIN_CAMERA_LAG * u))
+ {
+ mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
+ }
+ }
+ else
+ {
+ mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f));
+ }
+
+ camera_lag_d.setVec(mCameraLag);
+ camera_position_global = camera_position_global - camera_lag_d;
+ }
+ }
+ }
+ else
+ {
+ LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
+ // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value
+ camera_position_global = focusPosGlobal + mCameraFocusOffset;
+ }
+
+ if (!isDisableCameraConstraints() && !gAgent.isGodlike())
+ {
+ LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
+ bool constrain = true;
+ if(regionp && regionp->canManageEstate())
+ {
+ constrain = false;
+ }
+ if(constrain)
+ {
+ F32 max_dist = (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) ? APPEARANCE_MAX_ZOOM : mDrawDistance;
+
+ LLVector3d camera_offset = camera_position_global - gAgent.getPositionGlobal();
+ F32 camera_distance = (F32)camera_offset.magVec();
+
+ if(camera_distance > max_dist)
+ {
+ camera_position_global = gAgent.getPositionGlobal() + (max_dist/camera_distance)*camera_offset;
+ isConstrained = TRUE;
+ }
+ }
// JC - Could constrain camera based on parcel stuff here.
-// LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
-//
-// if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global)))
-// {
-// camera_position_global = last_position_global;
+// LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
+//
+// if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global)))
+// {
+// camera_position_global = last_position_global;
//
-// isConstrained = TRUE;
-// }
- }
+// isConstrained = TRUE;
+// }
+ }
- // Don't let camera go underground
- F32 camera_min_off_ground = getCameraMinOffGround();
- camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
- F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground);
- if (camera_position_global.mdV[VZ] < minZ)
- {
- camera_position_global.mdV[VZ] = minZ;
- isConstrained = TRUE;
- }
+ // Don't let camera go underground
+ F32 camera_min_off_ground = getCameraMinOffGround();
+ camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
+ F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground);
+ if (camera_position_global.mdV[VZ] < minZ)
+ {
+ camera_position_global.mdV[VZ] = minZ;
+ isConstrained = TRUE;
+ }
- if (hit_limit)
- {
- *hit_limit = isConstrained;
- }
+ if (hit_limit)
+ {
+ *hit_limit = isConstrained;
+ }
- return camera_position_global;
+ return camera_position_global;
}
LLVector3 LLAgentCamera::getCurrentCameraOffset()
{
- return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
+ return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
}
LLVector3d LLAgentCamera::getCurrentFocusOffset()
{
- return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation();
+ return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation();
}
LLQuaternion LLAgentCamera::getCurrentAvatarRotation()
{
- LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent();
-
- LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
- LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
- return av_rot * obj_rot;
+ LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent();
+
+ LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
+ LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
+ return av_rot * obj_rot;
}
bool LLAgentCamera::isJoystickCameraUsed()
{
- return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull());
+ return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull());
}
LLVector3 LLAgentCamera::getCameraOffsetInitial()
{
// getCameraOffsetInitial and getFocusOffsetInitial can be called on update from idle before init()
static LLCachedControl<LLVector3> camera_offset_initial (gSavedSettings, "CameraOffsetRearView", LLVector3());
- return camera_offset_initial;
+ return camera_offset_initial;
}
LLVector3d LLAgentCamera::getFocusOffsetInitial()
{
static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d());
- return focus_offset_initial;
+ return focus_offset_initial;
}
F32 LLAgentCamera::getCameraMaxZoomDistance()
@@ -2082,48 +2082,48 @@ LLVector3 LLAgentCamera::getAvatarRootPosition()
//-----------------------------------------------------------------------------
void LLAgentCamera::handleScrollWheel(S32 clicks)
{
- if (mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar())
- {
- if (!mFollowCam.getPositionLocked()) // not if the followCam position is locked in place
- {
- mFollowCam.zoom(clicks);
- if (mFollowCam.isZoomedToMinimumDistance())
- {
- changeCameraToMouselook(FALSE);
- }
- }
- }
- else
- {
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
-
- // Block if camera is animating
- if (mCameraAnimating)
- {
- return;
- }
-
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 zoom_factor = (F32)pow(0.8, -clicks);
- cameraZoomIn(zoom_factor);
- }
- else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON))
- {
- F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
-
- F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
- current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
-
- cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
- }
- else
- {
- F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
- cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
- }
- }
+ if (mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar())
+ {
+ if (!mFollowCam.getPositionLocked()) // not if the followCam position is locked in place
+ {
+ mFollowCam.zoom(clicks);
+ if (mFollowCam.isZoomedToMinimumDistance())
+ {
+ changeCameraToMouselook(FALSE);
+ }
+ }
+ }
+ else
+ {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
+
+ // Block if camera is animating
+ if (mCameraAnimating)
+ {
+ return;
+ }
+
+ if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 zoom_factor = (F32)pow(0.8, -clicks);
+ cameraZoomIn(zoom_factor);
+ }
+ else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON))
+ {
+ F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
+
+ F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
+ current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
+
+ cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
+ }
+ else
+ {
+ F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
+ cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
+ }
+ }
}
@@ -2132,17 +2132,17 @@ void LLAgentCamera::handleScrollWheel(S32 clicks)
//-----------------------------------------------------------------------------
F32 LLAgentCamera::getCameraMinOffGround()
{
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- return 0.f;
- }
+ if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ return 0.f;
+ }
- if (isDisableCameraConstraints())
- {
- return -1000.f;
- }
+ if (isDisableCameraConstraints())
+ {
+ return -1000.f;
+ }
- return 0.5f;
+ return 0.5f;
}
@@ -2151,15 +2151,15 @@ F32 LLAgentCamera::getCameraMinOffGround()
//-----------------------------------------------------------------------------
void LLAgentCamera::resetCamera()
{
- // Remove any pitch from the avatar
- LLVector3 at = gAgent.getFrameAgent().getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
- // have to explicitly clear field of view zoom now
- mCameraFOVZoomFactor = 0.f;
+ // Remove any pitch from the avatar
+ LLVector3 at = gAgent.getFrameAgent().getAtAxis();
+ at.mV[VZ] = 0.f;
+ at.normalize();
+ gAgent.resetAxes(at);
+ // have to explicitly clear field of view zoom now
+ mCameraFOVZoomFactor = 0.f;
- updateCamera();
+ updateCamera();
}
//-----------------------------------------------------------------------------
@@ -2167,58 +2167,58 @@ void LLAgentCamera::resetCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToMouselook(BOOL animate)
{
- if (!gSavedSettings.getBOOL("EnableMouselook")
- || LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
-
- // visibility changes at end of animation
- gViewerWindow->getWindow()->resetBusyCount();
-
- // Menus should not remain open on switching to mouselook...
- LLMenuGL::sMenuContainer->hideMenus();
- LLUI::getInstance()->clearPopups();
-
- // unpause avatar animation
- gAgent.unpauseAnimation();
-
- LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
-
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->stopMotion(ANIM_AGENT_BODY_NOISE);
- gAgentAvatarp->stopMotion(ANIM_AGENT_BREATHE_ROT);
- }
-
- //gViewerWindow->stopGrab();
- LLSelectMgr::getInstance()->deselectAll();
- gViewerWindow->hideCursor();
- gViewerWindow->moveCursorToCenter();
-
- if (mCameraMode != CAMERA_MODE_MOUSELOOK)
- {
- gFocusMgr.setKeyboardFocus(NULL);
-
- updateLastCamera();
- mCameraMode = CAMERA_MODE_MOUSELOOK;
- const U32 old_flags = gAgent.getControlFlags();
- gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK);
- if (old_flags != gAgent.getControlFlags())
- {
- gAgent.setFlagsDirty();
- }
-
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- gAgent.endAnimationUpdateUI();
- }
- }
+ if (!gSavedSettings.getBOOL("EnableMouselook")
+ || LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ return;
+ }
+
+ // visibility changes at end of animation
+ gViewerWindow->getWindow()->resetBusyCount();
+
+ // Menus should not remain open on switching to mouselook...
+ LLMenuGL::sMenuContainer->hideMenus();
+ LLUI::getInstance()->clearPopups();
+
+ // unpause avatar animation
+ gAgent.unpauseAnimation();
+
+ LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
+
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->stopMotion(ANIM_AGENT_BODY_NOISE);
+ gAgentAvatarp->stopMotion(ANIM_AGENT_BREATHE_ROT);
+ }
+
+ //gViewerWindow->stopGrab();
+ LLSelectMgr::getInstance()->deselectAll();
+ gViewerWindow->hideCursor();
+ gViewerWindow->moveCursorToCenter();
+
+ if (mCameraMode != CAMERA_MODE_MOUSELOOK)
+ {
+ gFocusMgr.setKeyboardFocus(NULL);
+
+ updateLastCamera();
+ mCameraMode = CAMERA_MODE_MOUSELOOK;
+ const U32 old_flags = gAgent.getControlFlags();
+ gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK);
+ if (old_flags != gAgent.getControlFlags())
+ {
+ gAgent.setFlagsDirty();
+ }
+
+ if (animate)
+ {
+ startCameraAnimation();
+ }
+ else
+ {
+ mCameraAnimating = FALSE;
+ gAgent.endAnimationUpdateUI();
+ }
+ }
}
@@ -2227,24 +2227,24 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate)
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToDefault()
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ return;
+ }
- if (LLFollowCamMgr::getInstance()->getActiveFollowCamParams())
- {
- changeCameraToFollow();
- }
- else
- {
- changeCameraToThirdPerson();
- }
- if (gSavedSettings.getBOOL("HideUIControls"))
- {
- gViewerWindow->setUIVisibility(false);
- LLPanelStandStopFlying::getInstance()->setVisible(false);
- }
+ if (LLFollowCamMgr::getInstance()->getActiveFollowCamParams())
+ {
+ changeCameraToFollow();
+ }
+ else
+ {
+ changeCameraToThirdPerson();
+ }
+ if (gSavedSettings.getBOOL("HideUIControls"))
+ {
+ gViewerWindow->setUIVisibility(false);
+ LLPanelStandStopFlying::getInstance()->setVisible(false);
+ }
}
@@ -2253,53 +2253,53 @@ void LLAgentCamera::changeCameraToDefault()
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToFollow(BOOL animate)
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
-
- if(mCameraMode != CAMERA_MODE_FOLLOW)
- {
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- animate = FALSE;
- }
- startCameraAnimation();
-
- updateLastCamera();
- mCameraMode = CAMERA_MODE_FOLLOW;
-
- // bang-in the current focus, position, and up vector of the follow cam
- mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
-
- if (gBasicToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- }
-
- if (isAgentAvatarValid())
- {
- // SL-315
- gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero);
- gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
- gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT );
- }
-
- // unpause avatar animation
- gAgent.unpauseAnimation();
-
- gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
-
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- gAgent.endAnimationUpdateUI();
- }
- }
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ return;
+ }
+
+ if(mCameraMode != CAMERA_MODE_FOLLOW)
+ {
+ if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ animate = FALSE;
+ }
+ startCameraAnimation();
+
+ updateLastCamera();
+ mCameraMode = CAMERA_MODE_FOLLOW;
+
+ // bang-in the current focus, position, and up vector of the follow cam
+ mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
+
+ if (gBasicToolset)
+ {
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ }
+
+ if (isAgentAvatarValid())
+ {
+ // SL-315
+ gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero);
+ gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
+ gAgentAvatarp->startMotion( ANIM_AGENT_BREATHE_ROT );
+ }
+
+ // unpause avatar animation
+ gAgent.unpauseAnimation();
+
+ gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+
+ if (animate)
+ {
+ startCameraAnimation();
+ }
+ else
+ {
+ mCameraAnimating = FALSE;
+ gAgent.endAnimationUpdateUI();
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -2307,69 +2307,69 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate)
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
-
- gViewerWindow->getWindow()->resetBusyCount();
-
- mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
-
- if (isAgentAvatarValid())
- {
- if (!gAgentAvatarp->isSitting())
- {
- // SL-315
- gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero);
- }
- gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE);
- gAgentAvatarp->startMotion(ANIM_AGENT_BREATHE_ROT);
- }
-
- LLVector3 at_axis;
-
- // unpause avatar animation
- gAgent.unpauseAnimation();
-
- if (mCameraMode != CAMERA_MODE_THIRD_PERSON)
- {
- if (gBasicToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- }
-
- mCameraLag.clearVec();
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
- mTargetCameraDistance = MIN_CAMERA_DISTANCE;
- animate = FALSE;
- }
- updateLastCamera();
- mCameraMode = CAMERA_MODE_THIRD_PERSON;
- gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
- }
-
- // Remove any pitch from the avatar
- if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
- {
- at_axis = gAgent.getFrameAgent().getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis);
- }
-
-
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- gAgent.endAnimationUpdateUI();
- }
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ return;
+ }
+
+ gViewerWindow->getWindow()->resetBusyCount();
+
+ mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
+
+ if (isAgentAvatarValid())
+ {
+ if (!gAgentAvatarp->isSitting())
+ {
+ // SL-315
+ gAgentAvatarp->mPelvisp->setPosition(LLVector3::zero);
+ }
+ gAgentAvatarp->startMotion(ANIM_AGENT_BODY_NOISE);
+ gAgentAvatarp->startMotion(ANIM_AGENT_BREATHE_ROT);
+ }
+
+ LLVector3 at_axis;
+
+ // unpause avatar animation
+ gAgent.unpauseAnimation();
+
+ if (mCameraMode != CAMERA_MODE_THIRD_PERSON)
+ {
+ if (gBasicToolset)
+ {
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ }
+
+ mCameraLag.clearVec();
+ if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ {
+ mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
+ mTargetCameraDistance = MIN_CAMERA_DISTANCE;
+ animate = FALSE;
+ }
+ updateLastCamera();
+ mCameraMode = CAMERA_MODE_THIRD_PERSON;
+ gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+ }
+
+ // Remove any pitch from the avatar
+ if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
+ {
+ at_axis = gAgent.getFrameAgent().getAtAxis();
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis);
+ }
+
+
+ if (animate)
+ {
+ startCameraAnimation();
+ }
+ else
+ {
+ mCameraAnimating = FALSE;
+ gAgent.endAnimationUpdateUI();
+ }
}
//-----------------------------------------------------------------------------
@@ -2377,89 +2377,89 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToCustomizeAvatar()
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
- {
- return;
- }
+ if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
+ {
+ return;
+ }
- gAgent.standUp(); // force stand up
- gViewerWindow->getWindow()->resetBusyCount();
+ gAgent.standUp(); // force stand up
+ gViewerWindow->getWindow()->resetBusyCount();
if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
{
LLSelectMgr::getInstance()->deselectAll();
}
- if (gFaceEditToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
- }
-
- startCameraAnimation();
-
- if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR)
- {
- updateLastCamera();
- mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
- gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
-
- gFocusMgr.setKeyboardFocus( NULL );
- gFocusMgr.setMouseCapture( NULL );
- if( gMorphView )
- {
- gMorphView->setVisible( TRUE );
- }
- // Remove any pitch or rotation from the avatar
- LLVector3 at = gAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
-
- gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
- gAgent.setCustomAnim(TRUE);
- gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
- LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
-
- if (turn_motion)
- {
- // delay camera animation long enough to play through turn animation
- setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
- }
- }
-
- LLVector3 agent_at = gAgent.getAtAxis();
- agent_at.mV[VZ] = 0.f;
- agent_at.normalize();
-
- // default focus point for customize avatar
- LLVector3 focus_target = isAgentAvatarValid()
- ? gAgentAvatarp->mHeadp->getWorldPosition()
- : gAgent.getPositionAgent();
-
- LLVector3d camera_offset(agent_at * -1.0);
- // push camera up and out from avatar
- camera_offset.mdV[VZ] = 0.1f;
- camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST;
- LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
- setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
- setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID());
+ if (gFaceEditToolset)
+ {
+ LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
+ }
+
+ startCameraAnimation();
+
+ if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR)
+ {
+ updateLastCamera();
+ mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
+ gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+
+ gFocusMgr.setKeyboardFocus( NULL );
+ gFocusMgr.setMouseCapture( NULL );
+ if( gMorphView )
+ {
+ gMorphView->setVisible( TRUE );
+ }
+ // Remove any pitch or rotation from the avatar
+ LLVector3 at = gAgent.getAtAxis();
+ at.mV[VZ] = 0.f;
+ at.normalize();
+ gAgent.resetAxes(at);
+
+ gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+ gAgent.setCustomAnim(TRUE);
+ gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+ LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
+
+ if (turn_motion)
+ {
+ // delay camera animation long enough to play through turn animation
+ setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
+ }
+ }
+
+ LLVector3 agent_at = gAgent.getAtAxis();
+ agent_at.mV[VZ] = 0.f;
+ agent_at.normalize();
+
+ // default focus point for customize avatar
+ LLVector3 focus_target = isAgentAvatarValid()
+ ? gAgentAvatarp->mHeadp->getWorldPosition()
+ : gAgent.getPositionAgent();
+
+ LLVector3d camera_offset(agent_at * -1.0);
+ // push camera up and out from avatar
+ camera_offset.mdV[VZ] = 0.1f;
+ camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST;
+ LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+ setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
+ setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID());
}
void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
{
- //zoom is supposed to be reset for the front and group views
- mCameraZoomFraction = 1.f;
+ //zoom is supposed to be reset for the front and group views
+ mCameraZoomFraction = 1.f;
- //focusing on avatar in that case means following him on movements
- mFocusOnAvatar = TRUE;
+ //focusing on avatar in that case means following him on movements
+ mFocusOnAvatar = TRUE;
- mCameraPreset = preset;
+ mCameraPreset = preset;
- resetPanDiff();
- resetOrbitDiff();
+ resetPanDiff();
+ resetOrbitDiff();
- gSavedSettings.setU32("CameraPresetType", mCameraPreset);
+ gSavedSettings.setU32("CameraPresetType", mCameraPreset);
}
@@ -2468,17 +2468,17 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
//
void LLAgentCamera::setAnimationDuration(F32 duration)
-{
- if (mCameraAnimating)
- {
- // do not cut any existing camera animation short
- F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32());
- mAnimationDuration = llmax(duration, animation_left);
- }
- else
- {
- mAnimationDuration = duration;
- }
+{
+ if (mCameraAnimating)
+ {
+ // do not cut any existing camera animation short
+ F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32());
+ mAnimationDuration = llmax(duration, animation_left);
+ }
+ else
+ {
+ mAnimationDuration = duration;
+ }
}
//-----------------------------------------------------------------------------
@@ -2486,11 +2486,11 @@ void LLAgentCamera::setAnimationDuration(F32 duration)
//-----------------------------------------------------------------------------
void LLAgentCamera::startCameraAnimation()
{
- mAnimationCameraStartGlobal = getCameraPositionGlobal();
- mAnimationFocusStartGlobal = mFocusGlobal;
- setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
- mAnimationTimer.reset();
- mCameraAnimating = TRUE;
+ mAnimationCameraStartGlobal = getCameraPositionGlobal();
+ mAnimationFocusStartGlobal = mFocusGlobal;
+ setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
+ mAnimationTimer.reset();
+ mCameraAnimating = TRUE;
}
//-----------------------------------------------------------------------------
@@ -2498,23 +2498,23 @@ void LLAgentCamera::startCameraAnimation()
//-----------------------------------------------------------------------------
void LLAgentCamera::stopCameraAnimation()
{
- mCameraAnimating = FALSE;
+ mCameraAnimating = FALSE;
}
void LLAgentCamera::clearFocusObject()
{
- if (mFocusObject.notNull())
- {
- startCameraAnimation();
+ if (mFocusObject.notNull())
+ {
+ startCameraAnimation();
- setFocusObject(NULL);
- mFocusObjectOffset.clearVec();
- }
+ setFocusObject(NULL);
+ mFocusObjectOffset.clearVec();
+ }
}
void LLAgentCamera::setFocusObject(LLViewerObject* object)
{
- mFocusObject = object;
+ mFocusObject = object;
}
// Focus on a point, but try to keep camera position stable.
@@ -2523,104 +2523,104 @@ void LLAgentCamera::setFocusObject(LLViewerObject* object)
//-----------------------------------------------------------------------------
void LLAgentCamera::setFocusGlobal(const LLPickInfo& pick)
{
- LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
+ LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
- if (objectp)
- {
- // focus on object plus designated offset
- // which may or may not be same as pick.mPosGlobal
- setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
- }
- else
- {
- // focus directly on point where user clicked
- setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
- }
+ if (objectp && pick.mGLTFNodeIndex == -1)
+ {
+ // focus on object plus designated offset
+ // which may or may not be same as pick.mPosGlobal
+ setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
+ }
+ else
+ {
+ // focus directly on point where user clicked
+ setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
+ }
}
void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
{
- setFocusObject(gObjectList.findObject(object_id));
- LLVector3d old_focus = mFocusTargetGlobal;
- LLViewerObject *focus_obj = mFocusObject;
-
- // if focus has changed
- if (old_focus != focus)
- {
- if (focus.isExactlyZero())
- {
- if (isAgentAvatarValid())
- {
- mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition());
- }
- else
- {
- mFocusTargetGlobal = gAgent.getPositionGlobal();
- }
- mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
- setLookAt(LOOKAT_TARGET_CLEAR);
- }
- else
- {
- mFocusTargetGlobal = focus;
- if (!focus_obj)
- {
- mCameraFOVZoomFactor = 0.f;
- }
-
- mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
-
- startCameraAnimation();
-
- if (focus_obj)
- {
- if (focus_obj->isAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (gAgent.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
- }
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
- }
- }
- }
- else // focus == mFocusTargetGlobal
- {
- if (focus.isExactlyZero())
- {
- if (isAgentAvatarValid())
- {
- mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition());
- }
- else
- {
- mFocusTargetGlobal = gAgent.getPositionGlobal();
- }
- }
- mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
- }
-
- if (mFocusObject.notNull())
- {
- // for attachments, make offset relative to avatar, not the attachment
- if (mFocusObject->isAttachment())
- {
- while (mFocusObject.notNull() && !mFocusObject->isAvatar())
- {
- mFocusObject = (LLViewerObject*) mFocusObject->getParent();
- }
- setFocusObject((LLViewerObject*)mFocusObject);
- }
- updateFocusOffset();
- }
+ setFocusObject(gObjectList.findObject(object_id));
+ LLVector3d old_focus = mFocusTargetGlobal;
+ LLViewerObject *focus_obj = mFocusObject;
+
+ // if focus has changed
+ if (old_focus != focus)
+ {
+ if (focus.isExactlyZero())
+ {
+ if (isAgentAvatarValid())
+ {
+ mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition());
+ }
+ else
+ {
+ mFocusTargetGlobal = gAgent.getPositionGlobal();
+ }
+ mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
+ mCameraFocusOffset = mCameraFocusOffsetTarget;
+ setLookAt(LOOKAT_TARGET_CLEAR);
+ }
+ else
+ {
+ mFocusTargetGlobal = focus;
+ if (!focus_obj)
+ {
+ mCameraFOVZoomFactor = 0.f;
+ }
+
+ mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
+
+ startCameraAnimation();
+
+ if (focus_obj)
+ {
+ if (focus_obj->isAvatar())
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
+ }
+ else
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (gAgent.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
+ }
+ }
+ else
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
+ }
+ }
+ }
+ else // focus == mFocusTargetGlobal
+ {
+ if (focus.isExactlyZero())
+ {
+ if (isAgentAvatarValid())
+ {
+ mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mHeadp->getWorldPosition());
+ }
+ else
+ {
+ mFocusTargetGlobal = gAgent.getPositionGlobal();
+ }
+ }
+ mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
+ mCameraFocusOffset = mCameraFocusOffsetTarget;
+ }
+
+ if (mFocusObject.notNull())
+ {
+ // for attachments, make offset relative to avatar, not the attachment
+ if (mFocusObject->isAttachment())
+ {
+ while (mFocusObject.notNull() && !mFocusObject->isAvatar())
+ {
+ mFocusObject = (LLViewerObject*) mFocusObject->getParent();
+ }
+ setFocusObject((LLViewerObject*)mFocusObject);
+ }
+ updateFocusOffset();
+ }
}
// Used for avatar customization
@@ -2629,48 +2629,48 @@ void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object
//-----------------------------------------------------------------------------
void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id)
{
- LLVector3d old_focus = mFocusTargetGlobal.isExactlyZero() ? focus : mFocusTargetGlobal;
-
- F64 focus_delta_squared = (old_focus - focus).magVecSquared();
- const F64 ANIM_EPSILON_SQUARED = 0.0001;
- if (focus_delta_squared > ANIM_EPSILON_SQUARED)
- {
- startCameraAnimation();
- }
-
- //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );
- setFocusObject(gObjectList.findObject(object_id));
- mFocusTargetGlobal = focus;
- mCameraFocusOffsetTarget = camera_pos - focus;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
-
- if (mFocusObject)
- {
- if (mFocusObject->isAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (gAgent.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
- }
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
- }
-
- if (mCameraAnimating)
- {
- const F64 ANIM_METERS_PER_SECOND = 10.0;
- const F64 MIN_ANIM_SECONDS = 0.5;
- const F64 MAX_ANIM_SECONDS = 10.0;
- F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
- anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
- setAnimationDuration( (F32)anim_duration );
- }
-
- updateFocusOffset();
+ LLVector3d old_focus = mFocusTargetGlobal.isExactlyZero() ? focus : mFocusTargetGlobal;
+
+ F64 focus_delta_squared = (old_focus - focus).magVecSquared();
+ const F64 ANIM_EPSILON_SQUARED = 0.0001;
+ if (focus_delta_squared > ANIM_EPSILON_SQUARED)
+ {
+ startCameraAnimation();
+ }
+
+ //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );
+ setFocusObject(gObjectList.findObject(object_id));
+ mFocusTargetGlobal = focus;
+ mCameraFocusOffsetTarget = camera_pos - focus;
+ mCameraFocusOffset = mCameraFocusOffsetTarget;
+
+ if (mFocusObject)
+ {
+ if (mFocusObject->isAvatar())
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
+ }
+ else
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (gAgent.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
+ }
+ }
+ else
+ {
+ setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
+ }
+
+ if (mCameraAnimating)
+ {
+ const F64 ANIM_METERS_PER_SECOND = 10.0;
+ const F64 MIN_ANIM_SECONDS = 0.5;
+ const F64 MAX_ANIM_SECONDS = 10.0;
+ F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
+ anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
+ setAnimationDuration( (F32)anim_duration );
+ }
+
+ updateFocusOffset();
}
//-----------------------------------------------------------------------------
@@ -2678,27 +2678,27 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con
//-----------------------------------------------------------------------------
void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus)
{
- BOOL camera_enabled = !object_id.isNull();
-
- if (camera_enabled)
- {
- LLViewerObject *reference_object = gObjectList.findObject(object_id);
- if (reference_object)
- {
- //convert to root object relative?
- mSitCameraPos = camera_pos;
- mSitCameraFocus = camera_focus;
- mSitCameraReferenceObject = reference_object;
- mSitCameraEnabled = TRUE;
- }
- }
- else
- {
- mSitCameraPos.clearVec();
- mSitCameraFocus.clearVec();
- mSitCameraReferenceObject = NULL;
- mSitCameraEnabled = FALSE;
- }
+ BOOL camera_enabled = !object_id.isNull();
+
+ if (camera_enabled)
+ {
+ LLViewerObject *reference_object = gObjectList.findObject(object_id);
+ if (reference_object)
+ {
+ //convert to root object relative?
+ mSitCameraPos = camera_pos;
+ mSitCameraFocus = camera_focus;
+ mSitCameraReferenceObject = reference_object;
+ mSitCameraEnabled = TRUE;
+ }
+ }
+ else
+ {
+ mSitCameraPos.clearVec();
+ mSitCameraFocus.clearVec();
+ mSitCameraReferenceObject = NULL;
+ mSitCameraEnabled = FALSE;
+ }
}
//-----------------------------------------------------------------------------
@@ -2706,30 +2706,30 @@ void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camer
//-----------------------------------------------------------------------------
void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL reset_axes)
{
- if (focus_on_avatar != mFocusOnAvatar)
- {
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- stopCameraAnimation();
- }
- }
-
- //RN: when focused on the avatar, we're not "looking" at it
- // looking implies intent while focusing on avatar means
- // you're just walking around with a camera on you...eesh.
- if (!mFocusOnAvatar && focus_on_avatar && reset_axes)
- {
- setFocusGlobal(LLVector3d::zero);
- mCameraFOVZoomFactor = 0.f;
- if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
- {
- LLVector3 at_axis;
- if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
- {
+ if (focus_on_avatar != mFocusOnAvatar)
+ {
+ if (animate)
+ {
+ startCameraAnimation();
+ }
+ else
+ {
+ stopCameraAnimation();
+ }
+ }
+
+ //RN: when focused on the avatar, we're not "looking" at it
+ // looking implies intent while focusing on avatar means
+ // you're just walking around with a camera on you...eesh.
+ if (!mFocusOnAvatar && focus_on_avatar && reset_axes)
+ {
+ setFocusGlobal(LLVector3d::zero);
+ mCameraFOVZoomFactor = 0.f;
+ if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
+ {
+ LLVector3 at_axis;
+ if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
+ {
// In case of front view rotate agent to look into direction opposite to camera
// In case of rear view rotate agent into diraction same as camera, e t c
LLVector3 vect = getCameraOffsetInitial();
@@ -2743,44 +2743,44 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL re
at_axis.normalize();
gAgent.resetAxes(at_axis);
gAgent.yaw(0);
- }
- }
- }
- // unlocking camera from avatar
- else if (mFocusOnAvatar && !focus_on_avatar)
- {
- // keep camera focus point consistent, even though it is now unlocked
- setFocusGlobal(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
- mAllowChangeToFollow = FALSE;
- }
-
- mFocusOnAvatar = focus_on_avatar;
+ }
+ }
+ }
+ // unlocking camera from avatar
+ else if (mFocusOnAvatar && !focus_on_avatar)
+ {
+ // keep camera focus point consistent, even though it is now unlocked
+ setFocusGlobal(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
+ mAllowChangeToFollow = FALSE;
+ }
+
+ mFocusOnAvatar = focus_on_avatar;
}
BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
{
- if(object && object->isAttachment())
- {
- LLViewerObject* parent = object;
- while(parent)
- {
- if (parent == gAgentAvatarp)
- {
- // looking at an attachment on ourselves, which we don't want to do
- object = gAgentAvatarp;
- position.clearVec();
- }
- parent = (LLViewerObject*)parent->getParent();
- }
- }
- if(!mLookAt || mLookAt->isDead())
- {
- mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
- mLookAt->setSourceObject(gAgentAvatarp);
- }
-
- return mLookAt->setLookAt(target_type, object, position);
+ if(object && object->isAttachment())
+ {
+ LLViewerObject* parent = object;
+ while(parent)
+ {
+ if (parent == gAgentAvatarp)
+ {
+ // looking at an attachment on ourselves, which we don't want to do
+ object = gAgentAvatarp;
+ position.clearVec();
+ }
+ parent = (LLViewerObject*)parent->getParent();
+ }
+ }
+ if(!mLookAt || mLookAt->isDead())
+ {
+ mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
+ mLookAt->setSourceObject(gAgentAvatarp);
+ }
+
+ return mLookAt->setLookAt(target_type, object, position);
}
//-----------------------------------------------------------------------------
@@ -2788,168 +2788,168 @@ BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, L
//-----------------------------------------------------------------------------
void LLAgentCamera::lookAtLastChat()
{
- // Block if camera is animating or not in normal third person camera mode
- if (mCameraAnimating || !cameraThirdPerson())
- {
- return;
- }
-
- LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter());
- if (!chatter)
- {
- return;
- }
-
- LLVector3 delta_pos;
- if (chatter->isAvatar())
- {
- LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
- if (isAgentAvatarValid() && chatter_av->mHeadp)
- {
- delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgentAvatarp->mHeadp->getWorldPosition();
- }
- else
- {
- delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent();
- }
- delta_pos.normalize();
-
- gAgent.setControlFlags(AGENT_CONTROL_STOP);
-
- changeCameraToThirdPerson();
-
- LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition();
- LLVector3 left = delta_pos % LLVector3::z_axis;
- left.normalize();
- LLVector3 up = left % delta_pos;
- up.normalize();
- new_camera_pos -= delta_pos * 0.4f;
- new_camera_pos += left * 0.3f;
- new_camera_pos += up * 0.2f;
-
- setFocusOnAvatar(FALSE, FALSE);
-
- if (chatter_av->mHeadp)
- {
- setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter());
- mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
- }
- else
- {
- setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
- mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
- }
- }
- else
- {
- delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent();
- delta_pos.normalize();
-
- gAgent.setControlFlags(AGENT_CONTROL_STOP);
-
- changeCameraToThirdPerson();
-
- LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition();
- LLVector3 left = delta_pos % LLVector3::z_axis;
- left.normalize();
- LLVector3 up = left % delta_pos;
- up.normalize();
- new_camera_pos -= delta_pos * 0.4f;
- new_camera_pos += left * 0.3f;
- new_camera_pos += up * 0.2f;
-
- setFocusOnAvatar(FALSE, FALSE);
-
- setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
- mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
- }
+ // Block if camera is animating or not in normal third person camera mode
+ if (mCameraAnimating || !cameraThirdPerson())
+ {
+ return;
+ }
+
+ LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter());
+ if (!chatter)
+ {
+ return;
+ }
+
+ LLVector3 delta_pos;
+ if (chatter->isAvatar())
+ {
+ LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
+ if (isAgentAvatarValid() && chatter_av->mHeadp)
+ {
+ delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgentAvatarp->mHeadp->getWorldPosition();
+ }
+ else
+ {
+ delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent();
+ }
+ delta_pos.normalize();
+
+ gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+ changeCameraToThirdPerson();
+
+ LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition();
+ LLVector3 left = delta_pos % LLVector3::z_axis;
+ left.normalize();
+ LLVector3 up = left % delta_pos;
+ up.normalize();
+ new_camera_pos -= delta_pos * 0.4f;
+ new_camera_pos += left * 0.3f;
+ new_camera_pos += up * 0.2f;
+
+ setFocusOnAvatar(FALSE, FALSE);
+
+ if (chatter_av->mHeadp)
+ {
+ setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter());
+ mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
+ }
+ else
+ {
+ setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
+ mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+ }
+ }
+ else
+ {
+ delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent();
+ delta_pos.normalize();
+
+ gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+ changeCameraToThirdPerson();
+
+ LLVector3 new_camera_pos = gAgentAvatarp->mHeadp->getWorldPosition();
+ LLVector3 left = delta_pos % LLVector3::z_axis;
+ left.normalize();
+ LLVector3 up = left % delta_pos;
+ up.normalize();
+ new_camera_pos -= delta_pos * 0.4f;
+ new_camera_pos += left * 0.3f;
+ new_camera_pos += up * 0.2f;
+
+ setFocusOnAvatar(FALSE, FALSE);
+
+ setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
+ mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+ }
}
bool LLAgentCamera::isfollowCamLocked()
{
- return mFollowCam.getPositionLocked();
+ return mFollowCam.getPositionLocked();
}
BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
{
- // disallow pointing at attachments and avatars
- if (object && (object->isAttachment() || object->isAvatar()))
- {
- return FALSE;
- }
- if (!mPointAt || mPointAt->isDead())
- {
- mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
- mPointAt->setSourceObject(gAgentAvatarp);
- }
- return mPointAt->setPointAt(target_type, object, position);
+ // disallow pointing at attachments and avatars
+ if (object && (object->isAttachment() || object->isAvatar()))
+ {
+ return FALSE;
+ }
+ if (!mPointAt || mPointAt->isDead())
+ {
+ mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
+ mPointAt->setSourceObject(gAgentAvatarp);
+ }
+ return mPointAt->setPointAt(target_type, object, position);
}
void LLAgentCamera::rotateToInitSitRot()
{
- gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
- gAgent.rotate(mInitSitRot);
+ gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
+ gAgent.rotate(mInitSitRot);
}
void LLAgentCamera::resetCameraZoomFraction()
-{
- mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
+{
+ mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
}
ELookAtType LLAgentCamera::getLookAtType()
{
- if (mLookAt)
- {
- return mLookAt->getLookAtType();
- }
- return LOOKAT_TARGET_NONE;
+ if (mLookAt)
+ {
+ return mLookAt->getLookAtType();
+ }
+ return LOOKAT_TARGET_NONE;
}
EPointAtType LLAgentCamera::getPointAtType()
-{
- if (mPointAt)
- {
- return mPointAt->getPointAtType();
- }
- return POINTAT_TARGET_NONE;
+{
+ if (mPointAt)
+ {
+ return mPointAt->getPointAtType();
+ }
+ return POINTAT_TARGET_NONE;
}
void LLAgentCamera::clearGeneralKeys()
{
- mAtKey = 0;
- mWalkKey = 0;
- mLeftKey = 0;
- mUpKey = 0;
- mYawKey = 0.f;
- mPitchKey = 0.f;
+ mAtKey = 0;
+ mWalkKey = 0;
+ mLeftKey = 0;
+ mUpKey = 0;
+ mYawKey = 0.f;
+ mPitchKey = 0.f;
}
void LLAgentCamera::clearOrbitKeys()
{
- mOrbitLeftKey = 0.f;
- mOrbitRightKey = 0.f;
- mOrbitUpKey = 0.f;
- mOrbitDownKey = 0.f;
- mOrbitInKey = 0.f;
- mOrbitOutKey = 0.f;
+ mOrbitLeftKey = 0.f;
+ mOrbitRightKey = 0.f;
+ mOrbitUpKey = 0.f;
+ mOrbitDownKey = 0.f;
+ mOrbitInKey = 0.f;
+ mOrbitOutKey = 0.f;
}
void LLAgentCamera::clearPanKeys()
{
- mPanRightKey = 0.f;
- mPanLeftKey = 0.f;
- mPanUpKey = 0.f;
- mPanDownKey = 0.f;
- mPanInKey = 0.f;
- mPanOutKey = 0.f;
+ mPanRightKey = 0.f;
+ mPanLeftKey = 0.f;
+ mPanUpKey = 0.f;
+ mPanDownKey = 0.f;
+ mPanInKey = 0.f;
+ mPanOutKey = 0.f;
}
// static
S32 LLAgentCamera::directionToKey(S32 direction)
{
- if (direction > 0) return 1;
- if (direction < 0) return -1;
- return 0;
+ if (direction > 0) return 1;
+ if (direction < 0) return -1;
+ return 0;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 754ee5aa23..90f9b38f2d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -108,7 +108,7 @@
#include "llscenemonitor.h"
#include "llavatarrenderinfoaccountant.h"
#include "lllocalbitmaps.h"
-#include "llperfstats.h"
+#include "llperfstats.h"
#include "llgltfmateriallist.h"
// Linden library includes
@@ -148,7 +148,7 @@
#include <boost/throw_exception.hpp>
#if LL_WINDOWS
-# include <share.h> // For _SH_DENYWR in processMarkerFiles
+# include <share.h> // For _SH_DENYWR in processMarkerFiles
#else
# include <sys/file.h> // For processMarkerFiles
#endif
@@ -228,6 +228,7 @@
#include "pipeline.h"
#include "llgesturemgr.h"
#include "llsky.h"
+#include "llvlcomposition.h"
#include "llvlmanager.h"
#include "llviewercamera.h"
#include "lldrawpoolbump.h"
@@ -238,6 +239,8 @@
#include "llavatariconctrl.h"
#include "llgroupiconctrl.h"
#include "llviewerassetstats.h"
+#include "gltfscenemanager.h"
+
#include "workqueue.h"
using namespace LL;
@@ -316,16 +319,16 @@ const char* gPlatform = LL_PLATFORM_KEY;
LLSD gDebugInfo;
-U32 gFrameCount = 0;
+U32 gFrameCount = 0;
U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground
LLPumpIO* gServicePump = NULL;
U64MicrosecondsImplicit gFrameTime = 0;
F32SecondsImplicit gFrameTimeSeconds = 0.f;
F32SecondsImplicit gFrameIntervalSeconds = 0.f;
-F32 gFPSClamped = 10.f; // Pretend we start at target rate.
-F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
-U64MicrosecondsImplicit gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
+F32 gFPSClamped = 10.f; // Pretend we start at target rate.
+F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
+U64MicrosecondsImplicit gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
LLTimer gRenderStartTime;
LLFrameTimer gForegroundTime;
@@ -338,24 +341,24 @@ F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
S32 gPendingMetricsUploads = 0;
-BOOL gDisconnected = FALSE;
+BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
-LLFrameTimer gRestoreGLTimer;
-BOOL gRestoreGL = FALSE;
-bool gUseWireframe = FALSE;
+LLFrameTimer gRestoreGLTimer;
+BOOL gRestoreGL = FALSE;
+bool gUseWireframe = FALSE;
LLMemoryInfo gSysMemory;
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
std::string gLastVersionChannel;
-LLVector3 gWindVec(3.0, 3.0, 0.0);
-LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
+LLVector3 gWindVec(3.0, 3.0, 0.0);
+LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
-U32 gPacketsIn = 0;
+U32 gPacketsIn = 0;
-BOOL gPrintMessagesThisFrame = FALSE;
+BOOL gPrintMessagesThisFrame = FALSE;
BOOL gRandomizeFramerate = FALSE;
BOOL gPeriodicSlowFrame = FALSE;
@@ -390,53 +393,53 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
static std::set<std::string> default_trans_args;
void init_default_trans_args()
{
- default_trans_args.insert("SECOND_LIFE"); // World
- default_trans_args.insert("APP_NAME");
- default_trans_args.insert("CAPITALIZED_APP_NAME");
- default_trans_args.insert("SECOND_LIFE_GRID");
- default_trans_args.insert("SUPPORT_SITE");
- // This URL shows up in a surprising number of places in various skin
- // files. We really only want to have to maintain a single copy of it.
- default_trans_args.insert("create_account_url");
+ default_trans_args.insert("SECOND_LIFE"); // World
+ default_trans_args.insert("APP_NAME");
+ default_trans_args.insert("CAPITALIZED_APP_NAME");
+ default_trans_args.insert("SECOND_LIFE_GRID");
+ default_trans_args.insert("SUPPORT_SITE");
+ // This URL shows up in a surprising number of places in various skin
+ // files. We really only want to have to maintain a single copy of it.
+ default_trans_args.insert("create_account_url");
}
struct SettingsFile : public LLInitParam::Block<SettingsFile>
{
- Mandatory<std::string> name;
- Optional<std::string> file_name;
- Optional<bool> required,
- persistent;
- Optional<std::string> file_name_setting;
-
- SettingsFile()
- : name("name"),
- file_name("file_name"),
- required("required", false),
- persistent("persistent", true),
- file_name_setting("file_name_setting")
- {}
+ Mandatory<std::string> name;
+ Optional<std::string> file_name;
+ Optional<bool> required,
+ persistent;
+ Optional<std::string> file_name_setting;
+
+ SettingsFile()
+ : name("name"),
+ file_name("file_name"),
+ required("required", false),
+ persistent("persistent", true),
+ file_name_setting("file_name_setting")
+ {}
};
struct SettingsGroup : public LLInitParam::Block<SettingsGroup>
{
- Mandatory<std::string> name;
- Mandatory<S32> path_index;
- Multiple<SettingsFile> files;
-
- SettingsGroup()
- : name("name"),
- path_index("path_index"),
- files("file")
- {}
+ Mandatory<std::string> name;
+ Mandatory<S32> path_index;
+ Multiple<SettingsFile> files;
+
+ SettingsGroup()
+ : name("name"),
+ path_index("path_index"),
+ files("file")
+ {}
};
struct SettingsFiles : public LLInitParam::Block<SettingsFiles>
{
- Multiple<SettingsGroup> groups;
+ Multiple<SettingsGroup> groups;
- SettingsFiles()
- : groups("group")
- {}
+ SettingsFiles()
+ : groups("group")
+ {}
};
static std::string gWindowTitle;
@@ -451,122 +454,122 @@ static bool app_metrics_qa_mode = false;
void idle_afk_check()
{
- // check idle timers
- F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
- F32 afk_timeout = gSavedSettings.getS32("AFKTimeout");
- if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK())
- {
- LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;
- gAgent.setAFK();
- }
+ // check idle timers
+ F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
+ F32 afk_timeout = gSavedSettings.getS32("AFKTimeout");
+ if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK())
+ {
+ LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;
+ gAgent.setAFK();
+ }
}
// A callback set in LLAppViewer::init()
static void ui_audio_callback(const LLUUID& uuid)
{
- if (gAudiop)
- {
- SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
- gAudiop->triggerSound(soundData);
- }
+ if (gAudiop)
+ {
+ SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ gAudiop->triggerSound(soundData);
+ }
}
// A callback set in LLAppViewer::init()
static void deferred_ui_audio_callback(const LLUUID& uuid)
{
- if (gAudiop)
- {
- SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
- LLDeferredSounds::instance().deferSound(soundData);
- }
+ if (gAudiop)
+ {
+ SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ LLDeferredSounds::instance().deferSound(soundData);
+ }
}
-bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
+bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
- if(!match || !base || base->getPlainText())
- return false;
-
- LLUUID match_id = match->getID();
-
- LLIconCtrl* icon;
-
- if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor
- || gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group
- {
- LLGroupIconCtrl::Params icon_params;
- icon_params.group_id = match_id;
- icon_params.rect = LLRect(0, 16, 16, 0);
- icon_params.visible = true;
- icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
- }
- else
- {
- LLAvatarIconCtrl::Params icon_params;
- icon_params.avatar_id = match_id;
- icon_params.rect = LLRect(0, 16, 16, 0);
- icon_params.visible = true;
- icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
- }
-
- LLInlineViewSegment::Params params;
- params.force_newline = false;
- params.view = icon;
- params.left_pad = 4;
- params.right_pad = 4;
- params.top_pad = -2;
- params.bottom_pad = 2;
-
- base->appendWidget(params," ",false);
-
- return true;
+ if(!match || !base || base->getPlainText())
+ return false;
+
+ LLUUID match_id = match->getID();
+
+ LLIconCtrl* icon;
+
+ if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor
+ || gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group
+ {
+ LLGroupIconCtrl::Params icon_params;
+ icon_params.group_id = match_id;
+ icon_params.rect = LLRect(0, 16, 16, 0);
+ icon_params.visible = true;
+ icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+ }
+ else
+ {
+ LLAvatarIconCtrl::Params icon_params;
+ icon_params.avatar_id = match_id;
+ icon_params.rect = LLRect(0, 16, 16, 0);
+ icon_params.visible = true;
+ icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+ }
+
+ LLInlineViewSegment::Params params;
+ params.force_newline = false;
+ params.view = icon;
+ params.left_pad = 4;
+ params.right_pad = 4;
+ params.top_pad = -2;
+ params.bottom_pad = 2;
+
+ base->appendWidget(params," ",false);
+
+ return true;
}
// Use these strictly for things that are constructed at startup,
// or for things that are performance critical. JC
static void settings_to_globals()
{
- LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
- BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
- BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
+ LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
+ BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
+ BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
- MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
- MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
+ MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
+ MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
- LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
+ LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
#if LL_DARWIN
LLRender::sGLCoreProfile = true;
#else
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
#endif
- LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
- LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
- LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
- LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
- LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
- LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
- LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
- LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
- LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
- LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors"));
- LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
- // clamp auto-open time to some minimum usable value
- LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
- LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
- LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
- LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
-
- gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns"));
- gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns"));
- gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
-
- gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
- gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
+ LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
+ LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
+ LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
+ LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
+ LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
+ LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
+ LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
+ LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
+ LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
+ LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors"));
+ LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
+ // clamp auto-open time to some minimum usable value
+ LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
+ LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
+ LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
+ LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
+
+ gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns"));
+ gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns"));
+ gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
+
+ gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
+ gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
-
+
#if LL_DARWIN
LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL");
- gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
+ gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
#endif
}
@@ -584,41 +587,41 @@ static void settings_modify()
class LLFastTimerLogThread : public LLThread
{
public:
- std::string mFile;
-
- LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log")
- {
- std::string file_name = test_name + std::string(".slp");
- mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name);
- }
-
- void run()
- {
- llofstream os(mFile.c_str());
-
- while (!LLAppViewer::instance()->isQuitting())
- {
- LLTrace::BlockTimer::writeLog(os);
- os.flush();
- ms_sleep(32);
- }
-
- os.close();
- }
+ std::string mFile;
+
+ LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log")
+ {
+ std::string file_name = test_name + std::string(".slp");
+ mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name);
+ }
+
+ void run()
+ {
+ llofstream os(mFile.c_str());
+
+ while (!LLAppViewer::instance()->isQuitting())
+ {
+ LLTrace::BlockTimer::writeLog(os);
+ os.flush();
+ ms_sleep(32);
+ }
+
+ os.close();
+ }
};
//virtual
bool LLAppViewer::initSLURLHandler()
{
- // does nothing unless subclassed
- return false;
+ // does nothing unless subclassed
+ return false;
}
//virtual
bool LLAppViewer::sendURLToOtherInstance(const std::string& url)
{
- // does nothing unless subclassed
- return false;
+ // does nothing unless subclassed
+ return false;
}
//----------------------------------------------------------------------------
@@ -634,402 +637,402 @@ LLPurgeDiskCacheThread* LLAppViewer::sPurgeDiskCacheThread = NULL;
std::string getRuntime()
{
- return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value());
+ return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value());
}
LLAppViewer::LLAppViewer()
-: mMarkerFile(),
- mLogoutMarkerFile(),
- mReportedCrash(false),
- mNumSessions(0),
+: mMarkerFile(),
+ mLogoutMarkerFile(),
+ mReportedCrash(false),
+ mNumSessions(0),
mGeneralThreadPool(nullptr),
- mPurgeCache(false),
- mPurgeCacheOnExit(false),
- mPurgeUserDataOnExit(false),
- mSecondInstance(false),
- mUpdaterNotFound(false),
- mSavedFinalSnapshot(false),
- mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
- mQuitRequested(false),
- mLogoutRequestSent(false),
- mLastAgentControlFlags(0),
- mLastAgentForceUpdate(0),
- mMainloopTimeout(NULL),
- mAgentRegionLastAlive(false),
- mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
- mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
- mFastTimerLogThread(NULL),
- mSettingsLocationList(NULL),
- mIsFirstRun(false)
+ mPurgeCache(false),
+ mPurgeCacheOnExit(false),
+ mPurgeUserDataOnExit(false),
+ mSecondInstance(false),
+ mUpdaterNotFound(false),
+ mSavedFinalSnapshot(false),
+ mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
+ mQuitRequested(false),
+ mLogoutRequestSent(false),
+ mLastAgentControlFlags(0),
+ mLastAgentForceUpdate(0),
+ mMainloopTimeout(NULL),
+ mAgentRegionLastAlive(false),
+ mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
+ mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
+ mFastTimerLogThread(NULL),
+ mSettingsLocationList(NULL),
+ mIsFirstRun(false)
{
- if(NULL != sInstance)
- {
- LL_ERRS() << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << LL_ENDL;
- }
+ if(NULL != sInstance)
+ {
+ LL_ERRS() << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << LL_ENDL;
+ }
mDumpPath ="";
- // Need to do this initialization before we do anything else, since anything
- // that touches files should really go through the lldir API
- gDirUtilp->initAppDirs("SecondLife");
- //
- // IMPORTANT! Do NOT put anything that will write
- // into the log files during normal startup until AFTER
- // we run the "program crashed last time" error handler below.
- //
- sInstance = this;
-
- gLoggedInTime.stop();
-
- processMarkerFiles();
- //
- // OK to write stuff to logs now, we've now crash reported if necessary
- //
-
- LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple());
-
- // Under some circumstances we want to read the static_debug_info.log file
- // from the previous viewer run between this constructor call and the
- // init() call, which will overwrite the static_debug_info.log file for
- // THIS run. So setDebugFileNames() early.
+ // Need to do this initialization before we do anything else, since anything
+ // that touches files should really go through the lldir API
+ gDirUtilp->initAppDirs("SecondLife");
+ //
+ // IMPORTANT! Do NOT put anything that will write
+ // into the log files during normal startup until AFTER
+ // we run the "program crashed last time" error handler below.
+ //
+ sInstance = this;
+
+ gLoggedInTime.stop();
+
+ processMarkerFiles();
+ //
+ // OK to write stuff to logs now, we've now crash reported if necessary
+ //
+
+ LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple());
+
+ // Under some circumstances we want to read the static_debug_info.log file
+ // from the previous viewer run between this constructor call and the
+ // init() call, which will overwrite the static_debug_info.log file for
+ // THIS run. So setDebugFileNames() early.
# ifdef LL_BUGSPLAT
- // MAINT-8917: don't create a dump directory just for the
- // static_debug_info.log file
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+ // MAINT-8917: don't create a dump directory just for the
+ // static_debug_info.log file
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
# else // ! LL_BUGSPLAT
- // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
# endif // ! LL_BUGSPLAT
- mDumpPath = logdir;
+ mDumpPath = logdir;
- setDebugFileNames(logdir);
+ setDebugFileNames(logdir);
}
LLAppViewer::~LLAppViewer()
{
- delete mSettingsLocationList;
+ delete mSettingsLocationList;
- destroyMainloopTimeout();
+ destroyMainloopTimeout();
- // If we got to this destructor somehow, the app didn't hang.
- removeMarkerFiles();
+ // If we got to this destructor somehow, the app didn't hang.
+ removeMarkerFiles();
}
class LLUITranslationBridge : public LLTranslationBridge
{
public:
- virtual std::string getString(const std::string &xml_desc)
- {
- return LLTrans::getString(xml_desc);
- }
+ virtual std::string getString(const std::string &xml_desc)
+ {
+ return LLTrans::getString(xml_desc);
+ }
};
bool LLAppViewer::init()
{
- setupErrorHandling(mSecondInstance);
+ setupErrorHandling(mSecondInstance);
- //
- // Start of the application
- //
+ //
+ // Start of the application
+ //
// initialize the LLSettingsType translation bridge.
LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();
LLSettingsType::initParamSingleton(trans);
- // initialize SSE options
- LLVector4a::initClass();
+ // initialize SSE options
+ LLVector4a::initClass();
- //initialize particle index pool
- LLVOPartGroup::initClass();
+ //initialize particle index pool
+ LLVOPartGroup::initClass();
- // set skin search path to default, will be overridden later
- // this allows simple skinned file lookups to work
- gDirUtilp->setSkinFolder("default", "en");
+ // set skin search path to default, will be overridden later
+ // this allows simple skinned file lookups to work
+ gDirUtilp->setSkinFolder("default", "en");
-// initLoggingAndGetLastDuration();
+// initLoggingAndGetLastDuration();
- //
- // OK to write stuff to logs now, we've now crash reported if necessary
- //
- init_default_trans_args();
+ //
+ // OK to write stuff to logs now, we've now crash reported if necessary
+ //
+ init_default_trans_args();
// inits from settings.xml and from strings.xml
- if (!initConfiguration())
- return false;
+ if (!initConfiguration())
+ return false;
- LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ;
+ LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ;
- //set the max heap size.
- initMaxHeapSize() ;
- LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
+ //set the max heap size.
+ initMaxHeapSize() ;
+ LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
- // Although initLoggingAndGetLastDuration() is the right place to mess with
- // setFatalFunction(), we can't query gSavedSettings until after
- // initConfiguration().
- S32 rc(gSavedSettings.getS32("QAModeTermCode"));
- if (rc >= 0)
- {
- // QAModeTermCode set, terminate with that rc on LL_ERRS. Use
- // _exit() rather than exit() because normal cleanup depends too
- // much on successful startup!
- LLError::setFatalFunction([rc](const std::string&){ _exit(rc); });
- }
+ // Although initLoggingAndGetLastDuration() is the right place to mess with
+ // setFatalFunction(), we can't query gSavedSettings until after
+ // initConfiguration().
+ S32 rc(gSavedSettings.getS32("QAModeTermCode"));
+ if (rc >= 0)
+ {
+ // QAModeTermCode set, terminate with that rc on LL_ERRS. Use
+ // _exit() rather than exit() because normal cleanup depends too
+ // much on successful startup!
+ LLError::setFatalFunction([rc](const std::string&){ _exit(rc); });
+ }
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
- // Initialize the non-LLCurl libcurl library. Should be called
- // before consumers (LLTextureFetch).
- mAppCoreHttp.init();
+ // Initialize the non-LLCurl libcurl library. Should be called
+ // before consumers (LLTextureFetch).
+ mAppCoreHttp.init();
- LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ;
+ LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ;
LLMachineID::init();
- {
- if (gSavedSettings.getBOOL("QAModeMetrics"))
- {
- app_metrics_qa_mode = true;
- app_metrics_interval = METRICS_INTERVAL_QA;
- }
- LLViewerAssetStatsFF::init();
- }
-
- initThreads();
- LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ;
-
- // Initialize settings early so that the defaults for ignorable dialogs are
- // picked up and then correctly re-saved after launching the updater (STORM-1268).
- LLUI::settings_map_t settings_map;
- settings_map["config"] = &gSavedSettings;
- settings_map["ignores"] = &gWarningSettings;
- settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
- settings_map["account"] = &gSavedPerAccountSettings;
-
- LLUI::initParamSingleton(settings_map,
- LLUIImageList::getInstance(),
- ui_audio_callback,
- deferred_ui_audio_callback);
- LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
-
- // NOW LLUI::getLanguage() should work. gDirUtilp must know the language
- // for this session ASAP so all the file-loading commands that follow,
- // that use findSkinnedFilenames(), will include the localized files.
- gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage());
-
- // Setup LLTrans after LLUI::initClass has been called.
- initStrings();
+ {
+ if (gSavedSettings.getBOOL("QAModeMetrics"))
+ {
+ app_metrics_qa_mode = true;
+ app_metrics_interval = METRICS_INTERVAL_QA;
+ }
+ LLViewerAssetStatsFF::init();
+ }
+
+ initThreads();
+ LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ;
+
+ // Initialize settings early so that the defaults for ignorable dialogs are
+ // picked up and then correctly re-saved after launching the updater (STORM-1268).
+ LLUI::settings_map_t settings_map;
+ settings_map["config"] = &gSavedSettings;
+ settings_map["ignores"] = &gWarningSettings;
+ settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
+ settings_map["account"] = &gSavedPerAccountSettings;
+
+ LLUI::initParamSingleton(settings_map,
+ LLUIImageList::getInstance(),
+ ui_audio_callback,
+ deferred_ui_audio_callback);
+ LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
+
+ // NOW LLUI::getLanguage() should work. gDirUtilp must know the language
+ // for this session ASAP so all the file-loading commands that follow,
+ // that use findSkinnedFilenames(), will include the localized files.
+ gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage());
+
+ // Setup LLTrans after LLUI::initClass has been called.
+ initStrings();
// initialize LLWearableType translation bridge.
// Will immediately use LLTranslationBridge to init LLWearableDictionary
LLWearableType::initParamSingleton(trans);
- // Setup notifications after LLUI::initClass() has been called.
- LLNotifications::instance();
- LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
+ // Setup notifications after LLUI::initClass() has been called.
+ LLNotifications::instance();
+ LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // *FIX: The following code isn't grouped into functions yet.
+ //////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
+ // *FIX: The following code isn't grouped into functions yet.
- //
- // Various introspection concerning the libs we're using - particularly
- // the libs involved in getting to a full login screen.
- //
- LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
- LL_INFOS("InitInfo") << "libcurl version is: " << LLCore::LLHttp::getCURLVersion() << LL_ENDL;
+ //
+ // Various introspection concerning the libs we're using - particularly
+ // the libs involved in getting to a full login screen.
+ //
+ LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
+ LL_INFOS("InitInfo") << "libcurl version is: " << LLCore::LLHttp::getCURLVersion() << LL_ENDL;
- /////////////////////////////////////////////////
- // OS-specific login dialogs
- /////////////////////////////////////////////////
+ /////////////////////////////////////////////////
+ // OS-specific login dialogs
+ /////////////////////////////////////////////////
- //test_cached_control();
+ //test_cached_control();
- // track number of times that app has run
- mNumSessions = gSavedSettings.getS32("NumSessions");
- mNumSessions++;
- gSavedSettings.setS32("NumSessions", mNumSessions);
+ // track number of times that app has run
+ mNumSessions = gSavedSettings.getS32("NumSessions");
+ mNumSessions++;
+ gSavedSettings.setS32("NumSessions", mNumSessions);
- // LLKeyboard relies on LLUI to know what some accelerator keys are called.
- LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
+ // LLKeyboard relies on LLUI to know what some accelerator keys are called.
+ LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
- // Provide the text fields with callbacks for opening Urls
- LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null));
- LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false));
- LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));
- LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
+ // Provide the text fields with callbacks for opening Urls
+ LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null));
+ LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false));
+ LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));
+ LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
- // Let code in llui access the viewer help floater
- LLUI::getInstance()->mHelpImpl = LLViewerHelp::getInstance();
+ // Let code in llui access the viewer help floater
+ LLUI::getInstance()->mHelpImpl = LLViewerHelp::getInstance();
- LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ;
+ LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ;
- // Load translations for tooltips
- LLFloater::initClass();
- LLUrlFloaterDispatchHandler::registerInDispatcher();
+ // Load translations for tooltips
+ LLFloater::initClass();
+ LLUrlFloaterDispatchHandler::registerInDispatcher();
- /////////////////////////////////////////////////
+ /////////////////////////////////////////////////
- LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
+ LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
- LLViewerFloaterReg::registerFloaters();
+ LLViewerFloaterReg::registerFloaters();
- /////////////////////////////////////////////////
- //
- // Load settings files
- //
- //
- LLGroupMgr::parseRoleActions("role_actions.xml");
+ /////////////////////////////////////////////////
+ //
+ // Load settings files
+ //
+ //
+ LLGroupMgr::parseRoleActions("role_actions.xml");
- LLAgent::parseTeleportMessages("teleport_strings.xml");
+ LLAgent::parseTeleportMessages("teleport_strings.xml");
- // load MIME type -> media impl mappings
- std::string mime_types_name;
+ // load MIME type -> media impl mappings
+ std::string mime_types_name;
#if LL_DARWIN
- mime_types_name = "mime_types_mac.xml";
+ mime_types_name = "mime_types_mac.xml";
#elif LL_LINUX
- mime_types_name = "mime_types_linux.xml";
+ mime_types_name = "mime_types_linux.xml";
#else
- mime_types_name = "mime_types.xml";
+ mime_types_name = "mime_types.xml";
#endif
- LLMIMETypes::parseMIMETypes( mime_types_name );
-
- // Copy settings to globals. *TODO: Remove or move to appropriage class initializers
- settings_to_globals();
- // Setup settings listeners
- settings_setup_listeners();
- // Modify settings based on system configuration and compile options
- settings_modify();
-
- // Find partition serial number (Windows) or hardware serial (Mac)
- mSerialNumber = generateSerialNumber();
-
- // do any necessary set-up for accepting incoming SLURLs from apps
- initSLURLHandler();
-
- if(false == initHardwareTest())
- {
- // Early out from user choice.
- return false;
- }
- LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ;
-
- // Prepare for out-of-memory situations, during which we will crash on
- // purpose and save a dump.
+ LLMIMETypes::parseMIMETypes( mime_types_name );
+
+ // Copy settings to globals. *TODO: Remove or move to appropriage class initializers
+ settings_to_globals();
+ // Setup settings listeners
+ settings_setup_listeners();
+ // Modify settings based on system configuration and compile options
+ settings_modify();
+
+ // Find partition serial number (Windows) or hardware serial (Mac)
+ mSerialNumber = generateSerialNumber();
+
+ // do any necessary set-up for accepting incoming SLURLs from apps
+ initSLURLHandler();
+
+ if(false == initHardwareTest())
+ {
+ // Early out from user choice.
+ return false;
+ }
+ LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ;
+
+ // Prepare for out-of-memory situations, during which we will crash on
+ // purpose and save a dump.
#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
- MemSetErrorHandler(first_mem_error_handler);
+ MemSetErrorHandler(first_mem_error_handler);
#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
- // *Note: this is where gViewerStats used to be created.
+ // *Note: this is where gViewerStats used to be created.
- if (!initCache())
- {
- LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
- std::ostringstream msg;
- msg << LLTrans::getString("MBUnableToAccessFile");
- OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
- return 0;
- }
- LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
+ if (!initCache())
+ {
+ LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
+ std::ostringstream msg;
+ msg << LLTrans::getString("MBUnableToAccessFile");
+ OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+ return 0;
+ }
+ LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
// Initialize event recorder
LLViewerEventRecorder::createInstance();
- //
- // Initialize the window
- //
- gGLActive = TRUE;
- initWindow();
- LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ;
+ //
+ // Initialize the window
+ //
+ gGLActive = TRUE;
+ initWindow();
+ LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ;
// writeSystemInfo can be called after window is initialized (gViewerWindow non-null)
writeSystemInfo();
- // initWindow also initializes the Feature List, so now we can initialize this global.
- LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
+ // initWindow also initializes the Feature List, so now we can initialize this global.
+ LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
- // call all self-registered classes
- LLInitClassList::instance().fireCallbacks();
+ // call all self-registered classes
+ LLInitClassList::instance().fireCallbacks();
- LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
+ LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
- gGLManager.getGLInfo(gDebugInfo);
- gGLManager.printGLInfoString();
+ gGLManager.getGLInfo(gDebugInfo);
+ gGLManager.printGLInfoString();
- // If we don't have the right GL requirements, exit.
- if (!gGLManager.mHasRequirements)
- {
+ // If we don't have the right GL requirements, exit.
+ if (!gGLManager.mHasRequirements)
+ {
// already handled with a MBVideoDrvErr
- return 0;
- }
-
- // Without SSE2 support we will crash almost immediately, warn here.
- if (!gSysCPU.hasSSE2())
- {
- // can't use an alert here since we're exiting and
- // all hell breaks lose.
- OSMessageBox(
- LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"),
- LLStringUtil::null,
- OSMB_OK);
- return 0;
- }
-
- // alert the user if they are using unsupported hardware
- if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
- {
- bool unsupported = false;
- LLSD args;
- std::string minSpecs;
-
- // get cpu data from xml
- std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount"));
- S32 minCPU = 0;
- minCPUString >> minCPU;
-
- // get RAM data from XML
- std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
- U64Bytes minRAM;
- minRAMString >> minRAM;
-
- if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
- {
- minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU");
- minSpecs += "\n";
- unsupported = true;
- }
- if(gSysCPU.getMHz() < minCPU)
- {
- minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
- minSpecs += "\n";
- unsupported = true;
- }
- if(gSysMemory.getPhysicalMemoryKB() < minRAM)
- {
- minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
- minSpecs += "\n";
- unsupported = true;
- }
-
- if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
- {
- LLNotificationsUtil::add("UnknownGPU");
- }
-
- if(unsupported)
- {
- if(!gSavedSettings.controlExists("WarnUnsupportedHardware")
- || gSavedSettings.getBOOL("WarnUnsupportedHardware"))
- {
- args["MINSPECS"] = minSpecs;
- LLNotificationsUtil::add("UnsupportedHardware", args );
- }
-
- }
- }
+ return 0;
+ }
+
+ // Without SSE2 support we will crash almost immediately, warn here.
+ if (!gSysCPU.hasSSE2())
+ {
+ // can't use an alert here since we're exiting and
+ // all hell breaks lose.
+ OSMessageBox(
+ LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"),
+ LLStringUtil::null,
+ OSMB_OK);
+ return 0;
+ }
+
+ // alert the user if they are using unsupported hardware
+ if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
+ {
+ bool unsupported = false;
+ LLSD args;
+ std::string minSpecs;
+
+ // get cpu data from xml
+ std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount"));
+ S32 minCPU = 0;
+ minCPUString >> minCPU;
+
+ // get RAM data from XML
+ std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
+ U64Bytes minRAM;
+ minRAMString >> minRAM;
+
+ if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
+ {
+ minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU");
+ minSpecs += "\n";
+ unsupported = true;
+ }
+ if(gSysCPU.getMHz() < minCPU)
+ {
+ minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
+ minSpecs += "\n";
+ unsupported = true;
+ }
+ if(gSysMemory.getPhysicalMemoryKB() < minRAM)
+ {
+ minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
+ minSpecs += "\n";
+ unsupported = true;
+ }
+
+ if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
+ {
+ LLNotificationsUtil::add("UnknownGPU");
+ }
+
+ if(unsupported)
+ {
+ if(!gSavedSettings.controlExists("WarnUnsupportedHardware")
+ || gSavedSettings.getBOOL("WarnUnsupportedHardware"))
+ {
+ args["MINSPECS"] = minSpecs;
+ LLNotificationsUtil::add("UnsupportedHardware", args );
+ }
+
+ }
+ }
#if LL_WINDOWS && ADDRESS_SIZE == 64
if (gGLManager.mIsIntel)
@@ -1080,54 +1083,54 @@ bool LLAppViewer::init()
// Obsolete? mExpectedGLVersion is always zero
#if LL_WINDOWS
- if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
- {
- std::string url;
- if (gGLManager.mIsIntel)
- {
- url = LLTrans::getString("IntelDriverPage");
- }
- else if (gGLManager.mIsNVIDIA)
- {
- url = LLTrans::getString("NvidiaDriverPage");
- }
- else if (gGLManager.mIsAMD)
- {
- url = LLTrans::getString("AMDDriverPage");
- }
-
- if (!url.empty())
- {
- LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url));
- }
- }
+ if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
+ {
+ std::string url;
+ if (gGLManager.mIsIntel)
+ {
+ url = LLTrans::getString("IntelDriverPage");
+ }
+ else if (gGLManager.mIsNVIDIA)
+ {
+ url = LLTrans::getString("NvidiaDriverPage");
+ }
+ else if (gGLManager.mIsAMD)
+ {
+ url = LLTrans::getString("AMDDriverPage");
+ }
+
+ if (!url.empty())
+ {
+ LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url));
+ }
+ }
#endif
- // save the graphics card
- gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
+ // save the graphics card
+ gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
- // Save the current version to the prefs file
- gSavedSettings.setString("LastRunVersion",
- LLVersionInfo::instance().getChannelAndVersion());
+ // Save the current version to the prefs file
+ gSavedSettings.setString("LastRunVersion",
+ LLVersionInfo::instance().getChannelAndVersion());
- gSimLastTime = gRenderStartTime.getElapsedTimeF32();
- gSimFrames = (F32)gFrameCount;
+ gSimLastTime = gRenderStartTime.getElapsedTimeF32();
+ gSimFrames = (F32)gFrameCount;
if (gSavedSettings.getBOOL("JoystickEnabled"))
{
LLViewerJoystick::getInstance()->init(false);
}
- try {
- initializeSecHandler();
- }
- catch (LLProtectedDataException&)
- {
- LLNotificationsUtil::add("CorruptedProtectedDataStore");
- }
+ try {
+ initializeSecHandler();
+ }
+ catch (LLProtectedDataException&)
+ {
+ LLNotificationsUtil::add("CorruptedProtectedDataStore");
+ }
- gGLActive = FALSE;
+ gGLActive = FALSE;
#if LL_RELEASE_FOR_DOWNLOAD
// Skip updater if this is a non-interactive instance
@@ -1225,25 +1228,25 @@ bool LLAppViewer::init()
<< LL_ENDL;
}
- LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
+ LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
- //EXT-7013 - On windows for some locale (Japanese) standard
- //datetime formatting functions didn't support some parameters such as "weekday".
- //Names for days and months localized in xml are also useful for Polish locale(STORM-107).
- std::string language = gSavedSettings.getString("Language");
- if(language == "ja" || language == "pl")
- {
- LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
- LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
- LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames"));
- LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames"));
- LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat"));
-
- LLStringOps::sAM = LLTrans::getString("dateTimeAM");
- LLStringOps::sPM = LLTrans::getString("dateTimePM");
- }
+ //EXT-7013 - On windows for some locale (Japanese) standard
+ //datetime formatting functions didn't support some parameters such as "weekday".
+ //Names for days and months localized in xml are also useful for Polish locale(STORM-107).
+ std::string language = gSavedSettings.getString("Language");
+ if(language == "ja" || language == "pl")
+ {
+ LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
+ LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
+ LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames"));
+ LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames"));
+ LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat"));
+
+ LLStringOps::sAM = LLTrans::getString("dateTimeAM");
+ LLStringOps::sPM = LLTrans::getString("dateTimePM");
+ }
- LLAgentLanguage::init();
+ LLAgentLanguage::init();
/// Tell the Coprocedure manager how to discover and store the pool sizes
// what I wanted
@@ -1251,33 +1254,35 @@ bool LLAppViewer::init()
boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1),
boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS));
- // TODO: consider moving proxy initialization here or LLCopocedureManager after proxy initialization, may be implement
- // some other protection to make sure we don't use network before initializng proxy
+ // TODO: consider moving proxy initialization here or LLCopocedureManager after proxy initialization, may be implement
+ // some other protection to make sure we don't use network before initializng proxy
- /*----------------------------------------------------------------------*/
- // nat 2016-06-29 moved the following here from the former mainLoop().
- mMainloopTimeout = new LLWatchdogTimeout();
+ /*----------------------------------------------------------------------*/
+ // nat 2016-06-29 moved the following here from the former mainLoop().
+ mMainloopTimeout = new LLWatchdogTimeout();
- // Create IO Pump to use for HTTP Requests.
- gServicePump = new LLPumpIO(gAPRPoolp);
+ // Create IO Pump to use for HTTP Requests.
+ gServicePump = new LLPumpIO(gAPRPoolp);
- // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
+ // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
- LLVoiceChannel::initClass();
- LLVoiceClient::initParamSingleton(gServicePump);
- LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
+ LLVoiceChannel::initClass();
+ LLVoiceClient::initParamSingleton(gServicePump);
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
- joystick = LLViewerJoystick::getInstance();
- joystick->setNeedsReset(true);
- /*----------------------------------------------------------------------*/
- // Load User's bindings
- loadKeyBindings();
+ joystick = LLViewerJoystick::getInstance();
+ joystick->setNeedsReset(true);
+ /*----------------------------------------------------------------------*/
+ // Load User's bindings
+ loadKeyBindings();
//LLSimpleton creations
LLEnvironment::createInstance();
LLWorld::createInstance();
LLSelectMgr::createInstance();
LLViewerCamera::createInstance();
+ LL::GLTFSceneManager::createInstance();
+
#if LL_WINDOWS
if (!mSecondInstance)
@@ -1286,23 +1291,23 @@ bool LLAppViewer::init()
}
#endif
- return true;
+ return true;
}
void LLAppViewer::initMaxHeapSize()
{
- //set the max heap size.
- //here is some info regarding to the max heap size:
- //------------------------------------------------------------------------------------------
- // OS | setting | SL address bits | max manageable memory space | max heap size
- // Win 32 | default | 32-bit | 2GB | < 1.7GB
- // Win 32 | /3G | 32-bit | 3GB | < 1.7GB or 2.7GB
- //Linux 32 | default | 32-bit | 3GB | < 2.7GB
- //Linux 32 |HUGEMEM | 32-bit | 4GB | < 3.7GB
- //64-bit OS |default | 32-bit | 4GB | < 3.7GB
- //64-bit OS |default | 64-bit | N/A (> 4GB) | N/A (> 4GB)
- //------------------------------------------------------------------------------------------
- //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB.
+ //set the max heap size.
+ //here is some info regarding to the max heap size:
+ //------------------------------------------------------------------------------------------
+ // OS | setting | SL address bits | max manageable memory space | max heap size
+ // Win 32 | default | 32-bit | 2GB | < 1.7GB
+ // Win 32 | /3G | 32-bit | 3GB | < 1.7GB or 2.7GB
+ //Linux 32 | default | 32-bit | 3GB | < 2.7GB
+ //Linux 32 |HUGEMEM | 32-bit | 4GB | < 3.7GB
+ //64-bit OS |default | 32-bit | 4GB | < 3.7GB
+ //64-bit OS |default | 64-bit | N/A (> 4GB) | N/A (> 4GB)
+ //------------------------------------------------------------------------------------------
+ //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB.
#ifndef LL_X86_64
F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ;
@@ -1319,42 +1324,42 @@ LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");
bool LLAppViewer::frame()
{
- bool ret = false;
-
- if (gSimulateMemLeak)
- {
- try
- {
- ret = doFrame();
- }
- catch (const LLContinueError&)
- {
- LOG_UNHANDLED_EXCEPTION("");
- }
- catch (std::bad_alloc&)
- {
- LLMemory::logMemoryInfo(TRUE);
- LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if (mem_leak_instance)
- {
- mem_leak_instance->stop();
- }
- LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL;
- }
- }
- else
- {
- try
- {
- ret = doFrame();
- }
- catch (const LLContinueError&)
- {
- LOG_UNHANDLED_EXCEPTION("");
- }
- }
-
- return ret;
+ bool ret = false;
+
+ if (gSimulateMemLeak)
+ {
+ try
+ {
+ ret = doFrame();
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ catch (std::bad_alloc&)
+ {
+ LLMemory::logMemoryInfo(TRUE);
+ LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if (mem_leak_instance)
+ {
+ mem_leak_instance->stop();
+ }
+ LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL;
+ }
+ }
+ else
+ {
+ try
+ {
+ ret = doFrame();
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ }
+
+ return ret;
}
bool LLAppViewer::doFrame()
@@ -1447,63 +1452,63 @@ bool LLAppViewer::doFrame()
}
}
- if (!LLApp::isExiting())
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" )
- pingMainloopTimeout("Main:JoystickKeyboard");
-
- // Scan keyboard for movement keys. Command keys and typing
- // are handled by windows callbacks. Don't do this until we're
- // done initializing. JC
- if (gViewerWindow
- && (gHeadlessClient || gViewerWindow->getWindow()->getVisible())
- && gViewerWindow->getActive()
- && !gViewerWindow->getWindow()->getMinimized()
- && LLStartUp::getStartupState() == STATE_STARTED
- && (gHeadlessClient || !gViewerWindow->getShowProgress())
- && !gFocusMgr.focusLocked())
- {
+ if (!LLApp::isExiting())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" )
+ pingMainloopTimeout("Main:JoystickKeyboard");
+
+ // Scan keyboard for movement keys. Command keys and typing
+ // are handled by windows callbacks. Don't do this until we're
+ // done initializing. JC
+ if (gViewerWindow
+ && (gHeadlessClient || gViewerWindow->getWindow()->getVisible())
+ && gViewerWindow->getActive()
+ && !gViewerWindow->getWindow()->getMinimized()
+ && LLStartUp::getStartupState() == STATE_STARTED
+ && (gHeadlessClient || !gViewerWindow->getShowProgress())
+ && !gFocusMgr.focusLocked())
+ {
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
- joystick->scanJoystick();
- gKeyboard->scanKeyboard();
+ joystick->scanJoystick();
+ gKeyboard->scanKeyboard();
gViewerInput.scanMouse();
- }
+ }
- // Update state based on messages, user input, object idle.
- {
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
- pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
- }
+ // Update state based on messages, user input, object idle.
+ {
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
+ pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
+ }
- {
+ {
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle");
- idle();
- }
+ idle();
+ }
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
- resumeMainloopTimeout();
- }
- }
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
+ resumeMainloopTimeout();
+ }
+ }
- if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
- {
- pauseMainloopTimeout();
- saveFinalSnapshot();
+ if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
+ {
+ pauseMainloopTimeout();
+ saveFinalSnapshot();
if (LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->terminate();
}
- disconnectViewer();
- resumeMainloopTimeout();
- }
+ disconnectViewer();
+ resumeMainloopTimeout();
+ }
- // Render scene.
- // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
+ // Render scene.
+ // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display");
@@ -1527,159 +1532,159 @@ bool LLAppViewer::doFrame()
LLViewerStatsRecorder::instance().idle();
}
}
- }
+ }
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
- pingMainloopTimeout("Main:Sleep");
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
+ pingMainloopTimeout("Main:Sleep");
- pauseMainloopTimeout();
- }
+ pauseMainloopTimeout();
+ }
- // Sleep and run background threads
- {
- //LL_RECORD_BLOCK_TIME(SLEEP2);
- LL_PROFILE_ZONE_WARN( "Sleep2" )
+ // Sleep and run background threads
+ {
+ //LL_RECORD_BLOCK_TIME(SLEEP2);
+ LL_PROFILE_ZONE_WARN( "Sleep2" )
- // yield some time to the os based on command line option
- static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
- if(yield_time >= 0)
- {
+ // yield some time to the os based on command line option
+ static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
+ if(yield_time >= 0)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Yield");
- LL_PROFILE_ZONE_NUM( yield_time )
- ms_sleep(yield_time);
- }
-
- if (gNonInteractive)
- {
- S32 non_interactive_ms_sleep_time = 100;
- LLAppViewer::getTextureCache()->pause();
- ms_sleep(non_interactive_ms_sleep_time);
- }
-
- // yield cooperatively when not running as foreground window
- // and when not quiting (causes trouble at mac's cleanup stage)
- if (!LLApp::isExiting()
- && ((gViewerWindow && !gViewerWindow->getWindow()->getVisible())
- || !gFocusMgr.getAppHasFocus()))
- {
- // Sleep if we're not rendering, or the window is minimized.
- static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40);
- S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000);
- // don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads
- // of equal priority on Windows
- if (milliseconds_to_sleep > 0)
- {
+ LL_PROFILE_ZONE_NUM( yield_time )
+ ms_sleep(yield_time);
+ }
+
+ if (gNonInteractive)
+ {
+ S32 non_interactive_ms_sleep_time = 100;
+ LLAppViewer::getTextureCache()->pause();
+ ms_sleep(non_interactive_ms_sleep_time);
+ }
+
+ // yield cooperatively when not running as foreground window
+ // and when not quiting (causes trouble at mac's cleanup stage)
+ if (!LLApp::isExiting()
+ && ((gViewerWindow && !gViewerWindow->getWindow()->getVisible())
+ || !gFocusMgr.getAppHasFocus()))
+ {
+ // Sleep if we're not rendering, or the window is minimized.
+ static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40);
+ S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000);
+ // don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads
+ // of equal priority on Windows
+ if (milliseconds_to_sleep > 0)
+ {
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP );
ms_sleep(milliseconds_to_sleep);
- // also pause worker threads during this wait period
- LLAppViewer::getTextureCache()->pause();
- }
- }
-
- if (mRandomizeFramerate)
- {
- ms_sleep(rand() % 200);
- }
-
- if (mPeriodicSlowFrame
- && (gFrameCount % 10 == 0))
- {
- LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL;
- ms_sleep(500);
- }
-
- S32 total_work_pending = 0;
- S32 total_io_pending = 0;
- {
- S32 work_pending = 0;
- S32 io_pending = 0;
- F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f);
-
- work_pending += updateTextureThreads(max_time);
-
- {
+ // also pause worker threads during this wait period
+ LLAppViewer::getTextureCache()->pause();
+ }
+ }
+
+ if (mRandomizeFramerate)
+ {
+ ms_sleep(rand() % 200);
+ }
+
+ if (mPeriodicSlowFrame
+ && (gFrameCount % 10 == 0))
+ {
+ LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL;
+ ms_sleep(500);
+ }
+
+ S32 total_work_pending = 0;
+ S32 total_io_pending = 0;
+ {
+ S32 work_pending = 0;
+ S32 io_pending = 0;
+ F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f);
+
+ work_pending += updateTextureThreads(max_time);
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("LFS Thread");
- io_pending += LLLFSThread::updateClass(1);
- }
-
- if (io_pending > 1000)
- {
- ms_sleep(llmin(io_pending/100,100)); // give the lfs some time to catch up
- }
-
- total_work_pending += work_pending ;
- total_io_pending += io_pending ;
-
- }
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" )
- gMeshRepo.update() ;
- }
-
- if(!total_work_pending) //pause texture fetching threads if nothing to process.
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" )
- LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getTextureFetch()->pause();
- }
- if(!total_io_pending) //pause file threads if nothing to process.
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df LLVFSThread" )
- LLLFSThread::sLocal->pause();
- }
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
- resumeMainloopTimeout();
- }
- pingMainloopTimeout("Main:End");
- }
- }
-
- if (LLApp::isExiting())
- {
- // Save snapshot for next time, if we made it through initialization
- if (STATE_STARTED == LLStartUp::getStartupState())
- {
- saveFinalSnapshot();
- }
-
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->terminate();
- }
-
- delete gServicePump;
- gServicePump = NULL;
-
- destroyMainloopTimeout();
-
- LL_INFOS() << "Exiting main_loop" << LL_ENDL;
- }
+ io_pending += LLLFSThread::updateClass(1);
+ }
+
+ if (io_pending > 1000)
+ {
+ ms_sleep(llmin(io_pending/100,100)); // give the lfs some time to catch up
+ }
+
+ total_work_pending += work_pending ;
+ total_io_pending += io_pending ;
+
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" )
+ gMeshRepo.update() ;
+ }
+
+ if(!total_work_pending) //pause texture fetching threads if nothing to process.
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" )
+ LLAppViewer::getTextureCache()->pause();
+ LLAppViewer::getTextureFetch()->pause();
+ }
+ if(!total_io_pending) //pause file threads if nothing to process.
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df LLVFSThread" )
+ LLLFSThread::sLocal->pause();
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
+ resumeMainloopTimeout();
+ }
+ pingMainloopTimeout("Main:End");
+ }
+ }
+
+ if (LLApp::isExiting())
+ {
+ // Save snapshot for next time, if we made it through initialization
+ if (STATE_STARTED == LLStartUp::getStartupState())
+ {
+ saveFinalSnapshot();
+ }
+
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->terminate();
+ }
+
+ delete gServicePump;
+ gServicePump = NULL;
+
+ destroyMainloopTimeout();
+
+ LL_INFOS() << "Exiting main_loop" << LL_ENDL;
+ }
}LLPerfStats::StatsRecorder::endFrame();
LL_PROFILER_FRAME_END
- return ! LLApp::isRunning();
+ return ! LLApp::isRunning();
}
S32 LLAppViewer::updateTextureThreads(F32 max_time)
{
- S32 work_pending = 0;
- {
+ S32 work_pending = 0;
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Texture Cache");
- work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- }
- {
+ work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ }
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Decode");
- work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- }
- {
+ work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ }
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Fetch");
- work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
- }
- return work_pending;
+ work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+ }
+ return work_pending;
}
void LLAppViewer::flushLFSIO()
@@ -1704,200 +1709,200 @@ bool LLAppViewer::cleanup()
{
LLAtmosphere::cleanupClass();
- //ditch LLVOAvatarSelf instance
- gAgentAvatarp = NULL;
+ //ditch LLVOAvatarSelf instance
+ gAgentAvatarp = NULL;
LLNotifications::instance().clear();
- // workaround for DEV-35406 crash on shutdown
- LLEventPumps::instance().reset(true);
+ // workaround for DEV-35406 crash on shutdown
+ LLEventPumps::instance().reset(true);
- //dump scene loading monitor results
- if (LLSceneMonitor::instanceExists())
- {
- if (!isSecondInstance())
- {
+ //dump scene loading monitor results
+ if (LLSceneMonitor::instanceExists())
+ {
+ if (!isSecondInstance())
+ {
std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv");
- LLSceneMonitor::instance().dumpToFile(dump_path);
- }
- LLSceneMonitor::deleteSingleton();
- }
-
- // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
- // here, completely redundant with the one that occurs later in this same
- // function. Presumably the duplication was due to an automated merge gone
- // bad. Not knowing which instance to prefer, we chose to retain the later
- // one because it happens just after mFastTimerLogThread is deleted. This
- // comment is in case we guessed wrong, so we can move it here instead.
+ LLSceneMonitor::instance().dumpToFile(dump_path);
+ }
+ LLSceneMonitor::deleteSingleton();
+ }
+
+ // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
+ // here, completely redundant with the one that occurs later in this same
+ // function. Presumably the duplication was due to an automated merge gone
+ // bad. Not knowing which instance to prefer, we chose to retain the later
+ // one because it happens just after mFastTimerLogThread is deleted. This
+ // comment is in case we guessed wrong, so we can move it here instead.
#if LL_LINUX
- // remove any old breakpad minidump files from the log directory
- if (! isError())
- {
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
- gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
- }
+ // remove any old breakpad minidump files from the log directory
+ if (! isError())
+ {
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+ gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
+ }
#endif
- // Kill off LLLeap objects. We can find them all because LLLeap is derived
- // from LLInstanceTracker.
- LLLeap::instance_snapshot().deleteAll();
+ // Kill off LLLeap objects. We can find them all because LLLeap is derived
+ // from LLInstanceTracker.
+ LLLeap::instance_snapshot().deleteAll();
- //flag all elements as needing to be destroyed immediately
- // to ensure shutdown order
- LLMortician::setZealous(TRUE);
+ //flag all elements as needing to be destroyed immediately
+ // to ensure shutdown order
+ LLMortician::setZealous(TRUE);
// Give any remaining SLPlugin instances a chance to exit cleanly.
LLPluginProcessParent::shutdown();
- disconnectViewer();
- LLViewerCamera::deleteSingleton();
+ disconnectViewer();
+ LLViewerCamera::deleteSingleton();
- LL_INFOS() << "Viewer disconnected" << LL_ENDL;
+ LL_INFOS() << "Viewer disconnected" << LL_ENDL;
+
+ if (gKeyboard)
+ {
+ gKeyboard->resetKeys();
+ }
- if (gKeyboard)
- {
- gKeyboard->resetKeys();
- }
+ display_cleanup();
- display_cleanup();
+ release_start_screen(); // just in case
- release_start_screen(); // just in case
+ LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder
- LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder
+ LL_INFOS() << "Cleaning Up" << LL_ENDL;
- LL_INFOS() << "Cleaning Up" << LL_ENDL;
+ // shut down mesh streamer
+ gMeshRepo.shutdown();
- // shut down mesh streamer
- gMeshRepo.shutdown();
+ // shut down Havok
+ LLPhysicsExtensions::quitSystem();
- // shut down Havok
- LLPhysicsExtensions::quitSystem();
+ // Must clean up texture references before viewer window is destroyed.
+ if(LLHUDManager::instanceExists())
+ {
+ LLHUDManager::getInstance()->updateEffects();
+ LLHUDObject::updateAll();
+ LLHUDManager::getInstance()->cleanupEffects();
+ LLHUDObject::cleanupHUDObjects();
+ LL_INFOS() << "HUD Objects cleaned up" << LL_ENDL;
+ }
- // Must clean up texture references before viewer window is destroyed.
- if(LLHUDManager::instanceExists())
- {
- LLHUDManager::getInstance()->updateEffects();
- LLHUDObject::updateAll();
- LLHUDManager::getInstance()->cleanupEffects();
- LLHUDObject::cleanupHUDObjects();
- LL_INFOS() << "HUD Objects cleaned up" << LL_ENDL;
- }
+ LLKeyframeDataCache::clear();
- LLKeyframeDataCache::clear();
-
- // End TransferManager before deleting systems it depends on (Audio, AssetStorage)
+ // End TransferManager before deleting systems it depends on (Audio, AssetStorage)
#if 0 // this seems to get us stuck in an infinite loop...
- gTransferManager.cleanup();
+ gTransferManager.cleanup();
#endif
- // Note: this is where gWorldMap used to be deleted.
+ // Note: this is where gWorldMap used to be deleted.
- // Note: this is where gHUDManager used to be deleted.
- if(LLHUDManager::instanceExists())
- {
- LLHUDManager::getInstance()->shutdownClass();
- }
+ // Note: this is where gHUDManager used to be deleted.
+ if(LLHUDManager::instanceExists())
+ {
+ LLHUDManager::getInstance()->shutdownClass();
+ }
- delete gAssetStorage;
- gAssetStorage = NULL;
+ delete gAssetStorage;
+ gAssetStorage = NULL;
- LLPolyMesh::freeAllMeshes();
+ LLPolyMesh::freeAllMeshes();
- LLStartUp::cleanupNameCache();
+ LLStartUp::cleanupNameCache();
- // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
+ // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
- if (LLWorldMap::instanceExists())
- {
- LLWorldMap::getInstance()->reset(); // release any images
- }
+ if (LLWorldMap::instanceExists())
+ {
+ LLWorldMap::getInstance()->reset(); // release any images
+ }
- LLCalc::cleanUp();
+ LLCalc::cleanUp();
- LL_INFOS() << "Global stuff deleted" << LL_ENDL;
+ LL_INFOS() << "Global stuff deleted" << LL_ENDL;
- if (gAudiop)
- {
+ if (gAudiop)
+ {
LL_INFOS() << "Shutting down audio" << LL_ENDL;
// be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it.
gAudiop->stopInternetStream();
// shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl();
- delete sai;
- gAudiop->setStreamingAudioImpl(NULL);
+ delete sai;
+ gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
gAudiop->shutdown();
- delete gAudiop;
- gAudiop = NULL;
- }
+ delete gAudiop;
+ gAudiop = NULL;
+ }
- // Note: this is where LLFeatureManager::getInstance()-> used to be deleted.
+ // Note: this is where LLFeatureManager::getInstance()-> used to be deleted.
- // Patch up settings for next time
- // Must do this before we delete the viewer window,
- // such that we can suck rectangle information out of
- // it.
- cleanupSavedSettings();
- LL_INFOS() << "Settings patched up" << LL_ENDL;
+ // Patch up settings for next time
+ // Must do this before we delete the viewer window,
+ // such that we can suck rectangle information out of
+ // it.
+ cleanupSavedSettings();
+ LL_INFOS() << "Settings patched up" << LL_ENDL;
- // delete some of the files left around in the cache.
- removeCacheFiles("*.wav");
- removeCacheFiles("*.tmp");
- removeCacheFiles("*.lso");
- removeCacheFiles("*.out");
- removeCacheFiles("*.dsf");
- removeCacheFiles("*.bodypart");
- removeCacheFiles("*.clothing");
+ // delete some of the files left around in the cache.
+ removeCacheFiles("*.wav");
+ removeCacheFiles("*.tmp");
+ removeCacheFiles("*.lso");
+ removeCacheFiles("*.out");
+ removeCacheFiles("*.dsf");
+ removeCacheFiles("*.bodypart");
+ removeCacheFiles("*.clothing");
- LL_INFOS() << "Cache files removed" << LL_ENDL;
+ LL_INFOS() << "Cache files removed" << LL_ENDL;
- LL_INFOS() << "Shutting down Views" << LL_ENDL;
+ LL_INFOS() << "Shutting down Views" << LL_ENDL;
- // Destroy the UI
- if( gViewerWindow)
- gViewerWindow->shutdownViews();
+ // Destroy the UI
+ if( gViewerWindow)
+ gViewerWindow->shutdownViews();
- LL_INFOS() << "Cleaning up Inventory" << LL_ENDL;
+ LL_INFOS() << "Cleaning up Inventory" << LL_ENDL;
- // Cleanup Inventory after the UI since it will delete any remaining observers
- // (Deleted observers should have already removed themselves)
- gInventory.cleanupInventory();
+ // Cleanup Inventory after the UI since it will delete any remaining observers
+ // (Deleted observers should have already removed themselves)
+ gInventory.cleanupInventory();
- LLCoros::getInstance()->printActiveCoroutines();
+ LLCoros::getInstance()->printActiveCoroutines();
- LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
+ LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
- // Clean up selection managers after UI is destroyed, as UI may be observing them.
- // Clean up before GL is shut down because we might be holding on to objects with texture references
- LLSelectMgr::cleanupGlobals();
+ // Clean up selection managers after UI is destroyed, as UI may be observing them.
+ // Clean up before GL is shut down because we might be holding on to objects with texture references
+ LLSelectMgr::cleanupGlobals();
- LL_INFOS() << "Shutting down OpenGL" << LL_ENDL;
+ LL_INFOS() << "Shutting down OpenGL" << LL_ENDL;
- // Shut down OpenGL
- if( gViewerWindow)
- {
- gViewerWindow->shutdownGL();
-
- // Destroy window, and make sure we're not fullscreen
- // This may generate window reshape and activation events.
- // Therefore must do this before destroying the message system.
- delete gViewerWindow;
- gViewerWindow = NULL;
- LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
- }
+ // Shut down OpenGL
+ if( gViewerWindow)
+ {
+ gViewerWindow->shutdownGL();
+
+ // Destroy window, and make sure we're not fullscreen
+ // This may generate window reshape and activation events.
+ // Therefore must do this before destroying the message system.
+ delete gViewerWindow;
+ gViewerWindow = NULL;
+ LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
+ }
LLSplashScreen::show();
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
- LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
+ LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
- // viewer UI relies on keyboard so keep it aound until viewer UI isa gone
- delete gKeyboard;
- gKeyboard = NULL;
+ // viewer UI relies on keyboard so keep it aound until viewer UI isa gone
+ delete gKeyboard;
+ gKeyboard = NULL;
if (LLViewerJoystick::instanceExists())
{
@@ -1905,142 +1910,142 @@ bool LLAppViewer::cleanup()
LLViewerJoystick::getInstance()->terminate();
}
- LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
+ LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
- LLViewerObject::cleanupVOClasses();
+ LLViewerObject::cleanupVOClasses();
- SUBSYSTEM_CLEANUP(LLAvatarAppearance);
+ SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLPostProcess);
+ SUBSYSTEM_CLEANUP(LLPostProcess);
- LLTracker::cleanupInstance();
+ LLTracker::cleanupInstance();
- // *FIX: This is handled in LLAppViewerWin32::cleanup().
- // I'm keeping the comment to remember its order in cleanup,
- // in case of unforseen dependency.
- //#if LL_WINDOWS
- // gDXHardware.cleanup();
- //#endif // LL_WINDOWS
+ // *FIX: This is handled in LLAppViewerWin32::cleanup().
+ // I'm keeping the comment to remember its order in cleanup,
+ // in case of unforseen dependency.
+ //#if LL_WINDOWS
+ // gDXHardware.cleanup();
+ //#endif // LL_WINDOWS
- LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager();
- if (!volume_manager->cleanup())
- {
- LL_WARNS() << "Remaining references in the volume manager!" << LL_ENDL;
- }
- LLPrimitive::cleanupVolumeManager();
+ LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager();
+ if (!volume_manager->cleanup())
+ {
+ LL_WARNS() << "Remaining references in the volume manager!" << LL_ENDL;
+ }
+ LLPrimitive::cleanupVolumeManager();
- LL_INFOS() << "Additional Cleanup..." << LL_ENDL;
+ LL_INFOS() << "Additional Cleanup..." << LL_ENDL;
- LLViewerParcelMgr::cleanupGlobals();
+ LLViewerParcelMgr::cleanupGlobals();
- // *Note: this is where gViewerStats used to be deleted.
+ // *Note: this is where gViewerStats used to be deleted.
- //end_messaging_system();
+ //end_messaging_system();
- LLPrimitive::cleanupVolumeManager();
- SUBSYSTEM_CLEANUP(LLWorldMapView);
- SUBSYSTEM_CLEANUP(LLFolderViewItem);
+ LLPrimitive::cleanupVolumeManager();
+ SUBSYSTEM_CLEANUP(LLWorldMapView);
+ SUBSYSTEM_CLEANUP(LLFolderViewItem);
- LL_INFOS() << "Saving Data" << LL_ENDL;
+ LL_INFOS() << "Saving Data" << LL_ENDL;
- // Store the time of our current logoff
- gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
+ // Store the time of our current logoff
+ gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
if (LLEnvironment::instanceExists())
{
- //Store environment settings if necessary
+ //Store environment settings if necessary
LLEnvironment::getInstance()->saveToSettings();
}
- // Must do this after all panels have been deleted because panels that have persistent rects
- // save their rects on delete.
- gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
-
- LLUIColorTable::instance().saveUserSettings();
-
- // PerAccountSettingsFile should be empty if no user has been logged on.
- // *FIX:Mani This should get really saved in a "logoff" mode.
- if (gSavedSettings.getString("PerAccountSettingsFile").empty())
- {
- LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL;
- }
- // Only save per account settings if the previous login succeeded, otherwise
- // we might end up with a cleared out settings file in case a previous login
- // failed after loading per account settings.
- else if (!mSavePerAccountSettings)
- {
- LL_INFOS() << "Not saving per-account settings; last login was not successful." << LL_ENDL;
- }
- else
- {
- gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
- LL_INFOS() << "Saved settings" << LL_ENDL;
-
- if (LLViewerParcelAskPlay::instanceExists())
- {
- LLViewerParcelAskPlay::getInstance()->saveSettings();
- }
- }
-
- std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
- gWarningSettings.saveToFile(warnings_settings_filename, TRUE);
-
- // Save URL history file
- LLURLHistory::saveFile("url_history.xml");
-
- // save mute list. gMuteList used to also be deleted here too.
- if (gAgent.isInitialized() && LLMuteList::instanceExists())
- {
- LLMuteList::getInstance()->cache(gAgent.getID());
- }
-
- //save call log list
- if (LLConversationLog::instanceExists())
- {
- LLConversationLog::instance().cache();
+ // Must do this after all panels have been deleted because panels that have persistent rects
+ // save their rects on delete.
+ gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+
+ LLUIColorTable::instance().saveUserSettings();
+
+ // PerAccountSettingsFile should be empty if no user has been logged on.
+ // *FIX:Mani This should get really saved in a "logoff" mode.
+ if (gSavedSettings.getString("PerAccountSettingsFile").empty())
+ {
+ LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL;
+ }
+ // Only save per account settings if the previous login succeeded, otherwise
+ // we might end up with a cleared out settings file in case a previous login
+ // failed after loading per account settings.
+ else if (!mSavePerAccountSettings)
+ {
+ LL_INFOS() << "Not saving per-account settings; last login was not successful." << LL_ENDL;
+ }
+ else
+ {
+ gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
+ LL_INFOS() << "Saved settings" << LL_ENDL;
+
+ if (LLViewerParcelAskPlay::instanceExists())
+ {
+ LLViewerParcelAskPlay::getInstance()->saveSettings();
+ }
+ }
+
+ std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
+ gWarningSettings.saveToFile(warnings_settings_filename, TRUE);
+
+ // Save URL history file
+ LLURLHistory::saveFile("url_history.xml");
+
+ // save mute list. gMuteList used to also be deleted here too.
+ if (gAgent.isInitialized() && LLMuteList::instanceExists())
+ {
+ LLMuteList::getInstance()->cache(gAgent.getID());
+ }
+
+ //save call log list
+ if (LLConversationLog::instanceExists())
+ {
+ LLConversationLog::instance().cache();
}
clearSecHandler();
- if (mPurgeCacheOnExit)
- {
- LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
- }
-
- writeDebugInfo();
-
- LLLocationHistory::getInstance()->save();
-
- LLAvatarIconIDCache::getInstance()->save();
-
- // Stop the plugin read thread if it's running.
- LLPluginProcessParent::setUseReadThread(false);
-
- LL_INFOS() << "Shutting down Threads" << LL_ENDL;
-
- // Let threads finish
- LLTimer idleTimer;
- idleTimer.reset();
- const F64 max_idle_time = 5.f; // 5 seconds
- while(1)
- {
- S32 pending = 0;
- pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
- pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
- pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
- pending += LLLFSThread::updateClass(0);
- F64 idle_time = idleTimer.getElapsedTimeF64();
- if(!pending)
- {
- break ; //done
- }
- else if(idle_time >= max_idle_time)
- {
- LL_WARNS() << "Quitting with pending background tasks." << LL_ENDL;
- break;
- }
- }
+ if (mPurgeCacheOnExit)
+ {
+ LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
+ }
+
+ writeDebugInfo();
+
+ LLLocationHistory::getInstance()->save();
+
+ LLAvatarIconIDCache::getInstance()->save();
+
+ // Stop the plugin read thread if it's running.
+ LLPluginProcessParent::setUseReadThread(false);
+
+ LL_INFOS() << "Shutting down Threads" << LL_ENDL;
+
+ // Let threads finish
+ LLTimer idleTimer;
+ idleTimer.reset();
+ const F64 max_idle_time = 5.f; // 5 seconds
+ while(1)
+ {
+ S32 pending = 0;
+ pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
+ pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+ pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+ pending += LLLFSThread::updateClass(0);
+ F64 idle_time = idleTimer.getElapsedTimeF64();
+ if(!pending)
+ {
+ break ; //done
+ }
+ else if(idle_time >= max_idle_time)
+ {
+ LL_WARNS() << "Quitting with pending background tasks." << LL_ENDL;
+ break;
+ }
+ }
if (mPurgeUserDataOnExit)
{
@@ -2050,32 +2055,32 @@ bool LLAppViewer::cleanup()
gDirUtilp->deleteDirAndContents(user_path);
}
- // Delete workers first
- // shotdown all worker threads before deleting them in case of co-dependencies
- mAppCoreHttp.requestStop();
- sTextureFetch->shutdown();
- sTextureCache->shutdown();
- sImageDecodeThread->shutdown();
- sPurgeDiskCacheThread->shutdown();
- if (mGeneralThreadPool)
- {
- mGeneralThreadPool->close();
- }
+ // Delete workers first
+ // shotdown all worker threads before deleting them in case of co-dependencies
+ mAppCoreHttp.requestStop();
+ sTextureFetch->shutdown();
+ sTextureCache->shutdown();
+ sImageDecodeThread->shutdown();
+ sPurgeDiskCacheThread->shutdown();
+ if (mGeneralThreadPool)
+ {
+ mGeneralThreadPool->close();
+ }
- sTextureFetch->shutDownTextureCacheThread() ;
+ sTextureFetch->shutDownTextureCacheThread() ;
LLLFSThread::sLocal->shutdown();
- LL_INFOS() << "Shutting down message system" << LL_ENDL;
- end_messaging_system();
+ LL_INFOS() << "Shutting down message system" << LL_ENDL;
+ end_messaging_system();
- // Non-LLCurl libcurl library
- mAppCoreHttp.cleanup();
+ // Non-LLCurl libcurl library
+ mAppCoreHttp.cleanup();
- SUBSYSTEM_CLEANUP(LLFilePickerThread);
- SUBSYSTEM_CLEANUP(LLDirPickerThread);
+ SUBSYSTEM_CLEANUP(LLFilePickerThread);
+ SUBSYSTEM_CLEANUP(LLDirPickerThread);
- //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
- delete sTextureCache;
+ //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
+ delete sTextureCache;
sTextureCache = NULL;
if (sTextureFetch)
{
@@ -2084,101 +2089,101 @@ bool LLAppViewer::cleanup()
delete sTextureFetch;
sTextureFetch = NULL;
}
- delete sImageDecodeThread;
+ delete sImageDecodeThread;
sImageDecodeThread = NULL;
- delete mFastTimerLogThread;
- mFastTimerLogThread = NULL;
- delete sPurgeDiskCacheThread;
- sPurgeDiskCacheThread = NULL;
+ delete mFastTimerLogThread;
+ mFastTimerLogThread = NULL;
+ delete sPurgeDiskCacheThread;
+ sPurgeDiskCacheThread = NULL;
delete mGeneralThreadPool;
mGeneralThreadPool = NULL;
- if (LLFastTimerView::sAnalyzePerformance)
- {
- LL_INFOS() << "Analyzing performance" << LL_ENDL;
+ if (LLFastTimerView::sAnalyzePerformance)
+ {
+ LL_INFOS() << "Analyzing performance" << LL_ENDL;
- std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp";
- std::string current_name = LLTrace::BlockTimer::sLogName + ".slp";
- std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv";
+ std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp";
+ std::string current_name = LLTrace::BlockTimer::sLogName + ".slp";
+ std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv";
- LLFastTimerView::doAnalysis(
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name),
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name));
- }
+ LLFastTimerView::doAnalysis(
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name));
+ }
- SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ;
+ SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ;
- LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL;
+ LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL;
- //Note:
- //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown()
- //because some new image might be generated during cleaning up media. --bao
- gTextureList.shutdown(); // shutdown again in case a callback added something
- LLUIImageList::getInstance()->cleanUp();
+ //Note:
+ //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown()
+ //because some new image might be generated during cleaning up media. --bao
+ gTextureList.shutdown(); // shutdown again in case a callback added something
+ LLUIImageList::getInstance()->cleanUp();
- SUBSYSTEM_CLEANUP(LLImage);
- SUBSYSTEM_CLEANUP(LLLFSThread);
+ SUBSYSTEM_CLEANUP(LLImage);
+ SUBSYSTEM_CLEANUP(LLLFSThread);
- LL_INFOS() << "Misc Cleanup" << LL_ENDL;
+ LL_INFOS() << "Misc Cleanup" << LL_ENDL;
- gSavedSettings.cleanup();
- LLUIColorTable::instance().clear();
+ gSavedSettings.cleanup();
+ LLUIColorTable::instance().clear();
- LLWatchdog::getInstance()->cleanup();
+ LLWatchdog::getInstance()->cleanup();
- LLViewerAssetStatsFF::cleanup();
+ LLViewerAssetStatsFF::cleanup();
- // If we're exiting to launch an URL, do that here so the screen
- // is at the right resolution before we launch IE.
- if (!gLaunchFileOnQuit.empty())
- {
- LL_INFOS() << "Launch file on quit." << LL_ENDL;
+ // If we're exiting to launch an URL, do that here so the screen
+ // is at the right resolution before we launch IE.
+ if (!gLaunchFileOnQuit.empty())
+ {
+ LL_INFOS() << "Launch file on quit." << LL_ENDL;
#if LL_WINDOWS
- // Indicate an application is starting.
- SetCursor(LoadCursor(NULL, IDC_WAIT));
+ // Indicate an application is starting.
+ SetCursor(LoadCursor(NULL, IDC_WAIT));
#endif
- // HACK: Attempt to wait until the screen res. switch is complete.
- ms_sleep(1000);
+ // HACK: Attempt to wait until the screen res. switch is complete.
+ ms_sleep(1000);
- LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
- LL_INFOS() << "File launched." << LL_ENDL;
- }
- // make sure nothing uses applyProxySettings by this point.
- LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
- SUBSYSTEM_CLEANUP(LLProxy);
+ LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
+ LL_INFOS() << "File launched." << LL_ENDL;
+ }
+ // make sure nothing uses applyProxySettings by this point.
+ LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
+ SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
- ll_close_fail_log();
-
- LLError::LLCallStacks::cleanup();
+ ll_close_fail_log();
- LLEnvironment::deleteSingleton();
- LLSelectMgr::deleteSingleton();
- LLViewerEventRecorder::deleteSingleton();
+ LLError::LLCallStacks::cleanup();
+ LL::GLTFSceneManager::deleteSingleton();
+ LLEnvironment::deleteSingleton();
+ LLSelectMgr::deleteSingleton();
+ LLViewerEventRecorder::deleteSingleton();
LLWorld::deleteSingleton();
LLVoiceClient::deleteSingleton();
- // It's not at first obvious where, in this long sequence, a generic cleanup
- // call OUGHT to go. So let's say this: as we migrate cleanup from
- // explicit hand-placed calls into the generic mechanism, eventually
- // all cleanup will get subsumed into the generic call. So the calls you
- // still see above are calls that MUST happen before the generic cleanup
- // kicks in.
+ // It's not at first obvious where, in this long sequence, a generic cleanup
+ // call OUGHT to go. So let's say this: as we migrate cleanup from
+ // explicit hand-placed calls into the generic mechanism, eventually
+ // all cleanup will get subsumed into the generic call. So the calls you
+ // still see above are calls that MUST happen before the generic cleanup
+ // kicks in.
- // This calls every remaining LLSingleton's cleanupSingleton() and
- // deleteSingleton() methods.
- LLSingletonBase::deleteAll();
+ // This calls every remaining LLSingleton's cleanupSingleton() and
+ // deleteSingleton() methods.
+ LLSingletonBase::deleteAll();
LLSplashScreen::hide();
LL_INFOS() << "Goodbye!" << LL_ENDL;
- removeDumpDir();
+ removeDumpDir();
- // return 0;
- return true;
+ // return 0;
+ return true;
}
void LLAppViewer::initGeneralThread()
@@ -2194,11 +2199,11 @@ void LLAppViewer::initGeneralThread()
bool LLAppViewer::initThreads()
{
- static const bool enable_threads = true;
+ static const bool enable_threads = true;
- LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
- LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
+ LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
//auto configure thread count
LLSD threadCounts = gSavedSettings.getLLSD("ThreadPoolSizes");
@@ -2213,39 +2218,39 @@ bool LLAppViewer::initThreads()
}
// The only configurable thread count right now is ImageDecode
- // The viewer typically starts around 8 threads not including image decode,
+ // The viewer typically starts around 8 threads not including image decode,
// so try to leave at least one core free
S32 image_decode_count = llclamp(cores - 9, 1, 8);
threadCounts["ImageDecode"] = image_decode_count;
gSavedSettings.setLLSD("ThreadPoolSizes", threadCounts);
- // Image decoding
- LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
- LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
- LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
- enable_threads && true,
- app_metrics_qa_mode);
+ // Image decoding
+ LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
+ LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
+ LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
+ enable_threads && true,
+ app_metrics_qa_mode);
// general task background thread (LLPerfStats, etc)
LLAppViewer::instance()->initGeneralThread();
- LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
+ LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
- if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
- {
- LLTrace::BlockTimer::setLogLock(new LLMutex());
- mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName);
- mFastTimerLogThread->start();
- }
+ if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
+ {
+ LLTrace::BlockTimer::setLogLock(new LLMutex());
+ mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName);
+ mFastTimerLogThread->start();
+ }
- // Mesh streaming and caching
- gMeshRepo.init();
+ // Mesh streaming and caching
+ gMeshRepo.init();
- LLFilePickerThread::initClass();
- LLDirPickerThread::initClass();
+ LLFilePickerThread::initClass();
+ LLDirPickerThread::initClass();
- // *FIX: no error handling here!
- return true;
+ // *FIX: no error handling here!
+ return true;
}
void errorCallback(LLError::ELevel level, const std::string &error_string)
@@ -2289,7 +2294,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
if (mSecondInstance)
{
LLFile::mkdir(gDirUtilp->getDumpLogsDirPath());
-
+
LLUUID uid;
uid.generate();
LLError::logToFile(gDirUtilp->getDumpLogsDirPath(uid.asString() + ".log"));
@@ -2360,123 +2365,123 @@ void LLAppViewer::initLoggingAndGetLastDuration()
}
bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
- bool set_defaults)
+ bool set_defaults)
{
- if (!mSettingsLocationList)
- {
- LL_ERRS() << "Invalid settings location list" << LL_ENDL;
- }
-
- for (const SettingsGroup& group : mSettingsLocationList->groups)
- {
- // skip settings groups that aren't the one we requested
- if (group.name() != location_key) continue;
-
- ELLPath path_index = (ELLPath)group.path_index();
- if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST)
- {
- LL_ERRS() << "Out of range path index in app_settings/settings_files.xml" << LL_ENDL;
- return false;
- }
-
- for (const SettingsFile& file : group.files)
- {
- LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
- << " - from location " << location_key << LL_ENDL;
-
- auto settings_group = LLControlGroup::getInstance(file.name);
- if(!settings_group)
- {
- LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
- continue;
- }
-
- std::string full_settings_path;
-
- if (file.file_name_setting.isProvided()
- && gSavedSettings.controlExists(file.file_name_setting))
- {
- // try to find filename stored in file_name_setting control
- full_settings_path = gSavedSettings.getString(file.file_name_setting);
- if (full_settings_path.empty())
- {
- continue;
- }
- else if (!gDirUtilp->fileExists(full_settings_path))
- {
- // search in default path
- full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, full_settings_path);
- }
- }
- else
- {
- // by default, use specified file name
- full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name());
- }
-
- if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
- { // success!
- LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
- }
- else
- { // failed to load
- if(file.required)
- {
+ if (!mSettingsLocationList)
+ {
+ LL_ERRS() << "Invalid settings location list" << LL_ENDL;
+ }
+
+ for (const SettingsGroup& group : mSettingsLocationList->groups)
+ {
+ // skip settings groups that aren't the one we requested
+ if (group.name() != location_key) continue;
+
+ ELLPath path_index = (ELLPath)group.path_index();
+ if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST)
+ {
+ LL_ERRS() << "Out of range path index in app_settings/settings_files.xml" << LL_ENDL;
+ return false;
+ }
+
+ for (const SettingsFile& file : group.files)
+ {
+ LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
+ << " - from location " << location_key << LL_ENDL;
+
+ auto settings_group = LLControlGroup::getInstance(file.name);
+ if(!settings_group)
+ {
+ LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
+ continue;
+ }
+
+ std::string full_settings_path;
+
+ if (file.file_name_setting.isProvided()
+ && gSavedSettings.controlExists(file.file_name_setting))
+ {
+ // try to find filename stored in file_name_setting control
+ full_settings_path = gSavedSettings.getString(file.file_name_setting);
+ if (full_settings_path.empty())
+ {
+ continue;
+ }
+ else if (!gDirUtilp->fileExists(full_settings_path))
+ {
+ // search in default path
+ full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, full_settings_path);
+ }
+ }
+ else
+ {
+ // by default, use specified file name
+ full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name());
+ }
+
+ if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
+ { // success!
+ LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
+ }
+ else
+ { // failed to load
+ if(file.required)
+ {
LLError::LLUserWarningMsg::showMissingFiles();
- LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL;
- return false;
- }
- else
- {
- // only complain if we actually have a filename at this point
- if (!full_settings_path.empty())
- {
- LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
- }
- }
- }
- }
- }
-
- return true;
+ LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ // only complain if we actually have a filename at this point
+ if (!full_settings_path.empty())
+ {
+ LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
}
std::string LLAppViewer::getSettingsFilename(const std::string& location_key,
- const std::string& file)
+ const std::string& file)
{
- for (const SettingsGroup& group : mSettingsLocationList->groups)
- {
- if (group.name() == location_key)
- {
- for (const SettingsFile& settings_file : group.files)
- {
- if (settings_file.name() == file)
- {
- return settings_file.file_name;
- }
- }
- }
- }
-
- return std::string();
+ for (const SettingsGroup& group : mSettingsLocationList->groups)
+ {
+ if (group.name() == location_key)
+ {
+ for (const SettingsFile& settings_file : group.files)
+ {
+ if (settings_file.name() == file)
+ {
+ return settings_file.file_name;
+ }
+ }
+ }
+ }
+
+ return std::string();
}
void LLAppViewer::loadColorSettings()
{
- LLUIColorTable::instance().loadFromSettings();
+ LLUIColorTable::instance().loadFromSettings();
}
namespace
{
void handleCommandLineError(LLControlGroupCLP& clp)
{
- LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL;
+ LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL;
- LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL;
+ LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL;
- OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
- LLStringUtil::null,
- OSMB_OK);
+ OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
+ LLStringUtil::null,
+ OSMB_OK);
}
} // anonymous namespace
@@ -2484,42 +2489,42 @@ namespace
// Name can be specified as "<control_group>.<control_name>", with default group being Global.
bool tempSetControl(const std::string& name, const std::string& value)
{
- std::string name_part;
- std::string group_part;
- LLControlVariable* control = NULL;
-
- // Name can be further split into ControlGroup.Name, with the default control group being Global
- size_t pos = name.find('.');
- if (pos != std::string::npos)
- {
- group_part = name.substr(0, pos);
- name_part = name.substr(pos+1);
- LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
- auto g = LLControlGroup::getInstance(group_part);
- if (g) control = g->getControl(name_part);
- }
- else
- {
- LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
- control = gSavedSettings.getControl(name);
- }
-
- if (control)
- {
- control->setValue(value, false);
- return true;
- }
- return false;
+ std::string name_part;
+ std::string group_part;
+ LLControlVariable* control = NULL;
+
+ // Name can be further split into ControlGroup.Name, with the default control group being Global
+ size_t pos = name.find('.');
+ if (pos != std::string::npos)
+ {
+ group_part = name.substr(0, pos);
+ name_part = name.substr(pos+1);
+ LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
+ auto g = LLControlGroup::getInstance(group_part);
+ if (g) control = g->getControl(name_part);
+ }
+ else
+ {
+ LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
+ control = gSavedSettings.getControl(name);
+ }
+
+ if (control)
+ {
+ control->setValue(value, false);
+ return true;
+ }
+ return false;
}
bool LLAppViewer::initConfiguration()
{
- //Load settings files list
- std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
- LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
- if (!success)
- {
+ //Load settings files list
+ std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
+ LLXMLNodePtr root;
+ BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
+ if (!success)
+ {
LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
LLError::LLUserWarningMsg::showMissingFiles();
if (gDirUtilp->fileExists(settings_file_list))
@@ -2536,175 +2541,175 @@ bool LLAppViewer::initConfiguration()
<< "and contact https://support.secondlife.com if issue persists after reinstall."
<< LL_ENDL;
}
- }
+ }
- mSettingsLocationList = new SettingsFiles();
+ mSettingsLocationList = new SettingsFiles();
- LLXUIParser parser;
- parser.readXUI(root, *mSettingsLocationList, settings_file_list);
+ LLXUIParser parser;
+ parser.readXUI(root, *mSettingsLocationList, settings_file_list);
- if (!mSettingsLocationList->validateBlock())
- {
+ if (!mSettingsLocationList->validateBlock())
+ {
LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL;
- }
-
- // The settings and command line parsing have a fragile
- // order-of-operation:
- // - load defaults from app_settings
- // - set procedural settings values
- // - read command line settings
- // - selectively apply settings needed to load user settings.
+ }
+
+ // The settings and command line parsing have a fragile
+ // order-of-operation:
+ // - load defaults from app_settings
+ // - set procedural settings values
+ // - read command line settings
+ // - selectively apply settings needed to load user settings.
// - load overrides from user_settings
- // - apply command line settings (to override the overrides)
- // - load per account settings (happens in llstartup
-
- // - load defaults
- bool set_defaults = true;
- if(!loadSettingsFromDirectory("Default", set_defaults))
- {
- OSMessageBox(
- "Unable to load default settings file. The installation may be corrupted.",
- LLStringUtil::null,OSMB_OK);
- return false;
- }
-
- initStrings(); // setup paths for LLTrans based on settings files only
- // - set procedural settings
- // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
- gSavedSettings.setString("ClientSettingsFile",
+ // - apply command line settings (to override the overrides)
+ // - load per account settings (happens in llstartup
+
+ // - load defaults
+ bool set_defaults = true;
+ if(!loadSettingsFromDirectory("Default", set_defaults))
+ {
+ OSMessageBox(
+ "Unable to load default settings file. The installation may be corrupted.",
+ LLStringUtil::null,OSMB_OK);
+ return false;
+ }
+
+ initStrings(); // setup paths for LLTrans based on settings files only
+ // - set procedural settings
+ // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
+ gSavedSettings.setString("ClientSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- // provide developer build only overrides for these control variables that are not
- // persisted to settings.xml
- LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers");
- if (c)
- {
- c->setValue(true, false);
- }
-
- gSavedSettings.setBOOL("QAMode", TRUE );
- gSavedSettings.setS32("WatchdogEnabled", 0);
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ // provide developer build only overrides for these control variables that are not
+ // persisted to settings.xml
+ LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers");
+ if (c)
+ {
+ c->setValue(true, false);
+ }
+
+ gSavedSettings.setBOOL("QAMode", TRUE );
+ gSavedSettings.setS32("WatchdogEnabled", 0);
#endif
- // These are warnings that appear on the first experience of that condition.
- // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse
- // for disable/reset ability
-// LLFirstUse::addConfigVariable("FirstBalanceIncrease");
-// LLFirstUse::addConfigVariable("FirstBalanceDecrease");
-// LLFirstUse::addConfigVariable("FirstSit");
-// LLFirstUse::addConfigVariable("FirstMap");
-// LLFirstUse::addConfigVariable("FirstGoTo");
-// LLFirstUse::addConfigVariable("FirstBuild");
-// LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
-// LLFirstUse::addConfigVariable("FirstTeleport");
-// LLFirstUse::addConfigVariable("FirstOverrideKeys");
-// LLFirstUse::addConfigVariable("FirstAttach");
-// LLFirstUse::addConfigVariable("FirstAppearance");
-// LLFirstUse::addConfigVariable("FirstInventory");
-// LLFirstUse::addConfigVariable("FirstSandbox");
-// LLFirstUse::addConfigVariable("FirstFlexible");
-// LLFirstUse::addConfigVariable("FirstDebugMenus");
-// LLFirstUse::addConfigVariable("FirstSculptedPrim");
-// LLFirstUse::addConfigVariable("FirstVoice");
-// LLFirstUse::addConfigVariable("FirstMedia");
-
- // - read command line settings.
- LLControlGroupCLP clp;
- std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
- "cmd_line.xml");
-
- clp.configure(cmd_line_config, &gSavedSettings);
-
- if(!initParseCommandLine(clp))
- {
- handleCommandLineError(clp);
- return false;
- }
-
- // - selectively apply settings
-
- // If the user has specified a alternate settings file name.
- // Load it now before loading the user_settings/settings.xml
- if(clp.hasOption("settings"))
- {
- std::string user_settings_filename =
- gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
- clp.getOption("settings")[0]);
- gSavedSettings.setString("ClientSettingsFile", user_settings_filename);
- LL_INFOS("Settings") << "Using command line specified settings filename: "
- << user_settings_filename << LL_ENDL;
- }
-
- // - load overrides from user_settings
- loadSettingsFromDirectory("User");
-
- if (gSavedSettings.getBOOL("FirstRunThisInstall"))
- {
- // Set firstrun flag to indicate that some further init actiona should be taken
- // like determining screen DPI value and so on
- mIsFirstRun = true;
-
- gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
- }
-
- if (clp.hasOption("sessionsettings"))
- {
- std::string session_settings_filename = clp.getOption("sessionsettings")[0];
- gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
- LL_INFOS("Settings") << "Using session settings filename: "
- << session_settings_filename << LL_ENDL;
- }
- loadSettingsFromDirectory("Session");
-
- if (clp.hasOption("usersessionsettings"))
- {
- std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
- gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
- LL_INFOS("Settings") << "Using user session settings filename: "
- << user_session_settings_filename << LL_ENDL;
-
- }
- loadSettingsFromDirectory("UserSession");
-
- // - apply command line settings
- if (! clp.notify())
- {
- handleCommandLineError(clp);
- return false;
- }
-
- // Register the core crash option as soon as we can
- // if we want gdb post-mortem on cores we need to be up and running
- // ASAP or we might miss init issue etc.
- if(gSavedSettings.getBOOL("DisableCrashLogger"))
- {
- LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
- disableCrashlogger();
- }
-
- gNonInteractive = gSavedSettings.getBOOL("NonInteractive");
- // Handle initialization from settings.
- // Start up the debugging console before handling other options.
- if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive)
- {
- initConsole();
- }
-
- if(clp.hasOption("help"))
- {
- std::ostringstream msg;
- msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp;
- LL_INFOS() << msg.str() << LL_ENDL;
-
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
-
- return false;
- }
+ // These are warnings that appear on the first experience of that condition.
+ // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse
+ // for disable/reset ability
+// LLFirstUse::addConfigVariable("FirstBalanceIncrease");
+// LLFirstUse::addConfigVariable("FirstBalanceDecrease");
+// LLFirstUse::addConfigVariable("FirstSit");
+// LLFirstUse::addConfigVariable("FirstMap");
+// LLFirstUse::addConfigVariable("FirstGoTo");
+// LLFirstUse::addConfigVariable("FirstBuild");
+// LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
+// LLFirstUse::addConfigVariable("FirstTeleport");
+// LLFirstUse::addConfigVariable("FirstOverrideKeys");
+// LLFirstUse::addConfigVariable("FirstAttach");
+// LLFirstUse::addConfigVariable("FirstAppearance");
+// LLFirstUse::addConfigVariable("FirstInventory");
+// LLFirstUse::addConfigVariable("FirstSandbox");
+// LLFirstUse::addConfigVariable("FirstFlexible");
+// LLFirstUse::addConfigVariable("FirstDebugMenus");
+// LLFirstUse::addConfigVariable("FirstSculptedPrim");
+// LLFirstUse::addConfigVariable("FirstVoice");
+// LLFirstUse::addConfigVariable("FirstMedia");
+
+ // - read command line settings.
+ LLControlGroupCLP clp;
+ std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
+ "cmd_line.xml");
+
+ clp.configure(cmd_line_config, &gSavedSettings);
+
+ if(!initParseCommandLine(clp))
+ {
+ handleCommandLineError(clp);
+ return false;
+ }
+
+ // - selectively apply settings
+
+ // If the user has specified a alternate settings file name.
+ // Load it now before loading the user_settings/settings.xml
+ if(clp.hasOption("settings"))
+ {
+ std::string user_settings_filename =
+ gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
+ clp.getOption("settings")[0]);
+ gSavedSettings.setString("ClientSettingsFile", user_settings_filename);
+ LL_INFOS("Settings") << "Using command line specified settings filename: "
+ << user_settings_filename << LL_ENDL;
+ }
+
+ // - load overrides from user_settings
+ loadSettingsFromDirectory("User");
+
+ if (gSavedSettings.getBOOL("FirstRunThisInstall"))
+ {
+ // Set firstrun flag to indicate that some further init actiona should be taken
+ // like determining screen DPI value and so on
+ mIsFirstRun = true;
+
+ gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
+ }
+
+ if (clp.hasOption("sessionsettings"))
+ {
+ std::string session_settings_filename = clp.getOption("sessionsettings")[0];
+ gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
+ LL_INFOS("Settings") << "Using session settings filename: "
+ << session_settings_filename << LL_ENDL;
+ }
+ loadSettingsFromDirectory("Session");
+
+ if (clp.hasOption("usersessionsettings"))
+ {
+ std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
+ gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
+ LL_INFOS("Settings") << "Using user session settings filename: "
+ << user_session_settings_filename << LL_ENDL;
+
+ }
+ loadSettingsFromDirectory("UserSession");
+
+ // - apply command line settings
+ if (! clp.notify())
+ {
+ handleCommandLineError(clp);
+ return false;
+ }
+
+ // Register the core crash option as soon as we can
+ // if we want gdb post-mortem on cores we need to be up and running
+ // ASAP or we might miss init issue etc.
+ if(gSavedSettings.getBOOL("DisableCrashLogger"))
+ {
+ LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
+ disableCrashlogger();
+ }
+
+ gNonInteractive = gSavedSettings.getBOOL("NonInteractive");
+ // Handle initialization from settings.
+ // Start up the debugging console before handling other options.
+ if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive)
+ {
+ initConsole();
+ }
+
+ if(clp.hasOption("help"))
+ {
+ std::ostringstream msg;
+ msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp;
+ LL_INFOS() << msg.str() << LL_ENDL;
+
+ OSMessageBox(
+ msg.str(),
+ LLStringUtil::null,
+ OSMB_OK);
+
+ return false;
+ }
if(clp.hasOption("set"))
{
@@ -2722,43 +2727,43 @@ bool LLAppViewer::initConfiguration()
const std::string& value = *(++itr);
if (!tempSetControl(name,value))
{
- LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;
+ LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;
}
}
}
}
if (clp.hasOption("logevents")) {
- LLViewerEventRecorder::instance().setEventLoggingOn();
+ LLViewerEventRecorder::instance().setEventLoggingOn();
}
- std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
- if(! CmdLineChannel.empty())
+ std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
+ if(! CmdLineChannel.empty())
{
- LLVersionInfo::instance().resetChannel(CmdLineChannel);
- }
+ LLVersionInfo::instance().resetChannel(CmdLineChannel);
+ }
- // If we have specified crash on startup, set the global so we'll trigger the crash at the right time
- gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
+ // If we have specified crash on startup, set the global so we'll trigger the crash at the right time
+ gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
- if (gSavedSettings.getBOOL("LogPerformance"))
- {
- LLTrace::BlockTimer::sLog = true;
- LLTrace::BlockTimer::sLogName = std::string("performance");
- }
+ if (gSavedSettings.getBOOL("LogPerformance"))
+ {
+ LLTrace::BlockTimer::sLog = true;
+ LLTrace::BlockTimer::sLogName = std::string("performance");
+ }
- std::string test_name(gSavedSettings.getString("LogMetrics"));
- if (! test_name.empty())
- {
- LLTrace::BlockTimer::sMetricLog = TRUE;
- // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
- // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
- LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL;
- LLTrace::BlockTimer::sLogName = test_name;
- }
+ std::string test_name(gSavedSettings.getString("LogMetrics"));
+ if (! test_name.empty())
+ {
+ LLTrace::BlockTimer::sMetricLog = TRUE;
+ // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
+ // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
+ LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL;
+ LLTrace::BlockTimer::sLogName = test_name;
+ }
- if (clp.hasOption("graphicslevel"))
- {
+ if (clp.hasOption("graphicslevel"))
+ {
// User explicitly requested --graphicslevel on the command line. We
// expect this switch has already set RenderQualityPerformance. Check
// that value for validity later.
@@ -2767,18 +2772,18 @@ bool LLAppViewer::initConfiguration()
// will call LLFeatureManager::applyRecommendedSettings(), which
// overwrites this settings variable!
mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance");
- }
+ }
- LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
- gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
+ LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
+ gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
- if (gSavedSettings.getBOOL("DebugSession"))
- {
- gDebugSession = TRUE;
- gDebugGL = TRUE;
+ if (gSavedSettings.getBOOL("DebugSession"))
+ {
+ gDebugSession = TRUE;
+ gDebugGL = TRUE;
- ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
- }
+ ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
+ }
if (gSavedSettings.getBOOL("RenderDebugGLSession"))
{
@@ -2789,47 +2794,47 @@ bool LLAppViewer::initConfiguration()
gSavedSettings.setBOOL("RenderDebugGLSession", FALSE);
}
- const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
- if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
- {
- // Examining "Language" may not suffice -- see LLUI::getLanguage()
- // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
- // good because we haven't yet called LLUI::initClass().
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
- gSavedSettings.getString("Language"));
- }
-
- if (gSavedSettings.getBOOL("SpellCheck"))
- {
- std::list<std::string> dict_list;
- std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
- boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
- if (!dict_list.empty())
- {
- LLSpellChecker::setUseSpellCheck(dict_list.front());
- dict_list.pop_front();
- LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
- }
- }
-
- if (gNonInteractive)
- {
- tempSetControl("AllowMultipleViewers", "TRUE");
- tempSetControl("SLURLPassToOtherInstance", "FALSE");
- tempSetControl("RenderWater", "FALSE");
- tempSetControl("FlyingAtExit", "FALSE");
- tempSetControl("WindowWidth", "1024");
- tempSetControl("WindowHeight", "200");
- LLError::setEnabledLogTypesMask(0);
- llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance"));
- }
-
-
- // Handle slurl use. NOTE: Don't let SL-55321 reappear.
- // This initial-SLURL logic, up through the call to
- // sendURLToOtherInstance(), must precede LLSplashScreen::show() --
- // because if sendURLToOtherInstance() succeeds, we take a fast exit,
- // SKIPPING the splash screen and everything else.
+ const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+ if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+ {
+ // Examining "Language" may not suffice -- see LLUI::getLanguage()
+ // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+ // good because we haven't yet called LLUI::initClass().
+ gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+ gSavedSettings.getString("Language"));
+ }
+
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ }
+ }
+
+ if (gNonInteractive)
+ {
+ tempSetControl("AllowMultipleViewers", "TRUE");
+ tempSetControl("SLURLPassToOtherInstance", "FALSE");
+ tempSetControl("RenderWater", "FALSE");
+ tempSetControl("FlyingAtExit", "FALSE");
+ tempSetControl("WindowWidth", "1024");
+ tempSetControl("WindowHeight", "200");
+ LLError::setEnabledLogTypesMask(0);
+ llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance"));
+ }
+
+
+ // Handle slurl use. NOTE: Don't let SL-55321 reappear.
+ // This initial-SLURL logic, up through the call to
+ // sendURLToOtherInstance(), must precede LLSplashScreen::show() --
+ // because if sendURLToOtherInstance() succeeds, we take a fast exit,
+ // SKIPPING the splash screen and everything else.
// *FIX: This init code should be made more robust to prevent
// the issue SL-55321 from returning. One thought is to allow
@@ -2847,143 +2852,143 @@ bool LLAppViewer::initConfiguration()
// other browsers) and do the rough equivalent of command
// injection and steal passwords. Phoenix. SL-55321
- std::string starting_location;
-
- std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation"));
- if(! cmd_line_login_location.empty())
- {
- starting_location = cmd_line_login_location;
- }
- else
- {
- std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation"));
- if (! default_login_location.empty())
- {
- starting_location = default_login_location;
- }
- }
-
- LLSLURL start_slurl;
- if (! starting_location.empty())
- {
- start_slurl = starting_location;
- LLStartUp::setStartSLURL(start_slurl);
- if(start_slurl.getType() == LLSLURL::LOCATION)
- {
- LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
- }
- }
-
- // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
- std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
- if ( !nextLoginLocation.empty() )
- {
- LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
- LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
- }
- else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
- && gSavedSettings.getString("CmdLineLoginLocation").empty())
- {
- // If automatic login from command line with --login switch
- // init StartSLURL location.
- std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
- LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
- LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
- }
- else
- {
- // the login location will be set by the login panel (see LLPanelLogin)
- }
-
- //RN: if we received a URL, hand it off to the existing instance.
- // don't call anotherInstanceRunning() when doing URL handoff, as
- // it relies on checking a marker file which will not work when running
- // out of different directories
-
- if (start_slurl.isValid() &&
- (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
- {
- if (sendURLToOtherInstance(start_slurl.getSLURLString()))
- {
- // successfully handed off URL to existing instance, exit
- return false;
- }
- }
-
- // Display splash screen. Must be after above check for previous
- // crash as this dialog is always frontmost.
- std::string splash_msg;
- LLStringUtil::format_map_t args;
- args["[APP_NAME]"] = LLTrans::getString("SECOND_LIFE");
- splash_msg = LLTrans::getString("StartupLoading", args);
- LLSplashScreen::show();
- LLSplashScreen::update(splash_msg);
-
- //LLVolumeMgr::initClass();
- LLVolumeMgr* volume_manager = new LLVolumeMgr();
- volume_manager->useMutex(); // LLApp and LLMutex magic must be manually enabled
- LLPrimitive::setVolumeManager(volume_manager);
-
- // Note: this is where we used to initialize gFeatureManagerp.
-
- gStartTime = totalTime();
-
- //
- // Set the name of the window
- //
- gWindowTitle = LLTrans::getString("APP_NAME");
+ std::string starting_location;
+
+ std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation"));
+ if(! cmd_line_login_location.empty())
+ {
+ starting_location = cmd_line_login_location;
+ }
+ else
+ {
+ std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation"));
+ if (! default_login_location.empty())
+ {
+ starting_location = default_login_location;
+ }
+ }
+
+ LLSLURL start_slurl;
+ if (! starting_location.empty())
+ {
+ start_slurl = starting_location;
+ LLStartUp::setStartSLURL(start_slurl);
+ if(start_slurl.getType() == LLSLURL::LOCATION)
+ {
+ LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
+ }
+ }
+
+ // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
+ std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
+ if ( !nextLoginLocation.empty() )
+ {
+ LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
+ }
+ else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
+ && gSavedSettings.getString("CmdLineLoginLocation").empty())
+ {
+ // If automatic login from command line with --login switch
+ // init StartSLURL location.
+ std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
+ LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
+ }
+ else
+ {
+ // the login location will be set by the login panel (see LLPanelLogin)
+ }
+
+ //RN: if we received a URL, hand it off to the existing instance.
+ // don't call anotherInstanceRunning() when doing URL handoff, as
+ // it relies on checking a marker file which will not work when running
+ // out of different directories
+
+ if (start_slurl.isValid() &&
+ (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
+ {
+ if (sendURLToOtherInstance(start_slurl.getSLURLString()))
+ {
+ // successfully handed off URL to existing instance, exit
+ return false;
+ }
+ }
+
+ // Display splash screen. Must be after above check for previous
+ // crash as this dialog is always frontmost.
+ std::string splash_msg;
+ LLStringUtil::format_map_t args;
+ args["[APP_NAME]"] = LLTrans::getString("SECOND_LIFE");
+ splash_msg = LLTrans::getString("StartupLoading", args);
+ LLSplashScreen::show();
+ LLSplashScreen::update(splash_msg);
+
+ //LLVolumeMgr::initClass();
+ LLVolumeMgr* volume_manager = new LLVolumeMgr();
+ volume_manager->useMutex(); // LLApp and LLMutex magic must be manually enabled
+ LLPrimitive::setVolumeManager(volume_manager);
+
+ // Note: this is where we used to initialize gFeatureManagerp.
+
+ gStartTime = totalTime();
+
+ //
+ // Set the name of the window
+ //
+ gWindowTitle = LLTrans::getString("APP_NAME");
#if LL_DEBUG
- gWindowTitle += std::string(" [DEBUG]");
+ gWindowTitle += std::string(" [DEBUG]");
#endif
- if (!gArgs.empty())
- {
- gWindowTitle += std::string(" ") + gArgs;
- }
- LLStringUtil::truncate(gWindowTitle, 255);
-
- //
- // Check for another instance of the app running
- // This happens AFTER LLSplashScreen::show(). That may or may not be
- // important.
- //
- if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
- {
- OSMessageBox(
- LLTrans::getString("MBAlreadyRunning"),
- LLStringUtil::null,
- OSMB_OK);
- return false;
- }
-
- if (mSecondInstance)
- {
- // This is the second instance of SL. Mute voice,
- // but make sure the setting is *not* persisted.
- // Also see LLVivoxVoiceClient::voiceEnabled()
- LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat");
- if(enable_voice)
- {
- const BOOL DO_NOT_PERSIST = FALSE;
- enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST);
- }
- }
-
- gLastRunVersion = gSavedSettings.getString("LastRunVersion");
-
- loadColorSettings();
-
- // Let anyone else who cares know that we've populated our settings
- // variables.
- for (const auto& key : LLControlGroup::key_snapshot())
- {
- // For each named instance of LLControlGroup, send an event saying
- // we've initialized an LLControlGroup instance by that name.
- LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key));
- }
+ if (!gArgs.empty())
+ {
+ gWindowTitle += std::string(" ") + gArgs;
+ }
+ LLStringUtil::truncate(gWindowTitle, 255);
+
+ //
+ // Check for another instance of the app running
+ // This happens AFTER LLSplashScreen::show(). That may or may not be
+ // important.
+ //
+ if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
+ {
+ OSMessageBox(
+ LLTrans::getString("MBAlreadyRunning"),
+ LLStringUtil::null,
+ OSMB_OK);
+ return false;
+ }
+
+ if (mSecondInstance)
+ {
+ // This is the second instance of SL. Mute voice,
+ // but make sure the setting is *not* persisted.
+ // Also see LLVivoxVoiceClient::voiceEnabled()
+ LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat");
+ if(enable_voice)
+ {
+ const BOOL DO_NOT_PERSIST = FALSE;
+ enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST);
+ }
+ }
+
+ gLastRunVersion = gSavedSettings.getString("LastRunVersion");
+
+ loadColorSettings();
+
+ // Let anyone else who cares know that we've populated our settings
+ // variables.
+ for (const auto& key : LLControlGroup::key_snapshot())
+ {
+ // For each named instance of LLControlGroup, send an event saying
+ // we've initialized an LLControlGroup instance by that name.
+ LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key));
+ }
LLError::LLUserWarningMsg::setOutOfMemoryStrings(LLTrans::getString("MBOutOfMemoryTitle"), LLTrans::getString("MBOutOfMemoryErr"));
- return true; // Config was successful.
+ return true; // Config was successful.
}
// The following logic is replicated in initConfiguration() (to be able to get
@@ -2992,214 +2997,214 @@ bool LLAppViewer::initConfiguration()
// keeps growing, necessitating a method all its own.
void LLAppViewer::initStrings()
{
- std::string strings_file = "strings.xml";
- std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
- if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
- {
- if (strings_path_full.empty())
- {
- LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
- }
- else
- {
- llstat st;
- int rc = LLFile::stat(strings_path_full, &st);
- if (rc != 0)
- {
- LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
- }
- else if (S_ISDIR(st.st_mode))
- {
- LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
- }
- }
-
- // initial check to make sure files are there failed
- gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
+ std::string strings_file = "strings.xml";
+ std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
+ if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
+ {
+ if (strings_path_full.empty())
+ {
+ LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
+ }
+ else
+ {
+ llstat st;
+ int rc = LLFile::stat(strings_path_full, &st);
+ if (rc != 0)
+ {
+ LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
+ }
+ else if (S_ISDIR(st.st_mode))
+ {
+ LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
+ }
+ }
+
+ // initial check to make sure files are there failed
+ gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LLError::LLUserWarningMsg::showMissingFiles();
- LL_ERRS() << "Viewer failed to find localization and UI files."
- << " Please reinstall viewer from https://secondlife.com/support/downloads"
- << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
- }
- LLTransUtil::parseStrings(strings_file, default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
-
- // parseStrings() sets up the LLTrans substitution table. Add this one item.
- LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid"));
-
- // Now that we've set "[sourceid]", have to go back through
- // default_trans_args and reinitialize all those other keys because some
- // of them, in turn, reference "[sourceid]".
- for (const std::string& key : default_trans_args)
- {
- std::string brackets(key), nobrackets(key);
- // Invalid to inspect key[0] if key is empty(). But then, the entire
- // body of this loop is pointless if key is empty().
- if (key.empty())
- continue;
-
- if (key[0] != '[')
- {
- // key was passed without brackets. That means that 'nobrackets'
- // is correct but 'brackets' is not.
- brackets = STRINGIZE('[' << brackets << ']');
- }
- else
- {
- // key was passed with brackets. That means that 'brackets' is
- // correct but 'nobrackets' is not. Erase the left bracket.
- nobrackets.erase(0, 1);
- std::string::size_type length(nobrackets.length());
- if (length && nobrackets[length - 1] == ']')
- {
- nobrackets.erase(length - 1);
- }
- }
- // Calling LLTrans::getString() is what embeds the other default
- // translation strings into this one.
- LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets));
- }
+ LL_ERRS() << "Viewer failed to find localization and UI files."
+ << " Please reinstall viewer from https://secondlife.com/support/downloads"
+ << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ }
+ LLTransUtil::parseStrings(strings_file, default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ // parseStrings() sets up the LLTrans substitution table. Add this one item.
+ LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid"));
+
+ // Now that we've set "[sourceid]", have to go back through
+ // default_trans_args and reinitialize all those other keys because some
+ // of them, in turn, reference "[sourceid]".
+ for (const std::string& key : default_trans_args)
+ {
+ std::string brackets(key), nobrackets(key);
+ // Invalid to inspect key[0] if key is empty(). But then, the entire
+ // body of this loop is pointless if key is empty().
+ if (key.empty())
+ continue;
+
+ if (key[0] != '[')
+ {
+ // key was passed without brackets. That means that 'nobrackets'
+ // is correct but 'brackets' is not.
+ brackets = STRINGIZE('[' << brackets << ']');
+ }
+ else
+ {
+ // key was passed with brackets. That means that 'brackets' is
+ // correct but 'nobrackets' is not. Erase the left bracket.
+ nobrackets.erase(0, 1);
+ std::string::size_type length(nobrackets.length());
+ if (length && nobrackets[length - 1] == ']')
+ {
+ nobrackets.erase(length - 1);
+ }
+ }
+ // Calling LLTrans::getString() is what embeds the other default
+ // translation strings into this one.
+ LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets));
+ }
}
bool LLAppViewer::meetsRequirementsForMaximizedStart()
{
bool maximizedOk = (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
- return maximizedOk;
+ return maximizedOk;
}
bool LLAppViewer::initWindow()
{
- LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL;
-
- // store setting in a global for easy access and modification
- gHeadlessClient = gSavedSettings.getBOOL("HeadlessClient");
-
- // always start windowed
- BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
-
- LLViewerWindow::Params window_params;
- window_params
- .title(gWindowTitle)
- .name(VIEWER_WINDOW_CLASSNAME)
- .x(gSavedSettings.getS32("WindowX"))
- .y(gSavedSettings.getS32("WindowY"))
- .width(gSavedSettings.getU32("WindowWidth"))
- .height(gSavedSettings.getU32("WindowHeight"))
- .min_width(gSavedSettings.getU32("MinWindowWidth"))
- .min_height(gSavedSettings.getU32("MinWindowHeight"))
- .fullscreen(gSavedSettings.getBOOL("FullScreen"))
- .ignore_pixel_depth(ignorePixelDepth)
- .first_run(mIsFirstRun);
-
- gViewerWindow = new LLViewerWindow(window_params);
-
- LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL;
-
- // Need to load feature table before cheking to start watchdog.
- bool use_watchdog = false;
- int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled");
- if (watchdog_enabled_setting == -1)
- {
- use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled");
- }
- else
- {
- // The user has explicitly set this setting; always use that value.
- use_watchdog = bool(watchdog_enabled_setting);
- }
-
- LL_INFOS("AppInit") << "watchdog"
- << (use_watchdog ? " " : " NOT ")
- << "enabled"
- << " (setting = " << watchdog_enabled_setting << ")"
- << LL_ENDL;
-
- if (use_watchdog)
- {
- LLWatchdog::getInstance()->init();
- }
-
- LLNotificationsUI::LLNotificationManager::getInstance();
+ LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL;
+
+ // store setting in a global for easy access and modification
+ gHeadlessClient = gSavedSettings.getBOOL("HeadlessClient");
+
+ // always start windowed
+ BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
+
+ LLViewerWindow::Params window_params;
+ window_params
+ .title(gWindowTitle)
+ .name(VIEWER_WINDOW_CLASSNAME)
+ .x(gSavedSettings.getS32("WindowX"))
+ .y(gSavedSettings.getS32("WindowY"))
+ .width(gSavedSettings.getU32("WindowWidth"))
+ .height(gSavedSettings.getU32("WindowHeight"))
+ .min_width(gSavedSettings.getU32("MinWindowWidth"))
+ .min_height(gSavedSettings.getU32("MinWindowHeight"))
+ .fullscreen(gSavedSettings.getBOOL("FullScreen"))
+ .ignore_pixel_depth(ignorePixelDepth)
+ .first_run(mIsFirstRun);
+
+ gViewerWindow = new LLViewerWindow(window_params);
+
+ LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL;
+
+ // Need to load feature table before cheking to start watchdog.
+ bool use_watchdog = false;
+ int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled");
+ if (watchdog_enabled_setting == -1)
+ {
+ use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled");
+ }
+ else
+ {
+ // The user has explicitly set this setting; always use that value.
+ use_watchdog = bool(watchdog_enabled_setting);
+ }
+
+ LL_INFOS("AppInit") << "watchdog"
+ << (use_watchdog ? " " : " NOT ")
+ << "enabled"
+ << " (setting = " << watchdog_enabled_setting << ")"
+ << LL_ENDL;
+
+ if (use_watchdog)
+ {
+ LLWatchdog::getInstance()->init();
+ }
+
+ LLNotificationsUI::LLNotificationManager::getInstance();
#ifdef LL_DARWIN
- //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later)
- LLOSInfo& os_info = LLOSInfo::instance();
- if (os_info.mMajorVer == 10 && os_info.mMinorVer < 7)
- {
- if ( os_info.mMinorVer == 6 && os_info.mBuild < 8 )
- gViewerWindow->getWindow()->setOldResize(true);
- }
+ //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later)
+ LLOSInfo& os_info = LLOSInfo::instance();
+ if (os_info.mMajorVer == 10 && os_info.mMinorVer < 7)
+ {
+ if ( os_info.mMinorVer == 6 && os_info.mBuild < 8 )
+ gViewerWindow->getWindow()->setOldResize(true);
+ }
#endif
- if (gSavedSettings.getBOOL("WindowMaximized"))
- {
- gViewerWindow->getWindow()->maximize();
- }
+ if (gSavedSettings.getBOOL("WindowMaximized"))
+ {
+ gViewerWindow->getWindow()->maximize();
+ }
- //
- // Initialize GL stuff
- //
+ //
+ // Initialize GL stuff
+ //
- if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel)))
- {
- LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
- gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
- }
+ if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel)))
+ {
+ LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
+ gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
+ }
- // Set this flag in case we crash while initializing GL
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ // Set this flag in case we crash while initializing GL
+ gSavedSettings.setBOOL("RenderInitError", TRUE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- gPipeline.init();
- LL_INFOS("AppInit") << "gPipeline Initialized" << LL_ENDL;
+ gPipeline.init();
+ LL_INFOS("AppInit") << "gPipeline Initialized" << LL_ENDL;
- stop_glerror();
- gViewerWindow->initGLDefaults();
+ stop_glerror();
+ gViewerWindow->initGLDefaults();
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ gSavedSettings.setBOOL("RenderInitError", FALSE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- //If we have a startup crash, it's usually near GL initialization, so simulate that.
- if(gCrashOnStartup)
- {
- LLAppViewer::instance()->forceErrorLLError();
- }
+ //If we have a startup crash, it's usually near GL initialization, so simulate that.
+ if(gCrashOnStartup)
+ {
+ LLAppViewer::instance()->forceErrorLLError();
+ }
- //
- // Determine if the window should start maximized on initial run based
- // on graphics capability
- //
- if (gSavedSettings.getBOOL("FirstLoginThisInstall") && meetsRequirementsForMaximizedStart())
- {
- LL_INFOS("AppInit") << "This client met the requirements for a maximized initial screen." << LL_ENDL;
- gSavedSettings.setBOOL("WindowMaximized", TRUE);
- }
+ //
+ // Determine if the window should start maximized on initial run based
+ // on graphics capability
+ //
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall") && meetsRequirementsForMaximizedStart())
+ {
+ LL_INFOS("AppInit") << "This client met the requirements for a maximized initial screen." << LL_ENDL;
+ gSavedSettings.setBOOL("WindowMaximized", TRUE);
+ }
- if (gSavedSettings.getBOOL("WindowMaximized"))
- {
- gViewerWindow->getWindow()->maximize();
- }
+ if (gSavedSettings.getBOOL("WindowMaximized"))
+ {
+ gViewerWindow->getWindow()->maximize();
+ }
- LLUI::getInstance()->mWindow = gViewerWindow->getWindow();
+ LLUI::getInstance()->mWindow = gViewerWindow->getWindow();
- // Show watch cursor
- gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ // Show watch cursor
+ gViewerWindow->setCursor(UI_CURSOR_WAIT);
- // Finish view initialization
- gViewerWindow->initBase();
+ // Finish view initialization
+ gViewerWindow->initBase();
- // show viewer window
- //gViewerWindow->getWindow()->show();
+ // show viewer window
+ //gViewerWindow->getWindow()->show();
- LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL;
+ LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL;
- return true;
+ return true;
}
bool LLAppViewer::isUpdaterMissing()
@@ -3238,28 +3243,28 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
LLSD LLAppViewer::getViewerInfo() const
{
- // The point of having one method build an LLSD info block and the other
- // construct the user-visible About string is to ensure that the same info
- // is available to a getInfo() caller as to the user opening
- // LLFloaterAbout.
- LLSD info;
- auto& versionInfo(LLVersionInfo::instance());
- // With GitHub builds, the build number is too big to fit in a 32-bit int,
- // and LLSD doesn't deal with integers wider than int. Use string.
- info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
- versionInfo.getPatch(), stringize(versionInfo.getBuild()));
- info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
- info["CHANNEL"] = versionInfo.getChannel();
- info["ADDRESS_SIZE"] = ADDRESS_SIZE;
- std::string build_config = versionInfo.getBuildConfig();
- if (build_config != "Release")
- {
- info["BUILD_CONFIG"] = build_config;
- }
-
- // return a URL to the release notes for this viewer, such as:
- // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
- std::string url = versionInfo.getReleaseNotes(); // VVM supplied
+ // The point of having one method build an LLSD info block and the other
+ // construct the user-visible About string is to ensure that the same info
+ // is available to a getInfo() caller as to the user opening
+ // LLFloaterAbout.
+ LLSD info;
+ auto& versionInfo(LLVersionInfo::instance());
+ // With GitHub builds, the build number is too big to fit in a 32-bit int,
+ // and LLSD doesn't deal with integers wider than int. Use string.
+ info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
+ versionInfo.getPatch(), stringize(versionInfo.getBuild()));
+ info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
+ info["CHANNEL"] = versionInfo.getChannel();
+ info["ADDRESS_SIZE"] = ADDRESS_SIZE;
+ std::string build_config = versionInfo.getBuildConfig();
+ if (build_config != "Release")
+ {
+ info["BUILD_CONFIG"] = build_config;
+ }
+
+ // return a URL to the release notes for this viewer, such as:
+ // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
+ std::string url = versionInfo.getReleaseNotes(); // VVM supplied
if (url.empty())
{
url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
@@ -3267,32 +3272,32 @@ LLSD LLAppViewer::getViewerInfo() const
url += "/";
url += LLURI::escape(versionInfo.getVersion()) + ".html";
}
- info["VIEWER_RELEASE_NOTES_URL"] = url;
-
- // Position
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- LLVector3d pos = gAgent.getPositionGlobal();
- info["POSITION"] = ll_sd_from_vector3d(pos);
- info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
- info["REGION"] = gAgent.getRegion()->getName();
-
- boost::regex regex("\\.(secondlife|lindenlab)\\..*");
- info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
- info["SERVER_VERSION"] = gLastVersionChannel;
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- info["SLURL"] = slurl.getSLURLString();
- }
-
- // CPU
- info["CPU"] = gSysCPU.getCPUString();
- info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits<LLUnits::Megabytes>());
- // Moved hack adjustment to Windows memory size into llsys.cpp
- info["OS_VERSION"] = LLOSInfo::instance().getOSString();
- info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR)));
- info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
+ info["VIEWER_RELEASE_NOTES_URL"] = url;
+
+ // Position
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ LLVector3d pos = gAgent.getPositionGlobal();
+ info["POSITION"] = ll_sd_from_vector3d(pos);
+ info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
+ info["REGION"] = gAgent.getRegion()->getName();
+
+ boost::regex regex("\\.(secondlife|lindenlab)\\..*");
+ info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
+ info["SERVER_VERSION"] = gLastVersionChannel;
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ info["SLURL"] = slurl.getSLURLString();
+ }
+
+ // CPU
+ info["CPU"] = gSysCPU.getCPUString();
+ info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits<LLUnits::Megabytes>());
+ // Moved hack adjustment to Windows memory size into llsys.cpp
+ info["OS_VERSION"] = LLOSInfo::instance().getOSString();
+ info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR)));
+ info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
#if LL_WINDOWS
std::string drvinfo;
@@ -3317,22 +3322,22 @@ LLSD LLAppViewer::getViewerInfo() const
drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY);
}
- if (!drvinfo.empty())
- {
- info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
- }
- else
- {
- LL_WARNS("DriverVersion")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL;
- LLSD driver_info = gDXHardware.getDisplayInfo();
- if (driver_info.has("DriverVersion"))
- {
- info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
- }
- }
+ if (!drvinfo.empty())
+ {
+ info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
+ }
+ else
+ {
+ LL_WARNS("DriverVersion")<< "Cannot get driver version from getDriverVersionWMI" << LL_ENDL;
+ LLSD driver_info = gDXHardware.getDisplayInfo();
+ if (driver_info.has("DriverVersion"))
+ {
+ info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
+ }
+ }
#endif
- info["OPENGL_VERSION"] = ll_safe_string((const char*)(glGetString(GL_VERSION)));
+ info["OPENGL_VERSION"] = ll_safe_string((const char*)(glGetString(GL_VERSION)));
// Settings
@@ -3351,16 +3356,16 @@ LLSD LLAppViewer::getViewerInfo() const
info["HIDPI"] = gHiDPISupport;
#endif
- // Libraries
+ // Libraries
- info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
- bool want_fullname = true;
- info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
- if(LLVoiceClient::getInstance()->voiceEnabled())
- {
+ info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
+ bool want_fullname = true;
+ info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
+ if(LLVoiceClient::getInstance()->voiceEnabled())
+ {
LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
const std::string build_version = version.mBuildVersion;
- std::ostringstream version_string;
+ std::ostringstream version_string;
if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
version.serverVersion.begin()))
{ // Normal case: Show type and build version.
@@ -3370,210 +3375,210 @@ LLSD LLAppViewer::getViewerInfo() const
{ // Mismatch: Show both versions.
version_string << version.serverVersion << "/" << build_version << std::endl;
}
- info["VOICE_VERSION"] = version_string.str();
- }
- else
- {
- info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
- }
+ info["VOICE_VERSION"] = version_string.str();
+ }
+ else
+ {
+ info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
+ }
#if !LL_LINUX
- std::ostringstream cef_ver_codec;
- cef_ver_codec << "Dullahan: ";
- cef_ver_codec << DULLAHAN_VERSION_MAJOR;
- cef_ver_codec << ".";
- cef_ver_codec << DULLAHAN_VERSION_MINOR;
- cef_ver_codec << ".";
- cef_ver_codec << DULLAHAN_VERSION_POINT;
- cef_ver_codec << ".";
- cef_ver_codec << DULLAHAN_VERSION_BUILD;
-
- cef_ver_codec << std::endl;
- cef_ver_codec << " CEF: ";
- cef_ver_codec << CEF_VERSION;
-
- cef_ver_codec << std::endl;
- cef_ver_codec << " Chromium: ";
- cef_ver_codec << CHROME_VERSION_MAJOR;
- cef_ver_codec << ".";
- cef_ver_codec << CHROME_VERSION_MINOR;
- cef_ver_codec << ".";
- cef_ver_codec << CHROME_VERSION_BUILD;
- cef_ver_codec << ".";
- cef_ver_codec << CHROME_VERSION_PATCH;
-
- info["LIBCEF_VERSION"] = cef_ver_codec.str();
+ std::ostringstream cef_ver_codec;
+ cef_ver_codec << "Dullahan: ";
+ cef_ver_codec << DULLAHAN_VERSION_MAJOR;
+ cef_ver_codec << ".";
+ cef_ver_codec << DULLAHAN_VERSION_MINOR;
+ cef_ver_codec << ".";
+ cef_ver_codec << DULLAHAN_VERSION_POINT;
+ cef_ver_codec << ".";
+ cef_ver_codec << DULLAHAN_VERSION_BUILD;
+
+ cef_ver_codec << std::endl;
+ cef_ver_codec << " CEF: ";
+ cef_ver_codec << CEF_VERSION;
+
+ cef_ver_codec << std::endl;
+ cef_ver_codec << " Chromium: ";
+ cef_ver_codec << CHROME_VERSION_MAJOR;
+ cef_ver_codec << ".";
+ cef_ver_codec << CHROME_VERSION_MINOR;
+ cef_ver_codec << ".";
+ cef_ver_codec << CHROME_VERSION_BUILD;
+ cef_ver_codec << ".";
+ cef_ver_codec << CHROME_VERSION_PATCH;
+
+ info["LIBCEF_VERSION"] = cef_ver_codec.str();
#else
- info["LIBCEF_VERSION"] = "Undefined";
+ info["LIBCEF_VERSION"] = "Undefined";
#endif
#if !LL_LINUX
- std::ostringstream vlc_ver_codec;
- vlc_ver_codec << LIBVLC_VERSION_MAJOR;
- vlc_ver_codec << ".";
- vlc_ver_codec << LIBVLC_VERSION_MINOR;
- vlc_ver_codec << ".";
- vlc_ver_codec << LIBVLC_VERSION_REVISION;
- info["LIBVLC_VERSION"] = vlc_ver_codec.str();
+ std::ostringstream vlc_ver_codec;
+ vlc_ver_codec << LIBVLC_VERSION_MAJOR;
+ vlc_ver_codec << ".";
+ vlc_ver_codec << LIBVLC_VERSION_MINOR;
+ vlc_ver_codec << ".";
+ vlc_ver_codec << LIBVLC_VERSION_REVISION;
+ info["LIBVLC_VERSION"] = vlc_ver_codec.str();
#else
- info["LIBVLC_VERSION"] = "Undefined";
+ info["LIBVLC_VERSION"] = "Undefined";
#endif
- S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
- if (packets_in > 0)
- {
- info["PACKETS_LOST"] = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST);
- info["PACKETS_IN"] = packets_in;
- info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
- }
-
- if (mServerReleaseNotesURL.empty())
- {
- if (gAgent.getRegion())
- {
- info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData");
- }
- else
- {
- info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("NotConnected");
- }
- }
- else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL
- {
- info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]";
- }
- else
- {
- info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
- }
+ S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
+ if (packets_in > 0)
+ {
+ info["PACKETS_LOST"] = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST);
+ info["PACKETS_IN"] = packets_in;
+ info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
+ }
+
+ if (mServerReleaseNotesURL.empty())
+ {
+ if (gAgent.getRegion())
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData");
+ }
+ else
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("NotConnected");
+ }
+ }
+ else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]";
+ }
+ else
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
+ }
// populate field for new local disk cache with some details
info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo();
- return info;
+ return info;
}
std::string LLAppViewer::getViewerInfoString(bool default_string) const
{
- std::ostringstream support;
-
- LLSD info(getViewerInfo());
-
- // Render the LLSD from getInfo() as a format_map_t
- LLStringUtil::format_map_t args;
-
- // allow the "Release Notes" URL label to be localized
- args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string);
-
- for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
- ii != iend; ++ii)
- {
- if (! ii->second.isArray())
- {
- // Scalar value
- if (ii->second.isUndefined())
- {
- args[ii->first] = LLTrans::getString("none_text", default_string);
- }
- else
- {
- // don't forget to render value asString()
- args[ii->first] = ii->second.asString();
- }
- }
- else
- {
- // array value: build KEY_0, KEY_1 etc. entries
- for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
- {
- args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
- }
- }
- }
-
- // Now build the various pieces
- support << LLTrans::getString("AboutHeader", args, default_string);
- if (info.has("BUILD_CONFIG"))
- {
- support << "\n" << LLTrans::getString("BuildConfig", args, default_string);
- }
- if (info.has("REGION"))
- {
- support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string);
- }
- support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string);
- support << "\n";
- if (info.has("GRAPHICS_DRIVER_VERSION"))
- {
- support << "\n" << LLTrans::getString("AboutDriver", args, default_string);
- }
- support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
- support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
+ std::ostringstream support;
+
+ LLSD info(getViewerInfo());
+
+ // Render the LLSD from getInfo() as a format_map_t
+ LLStringUtil::format_map_t args;
+
+ // allow the "Release Notes" URL label to be localized
+ args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string);
+
+ for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
+ ii != iend; ++ii)
+ {
+ if (! ii->second.isArray())
+ {
+ // Scalar value
+ if (ii->second.isUndefined())
+ {
+ args[ii->first] = LLTrans::getString("none_text", default_string);
+ }
+ else
+ {
+ // don't forget to render value asString()
+ args[ii->first] = ii->second.asString();
+ }
+ }
+ else
+ {
+ // array value: build KEY_0, KEY_1 etc. entries
+ for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
+ {
+ args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
+ }
+ }
+ }
+
+ // Now build the various pieces
+ support << LLTrans::getString("AboutHeader", args, default_string);
+ if (info.has("BUILD_CONFIG"))
+ {
+ support << "\n" << LLTrans::getString("BuildConfig", args, default_string);
+ }
+ if (info.has("REGION"))
+ {
+ support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string);
+ }
+ support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string);
+ support << "\n";
+ if (info.has("GRAPHICS_DRIVER_VERSION"))
+ {
+ support << "\n" << LLTrans::getString("AboutDriver", args, default_string);
+ }
+ support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
+ support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
#if LL_DARWIN
- support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string);
+ support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string);
#endif
- support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
- if (info.has("COMPILER"))
- {
- support << "\n" << LLTrans::getString("AboutCompiler", args, default_string);
- }
- if (info.has("PACKETS_IN"))
- {
- support << '\n' << LLTrans::getString("AboutTraffic", args, default_string);
- }
-
- // SLT timestamp
- LLSD substitution;
- substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected();
- support << "\n" << LLTrans::getString("AboutTime", substitution, default_string);
-
- return support.str();
+ support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
+ if (info.has("COMPILER"))
+ {
+ support << "\n" << LLTrans::getString("AboutCompiler", args, default_string);
+ }
+ if (info.has("PACKETS_IN"))
+ {
+ support << '\n' << LLTrans::getString("AboutTraffic", args, default_string);
+ }
+
+ // SLT timestamp
+ LLSD substitution;
+ substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected();
+ support << "\n" << LLTrans::getString("AboutTime", substitution, default_string);
+
+ return support.str();
}
void LLAppViewer::cleanupSavedSettings()
{
- gSavedSettings.setBOOL("MouseSun", FALSE);
+ gSavedSettings.setBOOL("MouseSun", FALSE);
- gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator
+ gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator
- gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
+ gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
- gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
+ gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
- if (gDebugView)
- {
- gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
- }
+ if (gDebugView)
+ {
+ gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
+ }
- // save window position if not maximized
- // as we don't track it in callbacks
- if(NULL != gViewerWindow)
- {
- BOOL maximized = gViewerWindow->getWindow()->getMaximized();
- if (!maximized)
- {
- LLCoordScreen window_pos;
+ // save window position if not maximized
+ // as we don't track it in callbacks
+ if(NULL != gViewerWindow)
+ {
+ BOOL maximized = gViewerWindow->getWindow()->getMaximized();
+ if (!maximized)
+ {
+ LLCoordScreen window_pos;
- if (gViewerWindow->getWindow()->getPosition(&window_pos))
- {
- gSavedSettings.setS32("WindowX", window_pos.mX);
- gSavedSettings.setS32("WindowY", window_pos.mY);
- }
- }
- }
+ if (gViewerWindow->getWindow()->getPosition(&window_pos))
+ {
+ gSavedSettings.setS32("WindowX", window_pos.mX);
+ gSavedSettings.setS32("WindowY", window_pos.mY);
+ }
+ }
+ }
gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
- // Some things are cached in LLAgent.
- if (gAgent.isInitialized())
- {
- gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance);
- }
+ // Some things are cached in LLAgent.
+ if (gAgent.isInitialized())
+ {
+ gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance);
+ }
}
void LLAppViewer::removeCacheFiles(const std::string& file_mask)
{
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
}
void LLAppViewer::writeSystemInfo()
@@ -3583,96 +3588,96 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["Dynamic"] = LLSD::emptyMap();
#if LL_WINDOWS && !LL_BUGSPLAT
- gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
+ gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
#else
//Not ideal but sufficient for good reporting.
gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
#endif
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
- gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize();
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
+ gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize();
- gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
+ gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
- gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
- gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
- gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz();
- gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
- gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
- gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
+ gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
+ gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
+ gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz();
+ gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
+ gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
+ gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
- gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value());
- gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
- gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple();
+ gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value());
+ gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
+ gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple();
- // The user is not logged on yet, but record the current grid choice login url
- // which may have been the intended grid.
- gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId();
+ // The user is not logged on yet, but record the current grid choice login url
+ // which may have been the intended grid.
+ gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId();
- // *FIX:Mani - move this down in llappviewerwin32
+ // *FIX:Mani - move this down in llappviewerwin32
#ifdef LL_WINDOWS
- DWORD thread_id = GetCurrentThreadId();
- gDebugInfo["MainloopThreadID"] = (S32)thread_id;
+ DWORD thread_id = GetCurrentThreadId();
+ gDebugInfo["MainloopThreadID"] = (S32)thread_id;
#endif
#ifndef LL_BUGSPLAT
- // "CrashNotHandled" is set here, while things are running well,
- // in case of a freeze. If there is a freeze, the crash logger will be launched
- // and can read this value from the debug_info.log.
- gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true);
+ // "CrashNotHandled" is set here, while things are running well,
+ // in case of a freeze. If there is a freeze, the crash logger will be launched
+ // and can read this value from the debug_info.log.
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true);
#else // LL_BUGSPLAT
- // "CrashNotHandled" is obsolete; it used (not very successsfully)
+ // "CrashNotHandled" is obsolete; it used (not very successsfully)
// to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze
- gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false);
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false);
#endif // ! LL_BUGSPLAT
- // Insert crash host url (url to post crash log to) if configured. This insures
- // that the crash report will go to the proper location in the case of a
- // prior freeze.
- std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
- if(crashHostUrl != "")
- {
- gDebugInfo["CrashHostUrl"] = crashHostUrl;
- }
-
- // Dump some debugging info
- LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
- LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL;
-
- // Dump the local time and time zone
- time_t now;
- time(&now);
- char tbuffer[256]; /* Flawfinder: ignore */
- strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now));
- LL_INFOS("SystemInfo") << "Local time: " << tbuffer << LL_ENDL;
-
- // query some system information
- LL_INFOS("SystemInfo") << "CPU info:\n" << gSysCPU << LL_ENDL;
- LL_INFOS("SystemInfo") << "Memory info:\n" << gSysMemory << LL_ENDL;
- LL_INFOS("SystemInfo") << "OS: " << LLOSInfo::instance().getOSStringSimple() << LL_ENDL;
- LL_INFOS("SystemInfo") << "OS info: " << LLOSInfo::instance() << LL_ENDL;
+ // Insert crash host url (url to post crash log to) if configured. This insures
+ // that the crash report will go to the proper location in the case of a
+ // prior freeze.
+ std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
+ if(crashHostUrl != "")
+ {
+ gDebugInfo["CrashHostUrl"] = crashHostUrl;
+ }
+
+ // Dump some debugging info
+ LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL;
+
+ // Dump the local time and time zone
+ time_t now;
+ time(&now);
+ char tbuffer[256]; /* Flawfinder: ignore */
+ strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now));
+ LL_INFOS("SystemInfo") << "Local time: " << tbuffer << LL_ENDL;
+
+ // query some system information
+ LL_INFOS("SystemInfo") << "CPU info:\n" << gSysCPU << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Memory info:\n" << gSysMemory << LL_ENDL;
+ LL_INFOS("SystemInfo") << "OS: " << LLOSInfo::instance().getOSStringSimple() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "OS info: " << LLOSInfo::instance() << LL_ENDL;
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
- gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
- gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
- gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin());
- gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
+ gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
+ gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
+ gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin());
+ gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
if (gViewerWindow)
{
- std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
- for (auto res_iter : resolutions)
- {
- gDebugInfo["DisplayInfo"].append(res_iter);
- }
+ std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
+ for (auto res_iter : resolutions)
+ {
+ gDebugInfo["DisplayInfo"].append(res_iter);
+ }
}
- writeDebugInfo(); // Save out debug_info.log early, in case of crash.
+ writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
#ifdef LL_WINDOWS
@@ -3684,265 +3689,265 @@ void LLAppViewer::writeSystemInfo()
// TODO make this a member function.
void getFileList()
{
- std::stringstream filenames;
-
- typedef std::vector<std::string> vec;
- std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
- vec file_vec = gDirUtilp->getFilesInDir(pathname);
- for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
- {
- filenames << *iter << " ";
- if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
- {
- std::string fullname = pathname + *iter;
- llifstream fdat( fullname.c_str(), std::ifstream::binary);
- if (fdat)
- {
- char buf[5];
- fdat.read(buf,4);
- fdat.close();
- if (!strncmp(buf,"MDMP",4))
- {
- gDebugInfo["Dynamic"]["MinidumpPath"] = fullname;
- break;
- }
- }
- }
- }
- filenames << std::endl;
- gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str();
+ std::stringstream filenames;
+
+ typedef std::vector<std::string> vec;
+ std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
+ vec file_vec = gDirUtilp->getFilesInDir(pathname);
+ for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
+ {
+ filenames << *iter << " ";
+ if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
+ {
+ std::string fullname = pathname + *iter;
+ llifstream fdat( fullname.c_str(), std::ifstream::binary);
+ if (fdat)
+ {
+ char buf[5];
+ fdat.read(buf,4);
+ fdat.close();
+ if (!strncmp(buf,"MDMP",4))
+ {
+ gDebugInfo["Dynamic"]["MinidumpPath"] = fullname;
+ break;
+ }
+ }
+ }
+ }
+ filenames << std::endl;
+ gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str();
}
#endif
// static
void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
{
- std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
- if ( marker_version.length() > MAX_MARKER_LENGTH )
- {
- LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
- << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
- << ": marker matching may be incorrect"
- << LL_ENDL;
- }
-
- // record the viewer version in the marker file
- marker_file.write(marker_version.data(), marker_version.length());
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
+ if ( marker_version.length() > MAX_MARKER_LENGTH )
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
+ }
+
+ // record the viewer version in the marker file
+ marker_file.write(marker_version.data(), marker_version.length());
}
bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
{
- bool sameVersion = false;
-
- std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
- char marker_version[MAX_MARKER_LENGTH];
- S32 marker_version_length;
-
- LLAPRFile marker_file;
- marker_file.open(marker_name, LL_APR_RB);
- if (marker_file.getFileHandle())
- {
- marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
- std::string marker_string(marker_version, marker_version_length);
- if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
- {
- sameVersion = true;
- }
- LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
- << "\n mine '" << my_version << "'"
- << "\n marker '" << marker_string << "'"
- << "\n " << ( sameVersion ? "same" : "different" ) << " version"
- << LL_ENDL;
- marker_file.close();
- }
- return sameVersion;
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
+ char marker_version[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
+ std::string marker_string(marker_version, marker_version_length);
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ {
+ sameVersion = true;
+ }
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << ( sameVersion ? "same" : "different" ) << " version"
+ << LL_ENDL;
+ marker_file.close();
+ }
+ return sameVersion;
}
void LLAppViewer::processMarkerFiles()
{
- //We've got 4 things to test for here
- // - Other Process Running (SecondLife.exec_marker present, locked)
- // - Freeze (SecondLife.exec_marker present, not locked)
- // - LLError Crash (SecondLife.llerror_marker present)
- // - Other Crash (SecondLife.error_marker present)
- // These checks should also remove these files for the last 2 cases if they currently exist
-
- std::ostringstream marker_log_stream;
- bool marker_is_same_version = true;
- // first, look for the marker created at startup and deleted on a clean exit
- mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
- {
- // File exists...
- // first, read it to see if it was created by the same version (we need this later)
- marker_is_same_version = markerIsSameVersion(mMarkerFileName);
-
- // now test to see if this file is locked by a running process (try to open for write)
- marker_log_stream << "Checking exec marker file for lock...";
- mMarkerFile.open(mMarkerFileName, LL_APR_WB);
- apr_file_t* fMarker = mMarkerFile.getFileHandle() ;
- if (!fMarker)
- {
- marker_log_stream << "Exec marker file open failed - assume it is locked.";
- mSecondInstance = true; // lock means that instance is running.
- }
- else
- {
- // We were able to open it, now try to lock it ourselves...
- if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
- {
- marker_log_stream << "Locking exec marker failed.";
- mSecondInstance = true; // lost a race? be conservative
- }
- else
- {
- // No other instances; we've locked this file now, so record our version; delete on quit.
- recordMarkerVersion(mMarkerFile);
- marker_log_stream << "Exec marker file existed but was not locked; rewritten.";
- }
- }
- initLoggingAndGetLastDuration();
-
- std::string marker_log_msg(marker_log_stream.str());
- LL_INFOS("MarkerFile") << marker_log_msg << LL_ENDL;
-
- if (mSecondInstance)
- {
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
- }
- else if (marker_is_same_version)
- {
- // the file existed, is ours, and matched our version, so we can report on what it says
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL;
- gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- }
- else
- {
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
- }
- }
- else // marker did not exist... last exec (if any) did not freeze
- {
- initLoggingAndGetLastDuration();
- // Create the marker file for this execution & lock it; it will be deleted on a clean exit
- apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);
-
- if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
- if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
- {
- recordMarkerVersion(mMarkerFile);
- LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL;
- }
- else
- {
- LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL;
- }
- }
-
- // now check for cases in which the exec marker may have been cleaned up by crash handlers
-
- // check for any last exec event report based on whether or not it happened during logout
- // (the logout marker is created when logout begins)
- std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(logout_marker_file))
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
- LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;
- }
- else
- {
- LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(logout_marker_file);
- }
- // further refine based on whether or not a marker created during an llerr crash is found
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(llerror_marker_file))
- {
- if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(llerror_marker_file);
- }
- // and last refine based on whether or not a marker created during a non-llerr crash is found
- std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(error_marker_file))
- {
- if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(error_marker_file);
- }
+ //We've got 4 things to test for here
+ // - Other Process Running (SecondLife.exec_marker present, locked)
+ // - Freeze (SecondLife.exec_marker present, not locked)
+ // - LLError Crash (SecondLife.llerror_marker present)
+ // - Other Crash (SecondLife.error_marker present)
+ // These checks should also remove these files for the last 2 cases if they currently exist
+
+ std::ostringstream marker_log_stream;
+ bool marker_is_same_version = true;
+ // first, look for the marker created at startup and deleted on a clean exit
+ mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
+ if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
+ {
+ // File exists...
+ // first, read it to see if it was created by the same version (we need this later)
+ marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+
+ // now test to see if this file is locked by a running process (try to open for write)
+ marker_log_stream << "Checking exec marker file for lock...";
+ mMarkerFile.open(mMarkerFileName, LL_APR_WB);
+ apr_file_t* fMarker = mMarkerFile.getFileHandle() ;
+ if (!fMarker)
+ {
+ marker_log_stream << "Exec marker file open failed - assume it is locked.";
+ mSecondInstance = true; // lock means that instance is running.
+ }
+ else
+ {
+ // We were able to open it, now try to lock it ourselves...
+ if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
+ {
+ marker_log_stream << "Locking exec marker failed.";
+ mSecondInstance = true; // lost a race? be conservative
+ }
+ else
+ {
+ // No other instances; we've locked this file now, so record our version; delete on quit.
+ recordMarkerVersion(mMarkerFile);
+ marker_log_stream << "Exec marker file existed but was not locked; rewritten.";
+ }
+ }
+ initLoggingAndGetLastDuration();
+
+ std::string marker_log_msg(marker_log_stream.str());
+ LL_INFOS("MarkerFile") << marker_log_msg << LL_ENDL;
+
+ if (mSecondInstance)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
+ }
+ else if (marker_is_same_version)
+ {
+ // the file existed, is ours, and matched our version, so we can report on what it says
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
+ }
+ }
+ else // marker did not exist... last exec (if any) did not freeze
+ {
+ initLoggingAndGetLastDuration();
+ // Create the marker file for this execution & lock it; it will be deleted on a clean exit
+ apr_status_t s;
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);
+
+ if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
+ if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
+ {
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL;
+ }
+ }
+
+ // now check for cases in which the exec marker may have been cleaned up by crash handlers
+
+ // check for any last exec event report based on whether or not it happened during logout
+ // (the logout marker is created when logout begins)
+ std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
+ if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
+ {
+ if (markerIsSameVersion(logout_marker_file))
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
+ LLAPRFile::remove(logout_marker_file);
+ }
+ // further refine based on whether or not a marker created during an llerr crash is found
+ std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
+ if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
+ {
+ if (markerIsSameVersion(llerror_marker_file))
+ {
+ if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
+ LLAPRFile::remove(llerror_marker_file);
+ }
+ // and last refine based on whether or not a marker created during a non-llerr crash is found
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ {
+ if (markerIsSameVersion(error_marker_file))
+ {
+ if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ }
+ LLAPRFile::remove(error_marker_file);
+ }
}
void LLAppViewer::removeMarkerFiles()
{
- if (!mSecondInstance)
- {
- if (mMarkerFile.getFileHandle())
- {
- mMarkerFile.close() ;
- LLAPRFile::remove( mMarkerFileName );
- LL_DEBUGS("MarkerFile") << "removed exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
- }
- else
- {
- LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
- }
-
- if (mLogoutMarkerFile.getFileHandle())
- {
- mLogoutMarkerFile.close();
- LLAPRFile::remove( mLogoutMarkerFileName );
- LL_DEBUGS("MarkerFile") << "removed logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
- }
- else
- {
- LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
- }
- }
- else
- {
- LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
- }
+ if (!mSecondInstance)
+ {
+ if (mMarkerFile.getFileHandle())
+ {
+ mMarkerFile.close() ;
+ LLAPRFile::remove( mMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ mLogoutMarkerFile.close();
+ LLAPRFile::remove( mLogoutMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
+ }
}
void LLAppViewer::removeDumpDir()
@@ -3965,212 +3970,212 @@ void LLAppViewer::removeDumpDir()
void LLAppViewer::forceQuit()
{
- LLApp::setQuitting();
+ LLApp::setQuitting();
}
//TODO: remove
void LLAppViewer::fastQuit(S32 error_code)
{
- // finish pending transfers
- flushLFSIO();
- // let sim know we're logging out
- sendLogoutRequest();
- // flush network buffers by shutting down messaging system
- end_messaging_system();
- // figure out the error code
- S32 final_error_code = error_code ? error_code : (S32)isError();
- // this isn't a crash
- removeMarkerFiles();
- // get outta here
- _exit(final_error_code);
+ // finish pending transfers
+ flushLFSIO();
+ // let sim know we're logging out
+ sendLogoutRequest();
+ // flush network buffers by shutting down messaging system
+ end_messaging_system();
+ // figure out the error code
+ S32 final_error_code = error_code ? error_code : (S32)isError();
+ // this isn't a crash
+ removeMarkerFiles();
+ // get outta here
+ _exit(final_error_code);
}
void LLAppViewer::requestQuit()
{
- LL_INFOS() << "requestQuit" << LL_ENDL;
-
- LLViewerRegion* region = gAgent.getRegion();
-
- if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
- {
- // If we have a region, make some attempt to send a logout request first.
- // This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes.
- if(region)
- {
- sendLogoutRequest();
- }
-
- // Quit immediately
- forceQuit();
- return;
- }
-
- // Try to send metrics back to the grid
- metricsSend(!gDisconnected);
-
- // Try to send last batch of avatar rez metrics.
- if (!gDisconnected && isAgentAvatarValid())
- {
- gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
- }
-
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
- effectp->setPositionGlobal(gAgent.getPositionGlobal());
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- LLHUDManager::getInstance()->sendEffects();
- effectp->markDead() ;//remove it.
-
- // Attempt to close all floaters that might be
- // editing things.
- if (gFloaterView)
- {
- // application is quitting
- gFloaterView->closeAllChildren(true);
- }
-
- // Send preferences once, when exiting
- bool include_preferences = true;
- send_viewer_stats(include_preferences);
-
- gLogoutTimer.reset();
- mQuitRequested = true;
+ LL_INFOS() << "requestQuit" << LL_ENDL;
+
+ LLViewerRegion* region = gAgent.getRegion();
+
+ if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
+ {
+ // If we have a region, make some attempt to send a logout request first.
+ // This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes.
+ if(region)
+ {
+ sendLogoutRequest();
+ }
+
+ // Quit immediately
+ forceQuit();
+ return;
+ }
+
+ // Try to send metrics back to the grid
+ metricsSend(!gDisconnected);
+
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
+
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+ effectp->setPositionGlobal(gAgent.getPositionGlobal());
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ LLHUDManager::getInstance()->sendEffects();
+ effectp->markDead() ;//remove it.
+
+ // Attempt to close all floaters that might be
+ // editing things.
+ if (gFloaterView)
+ {
+ // application is quitting
+ gFloaterView->closeAllChildren(true);
+ }
+
+ // Send preferences once, when exiting
+ bool include_preferences = true;
+ send_viewer_stats(include_preferences);
+
+ gLogoutTimer.reset();
+ mQuitRequested = true;
}
static bool finish_quit(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLAppViewer::instance()->requestQuit();
- }
- return false;
+ if (option == 0)
+ {
+ LLAppViewer::instance()->requestQuit();
+ }
+ return false;
}
static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_quit);
void LLAppViewer::userQuit()
{
- LL_INFOS() << "User requested quit" << LL_ENDL;
- if (gDisconnected
- || !gViewerWindow
- || !gViewerWindow->getProgressView()
- || gViewerWindow->getProgressView()->getVisible())
- {
- requestQuit();
- }
- else
- {
- LLNotificationsUtil::add("ConfirmQuit");
- }
+ LL_INFOS() << "User requested quit" << LL_ENDL;
+ if (gDisconnected
+ || !gViewerWindow
+ || !gViewerWindow->getProgressView()
+ || gViewerWindow->getProgressView()->getVisible())
+ {
+ requestQuit();
+ }
+ else
+ {
+ LLNotificationsUtil::add("ConfirmQuit");
+ }
}
static bool finish_early_exit(const LLSD& notification, const LLSD& response)
{
- LLAppViewer::instance()->forceQuit();
- return false;
+ LLAppViewer::instance()->forceQuit();
+ return false;
}
void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
{
- LL_WARNS() << "app_early_exit: " << name << LL_ENDL;
- gDoDisconnect = TRUE;
- LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit);
+ LL_WARNS() << "app_early_exit: " << name << LL_ENDL;
+ gDoDisconnect = TRUE;
+ LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit);
}
// case where we need the viewer to exit without any need for notifications
void LLAppViewer::earlyExitNoNotify()
{
- LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL;
- gDoDisconnect = TRUE;
- finish_early_exit( LLSD(), LLSD() );
+ LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL;
+ gDoDisconnect = TRUE;
+ finish_early_exit( LLSD(), LLSD() );
}
void LLAppViewer::abortQuit()
{
LL_INFOS() << "abortQuit()" << LL_ENDL;
- mQuitRequested = false;
+ mQuitRequested = false;
}
void LLAppViewer::migrateCacheDirectory()
{
#if LL_WINDOWS || LL_DARWIN
- // NOTE: (Nyx) as of 1.21, cache for mac is moving to /library/caches/SecondLife from
- // /library/application support/SecondLife/cache This should clear/delete the old dir.
-
- // As of 1.23 the Windows cache moved from
- // C:\Documents and Settings\James\Application Support\SecondLife\cache
- // to
- // C:\Documents and Settings\James\Local Settings\Application Support\SecondLife
- //
- // The Windows Vista equivalent is from
- // C:\Users\James\AppData\Roaming\SecondLife\cache
- // to
- // C:\Users\James\AppData\Local\SecondLife
- //
- // Note the absence of \cache on the second path. James.
-
- // Only do this once per fresh install of this version.
- if (gSavedSettings.getBOOL("MigrateCacheDirectory"))
- {
- gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE);
-
- std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache");
- std::string new_cache_dir = gDirUtilp->getCacheDir(true);
-
- if (gDirUtilp->fileExists(old_cache_dir))
- {
- LL_INFOS() << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << LL_ENDL;
-
- // Migrate inventory cache to avoid pain to inventory database after mass update
- S32 file_count = 0;
- std::string file_name;
- std::string mask = "*.*";
-
- LLDirIterator iter(old_cache_dir, mask);
- while (iter.next(file_name))
- {
- if (file_name == "." || file_name == "..") continue;
- std::string source_path = gDirUtilp->add(old_cache_dir, file_name);
- std::string dest_path = gDirUtilp->add(new_cache_dir, file_name);
- if (!LLFile::rename(source_path, dest_path))
- {
- file_count++;
- }
- }
- LL_INFOS() << "Moved " << file_count << " files" << LL_ENDL;
-
- // Nuke the old cache
- gDirUtilp->setCacheDir(old_cache_dir);
- purgeCache();
- gDirUtilp->setCacheDir(new_cache_dir);
+ // NOTE: (Nyx) as of 1.21, cache for mac is moving to /library/caches/SecondLife from
+ // /library/application support/SecondLife/cache This should clear/delete the old dir.
+
+ // As of 1.23 the Windows cache moved from
+ // C:\Documents and Settings\James\Application Support\SecondLife\cache
+ // to
+ // C:\Documents and Settings\James\Local Settings\Application Support\SecondLife
+ //
+ // The Windows Vista equivalent is from
+ // C:\Users\James\AppData\Roaming\SecondLife\cache
+ // to
+ // C:\Users\James\AppData\Local\SecondLife
+ //
+ // Note the absence of \cache on the second path. James.
+
+ // Only do this once per fresh install of this version.
+ if (gSavedSettings.getBOOL("MigrateCacheDirectory"))
+ {
+ gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE);
+
+ std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache");
+ std::string new_cache_dir = gDirUtilp->getCacheDir(true);
+
+ if (gDirUtilp->fileExists(old_cache_dir))
+ {
+ LL_INFOS() << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << LL_ENDL;
+
+ // Migrate inventory cache to avoid pain to inventory database after mass update
+ S32 file_count = 0;
+ std::string file_name;
+ std::string mask = "*.*";
+
+ LLDirIterator iter(old_cache_dir, mask);
+ while (iter.next(file_name))
+ {
+ if (file_name == "." || file_name == "..") continue;
+ std::string source_path = gDirUtilp->add(old_cache_dir, file_name);
+ std::string dest_path = gDirUtilp->add(new_cache_dir, file_name);
+ if (!LLFile::rename(source_path, dest_path))
+ {
+ file_count++;
+ }
+ }
+ LL_INFOS() << "Moved " << file_count << " files" << LL_ENDL;
+
+ // Nuke the old cache
+ gDirUtilp->setCacheDir(old_cache_dir);
+ purgeCache();
+ gDirUtilp->setCacheDir(new_cache_dir);
#if LL_DARWIN
- // Clean up Mac files not deleted by removing *.*
- std::string ds_store = old_cache_dir + "/.DS_Store";
- if (gDirUtilp->fileExists(ds_store))
- {
- LLFile::remove(ds_store);
- }
+ // Clean up Mac files not deleted by removing *.*
+ std::string ds_store = old_cache_dir + "/.DS_Store";
+ if (gDirUtilp->fileExists(ds_store))
+ {
+ LLFile::remove(ds_store);
+ }
#endif
- if (LLFile::rmdir(old_cache_dir) != 0)
- {
- LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL;
- }
- }
- }
+ if (LLFile::rmdir(old_cache_dir) != 0)
+ {
+ LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL;
+ }
+ }
+ }
#endif // LL_WINDOWS || LL_DARWIN
}
//static
U32 LLAppViewer::getTextureCacheVersion()
{
- // Viewer texture cache version, change if the texture cache format changes.
- // 2021-03-10 Bumping up by one to help obviate texture cache issues with
- // Simple Cache Viewer - see SL-14985 for more information
- //const U32 TEXTURE_CACHE_VERSION = 8;
- const U32 TEXTURE_CACHE_VERSION = 9;
+ // Viewer texture cache version, change if the texture cache format changes.
+ // 2021-03-10 Bumping up by one to help obviate texture cache issues with
+ // Simple Cache Viewer - see SL-14985 for more information
+ //const U32 TEXTURE_CACHE_VERSION = 8;
+ const U32 TEXTURE_CACHE_VERSION = 9;
- return TEXTURE_CACHE_VERSION ;
+ return TEXTURE_CACHE_VERSION ;
}
//static
@@ -4185,92 +4190,92 @@ U32 LLAppViewer::getDiskCacheVersion()
//static
U32 LLAppViewer::getObjectCacheVersion()
{
- // Viewer object cache version, change if object update
- // format changes. JC
- const U32 INDRA_OBJECT_CACHE_VERSION = 17;
+ // Viewer object cache version, change if object update
+ // format changes. JC
+ const U32 INDRA_OBJECT_CACHE_VERSION = 17;
- return INDRA_OBJECT_CACHE_VERSION;
+ return INDRA_OBJECT_CACHE_VERSION;
}
bool LLAppViewer::initCache()
{
- mPurgeCache = false;
- BOOL read_only = mSecondInstance ? TRUE : FALSE;
- LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
- LLVOCache::initParamSingleton(read_only);
+ mPurgeCache = false;
+ BOOL read_only = mSecondInstance ? TRUE : FALSE;
+ LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
+ LLVOCache::initParamSingleton(read_only);
- // initialize the new disk cache using saved settings
- const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
+ // initialize the new disk cache using saved settings
+ const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
- const U32 MB = 1024 * 1024;
+ const U32 MB = 1024 * 1024;
const uintmax_t MIN_CACHE_SIZE = 256 * MB;
- const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
const F64 texture_cache_percent = 100.0 - disk_cache_percent;
- // note that the maximum size of this cache is defined as a percentage of the
- // total cache size - the 'CacheSize' pref - for all caches.
+ // note that the maximum size of this cache is defined as a percentage of the
+ // total cache size - the 'CacheSize' pref - for all caches.
const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100);
- const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
+ const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
- bool texture_cache_mismatch = false;
+ bool texture_cache_mismatch = false;
bool remove_vfs_files = false;
- if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
- {
- texture_cache_mismatch = true;
- if(!read_only)
- {
- gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+ if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
+ {
+ texture_cache_mismatch = true;
+ if(!read_only)
+ {
+ gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
//texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
- remove_vfs_files = true;
- }
- }
-
- if(!read_only)
- {
- // Purge cache if user requested it
- if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
- gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
- {
- LL_INFOS("AppCache") << "Startup cache purge requested: " << (gSavedSettings.getBOOL("PurgeCacheOnStartup") ? "ALWAYS" : "ONCE") << LL_ENDL;
- gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
- mPurgeCache = true;
- // STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad
- texture_cache_mismatch = true;
- }
-
- // We have moved the location of the cache directory over time.
- migrateCacheDirectory();
-
- // Setup and verify the cache location
- std::string cache_location = gSavedSettings.getString("CacheLocation");
- std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
- if (new_cache_location != cache_location)
- {
- LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL;
- gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
- purgeCache(); // purge old cache
- gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name));
- gSavedSettings.setString("CacheLocation", new_cache_location);
- gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
- }
- }
-
- if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
- {
- LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
- gSavedSettings.setString("CacheLocation", "");
- gSavedSettings.setString("CacheLocationTopFolder", "");
- }
-
- const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
+ remove_vfs_files = true;
+ }
+ }
+
+ if(!read_only)
+ {
+ // Purge cache if user requested it
+ if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
+ gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
+ {
+ LL_INFOS("AppCache") << "Startup cache purge requested: " << (gSavedSettings.getBOOL("PurgeCacheOnStartup") ? "ALWAYS" : "ONCE") << LL_ENDL;
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
+ mPurgeCache = true;
+ // STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad
+ texture_cache_mismatch = true;
+ }
+
+ // We have moved the location of the cache directory over time.
+ migrateCacheDirectory();
+
+ // Setup and verify the cache location
+ std::string cache_location = gSavedSettings.getString("CacheLocation");
+ std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
+ if (new_cache_location != cache_location)
+ {
+ LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL;
+ gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
+ purgeCache(); // purge old cache
+ gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name));
+ gSavedSettings.setString("CacheLocation", new_cache_location);
+ gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
+ }
+ }
+
+ if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
+ {
+ LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
+ gSavedSettings.setString("CacheLocation", "");
+ gSavedSettings.setString("CacheLocationTopFolder", "");
+ }
+
+ const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info);
- if (!read_only)
- {
+ if (!read_only)
+ {
if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
{
LLDiskCache::getInstance()->clearCache();
@@ -4282,166 +4287,166 @@ bool LLAppViewer::initCache()
{
LLDiskCache::getInstance()->removeOldVFSFiles();
}
-
+
if (mPurgeCache)
- {
- LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
- purgeCache();
-
- // clear the new C++ file system based cache
- LLDiskCache::getInstance()->clearCache();
- }
- else
- {
- // purge excessive files from the new file system based cache
- LLDiskCache::getInstance()->purge();
- }
- }
- LLAppViewer::getPurgeDiskCacheThread()->start();
-
- LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
-
- // Init the texture cache
+ {
+ LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
+ purgeCache();
+
+ // clear the new C++ file system based cache
+ LLDiskCache::getInstance()->clearCache();
+ }
+ else
+ {
+ // purge excessive files from the new file system based cache
+ LLDiskCache::getInstance()->purge();
+ }
+ }
+ LLAppViewer::getPurgeDiskCacheThread()->start();
+
+ LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
+
+ // Init the texture cache
// Allocate the remaining percent which is not allocated to the disk cache
const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100);
LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
+ LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
{
- gMainloopWork.post(cb);
+ gMainloopWork.post(cb);
}
void LLAppViewer::loadKeyBindings()
{
- std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
- if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
- {
- // Failed to load custom bindings, try default ones
- key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
- if (!gViewerInput.loadBindingsXML(key_bindings_file))
- {
+ std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
+ if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+ {
+ // Failed to load custom bindings, try default ones
+ key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
+ if (!gViewerInput.loadBindingsXML(key_bindings_file))
+ {
LLError::LLUserWarningMsg::showMissingFiles();
- LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
- }
- }
+ LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+ }
+ }
LLUrlRegistry::instance().setKeybindingHandler(&gViewerInput);
}
void LLAppViewer::purgeCache()
{
- LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
- LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
- LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
- LLViewerShaderMgr::instance()->clearShaderCache();
- std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
- if (LLFile::isdir(browser_cache))
- {
- // cef does not support clear_cache and clear_cookies, so clear what we can manually.
- gDirUtilp->deleteDirAndContents(browser_cache);
- }
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");
+ LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
+ LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
+ LLViewerShaderMgr::instance()->clearShaderCache();
+ std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
+ if (LLFile::isdir(browser_cache))
+ {
+ // cef does not support clear_cache and clear_cookies, so clear what we can manually.
+ gDirUtilp->deleteDirAndContents(browser_cache);
+ }
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");
}
//purge cache immediately, do not wait until the next login.
void LLAppViewer::purgeCacheImmediate()
{
- LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
- LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
- LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+ LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
+ LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
}
std::string LLAppViewer::getSecondLifeTitle() const
{
- return LLTrans::getString("APP_NAME");
+ return LLTrans::getString("APP_NAME");
}
std::string LLAppViewer::getWindowTitle() const
{
- return gWindowTitle;
+ return gWindowTitle;
}
// Callback from a dialog indicating user was logged out.
bool finish_disconnect(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (1 == option)
- {
+ if (1 == option)
+ {
LLAppViewer::instance()->forceQuit();
- }
- return false;
+ }
+ return false;
}
// Callback from an early disconnect dialog, force an exit
bool finish_forced_disconnect(const LLSD& notification, const LLSD& response)
{
- LLAppViewer::instance()->forceQuit();
- return false;
+ LLAppViewer::instance()->forceQuit();
+ return false;
}
void LLAppViewer::forceDisconnect(const std::string& mesg)
{
- if (gDoDisconnect)
- {
- // Already popped up one of these dialogs, don't
- // do this again.
- return;
- }
-
- // *TODO: Translate the message if possible
- std::string big_reason = LLAgent::sTeleportErrorMessages[mesg];
- if ( big_reason.size() == 0 )
- {
- big_reason = mesg;
- }
-
- LLSD args;
- gDoDisconnect = TRUE;
-
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- // Tell users what happened
- args["ERROR_MESSAGE"] = big_reason;
- LLNotificationsUtil::add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
- }
- else
- {
- args["MESSAGE"] = big_reason;
- LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
- }
+ if (gDoDisconnect)
+ {
+ // Already popped up one of these dialogs, don't
+ // do this again.
+ return;
+ }
+
+ // *TODO: Translate the message if possible
+ std::string big_reason = LLAgent::sTeleportErrorMessages[mesg];
+ if ( big_reason.size() == 0 )
+ {
+ big_reason = mesg;
+ }
+
+ LLSD args;
+ gDoDisconnect = TRUE;
+
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ // Tell users what happened
+ args["ERROR_MESSAGE"] = big_reason;
+ LLNotificationsUtil::add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
+ }
+ else
+ {
+ args["MESSAGE"] = big_reason;
+ LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
+ }
}
void LLAppViewer::badNetworkHandler()
{
- // Dump the packet
- gMessageSystem->dumpPacketToLog();
-
- // Flush all of our caches on exit in the case of disconnect due to
- // invalid packets.
-
- mPurgeCacheOnExit = TRUE;
-
- std::ostringstream message;
- message <<
- "The viewer has detected mangled network data indicative\n"
- "of a bad upstream network connection or an incomplete\n"
- "local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n"
- " \n"
- "Try uninstalling and reinstalling to see if this resolves \n"
- "the issue. \n"
- " \n"
- "If the problem continues, see the Tech Support FAQ at: \n"
- "www.secondlife.com/support";
- forceDisconnect(message.str());
-
- LLApp::instance()->writeMiniDump();
+ // Dump the packet
+ gMessageSystem->dumpPacketToLog();
+
+ // Flush all of our caches on exit in the case of disconnect due to
+ // invalid packets.
+
+ mPurgeCacheOnExit = TRUE;
+
+ std::ostringstream message;
+ message <<
+ "The viewer has detected mangled network data indicative\n"
+ "of a bad upstream network connection or an incomplete\n"
+ "local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n"
+ " \n"
+ "Try uninstalling and reinstalling to see if this resolves \n"
+ "the issue. \n"
+ " \n"
+ "If the problem continues, see the Tech Support FAQ at: \n"
+ "www.secondlife.com/support";
+ forceDisconnect(message.str());
+
+ LLApp::instance()->writeMiniDump();
}
// This routine may get called more than once during the shutdown process.
@@ -4449,93 +4454,93 @@ void LLAppViewer::badNetworkHandler()
// is destroyed.
void LLAppViewer::saveFinalSnapshot()
{
- if (!mSavedFinalSnapshot)
- {
- gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal());
- gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal());
- gViewerWindow->setCursor(UI_CURSOR_WAIT);
- gAgentCamera.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch
- gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
- idle();
-
- std::string snap_filename = gDirUtilp->getLindenUserDir();
- snap_filename += gDirUtilp->getDirDelimiter();
- snap_filename += LLStartUp::getScreenLastFilename();
- // use full pixel dimensions of viewer window (not post-scale dimensions)
- gViewerWindow->saveSnapshot(snap_filename,
- gViewerWindow->getWindowWidthRaw(),
- gViewerWindow->getWindowHeightRaw(),
- FALSE,
- gSavedSettings.getBOOL("RenderHUDInSnapshot"),
- TRUE,
- LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
- LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
- mSavedFinalSnapshot = TRUE;
-
- if (gAgent.isInHomeRegion())
- {
- LLVector3d home;
- if (gAgent.getHomePosGlobal(&home) && dist_vec(home, gAgent.getPositionGlobal()) < 10)
- {
- // We are at home position or close to it, see if we need to create home screenshot
- // Notes:
- // 1. It might be beneficial to also replace home if file is too old
- // 2. This is far from best way/place to update screenshot since location might be not fully loaded,
- // but we don't have many options
- std::string snap_home = gDirUtilp->getLindenUserDir();
- snap_home += gDirUtilp->getDirDelimiter();
- snap_home += LLStartUp::getScreenHomeFilename();
- if (!gDirUtilp->fileExists(snap_home))
- {
- // We are at home position yet no home image exist, fix it
- LLFile::copy(snap_filename, snap_home);
- }
- }
- }
- }
+ if (!mSavedFinalSnapshot)
+ {
+ gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal());
+ gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal());
+ gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ gAgentCamera.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch
+ gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
+ idle();
+
+ std::string snap_filename = gDirUtilp->getLindenUserDir();
+ snap_filename += gDirUtilp->getDirDelimiter();
+ snap_filename += LLStartUp::getScreenLastFilename();
+ // use full pixel dimensions of viewer window (not post-scale dimensions)
+ gViewerWindow->saveSnapshot(snap_filename,
+ gViewerWindow->getWindowWidthRaw(),
+ gViewerWindow->getWindowHeightRaw(),
+ FALSE,
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
+ TRUE,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
+ mSavedFinalSnapshot = TRUE;
+
+ if (gAgent.isInHomeRegion())
+ {
+ LLVector3d home;
+ if (gAgent.getHomePosGlobal(&home) && dist_vec(home, gAgent.getPositionGlobal()) < 10)
+ {
+ // We are at home position or close to it, see if we need to create home screenshot
+ // Notes:
+ // 1. It might be beneficial to also replace home if file is too old
+ // 2. This is far from best way/place to update screenshot since location might be not fully loaded,
+ // but we don't have many options
+ std::string snap_home = gDirUtilp->getLindenUserDir();
+ snap_home += gDirUtilp->getDirDelimiter();
+ snap_home += LLStartUp::getScreenHomeFilename();
+ if (!gDirUtilp->fileExists(snap_home))
+ {
+ // We are at home position yet no home image exist, fix it
+ LLFile::copy(snap_filename, snap_home);
+ }
+ }
+ }
+ }
}
void LLAppViewer::loadNameCache()
{
- // display names cache
- std::string filename =
- gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
- LL_INFOS("AvNameCache") << filename << LL_ENDL;
- llifstream name_cache_stream(filename.c_str());
- if(name_cache_stream.is_open())
- {
- if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream))
+ // display names cache
+ std::string filename =
+ gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
+ LL_INFOS("AvNameCache") << filename << LL_ENDL;
+ llifstream name_cache_stream(filename.c_str());
+ if(name_cache_stream.is_open())
+ {
+ if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream))
{
LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL;
name_cache_stream.close();
LLFile::remove(filename);
}
- }
+ }
- if (!gCacheName) return;
+ if (!gCacheName) return;
- std::string name_cache;
- name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
- llifstream cache_file(name_cache.c_str());
- if(cache_file.is_open())
- {
- if(gCacheName->importFile(cache_file)) return;
- }
+ std::string name_cache;
+ name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+ llifstream cache_file(name_cache.c_str());
+ if(cache_file.is_open())
+ {
+ if(gCacheName->importFile(cache_file)) return;
+ }
}
void LLAppViewer::saveNameCache()
{
- // display names cache
- std::string filename =
- gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
- llofstream name_cache_stream(filename.c_str());
- if(name_cache_stream.is_open())
- {
- LLAvatarNameCache::getInstance()->exportFile(name_cache_stream);
+ // display names cache
+ std::string filename =
+ gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
+ llofstream name_cache_stream(filename.c_str());
+ if(name_cache_stream.is_open())
+ {
+ LLAvatarNameCache::getInstance()->exportFile(name_cache_stream);
}
// real names cache
- if (gCacheName)
+ if (gCacheName)
{
std::string name_cache;
name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
@@ -4544,24 +4549,24 @@ void LLAppViewer::saveNameCache()
{
gCacheName->exportFile(cache_file);
}
- }
+ }
}
-/*! @brief This class is an LLFrameTimer that can be created with
- an elapsed time that starts counting up from the given value
- rather than 0.0.
+/*! @brief This class is an LLFrameTimer that can be created with
+ an elapsed time that starts counting up from the given value
+ rather than 0.0.
- Otherwise it behaves the same way as LLFrameTimer.
+ Otherwise it behaves the same way as LLFrameTimer.
*/
class LLFrameStatsTimer : public LLFrameTimer
{
public:
- LLFrameStatsTimer(F64 elapsed_already = 0.0)
- : LLFrameTimer()
- {
- mStartTime -= elapsed_already;
- }
+ LLFrameStatsTimer(F64 elapsed_already = 0.0)
+ : LLFrameTimer()
+ {
+ mStartTime -= elapsed_already;
+ }
};
static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio");
@@ -4587,118 +4592,118 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects");
void LLAppViewer::idle()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
- pingMainloopTimeout("Main:Idle");
+ pingMainloopTimeout("Main:Idle");
- // Update frame timers
- static LLTimer idle_timer;
+ // Update frame timers
+ static LLTimer idle_timer;
- LLFrameTimer::updateFrameTime();
- LLFrameTimer::updateFrameCount();
- LLEventTimer::updateClass();
+ LLFrameTimer::updateFrameTime();
+ LLFrameTimer::updateFrameCount();
+ LLEventTimer::updateClass();
LLPerfStats::updateClass();
- // LLApp::stepFrame() performs the above three calls plus mRunner.run().
- // Not sure why we don't call stepFrame() here, except that LLRunner seems
- // completely redundant with LLEventTimer.
- LLNotificationsUI::LLToast::updateClass();
- LLSmoothInterpolation::updateInterpolants();
- LLMortician::updateClass();
- LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
- LLDirPickerThread::clearDead();
- F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
+ // LLApp::stepFrame() performs the above three calls plus mRunner.run().
+ // Not sure why we don't call stepFrame() here, except that LLRunner seems
+ // completely redundant with LLEventTimer.
+ LLNotificationsUI::LLToast::updateClass();
+ LLSmoothInterpolation::updateInterpolants();
+ LLMortician::updateClass();
+ LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
+ LLDirPickerThread::clearDead();
+ F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
LLGLTFMaterialList::flushUpdates();
- // Service the WorkQueue we use for replies from worker threads.
- // Use function statics for the timeslice setting so we only have to fetch
- // and convert MainWorkTime once.
- static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime");
- static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw);
- // MainWorkTime is specified in fractional milliseconds, but std::chrono
- // uses integer representations. What if we want less than a microsecond?
- // Use nanoseconds. We're very sure we will never need to specify a
- // MainWorkTime that would be larger than we could express in
- // std::chrono::nanoseconds.
- static std::chrono::nanoseconds MainWorkTimeNanoSec{
- std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)};
- gMainloopWork.runFor(MainWorkTimeNanoSec);
-
- // Cap out-of-control frame times
- // Too low because in menus, swapping, debugger, etc.
- // Too high because idle called with no objects in view, etc.
- const F32 MIN_FRAME_RATE = 1.f;
- const F32 MAX_FRAME_RATE = 200.f;
-
- F32 frame_rate_clamped = 1.f / dt_raw;
- frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE);
- gFrameDTClamped = 1.f / frame_rate_clamped;
-
- // Global frame timer
- // Smoothly weight toward current frame
- gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f;
-
- F32 qas = gSavedSettings.getF32("QuitAfterSeconds");
- if (qas > 0.f)
- {
- if (gRenderStartTime.getElapsedTimeF32() > qas)
- {
- LL_INFOS() << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << LL_ENDL;
- LLAppViewer::instance()->forceQuit();
- }
- }
-
- // Must wait until both have avatar object and mute list, so poll
- // here.
- LLIMProcessing::requestOfflineMessages();
-
- ///////////////////////////////////
- //
- // Special case idle if still starting up
- //
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- // Skip rest if idle startup returns false (essentially, no world yet)
- gGLActive = TRUE;
- if (!idle_startup())
- {
- gGLActive = FALSE;
- return;
- }
- gGLActive = FALSE;
- }
-
-
- F32 yaw = 0.f; // radians
-
- if (!gDisconnected)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK);
- // Update spaceserver timeinfo
- LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw));
-
-
- //////////////////////////////////////
- //
- // Update simulator agent state
- //
-
- if (gSavedSettings.getBOOL("RotateRight"))
- {
- gAgent.moveYaw(-1.f);
- }
-
- {
+ // Service the WorkQueue we use for replies from worker threads.
+ // Use function statics for the timeslice setting so we only have to fetch
+ // and convert MainWorkTime once.
+ static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime");
+ static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw);
+ // MainWorkTime is specified in fractional milliseconds, but std::chrono
+ // uses integer representations. What if we want less than a microsecond?
+ // Use nanoseconds. We're very sure we will never need to specify a
+ // MainWorkTime that would be larger than we could express in
+ // std::chrono::nanoseconds.
+ static std::chrono::nanoseconds MainWorkTimeNanoSec{
+ std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)};
+ gMainloopWork.runFor(MainWorkTimeNanoSec);
+
+ // Cap out-of-control frame times
+ // Too low because in menus, swapping, debugger, etc.
+ // Too high because idle called with no objects in view, etc.
+ const F32 MIN_FRAME_RATE = 1.f;
+ const F32 MAX_FRAME_RATE = 200.f;
+
+ F32 frame_rate_clamped = 1.f / dt_raw;
+ frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE);
+ gFrameDTClamped = 1.f / frame_rate_clamped;
+
+ // Global frame timer
+ // Smoothly weight toward current frame
+ gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f;
+
+ F32 qas = gSavedSettings.getF32("QuitAfterSeconds");
+ if (qas > 0.f)
+ {
+ if (gRenderStartTime.getElapsedTimeF32() > qas)
+ {
+ LL_INFOS() << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << LL_ENDL;
+ LLAppViewer::instance()->forceQuit();
+ }
+ }
+
+ // Must wait until both have avatar object and mute list, so poll
+ // here.
+ LLIMProcessing::requestOfflineMessages();
+
+ ///////////////////////////////////
+ //
+ // Special case idle if still starting up
+ //
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ // Skip rest if idle startup returns false (essentially, no world yet)
+ gGLActive = TRUE;
+ if (!idle_startup())
+ {
+ gGLActive = FALSE;
+ return;
+ }
+ gGLActive = FALSE;
+ }
+
+
+ F32 yaw = 0.f; // radians
+
+ if (!gDisconnected)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK);
+ // Update spaceserver timeinfo
+ LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw));
+
+
+ //////////////////////////////////////
+ //
+ // Update simulator agent state
+ //
+
+ if (gSavedSettings.getBOOL("RotateRight"))
+ {
+ gAgent.moveYaw(-1.f);
+ }
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Autopilot");
- // Handle automatic walking towards points
- gAgentPilot.updateTarget();
- gAgent.autoPilot(&yaw);
- }
+ // Handle automatic walking towards points
+ gAgentPilot.updateTarget();
+ gAgent.autoPilot(&yaw);
+ }
- static LLFrameTimer agent_update_timer;
+ static LLFrameTimer agent_update_timer;
- // When appropriate, update agent location to the simulator.
- F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
- F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time;
+ // When appropriate, update agent location to the simulator.
+ F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
+ F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time;
bool timed_out = agent_update_time > (1.0f / (F32)AGENT_UPDATES_PER_SECOND);
BOOL force_send =
// if there is something to send
@@ -4709,111 +4714,111 @@ void LLAppViewer::idle()
|| (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND));
// timing out doesn't warranty that an update will be sent,
// just that it will be checked.
- if (force_send || timed_out)
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- // Send avatar and camera info
- mLastAgentControlFlags = gAgent.getControlFlags();
- mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time;
- send_agent_update(force_send);
- agent_update_timer.reset();
- }
- }
-
- //////////////////////////////////////
- //
- // Manage statistics
- //
- //
- {
- // Initialize the viewer_stats_timer with an already elapsed time
- // of SEND_STATS_PERIOD so that the initial stats report will
- // be sent immediately.
- static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
-
- // Update session stats every large chunk of time
- // *FIX: (?) SAMANTHA
- if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
- {
- LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
- bool include_preferences = false;
- send_viewer_stats(include_preferences);
- viewer_stats_timer.reset();
- }
-
- // Print the object debugging stats
- static LLFrameTimer object_debug_timer;
- if (object_debug_timer.getElapsedTimeF32() > 5.f)
- {
- object_debug_timer.reset();
- if (gObjectList.mNumDeadObjectUpdates)
- {
- LL_INFOS() << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << LL_ENDL;
- gObjectList.mNumDeadObjectUpdates = 0;
- }
- if (gObjectList.mNumUnknownUpdates)
- {
- LL_INFOS() << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << LL_ENDL;
- gObjectList.mNumUnknownUpdates = 0;
- }
-
- }
- }
-
- if (!gDisconnected)
- {
+ if (force_send || timed_out)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ // Send avatar and camera info
+ mLastAgentControlFlags = gAgent.getControlFlags();
+ mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time;
+ send_agent_update(force_send);
+ agent_update_timer.reset();
+ }
+ }
+
+ //////////////////////////////////////
+ //
+ // Manage statistics
+ //
+ //
+ {
+ // Initialize the viewer_stats_timer with an already elapsed time
+ // of SEND_STATS_PERIOD so that the initial stats report will
+ // be sent immediately.
+ static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
+
+ // Update session stats every large chunk of time
+ // *FIX: (?) SAMANTHA
+ if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
+ {
+ LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
+ bool include_preferences = false;
+ send_viewer_stats(include_preferences);
+ viewer_stats_timer.reset();
+ }
+
+ // Print the object debugging stats
+ static LLFrameTimer object_debug_timer;
+ if (object_debug_timer.getElapsedTimeF32() > 5.f)
+ {
+ object_debug_timer.reset();
+ if (gObjectList.mNumDeadObjectUpdates)
+ {
+ LL_INFOS() << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << LL_ENDL;
+ gObjectList.mNumDeadObjectUpdates = 0;
+ }
+ if (gObjectList.mNumUnknownUpdates)
+ {
+ LL_INFOS() << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << LL_ENDL;
+ gObjectList.mNumUnknownUpdates = 0;
+ }
+
+ }
+ }
+
+ if (!gDisconnected)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Network");
- ////////////////////////////////////////////////
- //
- // Network processing
- //
- // NOTE: Starting at this point, we may still have pointers to "dead" objects
- // floating throughout the various object lists.
- //
- idleNameCache();
- idleNetwork();
+ ////////////////////////////////////////////////
+ //
+ // Network processing
+ //
+ // NOTE: Starting at this point, we may still have pointers to "dead" objects
+ // floating throughout the various object lists.
+ //
+ idleNameCache();
+ idleNetwork();
- // Check for away from keyboard, kick idle agents.
- idle_afk_check();
+ // Check for away from keyboard, kick idle agents.
+ idle_afk_check();
- // Update statistics for this frame
- update_statistics();
- }
+ // Update statistics for this frame
+ update_statistics();
+ }
- ////////////////////////////////////////
- //
- // Handle the regular UI idle callbacks as well as
- // hover callbacks
- //
+ ////////////////////////////////////////
+ //
+ // Handle the regular UI idle callbacks as well as
+ // hover callbacks
+ //
#ifdef LL_DARWIN
- if (!mQuitRequested) //MAINT-4243
+ if (!mQuitRequested) //MAINT-4243
#endif
- {
-// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB);
+ {
+// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB);
- // Do event notifications if necessary. Yes, we may want to move this elsewhere.
- gEventNotifier.update();
+ // Do event notifications if necessary. Yes, we may want to move this elsewhere.
+ gEventNotifier.update();
- gIdleCallbacks.callFunctions();
- gInventory.idleNotifyObservers();
- LLAvatarTracker::instance().idleNotifyObservers();
- }
+ gIdleCallbacks.callFunctions();
+ gInventory.idleNotifyObservers();
+ LLAvatarTracker::instance().idleNotifyObservers();
+ }
- // Metrics logging (LLViewerAssetStats, etc.)
- {
- static LLTimer report_interval;
+ // Metrics logging (LLViewerAssetStats, etc.)
+ {
+ static LLTimer report_interval;
- // *TODO: Add configuration controls for this
- F32 seconds = report_interval.getElapsedTimeF32();
- if (seconds >= app_metrics_interval)
- {
- metricsSend(! gDisconnected);
- report_interval.reset();
- }
- }
+ // *TODO: Add configuration controls for this
+ F32 seconds = report_interval.getElapsedTimeF32();
+ if (seconds >= app_metrics_interval)
+ {
+ metricsSend(! gDisconnected);
+ report_interval.reset();
+ }
+ }
// Update layonts, handle mouse events, tooltips, e t c
@@ -4822,335 +4827,336 @@ void LLAppViewer::idle()
// opening chat.
gViewerWindow->updateUI();
- if (gDisconnected)
+ if (gDisconnected)
{
- return;
+ return;
}
- if (gTeleportDisplay)
+ if (gTeleportDisplay)
{
- return;
+ return;
}
- ///////////////////////////////////////
- // Agent and camera movement
- //
- LLCoordGL current_mouse = gViewerWindow->getCurrentMouse();
+ ///////////////////////////////////////
+ // Agent and camera movement
+ //
+ LLCoordGL current_mouse = gViewerWindow->getCurrentMouse();
- {
- // After agent and camera moved, figure out if we need to
- // deselect objects.
- LLSelectMgr::getInstance()->deselectAllIfTooFar();
+ {
+ // After agent and camera moved, figure out if we need to
+ // deselect objects.
+ LLSelectMgr::getInstance()->deselectAllIfTooFar();
- }
+ }
- {
- // Handle pending gesture processing
- LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION);
- LLGestureMgr::instance().update();
+ {
+ // Handle pending gesture processing
+ LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION);
+ LLGestureMgr::instance().update();
- gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
- }
+ gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
+ }
- {
- LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE);
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
- {
- gObjectList.update(gAgent);
- }
- }
-
- //////////////////////////////////////
- //
- // Deletes objects...
- // Has to be done after doing idleUpdates (which can kill objects)
- //
-
- {
- LL_RECORD_BLOCK_TIME(FTM_CLEANUP);
- {
- gObjectList.cleanDeadObjects();
- }
- {
- LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES);
- LLDrawable::cleanupDeadDrawables();
- }
- }
-
- //
- // After this point, in theory we should never see a dead object
- // in the various object/drawable lists.
- //
-
- //////////////////////////////////////
- //
- // Update/send HUD effects
- //
- // At this point, HUD effects may clean up some references to
- // dead objects.
- //
-
- {
- LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS);
- LLSelectMgr::getInstance()->updateEffects();
- LLHUDManager::getInstance()->cleanupEffects();
- LLHUDManager::getInstance()->sendEffects();
- }
-
- ////////////////////////////////////////
- //
- // Unpack layer data that we've received
- //
-
- {
- LL_RECORD_BLOCK_TIME(FTM_NETWORK);
- gVLManager.unpackData();
- }
-
- /////////////////////////
- //
- // Update surfaces, and surface textures as well.
- //
-
- LLWorld::getInstance()->updateVisibilities();
- {
- const F32 max_region_update_time = .001f; // 1ms
- LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE);
- LLWorld::getInstance()->updateRegions(max_region_update_time);
- }
-
- /////////////////////////
- //
- // Update weather effects
- //
-
- // Update wind vector
- LLVector3 wind_position_region;
- static LLVector3 average_wind;
-
- LLViewerRegion *regionp;
- regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position
- if (regionp)
- {
- gWindVec = regionp->mWind.getVelocity(wind_position_region);
-
- // Compute average wind and use to drive motion of water
-
- average_wind = regionp->mWind.getAverage();
- gSky.setWind(average_wind);
- //LLVOWater::setWind(average_wind);
- }
- else
- {
- gWindVec.setVec(0.0f, 0.0f, 0.0f);
- }
-
- //////////////////////////////////////
- //
- // Sort and cull in the new renderer are moved to pipeline.cpp
- // Here, particles are updated and drawables are moved.
- //
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE);
- gPipeline.updateMove();
- }
-
- LLWorld::getInstance()->updateParticles();
-
- if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera())
- {
- gAgentPilot.moveCamera();
- }
- else if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- LLViewerJoystick::getInstance()->moveFlycam();
- }
- else
- {
- if (LLToolMgr::getInstance()->inBuildMode())
- {
- LLViewerJoystick::getInstance()->moveObjects();
- }
-
- gAgentCamera.updateCamera();
- }
-
- // update media focus
- LLViewerMediaFocus::getInstance()->update();
-
- // Update marketplace
- LLMarketplaceInventoryImporter::update();
- LLMarketplaceInventoryNotifications::update();
-
- // objects and camera should be in sync, do LOD calculations now
- {
- LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
- gObjectList.updateApparentAngles(gAgent);
- }
-
- // Update AV render info
- LLAvatarRenderInfoAccountant::getInstance()->idle();
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);
-
- if (gAudiop)
- {
- audio_update_volume(false);
- audio_update_listener();
- audio_update_wind(false);
-
- // this line actually commits the changes we've made to source positions, etc.
- gAudiop->idle();
- }
- }
-
- // Handle shutdown process, for example,
- // wait for floaters to close, send quit message,
- // forcibly quit if it has taken too long
- if (mQuitRequested)
- {
- gGLActive = TRUE;
- idleShutdown();
- }
+ {
+ gObjectList.update(gAgent);
+ LL::GLTFSceneManager::instance().update();
+ }
+ }
+
+ //////////////////////////////////////
+ //
+ // Deletes objects...
+ // Has to be done after doing idleUpdates (which can kill objects)
+ //
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP);
+ {
+ gObjectList.cleanDeadObjects();
+ }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES);
+ LLDrawable::cleanupDeadDrawables();
+ }
+ }
+
+ //
+ // After this point, in theory we should never see a dead object
+ // in the various object/drawable lists.
+ //
+
+ //////////////////////////////////////
+ //
+ // Update/send HUD effects
+ //
+ // At this point, HUD effects may clean up some references to
+ // dead objects.
+ //
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS);
+ LLSelectMgr::getInstance()->updateEffects();
+ LLHUDManager::getInstance()->cleanupEffects();
+ LLHUDManager::getInstance()->sendEffects();
+ }
+
+ ////////////////////////////////////////
+ //
+ // Unpack layer data that we've received
+ //
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_NETWORK);
+ gVLManager.unpackData();
+ }
+
+ /////////////////////////
+ //
+ // Update surfaces, and surface textures as well.
+ //
+
+ LLWorld::getInstance()->updateVisibilities();
+ {
+ const F32 max_region_update_time = .001f; // 1ms
+ LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE);
+ LLWorld::getInstance()->updateRegions(max_region_update_time);
+ }
+
+ /////////////////////////
+ //
+ // Update weather effects
+ //
+
+ // Update wind vector
+ LLVector3 wind_position_region;
+ static LLVector3 average_wind;
+
+ LLViewerRegion *regionp;
+ regionp = LLWorld::getInstance()->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal()); // puts agent's local coords into wind_position
+ if (regionp)
+ {
+ gWindVec = regionp->mWind.getVelocity(wind_position_region);
+
+ // Compute average wind and use to drive motion of water
+
+ average_wind = regionp->mWind.getAverage();
+ gSky.setWind(average_wind);
+ //LLVOWater::setWind(average_wind);
+ }
+ else
+ {
+ gWindVec.setVec(0.0f, 0.0f, 0.0f);
+ }
+
+ //////////////////////////////////////
+ //
+ // Sort and cull in the new renderer are moved to pipeline.cpp
+ // Here, particles are updated and drawables are moved.
+ //
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE);
+ gPipeline.updateMove();
+ }
+
+ LLWorld::getInstance()->updateParticles();
+
+ if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera())
+ {
+ gAgentPilot.moveCamera();
+ }
+ else if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ LLViewerJoystick::getInstance()->moveFlycam();
+ }
+ else
+ {
+ if (LLToolMgr::getInstance()->inBuildMode())
+ {
+ LLViewerJoystick::getInstance()->moveObjects();
+ }
+
+ gAgentCamera.updateCamera();
+ }
+
+ // update media focus
+ LLViewerMediaFocus::getInstance()->update();
+
+ // Update marketplace
+ LLMarketplaceInventoryImporter::update();
+ LLMarketplaceInventoryNotifications::update();
+
+ // objects and camera should be in sync, do LOD calculations now
+ {
+ LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
+ gObjectList.updateApparentAngles(gAgent);
+ }
+
+ // Update AV render info
+ LLAvatarRenderInfoAccountant::getInstance()->idle();
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);
+
+ if (gAudiop)
+ {
+ audio_update_volume(false);
+ audio_update_listener();
+ audio_update_wind(false);
+
+ // this line actually commits the changes we've made to source positions, etc.
+ gAudiop->idle();
+ }
+ }
+
+ // Handle shutdown process, for example,
+ // wait for floaters to close, send quit message,
+ // forcibly quit if it has taken too long
+ if (mQuitRequested)
+ {
+ gGLActive = TRUE;
+ idleShutdown();
+ }
}
void LLAppViewer::idleShutdown()
{
- // Wait for all modal alerts to get resolved
- if (LLModalDialog::activeCount() > 0)
- {
- return;
- }
-
- // close IM interface
- if(gIMMgr)
- {
- gIMMgr->disconnectAllSessions();
- }
-
- // Wait for all floaters to get resolved
- if (gFloaterView
- && !gFloaterView->allChildrenClosed())
- {
- return;
- }
-
-
-
-
- // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
- // *TODO: ugly
- static bool saved_teleport_history = false;
- if (!saved_teleport_history)
- {
- saved_teleport_history = true;
- LLTeleportHistory::getInstance()->dump();
- LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
- return;
- }
-
- static bool saved_snapshot = false;
- if (!saved_snapshot)
- {
- saved_snapshot = true;
- saveFinalSnapshot();
- return;
- }
-
- const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f;
-
- S32 pending_uploads = gAssetStorage->getNumPendingUploads();
- if (pending_uploads > 0
- && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
- && !logoutRequestSent())
- {
- static S32 total_uploads = 0;
- // Sometimes total upload count can change during logout.
- total_uploads = llmax(total_uploads, pending_uploads);
- gViewerWindow->setShowProgress(TRUE);
- S32 finished_uploads = total_uploads - pending_uploads;
- F32 percent = 100.f * finished_uploads / total_uploads;
- gViewerWindow->setProgressPercent(percent);
- gViewerWindow->setProgressString(LLTrans::getString("SavingSettings"));
- return;
- }
-
- if (gPendingMetricsUploads > 0
- && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
- && !logoutRequestSent())
- {
+ // Wait for all modal alerts to get resolved
+ if (LLModalDialog::activeCount() > 0)
+ {
+ return;
+ }
+
+ // close IM interface
+ if(gIMMgr)
+ {
+ gIMMgr->disconnectAllSessions();
+ }
+
+ // Wait for all floaters to get resolved
+ if (gFloaterView
+ && !gFloaterView->allChildrenClosed())
+ {
+ return;
+ }
+
+
+
+
+ // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
+ // *TODO: ugly
+ static bool saved_teleport_history = false;
+ if (!saved_teleport_history)
+ {
+ saved_teleport_history = true;
+ LLTeleportHistory::getInstance()->dump();
+ LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
+ return;
+ }
+
+ static bool saved_snapshot = false;
+ if (!saved_snapshot)
+ {
+ saved_snapshot = true;
+ saveFinalSnapshot();
+ return;
+ }
+
+ const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f;
+
+ S32 pending_uploads = gAssetStorage->getNumPendingUploads();
+ if (pending_uploads > 0
+ && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+ && !logoutRequestSent())
+ {
+ static S32 total_uploads = 0;
+ // Sometimes total upload count can change during logout.
+ total_uploads = llmax(total_uploads, pending_uploads);
+ gViewerWindow->setShowProgress(TRUE);
+ S32 finished_uploads = total_uploads - pending_uploads;
+ F32 percent = 100.f * finished_uploads / total_uploads;
+ gViewerWindow->setProgressPercent(percent);
+ gViewerWindow->setProgressString(LLTrans::getString("SavingSettings"));
+ return;
+ }
+
+ if (gPendingMetricsUploads > 0
+ && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+ && !logoutRequestSent())
+ {
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressPercent(100.f);
gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
- return;
- }
-
- // All floaters are closed. Tell server we want to quit.
- if( !logoutRequestSent() )
- {
- sendLogoutRequest();
-
- // Wait for a LogoutReply message
- gViewerWindow->setShowProgress(TRUE);
- gViewerWindow->setProgressPercent(100.f);
- gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
- return;
- }
-
- // Make sure that we quit if we haven't received a reply from the server.
- if( logoutRequestSent()
- && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime )
- {
- forceQuit();
- return;
- }
+ return;
+ }
+
+ // All floaters are closed. Tell server we want to quit.
+ if( !logoutRequestSent() )
+ {
+ sendLogoutRequest();
+
+ // Wait for a LogoutReply message
+ gViewerWindow->setShowProgress(TRUE);
+ gViewerWindow->setProgressPercent(100.f);
+ gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
+ return;
+ }
+
+ // Make sure that we quit if we haven't received a reply from the server.
+ if( logoutRequestSent()
+ && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime )
+ {
+ forceQuit();
+ return;
+ }
}
void LLAppViewer::sendLogoutRequest()
{
- if(!mLogoutRequestSent && gMessageSystem)
- {
- //Set internal status variables and marker files before actually starting the logout process
- gLogoutInProgress = TRUE;
- if (!mSecondInstance)
- {
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
- if (mLogoutMarkerFile.getFileHandle())
- {
- LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
- recordMarkerVersion(mLogoutMarkerFile);
- }
- else
- {
- LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL;
- }
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_LogoutRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
-
- gLogoutTimer.reset();
- gLogoutMaxTime = LOGOUT_REQUEST_TIME;
- mLogoutRequestSent = TRUE;
-
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->leaveChannel();
- }
- }
+ if(!mLogoutRequestSent && gMessageSystem)
+ {
+ //Set internal status variables and marker files before actually starting the logout process
+ gLogoutInProgress = TRUE;
+ if (!mSecondInstance)
+ {
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
+
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(mLogoutMarkerFile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
+ gLogoutTimer.reset();
+ gLogoutMaxTime = LOGOUT_REQUEST_TIME;
+ mLogoutRequestSent = TRUE;
+
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->leaveChannel();
+ }
+ }
}
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
@@ -5196,19 +5202,19 @@ void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
void LLAppViewer::idleNameCache()
{
- // Neither old nor new name cache can function before agent has a region
- LLViewerRegion* region = gAgent.getRegion();
+ // Neither old nor new name cache can function before agent has a region
+ LLViewerRegion* region = gAgent.getRegion();
if (!region)
{
return;
}
- // deal with any queued name requests and replies.
- gCacheName->processPending();
+ // deal with any queued name requests and replies.
+ gCacheName->processPending();
- // Can't run the new cache until we have the list of capabilities
- // for the agent region, and can therefore decide whether to use
- // display names or fall back to the old name system.
+ // Can't run the new cache until we have the list of capabilities
+ // for the agent region, and can therefore decide whether to use
+ // display names or fall back to the old name system.
if (!region->capabilitiesReceived())
{
return;
@@ -5238,141 +5244,141 @@ static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circ
void LLAppViewer::idleNetwork()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- pingMainloopTimeout("idleNetwork");
-
- gObjectList.mNumNewObjects = 0;
- S32 total_decoded = 0;
-
- if (!gSavedSettings.getBOOL("SpeedTest"))
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode
-
- LLTimer check_message_timer;
- // Read all available packets from network
- const S64 frame_count = gFrameCount; // U32->S64
- F32 total_time = 0.0f;
-
- {
- LockMessageChecker lmc(gMessageSystem);
- while (lmc.checkAllMessages(frame_count, gServicePump))
- {
- if (gDoDisconnect)
- {
- // We're disconnecting, don't process any more messages from the server
- // We're usually disconnecting due to either network corruption or a
- // server going down, so this is OK.
- break;
- }
-
- total_decoded++;
- gPacketsIn++;
-
- if (total_decoded > MESSAGE_MAX_PER_FRAME)
- {
- break;
- }
+ pingMainloopTimeout("idleNetwork");
+
+ gObjectList.mNumNewObjects = 0;
+ S32 total_decoded = 0;
+
+ if (!gSavedSettings.getBOOL("SpeedTest"))
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode
+
+ LLTimer check_message_timer;
+ // Read all available packets from network
+ const S64 frame_count = gFrameCount; // U32->S64
+ F32 total_time = 0.0f;
+
+ {
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(frame_count, gServicePump))
+ {
+ if (gDoDisconnect)
+ {
+ // We're disconnecting, don't process any more messages from the server
+ // We're usually disconnecting due to either network corruption or a
+ // server going down, so this is OK.
+ break;
+ }
+
+ total_decoded++;
+ gPacketsIn++;
+
+ if (total_decoded > MESSAGE_MAX_PER_FRAME)
+ {
+ break;
+ }
#ifdef TIME_THROTTLE_MESSAGES
- // Prevent slow packets from completely destroying the frame rate.
- // This usually happens due to clumps of avatars taking huge amount
- // of network processing time (which needs to be fixed, but this is
- // a good limit anyway).
- total_time = check_message_timer.getElapsedTimeF32();
- if (total_time >= CheckMessagesMaxTime)
- break;
+ // Prevent slow packets from completely destroying the frame rate.
+ // This usually happens due to clumps of avatars taking huge amount
+ // of network processing time (which needs to be fixed, but this is
+ // a good limit anyway).
+ total_time = check_message_timer.getElapsedTimeF32();
+ if (total_time >= CheckMessagesMaxTime)
+ break;
#endif
- }
+ }
- // Handle per-frame message system processing.
- lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
- }
+ // Handle per-frame message system processing.
+ lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
+ }
#ifdef TIME_THROTTLE_MESSAGES
- if (total_time >= CheckMessagesMaxTime)
- {
- // Increase CheckMessagesMaxTime so that we will eventually catch up
- CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
- }
- else
- {
- // Reset CheckMessagesMaxTime to default value
- CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
- }
+ if (total_time >= CheckMessagesMaxTime)
+ {
+ // Increase CheckMessagesMaxTime so that we will eventually catch up
+ CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
+ }
+ else
+ {
+ // Reset CheckMessagesMaxTime to default value
+ CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
+ }
#endif
- // we want to clear the control after sending out all necessary agent updates
- gAgent.resetControlFlags();
-
- // Decode enqueued messages...
- S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
-
- if( remaining_possible_decodes <= 0 )
- {
- LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
- }
-
- if (gPrintMessagesThisFrame)
- {
- LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
- gPrintMessagesThisFrame = FALSE;
- }
- }
- add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
-
- // Retransmit unacknowledged packets.
- gXferManager->retransmitUnackedPackets();
- gAssetStorage->checkForTimeouts();
- gViewerThrottle.updateDynamicThrottle();
-
- // Check that the circuit between the viewer and the agent's current
- // region is still alive
- LLViewerRegion *agent_region = gAgent.getRegion();
- if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED))
- {
- LLUUID this_region_id = agent_region->getRegionID();
- bool this_region_alive = agent_region->isAlive();
- if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
- && (mAgentRegionLastID == this_region_id)) // same region
- {
- forceDisconnect(LLTrans::getString("AgentLostConnection"));
- }
- mAgentRegionLastID = this_region_id;
- mAgentRegionLastAlive = this_region_alive;
- }
+ // we want to clear the control after sending out all necessary agent updates
+ gAgent.resetControlFlags();
+
+ // Decode enqueued messages...
+ S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
+
+ if( remaining_possible_decodes <= 0 )
+ {
+ LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
+ }
+
+ if (gPrintMessagesThisFrame)
+ {
+ LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
+ gPrintMessagesThisFrame = FALSE;
+ }
+ }
+ add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
+
+ // Retransmit unacknowledged packets.
+ gXferManager->retransmitUnackedPackets();
+ gAssetStorage->checkForTimeouts();
+ gViewerThrottle.updateDynamicThrottle();
+
+ // Check that the circuit between the viewer and the agent's current
+ // region is still alive
+ LLViewerRegion *agent_region = gAgent.getRegion();
+ if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED))
+ {
+ LLUUID this_region_id = agent_region->getRegionID();
+ bool this_region_alive = agent_region->isAlive();
+ if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
+ && (mAgentRegionLastID == this_region_id)) // same region
+ {
+ forceDisconnect(LLTrans::getString("AgentLostConnection"));
+ }
+ mAgentRegionLastID = this_region_id;
+ mAgentRegionLastAlive = this_region_alive;
+ }
}
void LLAppViewer::disconnectViewer()
{
- if (gDisconnected)
- {
- return;
- }
- //
- // Cleanup after quitting.
- //
- // Save snapshot for next time, if we made it through initialization
-
- LL_INFOS() << "Disconnecting viewer!" << LL_ENDL;
-
- // Dump our frame statistics
-
- // Remember if we were flying
- gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
-
- // Un-minimize all windows so they don't get saved minimized
- if (gFloaterView)
- {
- gFloaterView->restoreAll();
- }
-
- if (LLSelectMgr::instanceExists())
- {
- LLSelectMgr::getInstance()->deselectAll();
- }
-
- // save inventory if appropriate
+ if (gDisconnected)
+ {
+ return;
+ }
+ //
+ // Cleanup after quitting.
+ //
+ // Save snapshot for next time, if we made it through initialization
+
+ LL_INFOS() << "Disconnecting viewer!" << LL_ENDL;
+
+ // Dump our frame statistics
+
+ // Remember if we were flying
+ gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
+
+ // Un-minimize all windows so they don't get saved minimized
+ if (gFloaterView)
+ {
+ gFloaterView->restoreAll();
+ }
+
+ if (LLSelectMgr::instanceExists())
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ }
+
+ // save inventory if appropriate
if (gInventory.isInventoryUsable()
&& gAgent.getID().notNull()) // Shouldn't be null at this stage
{
@@ -5387,44 +5393,44 @@ void LLAppViewer::disconnectViewer()
}
}
- saveNameCache();
- if (LLExperienceCache::instanceExists())
- {
- // TODO: LLExperienceCache::cleanup() logic should be moved to
- // cleanupSingleton().
- LLExperienceCache::instance().cleanup();
- }
+ saveNameCache();
+ if (LLExperienceCache::instanceExists())
+ {
+ // TODO: LLExperienceCache::cleanup() logic should be moved to
+ // cleanupSingleton().
+ LLExperienceCache::instance().cleanup();
+ }
- // close inventory interface, close all windows
- LLSidepanelInventory::cleanup();
+ // close inventory interface, close all windows
+ LLSidepanelInventory::cleanup();
- gAgentWearables.cleanup();
- gAgentCamera.cleanup();
- // Also writes cached agent settings to gSavedSettings
- gAgent.cleanup();
+ gAgentWearables.cleanup();
+ gAgentCamera.cleanup();
+ // Also writes cached agent settings to gSavedSettings
+ gAgent.cleanup();
- // This is where we used to call gObjectList.destroy() and then delete gWorldp.
- // Now we just ask the LLWorld singleton to cleanly shut down.
- if(LLWorld::instanceExists())
- {
- LLWorld::getInstance()->resetClass();
- }
- LLVOCache::deleteSingleton();
+ // This is where we used to call gObjectList.destroy() and then delete gWorldp.
+ // Now we just ask the LLWorld singleton to cleanly shut down.
+ if(LLWorld::instanceExists())
+ {
+ LLWorld::getInstance()->resetClass();
+ }
+ LLVOCache::deleteSingleton();
- // call all self-registered classes
- LLDestroyClassList::instance().fireCallbacks();
+ // call all self-registered classes
+ LLDestroyClassList::instance().fireCallbacks();
- cleanup_xfer_manager();
- gDisconnected = TRUE;
+ cleanup_xfer_manager();
+ gDisconnected = TRUE;
- // Pass the connection state to LLUrlEntryParcel not to attempt
- // parcel info requests while disconnected.
- LLUrlEntryParcel::setDisconnected(gDisconnected);
+ // Pass the connection state to LLUrlEntryParcel not to attempt
+ // parcel info requests while disconnected.
+ LLUrlEntryParcel::setDisconnected(gDisconnected);
}
void LLAppViewer::forceErrorLLError()
{
- LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
+ LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
}
void LLAppViewer::forceErrorLLErrorMsg()
@@ -5437,7 +5443,7 @@ void LLAppViewer::forceErrorLLErrorMsg()
void LLAppViewer::forceErrorBreakpoint()
{
- LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
+ LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
#ifdef LL_WINDOWS
DebugBreak();
#else
@@ -5448,7 +5454,7 @@ void LLAppViewer::forceErrorBreakpoint()
void LLAppViewer::forceErrorBadMemoryAccess()
{
- LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL;
+ LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL;
S32* crash = NULL;
*crash = 0xDEADBEEF;
return;
@@ -5456,7 +5462,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
void LLAppViewer::forceErrorInfiniteLoop()
{
- LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
+ LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
// Loop is intentionally complicated to fool basic loop detection
LLTimer timer_total;
LLTimer timer_expiry;
@@ -5475,7 +5481,7 @@ void LLAppViewer::forceErrorInfiniteLoop()
void LLAppViewer::forceErrorSoftwareException()
{
- LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL;
+ LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL;
LLTHROW(LLException("User selected Force Software Exception"));
}
@@ -5488,8 +5494,8 @@ void LLAppViewer::forceErrorOSSpecificException()
void LLAppViewer::forceErrorDriverCrash()
{
- LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL;
- glDeleteTextures(1, NULL);
+ LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL;
+ glDeleteTextures(1, NULL);
}
void LLAppViewer::forceErrorCoroutineCrash()
@@ -5521,120 +5527,120 @@ void LLAppViewer::forceErrorThreadCrash()
void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
{
- if(!mMainloopTimeout)
- {
- mMainloopTimeout = new LLWatchdogTimeout();
- resumeMainloopTimeout(state, secs);
- }
+ if(!mMainloopTimeout)
+ {
+ mMainloopTimeout = new LLWatchdogTimeout();
+ resumeMainloopTimeout(state, secs);
+ }
}
void LLAppViewer::destroyMainloopTimeout()
{
- if(mMainloopTimeout)
- {
- delete mMainloopTimeout;
- mMainloopTimeout = NULL;
- }
+ if(mMainloopTimeout)
+ {
+ delete mMainloopTimeout;
+ mMainloopTimeout = NULL;
+ }
}
void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs)
{
- if(mMainloopTimeout)
- {
- if(secs < 0.0f)
- {
- static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
- secs = mainloop_timeout;
- }
-
- mMainloopTimeout->setTimeout(secs);
- mMainloopTimeout->start(state);
- }
+ if(mMainloopTimeout)
+ {
+ if(secs < 0.0f)
+ {
+ static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+ secs = mainloop_timeout;
+ }
+
+ mMainloopTimeout->setTimeout(secs);
+ mMainloopTimeout->start(state);
+ }
}
void LLAppViewer::pauseMainloopTimeout()
{
- if(mMainloopTimeout)
- {
- mMainloopTimeout->stop();
- }
+ if(mMainloopTimeout)
+ {
+ mMainloopTimeout->stop();
+ }
}
void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
- if(mMainloopTimeout)
- {
- if(secs < 0.0f)
- {
- static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
- secs = mainloop_timeout;
- }
-
- mMainloopTimeout->setTimeout(secs);
- mMainloopTimeout->ping(state);
- }
+ if(mMainloopTimeout)
+ {
+ if(secs < 0.0f)
+ {
+ static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+ secs = mainloop_timeout;
+ }
+
+ mMainloopTimeout->setTimeout(secs);
+ mMainloopTimeout->ping(state);
+ }
}
void LLAppViewer::handleLoginComplete()
{
- gLoggedInTime.start();
- initMainloopTimeout("Mainloop Init");
-
- // Store some data to DebugInfo in case of a freeze.
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
-
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if ( parcel && parcel->getMusicURL()[0])
- {
- gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL();
- }
- if ( parcel && parcel->getMediaURL()[0])
- {
- gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
- }
-
- gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
- gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
- gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
- gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
-
- if(gAgent.getRegion())
- {
- gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
- gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
- }
-
- if(LLAppViewer::instance()->mMainloopTimeout)
- {
- gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
- }
-
- mOnLoginCompleted();
-
- writeDebugInfo();
-
- // we logged in successfully, so save settings on logout
- LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL;
- mSavePerAccountSettings=true;
+ gLoggedInTime.start();
+ initMainloopTimeout("Mainloop Init");
+
+ // Store some data to DebugInfo in case of a freeze.
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
+
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if ( parcel && parcel->getMusicURL()[0])
+ {
+ gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL();
+ }
+ if ( parcel && parcel->getMediaURL()[0])
+ {
+ gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
+ }
+
+ gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
+ gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
+ gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
+ gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
+
+ if(gAgent.getRegion())
+ {
+ gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
+ gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
+ }
+
+ if(LLAppViewer::instance()->mMainloopTimeout)
+ {
+ gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
+ }
+
+ mOnLoginCompleted();
+
+ writeDebugInfo();
+
+ // we logged in successfully, so save settings on logout
+ LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL;
+ mSavePerAccountSettings=true;
}
//virtual
void LLAppViewer::setMasterSystemAudioMute(bool mute)
{
- gSavedSettings.setBOOL("MuteAudio", mute);
+ gSavedSettings.setBOOL("MuteAudio", mute);
}
//virtual
bool LLAppViewer::getMasterSystemAudioMute()
{
- return gSavedSettings.getBOOL("MuteAudio");
+ return gSavedSettings.getBOOL("MuteAudio");
}
//----------------------------------------------------------------------------
@@ -5650,10 +5656,10 @@ bool LLAppViewer::getMasterSystemAudioMute()
*/
void LLAppViewer::metricsUpdateRegion(U64 region_handle)
{
- if (0 != region_handle)
- {
- LLViewerAssetStatsFF::set_region(region_handle);
- }
+ if (0 != region_handle)
+ {
+ LLViewerAssetStatsFF::set_region(region_handle);
+ }
}
/**
@@ -5662,35 +5668,35 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)
*/
void LLAppViewer::metricsSend(bool enable_reporting)
{
- if (! gViewerAssetStats)
- return;
+ if (! gViewerAssetStats)
+ return;
- if (LLAppViewer::sTextureFetch)
- {
- LLViewerRegion * regionp = gAgent.getRegion();
+ if (LLAppViewer::sTextureFetch)
+ {
+ LLViewerRegion * regionp = gAgent.getRegion();
- if (enable_reporting && regionp)
- {
- std::string caps_url = regionp->getCapability("ViewerMetrics");
+ if (enable_reporting && regionp)
+ {
+ std::string caps_url = regionp->getCapability("ViewerMetrics");
LLSD sd = gViewerAssetStats->asLLSD(true);
- // Send a report request into 'thread1' to get the rest of the data
- // and provide some additional parameters while here.
- LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
- gAgentSessionID,
- gAgentID,
- sd);
- }
- else
- {
- LLAppViewer::sTextureFetch->commandDataBreak();
- }
- }
-
- // Reset even if we can't report. Rather than gather up a huge chunk of
- // data, we'll keep to our sampling interval and retain the data
- // resolution in time.
- gViewerAssetStats->restart();
+ // Send a report request into 'thread1' to get the rest of the data
+ // and provide some additional parameters while here.
+ LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
+ gAgentSessionID,
+ gAgentID,
+ sd);
+ }
+ else
+ {
+ LLAppViewer::sTextureFetch->commandDataBreak();
+ }
+ }
+
+ // Reset even if we can't report. Rather than gather up a huge chunk of
+ // data, we'll keep to our sampling interval and retain the data
+ // resolution in time.
+ gViewerAssetStats->restart();
}
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index e02d62ad45..fc182fc2e2 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawable.h
* @brief LLDrawable class definition
*
* $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$
*/
@@ -67,279 +67,280 @@ class LLDrawable
public:
typedef std::vector<LLFace*> face_list_t;
- LLDrawable(const LLDrawable& rhs)
+ LLDrawable(const LLDrawable& rhs)
: LLViewerOctreeEntryData(rhs)
- {
- *this = rhs;
- }
-
- const LLDrawable& operator=(const LLDrawable& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
-
- static void initClass();
-
- LLDrawable(LLViewerObject *vobj, bool new_entry = false);
-
- void markDead(); // Mark this drawable as dead
- BOOL isDead() const { return isState(DEAD); }
- BOOL isNew() const { return !isState(BUILT); }
- BOOL isUnload() const { return isState(FOR_UNLOAD); }
-
- BOOL isLight() const;
-
- virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
-
- LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();}
- LLViewerRegion* getRegion() const { return mVObjp->getRegion(); }
- const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }
- LLPointer<LLViewerObject>& getVObj() { return mVObjp; }
- const LLViewerObject *getVObj() const { return mVObjp; }
- LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK
-
- const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); }
- const LLMatrix4& getRenderMatrix() const;
- void setPosition(LLVector3 v) const { }
- const LLVector3& getPosition() const { return mXform.getPosition(); }
- const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
- const LLVector3 getPositionAgent() const;
- const LLVector3& getScale() const { return mCurrentScale; }
- void setScale(const LLVector3& scale) { mCurrentScale = scale; }
- const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); }
- const LLQuaternion& getRotation() const { return mXform.getRotation(); }
- F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
- S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
-
- void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
- LLXformMatrix* getXform() { return &mXform; }
-
- U32 getState() const { return mState; }
- BOOL isState (U32 bits) const { return ((mState & bits) != 0); }
- void setState (U32 bits) { mState |= bits; }
- void clearState(U32 bits) { mState &= ~bits; }
-
- BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); }
- BOOL isRoot() const { return !mParent || mParent->isAvatar(); }
+ {
+ *this = rhs;
+ }
+
+ const LLDrawable& operator=(const LLDrawable& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ static void initClass();
+
+ LLDrawable(LLViewerObject *vobj, bool new_entry = false);
+
+ void markDead(); // Mark this drawable as dead
+ BOOL isDead() const { return isState(DEAD); }
+ BOOL isNew() const { return !isState(BUILT); }
+ BOOL isUnload() const { return isState(FOR_UNLOAD); }
+
+ BOOL isLight() const;
+
+ virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
+
+ LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();}
+ LLViewerRegion* getRegion() const { return mVObjp->getRegion(); }
+ const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }
+ LLPointer<LLViewerObject>& getVObj() { return mVObjp; }
+ const LLViewerObject *getVObj() const { return mVObjp; }
+ LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK
+
+ const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); }
+ const LLMatrix4& getRenderMatrix() const;
+ void setPosition(LLVector3 v) const { }
+ const LLVector3& getPosition() const { return mXform.getPosition(); }
+ const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
+ const LLVector3 getPositionAgent() const;
+ const LLVector3& getScale() const { return mCurrentScale; }
+ void setScale(const LLVector3& scale) { mCurrentScale = scale; }
+ const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); }
+ const LLQuaternion& getRotation() const { return mXform.getRotation(); }
+ F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
+ S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
+
+ void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
+ LLXformMatrix* getXform() { return &mXform; }
+
+ U32 getState() const { return mState; }
+ BOOL isState (U32 bits) const { return ((mState & bits) != 0); }
+ void setState (U32 bits) { mState |= bits; }
+ void clearState(U32 bits) { mState &= ~bits; }
+
+ BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); }
+ BOOL isRoot() const { return !mParent || mParent->isAvatar(); }
LLDrawable* getRoot();
- BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); }
- virtual BOOL isSpatialBridge() const { return FALSE; }
- virtual LLSpatialPartition* asPartition() { return NULL; }
- LLDrawable* getParent() const { return mParent; }
-
- // must set parent through LLViewerObject:: ()
- //BOOL setParent(LLDrawable *parent);
-
- inline LLFace* getFace(const S32 i) const;
- inline S32 getNumFaces() const;
+ BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); }
+ virtual BOOL isSpatialBridge() const { return FALSE; }
+ virtual LLSpatialPartition* asPartition() { return NULL; }
+ LLDrawable* getParent() const { return mParent; }
+
+ // must set parent through LLViewerObject:: ()
+ //BOOL setParent(LLDrawable *parent);
+
+ inline LLFace* getFace(const S32 i) const;
+ inline S32 getNumFaces() const;
face_list_t& getFaces() { return mFaces; }
const face_list_t& getFaces() const { return mFaces; }
- //void removeFace(const S32 i); // SJB: Avoid using this, it's slow
- LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
- LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
- LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
- LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
- void deleteFaces(S32 offset, S32 count);
- void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
- void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
- void mergeFaces(LLDrawable* src);
-
- void init(bool new_entry);
- void unload();
- void destroy();
-
- void update();
- F32 updateXform(BOOL undamped);
-
- virtual void makeActive();
- /*virtual*/ void makeStatic(BOOL warning_enabled = TRUE);
-
- BOOL isActive() const { return isState(ACTIVE); }
- BOOL isStatic() const { return !isActive(); }
- BOOL isAnimating() const;
-
- virtual BOOL updateMove();
- virtual void movePartition();
-
- void updateTexture();
- void updateMaterial();
- virtual void updateDistance(LLCamera& camera, bool force_update);
- BOOL updateGeometry();
- void updateFaceSize(S32 idx);
-
- void updateSpecialHoverCursor(BOOL enabled);
-
- virtual void shiftPos(const LLVector4a &shift_vector);
-
- S32 getGeneration() const { return mGeneration; }
-
- BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; }
- void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); }
-
- bool isVisible() const;
- bool isRecentlyVisible() const;
-
- virtual void cleanupReferences();
-
- void setGroup(LLViewerOctreeGroup* group);
- void setRadius(const F32 radius);
- F32 getRadius() const { return mRadius; }
- F32 getVisibilityRadius() const;
-
- void updateUVMinMax(); // Updates the cache of sun space bounding box.
-
- const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
- virtual void updateSpatialExtents();
- virtual void updateBinRadius();
-
- void setRenderType(S32 type) { mRenderType = type; }
- BOOL isRenderType(S32 type) { return mRenderType == type; }
- S32 getRenderType() { return mRenderType; }
-
- // Debugging methods
- S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
-
- LLSpatialPartition* getSpatialPartition();
-
- void removeFromOctree();
-
- void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
- LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
-
- // Statics
- static void incrementVisible();
- static void cleanupDeadDrawables();
+ //void removeFace(const S32 i); // SJB: Avoid using this, it's slow
+ LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
+ void deleteFaces(S32 offset, S32 count);
+ void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
+ void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
+ void mergeFaces(LLDrawable* src);
+
+ void init(bool new_entry);
+ void unload();
+ void destroy();
+
+ void update();
+ F32 updateXform(BOOL undamped);
+
+ virtual void makeActive();
+ /*virtual*/ void makeStatic(BOOL warning_enabled = TRUE);
+
+ BOOL isActive() const { return isState(ACTIVE); }
+ BOOL isStatic() const { return !isActive(); }
+ BOOL isAnimating() const;
+
+ virtual BOOL updateMove();
+ virtual void movePartition();
+
+ void updateTexture();
+ void updateMaterial();
+ virtual void updateDistance(LLCamera& camera, bool force_update);
+ BOOL updateGeometry();
+ void updateFaceSize(S32 idx);
+
+ void updateSpecialHoverCursor(BOOL enabled);
+
+ virtual void shiftPos(const LLVector4a &shift_vector);
+
+ S32 getGeneration() const { return mGeneration; }
+
+ BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; }
+ void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); }
+
+ bool isVisible() const;
+ bool isRecentlyVisible() const;
+
+ virtual void cleanupReferences();
+
+ void setGroup(LLViewerOctreeGroup* group);
+ void setRadius(const F32 radius);
+ F32 getRadius() const { return mRadius; }
+ F32 getVisibilityRadius() const;
+
+ void updateUVMinMax(); // Updates the cache of sun space bounding box.
+
+ const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
+ virtual void updateSpatialExtents();
+ virtual void updateBinRadius();
+
+ void setRenderType(S32 type) { mRenderType = type; }
+ BOOL isRenderType(S32 type) { return mRenderType == type; }
+ S32 getRenderType() { return mRenderType; }
+
+ // Debugging methods
+ S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
+
+ LLSpatialPartition* getSpatialPartition();
+
+ void removeFromOctree();
+
+ void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
+ LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
+
+ // Statics
+ static void incrementVisible();
+ static void cleanupDeadDrawables();
protected:
- ~LLDrawable() { destroy(); }
- void moveUpdatePipeline(BOOL moved);
- void updatePartition();
- BOOL updateMoveDamped();
- BOOL updateMoveUndamped();
-
+ ~LLDrawable() { destroy(); }
+ void moveUpdatePipeline(BOOL moved);
+ void updatePartition();
+ BOOL updateMoveDamped();
+ BOOL updateMoveUndamped();
+
public:
- friend class LLPipeline;
- friend class LLDrawPool;
- friend class LLSpatialBridge;
-
- typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
+ friend class LLPipeline;
+ friend class LLDrawPool;
+ friend class LLSpatialBridge;
+
+ typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
typedef std::set<LLPointer<LLDrawable> > ordered_drawable_set_t;
- typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t;
- typedef std::list<LLPointer<LLDrawable> > drawable_list_t;
- typedef std::queue<LLPointer<LLDrawable> > drawable_queue_t;
-
- struct CompareDistanceGreater
- {
- bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs)
- {
- return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last
- }
- };
-
- struct CompareDistanceGreaterVisibleFirst
- {
- bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs)
- {
- if (lhs->isVisible() && !rhs->isVisible())
- {
- return TRUE; //visible things come first
- }
- else if (!lhs->isVisible() && rhs->isVisible())
- {
- return FALSE; //rhs is visible, comes first
- }
-
- return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last
- }
- };
-
- typedef enum e_drawable_flags
- {
- IN_REBUILD_Q = 0x00000001,
- EARLY_MOVE = 0x00000004,
- MOVE_UNDAMPED = 0x00000008,
- ON_MOVE_LIST = 0x00000010,
- UV = 0x00000020,
- UNLIT = 0x00000040,
- LIGHT = 0x00000080,
- REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed
- REBUILD_TCOORD = 0x00000200, //texture coordinates changed
- REBUILD_COLOR = 0x00000400, //color changed
- REBUILD_POSITION= 0x00000800, //vertex positions/normals changed
- REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR,
- REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR,
- REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME,
- REBUILD_RIGGED = 0x00001000,
- ON_SHIFT_LIST = 0x00002000,
- ACTIVE = 0x00004000,
- DEAD = 0x00008000,
- INVISIBLE = 0x00010000, // stay invisible until flag is cleared
- NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet
- BUILT = 0x00040000,
- FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
- HAS_ALPHA = 0x00100000,
- RIGGED = 0x00200000, //has a rigged face
+ typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t;
+ typedef std::list<LLPointer<LLDrawable> > drawable_list_t;
+ typedef std::queue<LLPointer<LLDrawable> > drawable_queue_t;
+
+ struct CompareDistanceGreater
+ {
+ bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs)
+ {
+ return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last
+ }
+ };
+
+ struct CompareDistanceGreaterVisibleFirst
+ {
+ bool operator()(const LLDrawable* const& lhs, const LLDrawable* const& rhs)
+ {
+ if (lhs->isVisible() && !rhs->isVisible())
+ {
+ return TRUE; //visible things come first
+ }
+ else if (!lhs->isVisible() && rhs->isVisible())
+ {
+ return FALSE; //rhs is visible, comes first
+ }
+
+ return lhs->mDistanceWRTCamera < rhs->mDistanceWRTCamera; // farthest = last
+ }
+ };
+
+ typedef enum e_drawable_flags
+ {
+ IN_REBUILD_Q = 0x00000001,
+ EARLY_MOVE = 0x00000004,
+ MOVE_UNDAMPED = 0x00000008,
+ ON_MOVE_LIST = 0x00000010,
+ UV = 0x00000020,
+ UNLIT = 0x00000040,
+ LIGHT = 0x00000080,
+ REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed
+ REBUILD_TCOORD = 0x00000200, //texture coordinates changed
+ REBUILD_COLOR = 0x00000400, //color changed
+ REBUILD_POSITION= 0x00000800, //vertex positions/normals changed
+ REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR,
+ REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR,
+ REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME,
+ REBUILD_RIGGED = 0x00001000,
+ ON_SHIFT_LIST = 0x00002000,
+ ACTIVE = 0x00004000,
+ DEAD = 0x00008000,
+ INVISIBLE = 0x00010000, // stay invisible until flag is cleared
+ NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet
+ BUILT = 0x00040000,
+ FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
+ HAS_ALPHA = 0x00100000,
+ RIGGED = 0x00200000, //has a rigged face
RIGGED_CHILD = 0x00400000, //has a child with a rigged face
- PARTITION_MOVE = 0x00800000,
- ANIMATED_CHILD = 0x01000000,
- ACTIVE_CHILD = 0x02000000,
- FOR_UNLOAD = 0x04000000, //should be unload from memory
- } EDrawableFlags;
+ PARTITION_MOVE = 0x00800000,
+ ANIMATED_CHILD = 0x01000000,
+ ACTIVE_CHILD = 0x02000000,
+ FOR_UNLOAD = 0x04000000, //should be unload from memory
+ MIRROR = 0x08000000, // Used as a mirror, needs a hero probe position to be calculated.
+ } EDrawableFlags;
public:
- LLXformMatrix mXform;
+ LLXformMatrix mXform;
- // vis data
- LLPointer<LLDrawable> mParent;
+ // vis data
+ LLPointer<LLDrawable> mParent;
- F32 mDistanceWRTCamera;
+ F32 mDistanceWRTCamera;
- static F32 sCurPixelAngle; //current pixels per radian
+ static F32 sCurPixelAngle; //current pixels per radian
private:
- U32 mState;
- S32 mRenderType;
- LLPointer<LLViewerObject> mVObjp;
- face_list_t mFaces;
- LLPointer<LLDrawable> mSpatialBridge;
-
- F32 mRadius;
- S32 mGeneration;
-
- LLVector3 mCurrentScale;
-
- static U32 sNumZombieDrawables;
- static std::vector<LLPointer<LLDrawable> > sDeadList;
+ U32 mState;
+ S32 mRenderType;
+ LLPointer<LLViewerObject> mVObjp;
+ face_list_t mFaces;
+ LLPointer<LLDrawable> mSpatialBridge;
+
+ F32 mRadius;
+ S32 mGeneration;
+
+ LLVector3 mCurrentScale;
+
+ static U32 sNumZombieDrawables;
+ static std::vector<LLPointer<LLDrawable> > sDeadList;
} LL_ALIGN_POSTFIX(16);
inline LLFace* LLDrawable::getFace(const S32 i) const
{
- //switch these asserts to LL_ERRS() -- davep
- //llassert((U32)i < mFaces.size());
- //llassert(mFaces[i]);
-
- if ((U32) i >= mFaces.size())
- {
- LL_WARNS() << "Invalid face index." << LL_ENDL;
- return NULL;
- }
-
- if (!mFaces[i])
- {
- LL_WARNS() << "Null face found." << LL_ENDL;
- return NULL;
- }
-
- return mFaces[i];
+ //switch these asserts to LL_ERRS() -- davep
+ //llassert((U32)i < mFaces.size());
+ //llassert(mFaces[i]);
+
+ if ((U32) i >= mFaces.size())
+ {
+ LL_WARNS() << "Invalid face index." << LL_ENDL;
+ return NULL;
+ }
+
+ if (!mFaces[i])
+ {
+ LL_WARNS() << "Null face found." << LL_ENDL;
+ return NULL;
+ }
+
+ return mFaces[i];
}
inline S32 LLDrawable::getNumFaces()const
{
- return (S32)mFaces.size();
+ return (S32)mFaces.size();
}
#endif
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 3b415f2b26..556760632a 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpool.cpp
* @brief LLDrawPool class implementation
*
* $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$
*/
@@ -60,81 +60,81 @@ S32 LLDrawPool::sNumDrawPools = 0;
//=============================
LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
{
- LLDrawPool *poolp = NULL;
- switch (type)
- {
- case POOL_SIMPLE:
- poolp = new LLDrawPoolSimple();
- break;
- case POOL_GRASS:
- poolp = new LLDrawPoolGrass();
- break;
- case POOL_ALPHA_MASK:
- poolp = new LLDrawPoolAlphaMask();
- break;
- case POOL_FULLBRIGHT_ALPHA_MASK:
- poolp = new LLDrawPoolFullbrightAlphaMask();
- break;
- case POOL_FULLBRIGHT:
- poolp = new LLDrawPoolFullbright();
- break;
- case POOL_GLOW:
- poolp = new LLDrawPoolGlow();
- break;
- case POOL_ALPHA_PRE_WATER:
- poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER);
- break;
+ LLDrawPool *poolp = NULL;
+ switch (type)
+ {
+ case POOL_SIMPLE:
+ poolp = new LLDrawPoolSimple();
+ break;
+ case POOL_GRASS:
+ poolp = new LLDrawPoolGrass();
+ break;
+ case POOL_ALPHA_MASK:
+ poolp = new LLDrawPoolAlphaMask();
+ break;
+ case POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = new LLDrawPoolFullbrightAlphaMask();
+ break;
+ case POOL_FULLBRIGHT:
+ poolp = new LLDrawPoolFullbright();
+ break;
+ case POOL_GLOW:
+ poolp = new LLDrawPoolGlow();
+ break;
+ case POOL_ALPHA_PRE_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER);
+ break;
case POOL_ALPHA_POST_WATER:
poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_POST_WATER);
break;
- case POOL_AVATAR:
- case POOL_CONTROL_AV:
- poolp = new LLDrawPoolAvatar(type);
- break;
- case POOL_TREE:
- poolp = new LLDrawPoolTree(tex0);
- break;
- case POOL_TERRAIN:
- poolp = new LLDrawPoolTerrain(tex0);
- break;
- case POOL_SKY:
- poolp = new LLDrawPoolSky();
- break;
- case POOL_VOIDWATER:
- case POOL_WATER:
- poolp = new LLDrawPoolWater();
- break;
- case POOL_BUMP:
- poolp = new LLDrawPoolBump();
- break;
- case POOL_MATERIALS:
- poolp = new LLDrawPoolMaterials();
- break;
- case POOL_WL_SKY:
- poolp = new LLDrawPoolWLSky();
- break;
- case POOL_GLTF_PBR:
- poolp = new LLDrawPoolGLTFPBR();
+ case POOL_AVATAR:
+ case POOL_CONTROL_AV:
+ poolp = new LLDrawPoolAvatar(type);
+ break;
+ case POOL_TREE:
+ poolp = new LLDrawPoolTree(tex0);
+ break;
+ case POOL_TERRAIN:
+ poolp = new LLDrawPoolTerrain(tex0);
+ break;
+ case POOL_SKY:
+ poolp = new LLDrawPoolSky();
+ break;
+ case POOL_VOIDWATER:
+ case POOL_WATER:
+ poolp = new LLDrawPoolWater();
+ break;
+ case POOL_BUMP:
+ poolp = new LLDrawPoolBump();
+ break;
+ case POOL_MATERIALS:
+ poolp = new LLDrawPoolMaterials();
+ break;
+ case POOL_WL_SKY:
+ poolp = new LLDrawPoolWLSky();
+ break;
+ case POOL_GLTF_PBR:
+ poolp = new LLDrawPoolGLTFPBR();
break;
case POOL_GLTF_PBR_ALPHA_MASK:
poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
- break;
- default:
- LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
- return NULL;
- }
+ break;
+ default:
+ LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
+ return NULL;
+ }
- llassert(poolp->mType == type);
- return poolp;
+ llassert(poolp->mType == type);
+ return poolp;
}
LLDrawPool::LLDrawPool(const U32 type)
{
- mType = type;
- sNumDrawPools++;
- mId = sNumDrawPools;
- mShaderLevel = 0;
- mSkipRender = false;
+ mType = type;
+ sNumDrawPools++;
+ mId = sNumDrawPools;
+ mShaderLevel = 0;
+ mSkipRender = false;
}
LLDrawPool::~LLDrawPool()
@@ -144,7 +144,7 @@ LLDrawPool::~LLDrawPool()
LLViewerTexture *LLDrawPool::getDebugTexture()
{
- return NULL;
+ return NULL;
}
//virtual
@@ -152,55 +152,55 @@ void LLDrawPool::beginRenderPass( S32 pass )
{
}
-//virtual
-S32 LLDrawPool::getNumPasses()
+//virtual
+S32 LLDrawPool::getNumPasses()
{
- return 1;
+ return 1;
}
-
-//virtual
+
+//virtual
void LLDrawPool::beginDeferredPass(S32 pass)
{
}
-//virtual
+//virtual
void LLDrawPool::endDeferredPass(S32 pass)
{
}
-//virtual
+//virtual
S32 LLDrawPool::getNumDeferredPasses()
{
- return 0;
+ return 0;
}
-//virtual
+//virtual
void LLDrawPool::renderDeferred(S32 pass)
{
}
-//virtual
+//virtual
void LLDrawPool::beginPostDeferredPass(S32 pass)
{
}
-//virtual
+//virtual
void LLDrawPool::endPostDeferredPass(S32 pass)
{
}
-//virtual
+//virtual
S32 LLDrawPool::getNumPostDeferredPasses()
{
- return 0;
+ return 0;
}
-//virtual
+//virtual
void LLDrawPool::renderPostDeferred(S32 pass)
{
@@ -209,29 +209,29 @@ void LLDrawPool::renderPostDeferred(S32 pass)
//virtual
void LLDrawPool::endRenderPass( S32 pass )
{
- //make sure channel 0 is active channel
- gGL.getTexUnit(0)->activate();
+ //make sure channel 0 is active channel
+ gGL.getTexUnit(0)->activate();
}
-//virtual
+//virtual
void LLDrawPool::beginShadowPass(S32 pass)
{
}
-//virtual
+//virtual
void LLDrawPool::endShadowPass(S32 pass)
{
}
-//virtual
+//virtual
S32 LLDrawPool::getNumShadowPasses()
{
- return 0;
+ return 0;
}
-//virtual
+//virtual
void LLDrawPool::renderShadow(S32 pass)
{
@@ -243,20 +243,20 @@ void LLDrawPool::renderShadow(S32 pass)
LLFacePool::LLFacePool(const U32 type)
: LLDrawPool(type)
{
- resetDrawOrders();
+ resetDrawOrders();
}
LLFacePool::~LLFacePool()
{
- destroy();
+ destroy();
}
void LLFacePool::destroy()
{
- if (!mReferences.empty())
- {
- LL_INFOS() << mReferences.size() << " references left on deletion of draw pool!" << LL_ENDL;
- }
+ if (!mReferences.empty())
+ {
+ LL_INFOS() << mReferences.size() << " references left on deletion of draw pool!" << LL_ENDL;
+ }
}
void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
@@ -265,59 +265,59 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures
void LLFacePool::enqueue(LLFace* facep)
{
- mDrawFace.push_back(facep);
+ mDrawFace.push_back(facep);
}
// virtual
BOOL LLFacePool::addFace(LLFace *facep)
{
- addFaceReference(facep);
- return TRUE;
+ addFaceReference(facep);
+ return TRUE;
}
// virtual
BOOL LLFacePool::removeFace(LLFace *facep)
{
- removeFaceReference(facep);
+ removeFaceReference(facep);
- vector_replace_with_last(mDrawFace, facep);
+ vector_replace_with_last(mDrawFace, facep);
- return TRUE;
+ return TRUE;
}
// Not absolutely sure if we should be resetting all of the chained pools as well - djs
void LLFacePool::resetDrawOrders()
{
- mDrawFace.resize(0);
+ mDrawFace.resize(0);
}
LLViewerTexture *LLFacePool::getTexture()
{
- return NULL;
+ return NULL;
}
void LLFacePool::removeFaceReference(LLFace *facep)
{
- if (facep->getReferenceIndex() != -1)
- {
- if (facep->getReferenceIndex() != (S32)mReferences.size())
- {
- LLFace *back = mReferences.back();
- mReferences[facep->getReferenceIndex()] = back;
- back->setReferenceIndex(facep->getReferenceIndex());
- }
- mReferences.pop_back();
- }
- facep->setReferenceIndex(-1);
+ if (facep->getReferenceIndex() != -1)
+ {
+ if (facep->getReferenceIndex() != (S32)mReferences.size())
+ {
+ LLFace *back = mReferences.back();
+ mReferences[facep->getReferenceIndex()] = back;
+ back->setReferenceIndex(facep->getReferenceIndex());
+ }
+ mReferences.pop_back();
+ }
+ facep->setReferenceIndex(-1);
}
void LLFacePool::addFaceReference(LLFace *facep)
{
- if (-1 == facep->getReferenceIndex())
- {
- facep->setReferenceIndex(mReferences.size());
- mReferences.push_back(facep);
- }
+ if (-1 == facep->getReferenceIndex())
+ {
+ facep->setReferenceIndex(mReferences.size());
+ mReferences.push_back(facep);
+ }
}
void LLFacePool::pushFaceGeometry()
@@ -330,47 +330,47 @@ void LLFacePool::pushFaceGeometry()
BOOL LLFacePool::verify() const
{
- BOOL ok = TRUE;
-
- for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- const LLFace* facep = *iter;
- if (facep->getPool() != this)
- {
- LL_INFOS() << "Face in wrong pool!" << LL_ENDL;
- facep->printDebugInfo();
- ok = FALSE;
- }
- else if (!facep->verify())
- {
- ok = FALSE;
- }
- }
-
- return ok;
+ BOOL ok = TRUE;
+
+ for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ const LLFace* facep = *iter;
+ if (facep->getPool() != this)
+ {
+ LL_INFOS() << "Face in wrong pool!" << LL_ENDL;
+ facep->printDebugInfo();
+ ok = FALSE;
+ }
+ else if (!facep->verify())
+ {
+ ok = FALSE;
+ }
+ }
+
+ return ok;
}
void LLFacePool::printDebugInfo() const
{
- LL_INFOS() << "Pool " << this << " Type: " << getType() << LL_ENDL;
+ LL_INFOS() << "Pool " << this << " Type: " << getType() << LL_ENDL;
}
BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
{
- gGL.diffuseColor4fv(color.mV);
+ gGL.diffuseColor4fv(color.mV);
}
void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
{
- glColor4ubv(color.mV);
+ glColor4ubv(color.mV);
}
void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
{
- gGL.diffuseColor4f(r,g,b,a);
+ gGL.diffuseColor4f(r,g,b,a);
}
@@ -391,16 +391,16 @@ LLRenderPass::~LLRenderPass()
void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
+ LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
- for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
- {
- LLDrawInfo *pparams = *k;
- if (pparams)
+ for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
+ {
+ LLDrawInfo *pparams = *k;
+ if (pparams)
{
pushBatch(*pparams, texture);
- }
- }
+ }
+ }
}
void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture)
@@ -409,11 +409,11 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
-
+
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo* pparams = *k;
- if (pparams)
+ if (pparams)
{
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
@@ -465,7 +465,7 @@ void LLRenderPass::pushUntexturedBatches(U32 type)
void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
-
+
if (texture)
{
LLVOAvatar* lastAvatar = nullptr;
@@ -521,13 +521,13 @@ void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
- for (LLCullResult::drawinfo_iterator i = begin; i != end; )
- {
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
- pushBatch(*pparams, texture, batch_textures);
- }
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
+ pushBatch(*pparams, texture, batch_textures);
+ }
}
void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures)
@@ -567,17 +567,22 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text
void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
{
- if (params.mModelMatrix != gGLLastMatrix)
- {
- gGLLastMatrix = params.mModelMatrix;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
- if (params.mModelMatrix)
- {
- gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
- }
- gPipeline.mMatrixOpCount++;
- }
+ applyModelMatrix(params.mModelMatrix);
+}
+
+void LLRenderPass::applyModelMatrix(const LLMatrix4* model_matrix)
+{
+ if (model_matrix != gGLLastMatrix)
+ {
+ gGLLastMatrix = model_matrix;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
}
void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures)
@@ -590,51 +595,51 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textur
return;
}
- applyModelMatrix(params);
-
- bool tex_setup = false;
-
- {
- if (batch_textures && params.mTextureList.size() > 1)
- {
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
- {
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTexture.notNull())
- {
- gGL.getTexUnit(0)->bindFast(params.mTexture);
- if (params.mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
- }
-
+ applyModelMatrix(params);
+
+ bool tex_setup = false;
+
+ {
+ if (batch_textures && params.mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ {
+ if (params.mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(0)->bindFast(params.mTexture);
+ if (params.mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
+
params.mVertexBuffer->setBuffer();
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
- if (tex_setup)
- {
+ if (tex_setup)
+ {
gGL.matrixMode(LLRender::MM_TEXTURE0);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
void LLRenderPass::pushUntexturedBatch(LLDrawInfo& params)
@@ -746,6 +751,7 @@ void LLRenderPass::pushUntexturedGLTFBatches(U32 type)
}
}
+// static
void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
{
auto& mat = params.mGLTFMaterial;
@@ -764,6 +770,7 @@ void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
teardown_texture_matrix(params);
}
+// static
void LLRenderPass::pushUntexturedGLTFBatch(LLDrawInfo& params)
{
auto& mat = params.mGLTFMaterial;
@@ -825,6 +832,7 @@ void LLRenderPass::pushUntexturedRiggedGLTFBatches(U32 type)
}
+// static
void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
{
if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
@@ -837,6 +845,7 @@ void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvat
pushGLTFBatch(params);
}
+// static
void LLRenderPass::pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
{
if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 7e5e6f2b17..c69f386c6d 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpool.h
* @brief LLDrawPool class definition
*
* $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$
*/
@@ -43,87 +43,87 @@ class LLMeshSkinInfo;
class LLDrawPool
{
public:
- static S32 sNumDrawPools;
+ static S32 sNumDrawPools;
- enum
- {
- // Correspond to LLPipeline render type
+ enum
+ {
+ // Correspond to LLPipeline render type
// Also controls render order, so passes that don't use alpha masking/blending should come before
// other passes to preserve hierarchical Z for occlusion queries. Occlusion queries happen just
// before grass, so grass should be the first alpha masked pool. Other ordering should be done
// based on fill rate and likelihood to occlude future passes (faster, large occluders first).
- //
+ //
POOL_SKY = 1,
POOL_WL_SKY,
- POOL_SIMPLE,
- POOL_FULLBRIGHT,
- POOL_BUMP,
- POOL_TERRAIN,
+ POOL_SIMPLE,
+ POOL_FULLBRIGHT,
+ POOL_BUMP,
POOL_MATERIALS,
POOL_GLTF_PBR,
+ POOL_TERRAIN,
POOL_GRASS,
POOL_GLTF_PBR_ALPHA_MASK,
- POOL_TREE,
- POOL_ALPHA_MASK,
- POOL_FULLBRIGHT_ALPHA_MASK,
- POOL_AVATAR,
- POOL_CONTROL_AV, // Animesh
- POOL_GLOW,
- POOL_ALPHA_PRE_WATER,
+ POOL_TREE,
+ POOL_ALPHA_MASK,
+ POOL_FULLBRIGHT_ALPHA_MASK,
+ POOL_AVATAR,
+ POOL_CONTROL_AV, // Animesh
+ POOL_GLOW,
+ POOL_ALPHA_PRE_WATER,
POOL_VOIDWATER,
POOL_WATER,
POOL_ALPHA_POST_WATER,
POOL_ALPHA, // note there is no actual "POOL_ALPHA" but pre-water and post-water pools consume POOL_ALPHA faces
- NUM_POOL_TYPES,
- };
-
- LLDrawPool(const U32 type);
- virtual ~LLDrawPool();
-
- virtual BOOL isDead() = 0;
-
- S32 getId() const { return mId; }
- U32 getType() const { return mType; }
-
- BOOL getSkipRenderFlag() const { return mSkipRender;}
- void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; }
-
- virtual LLViewerTexture *getDebugTexture();
- virtual void beginRenderPass( S32 pass );
- virtual void endRenderPass( S32 pass );
- virtual S32 getNumPasses();
-
- virtual void beginDeferredPass(S32 pass);
- virtual void endDeferredPass(S32 pass);
- virtual S32 getNumDeferredPasses();
- virtual void renderDeferred(S32 pass = 0);
-
- virtual void beginPostDeferredPass(S32 pass);
- virtual void endPostDeferredPass(S32 pass);
- virtual S32 getNumPostDeferredPasses();
- virtual void renderPostDeferred(S32 pass = 0);
-
- virtual void beginShadowPass(S32 pass);
- virtual void endShadowPass(S32 pass);
- virtual S32 getNumShadowPasses();
- virtual void renderShadow(S32 pass = 0);
+ NUM_POOL_TYPES,
+ };
+
+ LLDrawPool(const U32 type);
+ virtual ~LLDrawPool();
+
+ virtual BOOL isDead() = 0;
+
+ S32 getId() const { return mId; }
+ U32 getType() const { return mType; }
+
+ BOOL getSkipRenderFlag() const { return mSkipRender;}
+ void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; }
+
+ virtual LLViewerTexture *getDebugTexture();
+ virtual void beginRenderPass( S32 pass );
+ virtual void endRenderPass( S32 pass );
+ virtual S32 getNumPasses();
+
+ virtual void beginDeferredPass(S32 pass);
+ virtual void endDeferredPass(S32 pass);
+ virtual S32 getNumDeferredPasses();
+ virtual void renderDeferred(S32 pass = 0);
+
+ virtual void beginPostDeferredPass(S32 pass);
+ virtual void endPostDeferredPass(S32 pass);
+ virtual S32 getNumPostDeferredPasses();
+ virtual void renderPostDeferred(S32 pass = 0);
+
+ virtual void beginShadowPass(S32 pass);
+ virtual void endShadowPass(S32 pass);
+ virtual S32 getNumShadowPasses();
+ virtual void renderShadow(S32 pass = 0);
virtual void render(S32 pass = 0) {};
virtual void prerender() {};
virtual U32 getVertexDataMask() { return 0; } // DEPRECATED -- draw pool doesn't actually determine vertex data mask any more
- virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
- virtual S32 getShaderLevel() const { return mShaderLevel; }
-
- static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
- virtual LLViewerTexture* getTexture() = 0;
- virtual BOOL isFacePool() { return FALSE; }
- virtual void resetDrawOrders() = 0;
+ virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
+ virtual S32 getShaderLevel() const { return mShaderLevel; }
+
+ static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
+ virtual LLViewerTexture* getTexture() = 0;
+ virtual BOOL isFacePool() { return FALSE; }
+ virtual void resetDrawOrders() = 0;
virtual void pushFaceGeometry() {}
- S32 mShaderLevel;
- S32 mId;
- U32 mType; // Type of draw pool
- BOOL mSkipRender;
+ S32 mShaderLevel;
+ S32 mId;
+ U32 mType; // Type of draw pool
+ BOOL mSkipRender;
};
class LLRenderPass : public LLDrawPool
@@ -132,77 +132,77 @@ public:
// list of possible LLRenderPass types to assign a render batch to
// NOTE: "rigged" variant MUST be non-rigged variant + 1
// see LLVolumeGeometryManager::registerFace()
- enum
- {
- PASS_SIMPLE = NUM_POOL_TYPES,
+ enum
+ {
+ PASS_SIMPLE = NUM_POOL_TYPES,
PASS_SIMPLE_RIGGED,
- PASS_GRASS,
- PASS_FULLBRIGHT,
+ PASS_GRASS,
+ PASS_FULLBRIGHT,
PASS_FULLBRIGHT_RIGGED,
- PASS_INVISIBLE,
+ PASS_INVISIBLE,
PASS_INVISIBLE_RIGGED,
- PASS_INVISI_SHINY,
+ PASS_INVISI_SHINY,
PASS_INVISI_SHINY_RIGGED,
- PASS_FULLBRIGHT_SHINY,
+ PASS_FULLBRIGHT_SHINY,
PASS_FULLBRIGHT_SHINY_RIGGED,
- PASS_SHINY,
+ PASS_SHINY,
PASS_SHINY_RIGGED,
- PASS_BUMP,
+ PASS_BUMP,
PASS_BUMP_RIGGED,
- PASS_POST_BUMP,
+ PASS_POST_BUMP,
PASS_POST_BUMP_RIGGED,
- PASS_MATERIAL,
+ PASS_MATERIAL,
PASS_MATERIAL_RIGGED,
- PASS_MATERIAL_ALPHA,
+ PASS_MATERIAL_ALPHA,
PASS_MATERIAL_ALPHA_RIGGED,
- PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask
+ PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask
PASS_MATERIAL_ALPHA_MASK_RIGGED,
- PASS_MATERIAL_ALPHA_EMISSIVE,
+ PASS_MATERIAL_ALPHA_EMISSIVE,
PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,
- PASS_SPECMAP,
+ PASS_SPECMAP,
PASS_SPECMAP_RIGGED,
- PASS_SPECMAP_BLEND,
+ PASS_SPECMAP_BLEND,
PASS_SPECMAP_BLEND_RIGGED,
- PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map)
+ PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map)
PASS_SPECMAP_MASK_RIGGED,
- PASS_SPECMAP_EMISSIVE,
+ PASS_SPECMAP_EMISSIVE,
PASS_SPECMAP_EMISSIVE_RIGGED,
- PASS_NORMMAP,
+ PASS_NORMMAP,
PASS_NORMMAP_RIGGED,
- PASS_NORMMAP_BLEND,
+ PASS_NORMMAP_BLEND,
PASS_NORMMAP_BLEND_RIGGED,
- PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map
+ PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map
PASS_NORMMAP_MASK_RIGGED,
- PASS_NORMMAP_EMISSIVE,
+ PASS_NORMMAP_EMISSIVE,
PASS_NORMMAP_EMISSIVE_RIGGED,
- PASS_NORMSPEC,
+ PASS_NORMSPEC,
PASS_NORMSPEC_RIGGED,
- PASS_NORMSPEC_BLEND,
+ PASS_NORMSPEC_BLEND,
PASS_NORMSPEC_BLEND_RIGGED,
- PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map
+ PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map
PASS_NORMSPEC_MASK_RIGGED,
- PASS_NORMSPEC_EMISSIVE,
+ PASS_NORMSPEC_EMISSIVE,
PASS_NORMSPEC_EMISSIVE_RIGGED,
- PASS_GLOW,
+ PASS_GLOW,
PASS_GLOW_RIGGED,
PASS_GLTF_GLOW,
PASS_GLTF_GLOW_RIGGED,
- PASS_ALPHA,
+ PASS_ALPHA,
PASS_ALPHA_RIGGED,
- PASS_ALPHA_MASK,
+ PASS_ALPHA_MASK,
PASS_ALPHA_MASK_RIGGED,
- PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright
+ PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright
PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
- PASS_ALPHA_INVISIBLE,
+ PASS_ALPHA_INVISIBLE,
PASS_ALPHA_INVISIBLE_RIGGED,
PASS_GLTF_PBR,
PASS_GLTF_PBR_RIGGED,
PASS_GLTF_PBR_ALPHA_MASK,
PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
- NUM_RENDER_TYPES,
- };
+ NUM_RENDER_TYPES,
+ };
- #ifdef LL_PROFILER_ENABLE_RENDER_DOC
+ #ifdef LL_PROFILER_ENABLE_RENDER_DOC
static inline const char* lookupPassName(U32 pass)
{
switch (pass)
@@ -336,22 +336,22 @@ public:
default:
return "Unknown pass";
}
- }
- #else
+ }
+ #else
static inline const char* lookupPass(U32 pass) { return ""; }
- #endif
-
- LLRenderPass(const U32 type);
- virtual ~LLRenderPass();
- /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
- LLViewerTexture* getTexture() { return NULL; }
- BOOL isDead() { return FALSE; }
- void resetDrawOrders() { }
-
- static void applyModelMatrix(const LLDrawInfo& params);
- // Use before a non-GLTF batch if it is interleaved with GLTF batches that share the same shader
- static void resetGLTFTextureTransform();
- void pushBatches(U32 type, bool texture = true, bool batch_textures = false);
+ #endif
+
+ LLRenderPass(const U32 type);
+ virtual ~LLRenderPass();
+ /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
+ LLViewerTexture* getTexture() { return NULL; }
+ BOOL isDead() { return FALSE; }
+ void resetDrawOrders() { }
+
+ static void applyModelMatrix(const LLDrawInfo& params);
+ // For rendering that doesn't use LLDrawInfo for some reason
+ static void applyModelMatrix(const LLMatrix4* model_matrix);
+ void pushBatches(U32 type, bool texture = true, bool batch_textures = false);
void pushUntexturedBatches(U32 type);
void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false);
@@ -374,109 +374,109 @@ public:
void pushUntexturedRiggedGLTFBatches(U32 type);
// push a single GLTF draw call
- void pushGLTFBatch(LLDrawInfo& params);
- void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
- void pushUntexturedGLTFBatch(LLDrawInfo& params);
- void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+ static void pushGLTFBatch(LLDrawInfo& params);
+ static void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+ static void pushUntexturedGLTFBatch(LLDrawInfo& params);
+ static void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
- void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
+ void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
- void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
+ void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
void pushUntexturedBatch(LLDrawInfo& params);
- void pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
+ void pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
static bool uploadMatrixPalette(LLDrawInfo& params);
static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo);
- virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true);
+ virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true);
virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture = true);
};
class LLFacePool : public LLDrawPool
{
public:
- typedef std::vector<LLFace*> face_array_t;
-
- enum
- {
- SHADER_LEVEL_SCATTERING = 2
- };
+ typedef std::vector<LLFace*> face_array_t;
+
+ enum
+ {
+ SHADER_LEVEL_SCATTERING = 2
+ };
public:
- LLFacePool(const U32 type);
- virtual ~LLFacePool();
-
- BOOL isDead() { return mReferences.empty(); }
-
- virtual LLViewerTexture *getTexture();
- virtual void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
-
- virtual void enqueue(LLFace *face);
- virtual BOOL addFace(LLFace *face);
- virtual BOOL removeFace(LLFace *face);
+ LLFacePool(const U32 type);
+ virtual ~LLFacePool();
+
+ BOOL isDead() { return mReferences.empty(); }
+
+ virtual LLViewerTexture *getTexture();
+ virtual void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
- virtual BOOL verify() const; // Verify that all data in the draw pool is correct!
+ virtual void enqueue(LLFace *face);
+ virtual BOOL addFace(LLFace *face);
+ virtual BOOL removeFace(LLFace *face);
- virtual void resetDrawOrders();
- void resetAll();
+ virtual BOOL verify() const; // Verify that all data in the draw pool is correct!
+
+ virtual void resetDrawOrders();
+ void resetAll();
- void destroy();
+ void destroy();
- void buildEdges();
+ void buildEdges();
- void addFaceReference(LLFace *facep);
- void removeFaceReference(LLFace *facep);
+ void addFaceReference(LLFace *facep);
+ void removeFaceReference(LLFace *facep);
- void printDebugInfo() const;
-
- BOOL isFacePool() { return TRUE; }
+ void printDebugInfo() const;
+
+ BOOL isFacePool() { return TRUE; }
// call drawIndexed on every draw face
void pushFaceGeometry();
- friend class LLFace;
- friend class LLPipeline;
+ friend class LLFace;
+ friend class LLPipeline;
public:
- face_array_t mDrawFace;
- face_array_t mMoveFace;
- face_array_t mReferences;
+ face_array_t mDrawFace;
+ face_array_t mMoveFace;
+ face_array_t mReferences;
public:
- class LLOverrideFaceColor
- {
- public:
- LLOverrideFaceColor(LLDrawPool* pool)
- : mOverride(sOverrideFaceColor), mPool(pool)
- {
- sOverrideFaceColor = TRUE;
- }
- LLOverrideFaceColor(LLDrawPool* pool, const LLColor4& color)
- : mOverride(sOverrideFaceColor), mPool(pool)
- {
- sOverrideFaceColor = TRUE;
- setColor(color);
- }
- LLOverrideFaceColor(LLDrawPool* pool, const LLColor4U& color)
- : mOverride(sOverrideFaceColor), mPool(pool)
- {
- sOverrideFaceColor = TRUE;
- setColor(color);
- }
- LLOverrideFaceColor(LLDrawPool* pool, F32 r, F32 g, F32 b, F32 a)
- : mOverride(sOverrideFaceColor), mPool(pool)
- {
- sOverrideFaceColor = TRUE;
- setColor(r, g, b, a);
- }
- ~LLOverrideFaceColor()
- {
- sOverrideFaceColor = mOverride;
- }
- void setColor(const LLColor4& color);
- void setColor(const LLColor4U& color);
- void setColor(F32 r, F32 g, F32 b, F32 a);
- BOOL mOverride;
- LLDrawPool* mPool;
- static BOOL sOverrideFaceColor;
- };
+ class LLOverrideFaceColor
+ {
+ public:
+ LLOverrideFaceColor(LLDrawPool* pool)
+ : mOverride(sOverrideFaceColor), mPool(pool)
+ {
+ sOverrideFaceColor = TRUE;
+ }
+ LLOverrideFaceColor(LLDrawPool* pool, const LLColor4& color)
+ : mOverride(sOverrideFaceColor), mPool(pool)
+ {
+ sOverrideFaceColor = TRUE;
+ setColor(color);
+ }
+ LLOverrideFaceColor(LLDrawPool* pool, const LLColor4U& color)
+ : mOverride(sOverrideFaceColor), mPool(pool)
+ {
+ sOverrideFaceColor = TRUE;
+ setColor(color);
+ }
+ LLOverrideFaceColor(LLDrawPool* pool, F32 r, F32 g, F32 b, F32 a)
+ : mOverride(sOverrideFaceColor), mPool(pool)
+ {
+ sOverrideFaceColor = TRUE;
+ setColor(r, g, b, a);
+ }
+ ~LLOverrideFaceColor()
+ {
+ sOverrideFaceColor = mOverride;
+ }
+ void setColor(const LLColor4& color);
+ void setColor(const LLColor4U& color);
+ void setColor(F32 r, F32 g, F32 b, F32 a);
+ BOOL mOverride;
+ LLDrawPool* mPool;
+ static BOOL sOverrideFaceColor;
+ };
};
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index bc177ddd99..fd27010877 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolalpha.cpp
* @brief LLDrawPoolAlpha class implementation
*
* $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$
*/
@@ -39,7 +39,7 @@
#include "lldrawable.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "llviewertexturelist.h" // For debugging
+#include "llviewertexturelist.h" // For debugging
#include "llviewerobjectlist.h" // For debugging
#include "llviewerwindow.h"
#include "pipeline.h"
@@ -49,6 +49,7 @@
#include "llspatialpartition.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
+#include "gltfscenemanager.h"
#include "llenvironment.h"
@@ -65,11 +66,11 @@ static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
- LLRenderPass(type), target_shader(NULL),
- mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
- mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
+ LLRenderPass(type), target_shader(NULL),
+ mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
+ mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
{
-
+
}
LLDrawPoolAlpha::~LLDrawPoolAlpha()
@@ -79,15 +80,15 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
void LLDrawPoolAlpha::prerender()
{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
// TODO: is this even necessay? These are probably set to never discard
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
}
-S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
-{
+S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
+{
return 1;
}
@@ -107,7 +108,7 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
{
shader->mCanBindFast = false;
}
-
+
shader->bind();
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
@@ -138,15 +139,15 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
- {
+ {
prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
extern BOOL gCubeSnapshot;
-void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
-{
+void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
if (LLPipeline::isWaterClip() && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
@@ -176,13 +177,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
prepare_alpha_shader(pbr_emissive_shader, true, false, water_sign);
- fullbright_shader =
+ fullbright_shader =
(LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
(LLPipeline::sRenderingHUDs) ? &gHUDFullbrightAlphaMaskAlphaProgram :
&gDeferredFullbrightAlphaMaskAlphaProgram;
prepare_alpha_shader(fullbright_shader, true, true, water_sign);
- simple_shader =
+ simple_shader =
(LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sRenderingHUDs) ? &gHUDAlphaProgram :
&gDeferredAlphaProgram;
@@ -195,8 +196,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
prepare_alpha_shader(&materialShader[i], false, true, water_sign);
}
- pbr_shader =
- (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram :
+ pbr_shader =
+ (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram :
&gDeferredPBRAlphaProgram;
prepare_alpha_shader(pbr_shader, false, true, water_sign);
@@ -216,7 +217,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
// final pass, render to depth for depth of field effects
if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot && !LLPipeline::sRenderingHUDs && getType() == LLDrawPool::POOL_ALPHA_POST_WATER)
- {
+ {
//update depth buffer sampler
simple_shader = fullbright_shader = &gDeferredFullbrightAlphaMaskProgram;
@@ -228,7 +229,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
// We don't want the nearly invisible objects to cause of DoF effects
- renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
true); // <--- discard mostly transparent faces
gGL.setColorMask(true, false);
@@ -260,6 +261,15 @@ void LLDrawPoolAlpha::forwardRender(bool rigged)
mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+ if (rigged)
+ { // draw GLTF scene to depth buffer before rigged alpha
+ gPipeline.bindDeferredShader(gDeferredPBRAlphaProgram);
+ LL::GLTFSceneManager::instance().render(false, false);
+
+ gPipeline.bindDeferredShader(*gDeferredPBRAlphaProgram.mRiggedVariant);
+ LL::GLTFSceneManager::instance().render(false, true);
+ }
+
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
// We don't want the nearly invisible objects to cause of DoF effects
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, false, rigged);
@@ -277,8 +287,8 @@ void LLDrawPoolAlpha::forwardRender(bool rigged)
void LLDrawPoolAlpha::renderDebugAlpha()
{
- if (sShowDebugAlpha)
- {
+ if (sShowDebugAlpha)
+ {
gHighlightProgram.bind();
gGL.diffuseColor4f(1, 0, 0, 1);
gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::getSmokeImage());
@@ -286,19 +296,19 @@ void LLDrawPoolAlpha::renderDebugAlpha()
renderAlphaHighlight();
- pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK);
- pushUntexturedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE);
+ pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE);
- // Material alpha mask
- gGL.diffuseColor4f(0, 0, 1, 1);
- pushUntexturedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK);
- pushUntexturedBatches(LLRenderPass::PASS_NORMMAP_MASK);
- pushUntexturedBatches(LLRenderPass::PASS_SPECMAP_MASK);
- pushUntexturedBatches(LLRenderPass::PASS_NORMSPEC_MASK);
- pushUntexturedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ // Material alpha mask
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ pushUntexturedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_NORMMAP_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_SPECMAP_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_NORMSPEC_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
pushUntexturedBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK);
- gGL.diffuseColor4f(0, 1, 0, 1);
+ gGL.diffuseColor4f(0, 1, 0, 1);
pushUntexturedBatches(LLRenderPass::PASS_INVISIBLE);
gHighlightProgram.mRiggedVariant->bind();
@@ -319,7 +329,7 @@ void LLDrawPoolAlpha::renderDebugAlpha()
gGL.diffuseColor4f(0, 1, 0, 1);
pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, false);
LLGLSLShader::sCurBoundShaderPtr->unbind();
- }
+ }
}
void LLDrawPoolAlpha::renderAlphaHighlight()
@@ -338,7 +348,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight()
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
- LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
+ LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
@@ -393,7 +403,7 @@ inline void Draw(LLDrawInfo* draw, U32 mask)
{
draw->mVertexBuffer->setBuffer();
LLRenderPass::applyModelMatrix(*draw);
- draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
@@ -475,19 +485,19 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
{
if (tex_setup)
- {
- gGL.getTexUnit(0)->activate();
+ {
+ gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
void LLDrawPoolAlpha::drawEmissive(LLDrawInfo* draw)
{
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
draw->mVertexBuffer->setBuffer();
- draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
@@ -551,7 +561,7 @@ void LLDrawPoolAlpha::renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissiv
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter
pbr_emissive_shader->bind(true);
-
+
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
@@ -578,7 +588,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
BOOL initialized_lighting = FALSE;
- BOOL light_enabled = TRUE;
+ BOOL light_enabled = TRUE;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
@@ -597,7 +607,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
begin = gPipeline.beginAlphaGroups();
end = gPipeline.endAlphaGroups();
}
-
+
LLEnvironment& env = LLEnvironment::instance();
F32 water_height = env.getWaterHeight();
@@ -609,15 +619,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("renderAlpha - group");
- LLSpatialGroup* group = *i;
- llassert(group);
- llassert(group->getSpatialPartition());
+ LLSpatialGroup* group = *i;
+ llassert(group);
+ llassert(group->getSpatialPartition());
- if (group->getSpatialPartition()->mRenderByGroup &&
- !group->isDead())
- {
+ if (group->getSpatialPartition()->mRenderByGroup &&
+ !group->isDead())
+ {
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents();
@@ -650,17 +660,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
pbr_emissives.resize(0);
pbr_rigged_emissives.resize(0);
- bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
- || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
+ bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
+ || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
- bool disable_cull = is_particle_or_hud_particle;
- LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
+ bool disable_cull = is_particle_or_hud_particle;
+ LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
- LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
+ LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
- {
- LLDrawInfo& params = **k;
+ {
+ LLDrawInfo& params = **k;
if ((bool)params.mAvatar != rigged)
{
continue;
@@ -671,7 +681,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
- LLGLTFMaterial *gltf_mat = params.mGLTFMaterial;
+ LLGLTFMaterial *gltf_mat = params.mGLTFMaterial;
LLGLDisable cull_face(gltf_mat && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0);
@@ -793,8 +803,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
bool tex_setup = TexSetup(&params, (mat != nullptr));
- {
- gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+ {
+ gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
bool reset_minimum_alpha = false;
if (!LLPipeline::sImpostorRender &&
@@ -807,17 +817,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
params.mVertexBuffer->setBuffer();
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ stop_glerror();
if (reset_minimum_alpha)
{
current_shader->setMinimumAlpha(MINIMUM_ALPHA);
}
- }
+ }
- // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
- if (getType() != LLDrawPool::POOL_ALPHA_PRE_WATER &&
- params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
- {
+ // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
+ if (getType() != LLDrawPool::POOL_ALPHA_PRE_WATER &&
+ params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
+ {
if (params.mAvatar != nullptr)
{
if (params.mGLTFMaterial.isNull())
@@ -840,16 +851,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
pbr_emissives.push_back(&params);
}
}
- }
-
- if (tex_setup)
- {
- gGL.getTexUnit(0)->activate();
+ }
+
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
- }
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ }
// render emissive faces into alpha channel for bloom effects
if (!depth_only)
@@ -898,17 +909,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
lastShader->bind();
}
}
- }
- }
+ }
+ }
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- if (!light_enabled)
- {
- gPipeline.enableLightsDynamic();
- }
+ if (!light_enabled)
+ {
+ gPipeline.enableLightsDynamic();
+ }
}
bool LLDrawPoolAlpha::uploadMatrixPalette(const LLDrawInfo& params)
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 99d0853ff1..24df11c158 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolbump.cpp
* @brief LLDrawPoolBump class implementation
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -54,7 +54,7 @@
//#include "../tools/imdebug/imdebug.h"
// static
-LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
+LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
LLRenderTarget LLBumpImageList::sRenderTarget;
@@ -84,13 +84,13 @@ static BOOL shiny = FALSE;
#define LL_BUMPLIST_MULTITHREADED 1
-// static
+// static
void LLStandardBumpmap::shutdown()
{
- LLStandardBumpmap::destroyGL();
+ LLStandardBumpmap::destroyGL();
}
-// static
+// static
void LLStandardBumpmap::restoreGL()
{
addstandard();
@@ -99,12 +99,12 @@ void LLStandardBumpmap::restoreGL()
// static
void LLStandardBumpmap::addstandard()
{
- if(!gTextureList.isInitialized())
- {
- //Note: loading pre-configuration sometimes triggers this call.
- //But it is safe to return here because bump images will be reloaded during initialization later.
- return ;
- }
+ if(!gTextureList.isInitialized())
+ {
+ //Note: loading pre-configuration sometimes triggers this call.
+ //But it is safe to return here because bump images will be reloaded during initialization later.
+ return ;
+ }
if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED)
{
@@ -112,99 +112,99 @@ void LLStandardBumpmap::addstandard()
return;
}
- // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps.
- //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 );
- clear();
- LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL;
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS
-
- std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" );
- LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/
- if( !file )
- {
- LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL;
- return;
- }
-
- S32 file_version = 0;
-
- S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version );
- if( fields_read != 1 )
- {
- LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL;
- return;
- }
-
- if( file_version > STD_BUMP_LATEST_FILE_VERSION )
- {
- LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL;
- return;
- }
-
- while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) )
- {
- // *NOTE: This buffer size is hard coded into scanf() below.
- char label[2048] = ""; /* Flawfinder: ignore */
- char bump_image_id[2048] = ""; /* Flawfinder: ignore */
- fields_read = fscanf( /* Flawfinder: ignore */
- file, "\n%2047s %2047s", label, bump_image_id);
- if( EOF == fields_read )
- {
- break;
- }
- if( fields_read != 2 )
- {
- LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL;
- return;
- }
-
-// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL;
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
- LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ;
- LLStandardBumpmap::sStandardBumpmapCount++;
- }
-
- fclose( file );
+ // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps.
+ //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 );
+ clear();
+ LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS
+
+ std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" );
+ LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/
+ if( !file )
+ {
+ LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL;
+ return;
+ }
+
+ S32 file_version = 0;
+
+ S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version );
+ if( fields_read != 1 )
+ {
+ LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL;
+ return;
+ }
+
+ if( file_version > STD_BUMP_LATEST_FILE_VERSION )
+ {
+ LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL;
+ return;
+ }
+
+ while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) )
+ {
+ // *NOTE: This buffer size is hard coded into scanf() below.
+ char label[2048] = ""; /* Flawfinder: ignore */
+ char bump_image_id[2048] = ""; /* Flawfinder: ignore */
+ fields_read = fscanf( /* Flawfinder: ignore */
+ file, "\n%2047s %2047s", label, bump_image_id);
+ if( EOF == fields_read )
+ {
+ break;
+ }
+ if( fields_read != 2 )
+ {
+ LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL;
+ return;
+ }
+
+// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
+ LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ;
+ LLStandardBumpmap::sStandardBumpmapCount++;
+ }
+
+ fclose( file );
}
// static
void LLStandardBumpmap::clear()
{
- LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL;
- for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ )
- {
- gStandardBumpmapList[i].mLabel.assign("");
- gStandardBumpmapList[i].mImage = NULL;
- }
- sStandardBumpmapCount = 0;
+ LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL;
+ for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ )
+ {
+ gStandardBumpmapList[i].mLabel.assign("");
+ gStandardBumpmapList[i].mImage = NULL;
+ }
+ sStandardBumpmapCount = 0;
}
// static
void LLStandardBumpmap::destroyGL()
{
- clear();
+ clear();
}
////////////////////////////////////////////////////////////////
-LLDrawPoolBump::LLDrawPoolBump()
+LLDrawPoolBump::LLDrawPoolBump()
: LLRenderPass(LLDrawPool::POOL_BUMP)
{
- shiny = FALSE;
+ shiny = FALSE;
}
void LLDrawPoolBump::prerender()
{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
// static
@@ -217,88 +217,88 @@ S32 LLDrawPoolBump::numBumpPasses()
//static
void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map && !LLPipeline::sReflectionProbesEnabled )
- {
- if (shader )
- {
- LLMatrix4 mat;
- mat.initRows(LLVector4(gGLModelView+0),
- LLVector4(gGLModelView+4),
- LLVector4(gGLModelView+8),
- LLVector4(gGLModelView+12));
- LLVector3 vec = LLVector3(gShinyOrigin) * mat;
- LLVector4 vec4(vec, gShinyOrigin.mV[3]);
- shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
- if (shader_level > 1)
- {
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled )
+ {
+ if (shader )
+ {
+ LLMatrix4 mat;
+ mat.initRows(LLVector4(gGLModelView+0),
+ LLVector4(gGLModelView+4),
+ LLVector4(gGLModelView+8),
+ LLVector4(gGLModelView+12));
+ LLVector3 vec = LLVector3(gShinyOrigin) * mat;
+ LLVector4 vec4(vec, gShinyOrigin.mV[3]);
+ shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
+ if (shader_level > 1)
+ {
cube_map->setMatrix(1);
- // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
- // the cube map in the one pass shiny shaders
- cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- cube_map->enableTexture(cube_channel);
- diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- else
- {
+ // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
+ // the cube map in the one pass shiny shaders
+ cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ cube_map->enableTexture(cube_channel);
+ diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+ else
+ {
cube_map->setMatrix(0);
- cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- diffuse_channel = -1;
- cube_map->enable(cube_channel);
- }
- gGL.getTexUnit(cube_channel)->bind(cube_map);
- gGL.getTexUnit(0)->activate();
- }
- else
- {
- cube_channel = 0;
- diffuse_channel = -1;
- gGL.getTexUnit(0)->disable();
- cube_map->enable(0);
+ cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ diffuse_channel = -1;
+ cube_map->enable(cube_channel);
+ }
+ gGL.getTexUnit(cube_channel)->bind(cube_map);
+ gGL.getTexUnit(0)->activate();
+ }
+ else
+ {
+ cube_channel = 0;
+ diffuse_channel = -1;
+ gGL.getTexUnit(0)->disable();
+ cube_map->enable(0);
cube_map->setMatrix(0);
- gGL.getTexUnit(0)->bind(cube_map);
- }
- }
+ gGL.getTexUnit(0)->bind(cube_map);
+ }
+ }
}
//static
void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map && !LLPipeline::sReflectionProbesEnabled)
- {
- if (shader_level > 1)
- {
- shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
-
- if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
- {
- if (diffuse_channel != 0)
- {
- shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- }
- }
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled)
+ {
+ if (shader_level > 1)
+ {
+ shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+ {
+ if (diffuse_channel != 0)
+ {
+ shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+ }
+ }
// Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
// MAINT-755
- cube_map->disable();
+ cube_map->disable();
cube_map->restoreMatrix();
- }
+ }
}
void LLDrawPoolBump::beginFullbrightShiny()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
+
+ sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
- sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
-
- // Second pass: environment map
- shader = &gDeferredFullbrightShinyProgram;
+ // Second pass: environment map
+ shader = &gDeferredFullbrightShinyProgram;
if (LLPipeline::sRenderingHUDs)
{
shader = &gHUDFullbrightShinyProgram;
}
-
+
if (mRigged)
{
llassert(shader->mRiggedVariant);
@@ -312,32 +312,32 @@ void LLDrawPoolBump::beginFullbrightShiny()
gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap);
}
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
-
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+
if (cube_map && !LLPipeline::sReflectionProbesEnabled)
{
- // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
- // the cube map in the one pass shiny shaders
- gGL.getTexUnit(1)->disable();
- cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- cube_map->enableTexture(cube_channel);
- diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
- gGL.getTexUnit(cube_channel)->bind(cube_map);
- gGL.getTexUnit(0)->activate();
+ // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
+ // the cube map in the one pass shiny shaders
+ gGL.getTexUnit(1)->disable();
+ cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ cube_map->enableTexture(cube_channel);
+ diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+ gGL.getTexUnit(cube_channel)->bind(cube_map);
+ gGL.getTexUnit(0)->activate();
}
- {
- LLMatrix4 mat;
- mat.initRows(LLVector4(gGLModelView+0),
- LLVector4(gGLModelView+4),
- LLVector4(gGLModelView+8),
- LLVector4(gGLModelView+12));
- shader->bind();
-
- LLVector3 vec = LLVector3(gShinyOrigin) * mat;
- LLVector4 vec4(vec, gShinyOrigin.mV[3]);
- shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
+ {
+ LLMatrix4 mat;
+ mat.initRows(LLVector4(gGLModelView+0),
+ LLVector4(gGLModelView+4),
+ LLVector4(gGLModelView+8),
+ LLVector4(gGLModelView+12));
+ shader->bind();
+
+ LLVector3 vec = LLVector3(gShinyOrigin) * mat;
+ LLVector4 vec4(vec, gShinyOrigin.mV[3]);
+ shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
if (LLPipeline::sReflectionProbesEnabled)
{
@@ -347,25 +347,25 @@ void LLDrawPoolBump::beginFullbrightShiny()
{
gPipeline.setEnvMat(*shader);
}
- }
+ }
- if (mShaderLevel > 1)
- { //indexed texture rendering, channel 0 is always diffuse
- diffuse_channel = 0;
- }
+ if (mShaderLevel > 1)
+ { //indexed texture rendering, channel 0 is always diffuse
+ diffuse_channel = 0;
+ }
- shiny = TRUE;
+ shiny = TRUE;
}
void LLDrawPoolBump::renderFullbrightShiny()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- {
- LLGLEnable blend_enable(GL_BLEND);
+ {
+ LLGLEnable blend_enable(GL_BLEND);
- if (mShaderLevel > 1)
- {
+ if (mShaderLevel > 1)
+ {
if (mRigged)
{
LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, true, true);
@@ -374,9 +374,9 @@ void LLDrawPoolBump::renderFullbrightShiny()
{
LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, true, true);
}
- }
- else
- {
+ }
+ else
+ {
if (mRigged)
{
LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED);
@@ -385,125 +385,125 @@ void LLDrawPoolBump::renderFullbrightShiny()
{
LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY);
}
- }
- }
+ }
+ }
}
void LLDrawPoolBump::endFullbrightShiny()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map && !LLPipeline::sReflectionProbesEnabled )
- {
- cube_map->disable();
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled )
+ {
+ cube_map->disable();
if (shader->mFeatures.hasReflectionProbes)
{
gPipeline.unbindReflectionProbes(*shader);
}
- shader->unbind();
- }
-
- diffuse_channel = -1;
- cube_channel = 0;
- shiny = FALSE;
+ shader->unbind();
+ }
+
+ diffuse_channel = -1;
+ cube_channel = 0;
+ shiny = FALSE;
}
void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true)
-{
- LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
-
- for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
- {
- LLDrawInfo& params = **k;
-
- applyModelMatrix(params);
-
- params.mVertexBuffer->setBuffer();
- params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
- }
+{
+ LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
+
+ for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
+ {
+ LLDrawInfo& params = **k;
+
+ applyModelMatrix(params);
+
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ }
}
// static
BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
{
- U8 bump_code = params.mBump;
+ U8 bump_code = params.mBump;
- return bindBumpMap(bump_code, params.mTexture, channel);
+ return bindBumpMap(bump_code, params.mTexture, channel);
}
//static
BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel)
{
- const LLTextureEntry* te = face->getTextureEntry();
- if (te)
- {
- U8 bump_code = te->getBumpmap();
- return bindBumpMap(bump_code, face->getTexture(), channel);
- }
-
- return FALSE;
+ const LLTextureEntry* te = face->getTextureEntry();
+ if (te)
+ {
+ U8 bump_code = te->getBumpmap();
+ return bindBumpMap(bump_code, face->getTexture(), channel);
+ }
+
+ return FALSE;
}
//static
BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- //Note: texture atlas does not support bump texture now.
- LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ;
- if(!tex)
- {
- //if the texture is not a fetched texture
- return FALSE;
- }
-
- LLViewerTexture* bump = NULL;
-
- switch( bump_code )
- {
- case BE_NO_BUMP:
- break;
- case BE_BRIGHTNESS:
- case BE_DARKNESS:
- bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
- break;
-
- default:
- if( bump_code < LLStandardBumpmap::sStandardBumpmapCount )
- {
- bump = gStandardBumpmapList[bump_code].mImage;
- gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize());
- }
- break;
- }
-
- if (bump)
- {
- if (channel == -2)
- {
- gGL.getTexUnit(1)->bindFast(bump);
- gGL.getTexUnit(0)->bindFast(bump);
- }
- else
- {
+ //Note: texture atlas does not support bump texture now.
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ;
+ if(!tex)
+ {
+ //if the texture is not a fetched texture
+ return FALSE;
+ }
+
+ LLViewerTexture* bump = NULL;
+
+ switch( bump_code )
+ {
+ case BE_NO_BUMP:
+ break;
+ case BE_BRIGHTNESS:
+ case BE_DARKNESS:
+ bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
+ break;
+
+ default:
+ if( bump_code < LLStandardBumpmap::sStandardBumpmapCount )
+ {
+ bump = gStandardBumpmapList[bump_code].mImage;
+ gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize());
+ }
+ break;
+ }
+
+ if (bump)
+ {
+ if (channel == -2)
+ {
+ gGL.getTexUnit(1)->bindFast(bump);
+ gGL.getTexUnit(0)->bindFast(bump);
+ }
+ else
+ {
// NOTE: do not use bindFast here (see SL-16222)
gGL.getTexUnit(channel)->bind(bump);
- }
+ }
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
//static
void LLDrawPoolBump::beginBump()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- sVertexMask = VERTEX_MASK_BUMP;
- // Optional second pass: emboss bump map
- stop_glerror();
+ sVertexMask = VERTEX_MASK_BUMP;
+ // Optional second pass: emboss bump map
+ stop_glerror();
shader = &gObjectBumpProgram;
@@ -515,21 +515,21 @@ void LLDrawPoolBump::beginBump()
shader->bind();
- gGL.setSceneBlendType(LLRender::BT_MULT_X2);
- stop_glerror();
+ gGL.setSceneBlendType(LLRender::BT_MULT_X2);
+ stop_glerror();
}
//static
void LLDrawPoolBump::renderBump(U32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
- LLGLEnable blend(GL_BLEND);
- gGL.diffuseColor4f(1,1,1,1);
- /// Get rid of z-fighting with non-bump pass.
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- pushBumpBatches(pass);
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+ LLGLEnable blend(GL_BLEND);
+ gGL.diffuseColor4f(1,1,1,1);
+ /// Get rid of z-fighting with non-bump pass.
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
+ pushBumpBatches(pass);
}
//static
@@ -541,7 +541,7 @@ void LLDrawPoolBump::endBump(U32 pass)
}
S32 LLDrawPoolBump::getNumDeferredPasses()
-{
+{
return 1;
}
@@ -604,7 +604,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
-
+
S32 num_passes = LLPipeline::sRenderingHUDs ? 1 : 2; // skip rigged pass when rendering HUDs
for (int i = 0; i < num_passes; ++i)
@@ -632,126 +632,127 @@ void LLDrawPoolBump::renderPostDeferred(S32 pass)
void LLBumpImageList::init()
{
- llassert( mBrightnessEntries.size() == 0 );
- llassert( mDarknessEntries.size() == 0 );
+ llassert( mBrightnessEntries.size() == 0 );
+ llassert( mDarknessEntries.size() == 0 );
- LLStandardBumpmap::restoreGL();
+ LLStandardBumpmap::restoreGL();
sMainQueue = LL::WorkQueue::getInstance("mainloop");
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
}
void LLBumpImageList::clear()
{
- LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL;
- // these will be re-populated on-demand
- mBrightnessEntries.clear();
- mDarknessEntries.clear();
+ LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL;
+ // these will be re-populated on-demand
+ mBrightnessEntries.clear();
+ mDarknessEntries.clear();
sRenderTarget.release();
- LLStandardBumpmap::clear();
+ LLStandardBumpmap::clear();
}
void LLBumpImageList::shutdown()
{
- clear();
- LLStandardBumpmap::shutdown();
+ clear();
+ LLStandardBumpmap::shutdown();
}
void LLBumpImageList::destroyGL()
{
- clear();
- LLStandardBumpmap::destroyGL();
+ clear();
+ LLStandardBumpmap::destroyGL();
}
void LLBumpImageList::restoreGL()
{
- if(!gTextureList.isInitialized())
- {
- //safe to return here because bump images will be reloaded during initialization later.
- return ;
- }
-
- LLStandardBumpmap::restoreGL();
- // Images will be recreated as they are needed.
+ if(!gTextureList.isInitialized())
+ {
+ //safe to return here because bump images will be reloaded during initialization later.
+ return ;
+ }
+
+ LLStandardBumpmap::restoreGL();
+ // Images will be recreated as they are needed.
}
LLBumpImageList::~LLBumpImageList()
{
- // Shutdown should have already been called.
- llassert( mBrightnessEntries.size() == 0 );
- llassert( mDarknessEntries.size() == 0 );
+ // Shutdown should have already been called.
+ llassert( mBrightnessEntries.size() == 0 );
+ llassert( mDarknessEntries.size() == 0 );
}
// Note: Does nothing for entries in gStandardBumpmapList that are not actually standard bump images (e.g. none, brightness, and darkness)
void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size)
{
- bump &= TEM_BUMP_MASK;
- LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage;
- if( bump_image )
- {
- bump_image->addTextureStats(virtual_size);
- }
+ bump &= TEM_BUMP_MASK;
+ LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage;
+ if( bump_image )
+ {
+ bump_image->addTextureStats(virtual_size);
+ }
}
void LLBumpImageList::updateImages()
-{
- for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); )
- {
- bump_image_map_t::iterator curiter = iter++;
- LLViewerTexture* image = curiter->second;
- if( image )
- {
- BOOL destroy = TRUE;
- if( image->hasGLTexture())
- {
- if( image->getBoundRecently() )
- {
- destroy = FALSE;
- }
- else
- {
- image->destroyGLTexture();
- }
- }
-
- if( destroy )
- {
- //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL;
- mBrightnessEntries.erase(curiter); // deletes the image thanks to reference counting
- }
- }
- }
-
- for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )
- {
- bump_image_map_t::iterator curiter = iter++;
- LLViewerTexture* image = curiter->second;
- if( image )
- {
- BOOL destroy = TRUE;
- if( image->hasGLTexture())
- {
- if( image->getBoundRecently() )
- {
- destroy = FALSE;
- }
- else
- {
- image->destroyGLTexture();
- }
- }
-
- if( destroy )
- {
- //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;;
- mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting
- }
- }
- }
+{
+ for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); )
+ {
+ LLViewerTexture* image = iter->second;
+ if( image )
+ {
+ BOOL destroy = TRUE;
+ if( image->hasGLTexture())
+ {
+ if( image->getBoundRecently() )
+ {
+ destroy = FALSE;
+ }
+ else
+ {
+ image->destroyGLTexture();
+ }
+ }
+
+ if( destroy )
+ {
+ //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL;
+ iter = mBrightnessEntries.erase(iter); // deletes the image thanks to reference counting
+ continue;
+ }
+ }
+ ++iter;
+ }
+
+ for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )
+ {
+ bump_image_map_t::iterator curiter = iter++;
+ LLViewerTexture* image = curiter->second;
+ if( image )
+ {
+ BOOL destroy = TRUE;
+ if( image->hasGLTexture())
+ {
+ if( image->getBoundRecently() )
+ {
+ destroy = FALSE;
+ }
+ else
+ {
+ image->destroyGLTexture();
+ }
+ }
+
+ if( destroy )
+ {
+ //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;;
+ mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting
+ }
+ }
+ }
}
@@ -759,52 +760,52 @@ void LLBumpImageList::updateImages()
LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code )
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
-
- LLViewerTexture* bump = NULL;
-
- bump_image_map_t* entries_list = NULL;
- void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
-
- switch( bump_code )
- {
- case BE_BRIGHTNESS:
- entries_list = &mBrightnessEntries;
- callback_func = LLBumpImageList::onSourceBrightnessLoaded;
- break;
- case BE_DARKNESS:
- entries_list = &mDarknessEntries;
- callback_func = LLBumpImageList::onSourceDarknessLoaded;
- break;
- default:
- llassert(0);
- return NULL;
- }
-
- bump_image_map_t::iterator iter = entries_list->find(src_image->getID());
- if (iter != entries_list->end() && iter->second.notNull())
- {
- bump = iter->second;
- }
- else
- {
- (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE );
- bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
- }
-
- if (!src_image->hasCallbacks())
- { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again
- if (src_image->getWidth() != bump->getWidth() ||
- src_image->getHeight() != bump->getHeight())// ||
- //(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
- {
- src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
- src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
- src_image->forceToSaveRawImage(0) ;
- }
- }
-
- return bump;
+ llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
+
+ LLViewerTexture* bump = NULL;
+
+ bump_image_map_t* entries_list = NULL;
+ void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
+
+ switch( bump_code )
+ {
+ case BE_BRIGHTNESS:
+ entries_list = &mBrightnessEntries;
+ callback_func = LLBumpImageList::onSourceBrightnessLoaded;
+ break;
+ case BE_DARKNESS:
+ entries_list = &mDarknessEntries;
+ callback_func = LLBumpImageList::onSourceDarknessLoaded;
+ break;
+ default:
+ llassert(0);
+ return NULL;
+ }
+
+ bump_image_map_t::iterator iter = entries_list->find(src_image->getID());
+ if (iter != entries_list->end() && iter->second.notNull())
+ {
+ bump = iter->second;
+ }
+ else
+ {
+ (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE );
+ bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
+ }
+
+ if (!src_image->hasCallbacks())
+ { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again
+ if (src_image->getWidth() != bump->getWidth() ||
+ src_image->getHeight() != bump->getHeight())// ||
+ //(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
+ {
+ src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
+ src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
+ src_image->forceToSaveRawImage(0) ;
+ }
+ }
+
+ return bump;
}
@@ -812,94 +813,94 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLUUID* source_asset_id = (LLUUID*)userdata;
- LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
- if( final )
- {
- delete source_asset_id;
- }
+ LLUUID* source_asset_id = (LLUUID*)userdata;
+ LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
+ if( final )
+ {
+ delete source_asset_id;
+ }
}
// static
void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
- LLUUID* source_asset_id = (LLUUID*)userdata;
- LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS );
- if( final )
- {
- delete source_asset_id;
- }
+ LLUUID* source_asset_id = (LLUUID*)userdata;
+ LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS );
+ if( final )
+ {
+ delete source_asset_id;
+ }
}
void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
- if (success && LLPipeline::sRenderDeferred)
- {
+ if (success && LLPipeline::sRenderDeferred)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4);
- {
- generateNormalMapFromAlpha(src, nrm_image);
- }
- src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
- {
- src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
- }
- }
+ LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4);
+ {
+ generateNormalMapFromAlpha(src, nrm_image);
+ }
+ src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
+ {
+ src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
+ }
+ }
}
void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image)
{
- U8* nrm_data = nrm_image->getData();
- S32 resX = src->getWidth();
- S32 resY = src->getHeight();
-
- U8* src_data = src->getData();
-
- S32 src_cmp = src->getComponents();
-
- F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale");
-
- U32 idx = 0;
- //generate normal map from pseudo-heightfield
- for (S32 j = 0; j < resY; ++j)
- {
- for (S32 i = 0; i < resX; ++i)
- {
- S32 rX = (i+1)%resX;
- S32 rY = (j+1)%resY;
- S32 lX = (i-1)%resX;
- S32 lY = (j-1)%resY;
-
- if (lX < 0)
- {
- lX += resX;
- }
- if (lY < 0)
- {
- lY += resY;
- }
-
- F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1];
-
- LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH);
- LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH);
- LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH);
- LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH);
-
- LLVector3 norm = right%down + down%left + left%up + up%right;
-
- norm.normVec();
-
- norm *= 0.5f;
- norm += LLVector3(0.5f,0.5f,0.5f);
-
- idx = (j*resX+i)*4;
- nrm_data[idx+0]= (U8) (norm.mV[0]*255);
- nrm_data[idx+1]= (U8) (norm.mV[1]*255);
- nrm_data[idx+2]= (U8) (norm.mV[2]*255);
- nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1];
- }
- }
+ U8* nrm_data = nrm_image->getData();
+ S32 resX = src->getWidth();
+ S32 resY = src->getHeight();
+
+ U8* src_data = src->getData();
+
+ S32 src_cmp = src->getComponents();
+
+ F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale");
+
+ U32 idx = 0;
+ //generate normal map from pseudo-heightfield
+ for (S32 j = 0; j < resY; ++j)
+ {
+ for (S32 i = 0; i < resX; ++i)
+ {
+ S32 rX = (i+1)%resX;
+ S32 rY = (j+1)%resY;
+ S32 lX = (i-1)%resX;
+ S32 lY = (j-1)%resY;
+
+ if (lX < 0)
+ {
+ lX += resX;
+ }
+ if (lY < 0)
+ {
+ lY += resY;
+ }
+
+ F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1];
+
+ LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH);
+ LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH);
+ LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH);
+ LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH);
+
+ LLVector3 norm = right%down + down%left + left%up + up%right;
+
+ norm.normVec();
+
+ norm *= 0.5f;
+ norm += LLVector3(0.5f,0.5f,0.5f);
+
+ idx = (j*resX+i)*4;
+ nrm_data[idx+0]= (U8) (norm.mV[0]*255);
+ nrm_data[idx+1]= (U8) (norm.mV[1]*255);
+ nrm_data[idx+2]= (U8) (norm.mV[2]*255);
+ nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1];
+ }
+ }
}
// static
@@ -907,147 +908,147 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
{
LL_PROFILE_ZONE_SCOPED;
- if( success )
- {
+ if( success )
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
- bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
-
- {
- if (iter == entries_list.end() ||
- iter->second.isNull() ||
- iter->second->getWidth() != src->getWidth() ||
- iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
- { //make sure an entry exists for this image
- entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE);
- iter = entries_list.find(src_vi->getID());
- }
- }
-
- if (iter->second->getWidth() != src->getWidth() ||
- iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
- {
- LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1);
- U8* dst_data = dst_image->getData();
- S32 dst_data_size = dst_image->getDataSize();
-
- U8* src_data = src->getData();
- S32 src_data_size = src->getDataSize();
-
- S32 src_components = src->getComponents();
-
- // Convert to luminance and then scale and bias that to get ready for
- // embossed bump mapping. (0-255 maps to 127-255)
-
- // Convert to fixed point so we don't have to worry about precision/clamping.
- const S32 FIXED_PT = 8;
- const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT));
- const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT));
- const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT));
-
- S32 minimum = 255;
- S32 maximum = 0;
-
- switch( src_components )
- {
- case 1:
- case 2:
- {
- if( src_data_size == dst_data_size * src_components )
- {
- for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
- {
- dst_data[i] = src_data[j];
- if( dst_data[i] < minimum )
- {
- minimum = dst_data[i];
- }
- if( dst_data[i] > maximum )
- {
- maximum = dst_data[i];
- }
- }
- }
- else
- {
- llassert(0);
- dst_image->clear();
- }
- }
- break;
- case 3:
- case 4:
- {
- if( src_data_size == dst_data_size * src_components )
- {
- for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
- {
- // RGB to luminance
- dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT;
- //llassert( dst_data[i] <= 255 );true because it's 8bit
- if( dst_data[i] < minimum )
- {
- minimum = dst_data[i];
- }
- if( dst_data[i] > maximum )
- {
- maximum = dst_data[i];
- }
- }
- }
- else
- {
- llassert(0);
- dst_image->clear();
- }
- }
- break;
- default:
- llassert(0);
- dst_image->clear();
- break;
- }
-
- if( maximum > minimum )
- {
- U8 bias_and_scale_lut[256];
- F32 twice_one_over_range = 2.f / (maximum - minimum);
- S32 i;
-
- const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes.
- if (BE_DARKNESS == bump_code)
- {
- for( i = minimum; i <= maximum; i++ )
- {
- F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f;
- bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
- }
- }
- else
- {
- for( i = minimum; i <= maximum; i++ )
- {
- F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f;
- bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
- }
- }
-
- for( i = 0; i < dst_data_size; i++ )
- {
- dst_data[i] = bias_and_scale_lut[dst_data[i]];
- }
- }
-
- //---------------------------------------------------
- // immediately assign bump to a smart pointer in case some local smart pointer
- // accidentally releases it.
+ bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
+ bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
+
+ {
+ if (iter == entries_list.end() ||
+ iter->second.isNull() ||
+ iter->second->getWidth() != src->getWidth() ||
+ iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
+ { //make sure an entry exists for this image
+ entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE);
+ iter = entries_list.find(src_vi->getID());
+ }
+ }
+
+ if (iter->second->getWidth() != src->getWidth() ||
+ iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
+ {
+ LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1);
+ U8* dst_data = dst_image->getData();
+ S32 dst_data_size = dst_image->getDataSize();
+
+ U8* src_data = src->getData();
+ S32 src_data_size = src->getDataSize();
+
+ S32 src_components = src->getComponents();
+
+ // Convert to luminance and then scale and bias that to get ready for
+ // embossed bump mapping. (0-255 maps to 127-255)
+
+ // Convert to fixed point so we don't have to worry about precision/clamping.
+ const S32 FIXED_PT = 8;
+ const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT));
+ const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT));
+ const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT));
+
+ S32 minimum = 255;
+ S32 maximum = 0;
+
+ switch( src_components )
+ {
+ case 1:
+ case 2:
+ {
+ if( src_data_size == dst_data_size * src_components )
+ {
+ for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
+ {
+ dst_data[i] = src_data[j];
+ if( dst_data[i] < minimum )
+ {
+ minimum = dst_data[i];
+ }
+ if( dst_data[i] > maximum )
+ {
+ maximum = dst_data[i];
+ }
+ }
+ }
+ else
+ {
+ llassert(0);
+ dst_image->clear();
+ }
+ }
+ break;
+ case 3:
+ case 4:
+ {
+ if( src_data_size == dst_data_size * src_components )
+ {
+ for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
+ {
+ // RGB to luminance
+ dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT;
+ //llassert( dst_data[i] <= 255 );true because it's 8bit
+ if( dst_data[i] < minimum )
+ {
+ minimum = dst_data[i];
+ }
+ if( dst_data[i] > maximum )
+ {
+ maximum = dst_data[i];
+ }
+ }
+ }
+ else
+ {
+ llassert(0);
+ dst_image->clear();
+ }
+ }
+ break;
+ default:
+ llassert(0);
+ dst_image->clear();
+ break;
+ }
+
+ if( maximum > minimum )
+ {
+ U8 bias_and_scale_lut[256];
+ F32 twice_one_over_range = 2.f / (maximum - minimum);
+ S32 i;
+
+ const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes.
+ if (BE_DARKNESS == bump_code)
+ {
+ for( i = minimum; i <= maximum; i++ )
+ {
+ F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f;
+ bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
+ }
+ }
+ else
+ {
+ for( i = minimum; i <= maximum; i++ )
+ {
+ F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f;
+ bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128));
+ }
+ }
+
+ for( i = 0; i < dst_data_size; i++ )
+ {
+ dst_data[i] = bias_and_scale_lut[dst_data[i]];
+ }
+ }
+
+ //---------------------------------------------------
+ // immediately assign bump to a smart pointer in case some local smart pointer
+ // accidentally releases it.
LLPointer<LLViewerTexture> bump = iter->second;
- if (!LLPipeline::sRenderDeferred)
- {
- bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
+ if (!LLPipeline::sRenderDeferred)
+ {
+ bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
#if LL_BUMPLIST_MULTITHREADED
auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr;
@@ -1073,9 +1074,9 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
{
bump->createGLTexture(0, dst_image);
}
- }
- else
- { //convert to normal map
+ }
+ else
+ { //convert to normal map
LL_PROFILE_ZONE_NAMED("bil - create normal map");
LLImageGL* img = bump->getGLTexture();
LLImageRaw* dst_ptr = dst_image.get();
@@ -1179,16 +1180,16 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
- }
+ }
- iter->second = bump; // derefs (and deletes) old image
- //---------------------------------------------------
- }
- }
+ iter->second = bump; // derefs (and deletes) old image
+ //---------------------------------------------------
+ }
+ }
}
void LLDrawPoolBump::pushBumpBatches(U32 type)
-{
+{
LLVOAvatar* avatar = nullptr;
U64 skin = 0;
@@ -1200,12 +1201,12 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
- {
- LLDrawInfo& params = **i;
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
- if (LLDrawPoolBump::bindBumpMap(params))
- {
+ if (LLDrawPoolBump::bindBumpMap(params))
+ {
if (mRigged)
{
if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
@@ -1221,80 +1222,80 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)
}
}
}
- pushBumpBatch(params, false);
- }
- }
+ pushBumpBatch(params, false);
+ }
+ }
}
void LLRenderPass::pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- applyModelMatrix(params);
-
- bool tex_setup = false;
-
- if (batch_textures && params.mTextureList.size() > 1)
- {
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
- {
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTextureMatrix)
- {
- if (shiny)
- {
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- }
- else
- {
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
-
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
-
- tex_setup = true;
- }
-
- if (shiny && mShaderLevel > 1 && texture)
- {
- if (params.mTexture.notNull())
- {
- gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
- }
- else
- {
- gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
- }
-
- params.mVertexBuffer->setBuffer();
- params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ applyModelMatrix(params);
+
+ bool tex_setup = false;
+
+ if (batch_textures && params.mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ {
+ if (params.mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
+ {
+ if (shiny)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+
+ tex_setup = true;
+ }
+
+ if (shiny && mShaderLevel > 1 && texture)
+ {
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
+
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
if (tex_setup)
- {
- if (shiny)
- {
- gGL.getTexUnit(0)->activate();
- }
- else
- {
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- }
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
+ {
+ if (shiny)
+ {
+ gGL.getTexUnit(0)->activate();
+ }
+ else
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ }
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
index 303afa51db..a32b6b1687 100644
--- a/indra/newview/lldrawpoolpbropaque.cpp
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolpbropaque.cpp
* @brief LLDrawPoolGLTFPBR class implementation
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -30,6 +30,7 @@
#include "lldrawpoolpbropaque.h"
#include "llviewershadermgr.h"
#include "pipeline.h"
+#include "gltfscenemanager.h"
LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR(U32 type) :
LLRenderPass(type)
@@ -54,9 +55,13 @@ void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)
llassert(!LLPipeline::sRenderingHUDs);
gDeferredPBROpaqueProgram.bind();
+
+ LL::GLTFSceneManager::instance().renderOpaque();
pushGLTFBatches(mRenderType);
+
gDeferredPBROpaqueProgram.bind(true);
+ LL::GLTFSceneManager::instance().render(true, true);
pushRiggedGLTFBatches(mRenderType + 1);
}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index c86c4b3472..c5932a6ad9 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolterrain.cpp
* @brief LLDrawPoolTerrain class implementation
*
* $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$
*/
@@ -39,7 +39,7 @@
#include "llsurfacepatch.h"
#include "llviewerregion.h"
#include "llvlcomposition.h"
-#include "llviewerparcelmgr.h" // for gRenderParcelOwnership
+#include "llviewerparcelmgr.h" // for gRenderParcelOwnership
#include "llviewerparceloverlay.h"
#include "llvosurfacepatch.h"
#include "llviewercamera.h"
@@ -54,121 +54,109 @@
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
-S32 LLDrawPoolTerrain::sDetailMode = 1;
+S32 LLDrawPoolTerrain::sPBRDetailMode = 0;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
+F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE;
static LLGLSLShader* sShader = NULL;
static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow");
LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
- LLFacePool(POOL_TERRAIN),
- mTexturep(texturep)
+ LLFacePool(POOL_TERRAIN),
+ mTexturep(texturep)
{
- // Hack!
- sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
- sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
- mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD);
-
- //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
- mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD_2D);
-
- //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
- m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
-
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ // Hack!
+ sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
+ sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale");
+ sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail");
+ mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD);
+
+ //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
+ mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD_2D);
+
+ //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
+ m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
+
+ //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
LLDrawPoolTerrain::~LLDrawPoolTerrain()
{
- llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
+ llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
}
-U32 LLDrawPoolTerrain::getVertexDataMask()
-{
- if (LLPipeline::sShadowRender)
- {
- return LLVertexBuffer::MAP_VERTEX;
- }
- else if (LLGLSLShader::sCurBoundShaderPtr)
- {
- return VERTEX_DATA_MASK & ~(LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_TEXCOORD3);
- }
- else
- {
- return VERTEX_DATA_MASK;
- }
+U32 LLDrawPoolTerrain::getVertexDataMask()
+{
+ if (LLPipeline::sShadowRender)
+ {
+ return LLVertexBuffer::MAP_VERTEX;
+ }
+ else if (LLGLSLShader::sCurBoundShaderPtr)
+ {
+ return VERTEX_DATA_MASK & ~(LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_TEXCOORD3);
+ }
+ else
+ {
+ return VERTEX_DATA_MASK;
+ }
}
void LLDrawPoolTerrain::prerender()
{
- sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
-}
-
-//static
-S32 LLDrawPoolTerrain::getDetailMode()
-{
- return sDetailMode;
+ sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail");
}
void LLDrawPoolTerrain::boostTerrainDetailTextures()
{
// Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- for (S32 i = 0; i < 4; i++)
- {
- compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- compp->mDetailTextures[i]->addTextureStats(1024.f * 1024.f);
- }
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ compp->boost();
}
void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
- LLFacePool::beginRenderPass(pass);
-
- sShader = &gDeferredTerrainProgram;
-
- sShader->bind();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
+ LLFacePool::beginRenderPass(pass);
}
void LLDrawPoolTerrain::endDeferredPass(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
- LLFacePool::endRenderPass(pass);
- sShader->unbind();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
+ LLFacePool::endRenderPass(pass);
+ sShader->unbind();
}
void LLDrawPoolTerrain::renderDeferred(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
- if (mDrawFace.empty())
- {
- return;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
+ if (mDrawFace.empty())
+ {
+ return;
+ }
boostTerrainDetailTextures();
- renderFullShader();
+ renderFullShader();
- // Special-case for land ownership feedback
- if (gSavedSettings.getBOOL("ShowParcelOwners"))
- {
- hilightParcelOwners();
- }
+ // Special-case for land ownership feedback
+ if (gSavedSettings.getBOOL("ShowParcelOwners"))
+ {
+ hilightParcelOwners();
+ }
}
void LLDrawPoolTerrain::beginShadowPass(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
- LLFacePool::beginRenderPass(pass);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gDeferredShadowProgram.bind();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
+ LLFacePool::beginRenderPass(pass);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gDeferredShadowProgram.bind();
LLEnvironment& environment = LLEnvironment::instance();
gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -176,614 +164,858 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass)
void LLDrawPoolTerrain::endShadowPass(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
- LLFacePool::endRenderPass(pass);
- gDeferredShadowProgram.unbind();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
+ LLFacePool::endRenderPass(pass);
+ gDeferredShadowProgram.unbind();
}
void LLDrawPoolTerrain::renderShadow(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
- if (mDrawFace.empty())
- {
- return;
- }
- //LLGLEnable offset(GL_POLYGON_OFFSET);
- //glCullFace(GL_FRONT);
- drawLoop();
- //glCullFace(GL_BACK);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN);
+ if (mDrawFace.empty())
+ {
+ return;
+ }
+ //LLGLEnable offset(GL_POLYGON_OFFSET);
+ //glCullFace(GL_FRONT);
+ drawLoop();
+ //glCullFace(GL_BACK);
}
void LLDrawPoolTerrain::drawLoop()
{
- if (!mDrawFace.empty())
- {
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *facep = *iter;
-
- LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);
-
- if (model_matrix != gGLLastMatrix)
- {
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
- gGLLastMatrix = model_matrix;
- gGL.loadMatrix(gGLModelView);
- if (model_matrix)
- {
- gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
- }
- gPipeline.mMatrixOpCount++;
- }
-
- facep->renderIndexed();
- }
- }
+ if (!mDrawFace.empty())
+ {
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ LLFace *facep = *iter;
+
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix);
+
+ facep->renderIndexed();
+ }
+ }
}
void LLDrawPoolTerrain::renderFullShader()
{
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
-
- LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
- F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
- F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
-
- LLVector4 tp0, tp1;
-
- tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
- tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
+ const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false);
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::Type::TEXTURE);
+
+ if (use_textures)
+ {
+ // Use textures
+ sShader = &gDeferredTerrainProgram;
+ sShader->bind();
+ renderFullShaderTextures();
+ }
+ else
+ {
+ // Use materials
+ sShader = &gDeferredPBRTerrainProgram;
+ sShader->bind();
+ renderFullShaderPBR(use_local_materials);
+ }
+}
- //
- // detail texture 0
- //
- S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
- gGL.getTexUnit(detail0)->bind(detail_texture0p);
+void LLDrawPoolTerrain::renderFullShaderTextures()
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
+
+ LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
+ F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
+ F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
+
+ LLVector4 tp0, tp1;
+
+ tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
+ tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
+
+ //
+ // detail texture 0
+ //
+ S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
+ gGL.getTexUnit(detail0)->bind(detail_texture0p);
gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail0)->activate();
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader);
+ gGL.getTexUnit(detail0)->activate();
- shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
- shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- //
- // detail texture 1
- //
- S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
- gGL.getTexUnit(detail1)->bind(detail_texture1p);
- gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail1)->activate();
-
- // detail texture 2
- //
- S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
- gGL.getTexUnit(detail2)->bind(detail_texture2p);
+ //
+ // detail texture 1
+ //
+ S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
+ gGL.getTexUnit(detail1)->bind(detail_texture1p);
+ gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail1)->activate();
+
+ // detail texture 2
+ //
+ S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
+ gGL.getTexUnit(detail2)->bind(detail_texture2p);
gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail2)->activate();
-
-
- // detail texture 3
- //
- S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
- gGL.getTexUnit(detail3)->bind(detail_texture3p);
- gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail3)->activate();
-
- //
- // Alpha Ramp
- //
- S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
- gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
+ gGL.getTexUnit(detail2)->activate();
+
+
+ // detail texture 3
+ //
+ S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
+ gGL.getTexUnit(detail3)->bind(detail_texture3p);
+ gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail3)->activate();
+
+ //
+ // Alpha Ramp
+ //
+ S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
+ gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- // GL_BLEND disabled by default
- drawLoop();
-
- // Disable multitexture
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
-
- gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(alpha_ramp)->disable();
- gGL.getTexUnit(alpha_ramp)->activate();
-
- gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail3)->disable();
- gGL.getTexUnit(detail3)->activate();
-
- gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail2)->disable();
- gGL.getTexUnit(detail2)->activate();
-
- gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail1)->disable();
- gGL.getTexUnit(detail1)->activate();
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail0)->activate();
+ // GL_BLEND disabled by default
+ drawLoop();
+
+ // Disable multitexture
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
+
+ gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(alpha_ramp)->disable();
+ gGL.getTexUnit(alpha_ramp)->activate();
+
+ gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail3)->disable();
+ gGL.getTexUnit(detail3)->activate();
+
+ gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail2)->disable();
+ gGL.getTexUnit(detail2)->activate();
+
+ gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail1)->disable();
+ gGL.getTexUnit(detail1)->activate();
+
+ //----------------------------------------------------------------------------
+ // Restore Texture Unit 0 defaults
+
+ gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail0)->activate();
}
-void LLDrawPoolTerrain::hilightParcelOwners()
+// *TODO: Investigate use of bindFast for PBR terrain textures
+void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
{
- { //use fullbright shader for highlighting
- LLGLSLShader* old_shader = sShader;
- sShader->unbind();
- sShader = &gDeferredHighlightProgram;
- sShader->bind();
- gGL.diffuseColor4f(1, 1, 1, 1);
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- renderOwnership();
- sShader = old_shader;
- sShader->bind();
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ LLPointer<LLFetchedGLTFMaterial> (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+
+ constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT;
+#ifdef SHOW_ASSERT
+ constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
+ llassert(shader_material_count == terrain_material_count);
+#endif
+
+ if (local_materials)
+ {
+ // Override region terrain with the global local override terrain
+ fetched_materials = &gLocalTerrainMaterials.mDetailMaterials;
}
+ const LLGLTFMaterial* materials[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ materials[i] = (*fetched_materials)[i].get();
+ if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; }
+ }
+
+ S32 detail_basecolor[terrain_material_count];
+ S32 detail_normal[terrain_material_count];
+ S32 detail_metalrough[terrain_material_count];
+ S32 detail_emissive[terrain_material_count];
+
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ LLViewerTexture* detail_basecolor_texturep = nullptr;
+ LLViewerTexture* detail_normal_texturep = nullptr;
+ LLViewerTexture* detail_metalrough_texturep = nullptr;
+ LLViewerTexture* detail_emissive_texturep = nullptr;
+
+ const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
+ if (fetched_material)
+ {
+ detail_basecolor_texturep = fetched_material->mBaseColorTexture;
+ detail_normal_texturep = fetched_material->mNormalTexture;
+ detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture;
+ detail_emissive_texturep = fetched_material->mEmissiveTexture;
+ }
+
+ detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ if (detail_basecolor_texturep)
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_basecolor[i])->activate();
-}
-
-void LLDrawPoolTerrain::renderFull4TU()
-{
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
-
- LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
- F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
- F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
-
- LLVector4 tp0, tp1;
-
- tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
- tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
-
- gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
-
- //----------------------------------------------------------------------------
- // Pass 1/1
-
- //
- // Stage 0: detail texture 0
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(detail_texture0p);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 1: Generate alpha ramp for detail0/detail1 transition
- //
-
- gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- //
- // Stage 2: Interpolate detail1 with existing based on ramp
- //
- gGL.getTexUnit(2)->bind(detail_texture1p);
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- //
- // Stage 3: Modulate with primary (vertex) color for lighting
- //
- gGL.getTexUnit(3)->bind(detail_texture1p);
- gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->activate();
-
- gGL.getTexUnit(0)->activate();
-
- // GL_BLEND disabled by default
- drawLoop();
-
- //----------------------------------------------------------------------------
- // Second pass
-
- // Stage 0: Write detail3 into base
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(detail_texture3p);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ if (detail_normal_texturep)
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+ gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_normal[i])->activate();
+ }
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ if (detail_metalrough_texturep)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+ }
- //
- // Stage 1: Generate alpha ramp for detail2/detail3 transition
- //
- gGL.getTexUnit(1)->bind(m2DAlphaRampImagep);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
+ if (detail_emissive_texturep)
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
+ }
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+
+ // *TODO: Figure out why this offset is *sometimes* producing seams at the
+ // region edge, and repeat jumps when crossing regions, when
+ // RenderTerrainPBRScale is not a factor of the region scale.
+ LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
+ F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale;
+ F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale;
+
+ LLGLTFMaterial::TextureTransform base_color_transform;
+ base_color_transform.mScale = LLVector2(sPBRDetailScale, sPBRDetailScale);
+ base_color_transform.mOffset = LLVector2(offset_x, offset_y);
+ F32 base_color_packed[8];
+ base_color_transform.getPacked(base_color_packed);
+ // *HACK: Use the same texture repeats for all PBR terrain textures for now
+ // (not compliant with KHR texture transform spec)
+ shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed);
- //
- // Stage 2: Interpolate detail2 with existing based on ramp
- //
- gGL.getTexUnit(2)->bind(detail_texture2p);
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->activate();
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+ //
+ // Alpha Ramp
+ //
+ S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
+ gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
+ gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
//
- // Stage 3: Generate alpha ramp for detail1/detail2 transition
+ // GLTF uniforms
//
- gGL.getTexUnit(3)->bind(m2DAlphaRampImagep);
- gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->activate();
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(0)->activate();
+ LLColor4 base_color_factors[terrain_material_count];
+ F32 metallic_factors[terrain_material_count];
+ F32 roughness_factors[terrain_material_count];
+ LLColor3 emissive_colors[terrain_material_count];
+ F32 minimum_alphas[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
{
- LLGLEnable blend(GL_BLEND);
- drawLoop();
+ const LLGLTFMaterial* material = materials[i];
+
+ base_color_factors[i] = material->mBaseColor;
+ metallic_factors[i] = material->mMetallicFactor;
+ roughness_factors[i] = material->mRoughnessFactor;
+ emissive_colors[i] = material->mEmissiveColor;
+ // glTF 2.0 Specification 3.9.4. Alpha Coverage
+ // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
+ // Use 0 here due to GLTF terrain blending (LLGLTFMaterial::bind uses
+ // -1 for easier debugging)
+ F32 min_alpha = -0.0f;
+ if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ // dividing the alpha cutoff by transparency here allows the shader to compare against
+ // the alpha value of the texture without needing the transparency value
+ min_alpha = material->mAlphaCutoff/material->mBaseColor.mV[3];
+ }
+ minimum_alphas[i] = min_alpha;
}
-
- LLVertexBuffer::unbind();
- // Disable multitexture
- gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->disable();
- gGL.getTexUnit(3)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
- gGL.getTexUnit(2)->activate();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- // Restore blend state
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-}
-
-void LLDrawPoolTerrain::renderFull2TU()
-{
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
-
- LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
- F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
- F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
-
- LLVector4 tp0, tp1;
-
- tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
- tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
-
- gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
-
- //----------------------------------------------------------------------------
- // Pass 1/4
-
- //
- // Stage 0: Render detail 0 into base
- //
- gGL.getTexUnit(0)->bind(detail_texture0p);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- drawLoop();
-
- //----------------------------------------------------------------------------
- // Pass 2/4
-
- //
- // Stage 0: Generate alpha ramp for detail0/detail1 transition
- //
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
-
- //
- // Stage 1: Write detail1
- //
- gGL.getTexUnit(1)->bind(detail_texture1p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- gGL.getTexUnit(0)->activate();
+ shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
- LLGLEnable blend(GL_BLEND);
- drawLoop();
+ shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
+ shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
}
- //----------------------------------------------------------------------------
- // Pass 3/4
-
- //
- // Stage 0: Generate alpha ramp for detail1/detail2 transition
- //
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
-
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- //
- // Stage 1: Write detail2
- //
- gGL.getTexUnit(1)->bind(detail_texture2p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
- LLGLEnable blend(GL_BLEND);
- drawLoop();
+ shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors);
}
+ shader->uniform4f(LLShaderMgr::TERRAIN_MINIMUM_ALPHAS, minimum_alphas[0], minimum_alphas[1], minimum_alphas[2], minimum_alphas[3]);
- //----------------------------------------------------------------------------
- // Pass 4/4
+ // GL_BLEND disabled by default
+ drawLoop();
- //
- // Stage 0: Generate alpha ramp for detail2/detail3 transition
- //
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
- // Set the texture matrix
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- // Stage 1: Write detail3
- gGL.getTexUnit(1)->bind(detail_texture3p);
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->activate();
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-
- gGL.getTexUnit(0)->activate();
- {
- LLGLEnable blend(GL_BLEND);
- drawLoop();
- }
+ // Disable multitexture
- // Restore blend state
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
- // Disable multitexture
+ gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(alpha_ramp)->disable();
+ gGL.getTexUnit(alpha_ramp)->activate();
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
+ }
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail_basecolor[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_basecolor[i])->disable();
+ gGL.getTexUnit(detail_basecolor[i])->activate();
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_normal[i])->disable();
+ gGL.getTexUnit(detail_normal[i])->activate();
+ }
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_metalrough[i])->disable();
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+ }
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_emissive[i])->disable();
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
+ }
}
-
-void LLDrawPoolTerrain::renderSimple()
+void LLDrawPoolTerrain::hilightParcelOwners()
{
- LLVector4 tp0, tp1;
-
- //----------------------------------------------------------------------------
- // Pass 1/1
-
- // Stage 0: Base terrain texture pass
- mTexturep->addTextureStats(1024.f*1024.f);
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->bind(mTexturep);
-
- LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
- F32 tscale = 1.f/256.f;
- tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
- tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
+ { //use fullbright shader for highlighting
+ LLGLSLShader* old_shader = sShader;
+ sShader->unbind();
+ sShader = &gDeferredHighlightProgram;
+ sShader->bind();
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
+ renderOwnership();
+ sShader = old_shader;
+ sShader->bind();
+ }
+
+}
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
+void LLDrawPoolTerrain::renderFull4TU()
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
+
+ LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
+ F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
+ F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
+
+ LLVector4 tp0, tp1;
+
+ tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
+ tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
+
+ gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
+
+ //----------------------------------------------------------------------------
+ // Pass 1/1
+
+ //
+ // Stage 0: detail texture 0
+ //
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->bind(detail_texture0p);
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ //
+ // Stage 1: Generate alpha ramp for detail0/detail1 transition
+ //
+
+ gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->activate();
+
+ //
+ // Stage 2: Interpolate detail1 with existing based on ramp
+ //
+ gGL.getTexUnit(2)->bind(detail_texture1p);
+ gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->activate();
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ //
+ // Stage 3: Modulate with primary (vertex) color for lighting
+ //
+ gGL.getTexUnit(3)->bind(detail_texture1p);
+ gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(3)->activate();
+
+ gGL.getTexUnit(0)->activate();
+
+ // GL_BLEND disabled by default
+ drawLoop();
+
+ //----------------------------------------------------------------------------
+ // Second pass
+
+ // Stage 0: Write detail3 into base
+ //
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->bind(detail_texture3p);
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ //
+ // Stage 1: Generate alpha ramp for detail2/detail3 transition
+ //
+ gGL.getTexUnit(1)->bind(m2DAlphaRampImagep);
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->activate();
+
+ // Set the texture matrix
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.translatef(-2.f, 0.f, 0.f);
+
+ //
+ // Stage 2: Interpolate detail2 with existing based on ramp
+ //
+ gGL.getTexUnit(2)->bind(detail_texture2p);
+ gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->activate();
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ //
+ // Stage 3: Generate alpha ramp for detail1/detail2 transition
+ //
+ gGL.getTexUnit(3)->bind(m2DAlphaRampImagep);
+ gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(3)->activate();
+
+ // Set the texture matrix
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.translatef(-1.f, 0.f, 0.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ gGL.getTexUnit(0)->activate();
+ {
+ LLGLEnable blend(GL_BLEND);
+ drawLoop();
+ }
+
+ LLVertexBuffer::unbind();
+ // Disable multitexture
+ gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(3)->disable();
+ gGL.getTexUnit(3)->activate();
+
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->disable();
+ gGL.getTexUnit(2)->activate();
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->disable();
+ gGL.getTexUnit(1)->activate();
+
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ // Restore blend state
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ //----------------------------------------------------------------------------
+ // Restore Texture Unit 0 defaults
+
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+}
- drawLoop();
+void LLDrawPoolTerrain::renderFull2TU()
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
+
+ LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
+ F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
+ F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale;
+
+ LLVector4 tp0, tp1;
+
+ tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
+ tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
+
+ gGL.blendFunc(LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_SOURCE_ALPHA);
+
+ //----------------------------------------------------------------------------
+ // Pass 1/4
+
+ //
+ // Stage 0: Render detail 0 into base
+ //
+ gGL.getTexUnit(0)->bind(detail_texture0p);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ drawLoop();
+
+ //----------------------------------------------------------------------------
+ // Pass 2/4
+
+ //
+ // Stage 0: Generate alpha ramp for detail0/detail1 transition
+ //
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+
+ //
+ // Stage 1: Write detail1
+ //
+ gGL.getTexUnit(1)->bind(detail_texture1p);
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->activate();
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ gGL.getTexUnit(0)->activate();
+ {
+ LLGLEnable blend(GL_BLEND);
+ drawLoop();
+ }
+ //----------------------------------------------------------------------------
+ // Pass 3/4
+
+ //
+ // Stage 0: Generate alpha ramp for detail1/detail2 transition
+ //
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
+
+ // Set the texture matrix
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.translatef(-1.f, 0.f, 0.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ //
+ // Stage 1: Write detail2
+ //
+ gGL.getTexUnit(1)->bind(detail_texture2p);
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->activate();
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ {
+ LLGLEnable blend(GL_BLEND);
+ drawLoop();
+ }
+
+ //----------------------------------------------------------------------------
+ // Pass 4/4
+
+ //
+ // Stage 0: Generate alpha ramp for detail2/detail3 transition
+ //
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
+ // Set the texture matrix
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.translatef(-2.f, 0.f, 0.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ // Stage 1: Write detail3
+ gGL.getTexUnit(1)->bind(detail_texture3p);
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->activate();
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+
+ gGL.getTexUnit(0)->activate();
+ {
+ LLGLEnable blend(GL_BLEND);
+ drawLoop();
+ }
+
+ // Restore blend state
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ // Disable multitexture
+
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->disable();
+ gGL.getTexUnit(1)->activate();
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ //----------------------------------------------------------------------------
+ // Restore Texture Unit 0 defaults
+
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+}
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+void LLDrawPoolTerrain::renderSimple()
+{
+ LLVector4 tp0, tp1;
+
+ //----------------------------------------------------------------------------
+ // Pass 1/1
+
+ // Stage 0: Base terrain texture pass
+ mTexturep->addTextureStats(1024.f*1024.f);
+
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->bind(mTexturep);
+
+ LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
+ F32 tscale = 1.f/256.f;
+ tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
+ tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
+
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
+
+ drawLoop();
+
+ //----------------------------------------------------------------------------
+ // Restore Texture Unit 0 defaults
+
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
}
//============================================================================
void LLDrawPoolTerrain::renderOwnership()
{
- LLGLSPipelineAlpha gls_pipeline_alpha;
-
- llassert(!mDrawFace.empty());
-
- // Each terrain pool is associated with a single region.
- // We need to peek back into the viewer's data to find out
- // which ownership overlay texture to use.
- LLFace *facep = mDrawFace[0];
- LLDrawable *drawablep = facep->getDrawable();
- const LLViewerObject *objectp = drawablep->getVObj();
- const LLVOSurfacePatch *vo_surface_patchp = (LLVOSurfacePatch *)objectp;
- LLSurfacePatch *surface_patchp = vo_surface_patchp->getPatch();
- LLSurface *surfacep = surface_patchp->getSurface();
- LLViewerRegion *regionp = surfacep->getRegion();
- LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay();
- LLViewerTexture *texturep = overlayp->getTexture();
-
- gGL.getTexUnit(0)->bind(texturep);
-
- // *NOTE: Because the region is 256 meters wide, but has 257 pixels, the
- // texture coordinates for pixel 256x256 is not 1,1. This makes the
- // ownership map not line up with the selection. We address this with
- // a texture matrix multiply.
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.pushMatrix();
-
- const F32 TEXTURE_FUDGE = 257.f / 256.f;
- gGL.scalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *facep = *iter;
- facep->renderIndexed();
- }
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ LLGLSPipelineAlpha gls_pipeline_alpha;
+
+ llassert(!mDrawFace.empty());
+
+ // Each terrain pool is associated with a single region.
+ // We need to peek back into the viewer's data to find out
+ // which ownership overlay texture to use.
+ LLFace *facep = mDrawFace[0];
+ LLDrawable *drawablep = facep->getDrawable();
+ const LLViewerObject *objectp = drawablep->getVObj();
+ const LLVOSurfacePatch *vo_surface_patchp = (LLVOSurfacePatch *)objectp;
+ LLSurfacePatch *surface_patchp = vo_surface_patchp->getPatch();
+ LLSurface *surfacep = surface_patchp->getSurface();
+ LLViewerRegion *regionp = surfacep->getRegion();
+ LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay();
+ LLViewerTexture *texturep = overlayp->getTexture();
+
+ gGL.getTexUnit(0)->bind(texturep);
+
+ // *NOTE: Because the region is 256 meters wide, but has 257 pixels, the
+ // texture coordinates for pixel 256x256 is not 1,1. This makes the
+ // ownership map not line up with the selection. We address this with
+ // a texture matrix multiply.
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.pushMatrix();
+
+ const F32 TEXTURE_FUDGE = 257.f / 256.f;
+ gGL.scalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ LLFace *facep = *iter;
+ facep->renderIndexed();
+ }
+
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
}
void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
- if (tex && textures.find(tex) != textures.end())
- {
- for (std::vector<LLFace*>::iterator iter = mReferences.begin();
- iter != mReferences.end(); iter++)
- {
- LLFace *facep = *iter;
- gPipeline.markTextured(facep->getDrawable());
- }
- }
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
+ if (tex && textures.find(tex) != textures.end())
+ {
+ for (std::vector<LLFace*>::iterator iter = mReferences.begin();
+ iter != mReferences.end(); iter++)
+ {
+ LLFace *facep = *iter;
+ gPipeline.markTextured(facep->getDrawable());
+ }
+ }
}
LLViewerTexture *LLDrawPoolTerrain::getTexture()
{
- return mTexturep;
+ return mTexturep;
}
LLViewerTexture *LLDrawPoolTerrain::getDebugTexture()
{
- return mTexturep;
+ return mTexturep;
}
LLColor3 LLDrawPoolTerrain::getDebugColor() const
{
- return LLColor3(0.f, 0.f, 1.f);
+ return LLColor3(0.f, 0.f, 1.f);
}
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 2c27733f37..13f031c8e7 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolterrain.h
* @brief LLDrawPoolTerrain class definition
*
* $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$
*/
@@ -31,58 +31,60 @@
class LLDrawPoolTerrain : public LLFacePool
{
- LLPointer<LLViewerTexture> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
public:
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TANGENT | // Only PBR terrain uses this currently
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TEXCOORD1
- };
-
- virtual U32 getVertexDataMask();
- static S32 getDetailMode();
+ };
- LLDrawPoolTerrain(LLViewerTexture *texturep);
- virtual ~LLDrawPoolTerrain();
+ virtual U32 getVertexDataMask();
+ LLDrawPoolTerrain(LLViewerTexture *texturep);
+ virtual ~LLDrawPoolTerrain();
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
+ /*virtual*/ S32 getNumDeferredPasses() { return 1; }
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
- /*virtual*/ S32 getNumShadowPasses() { return 1; }
- /*virtual*/ void beginShadowPass(S32 pass);
- /*virtual*/ void endShadowPass(S32 pass);
- /*virtual*/ void renderShadow(S32 pass);
+ /*virtual*/ S32 getNumShadowPasses() { return 1; }
+ /*virtual*/ void beginShadowPass(S32 pass);
+ /*virtual*/ void endShadowPass(S32 pass);
+ /*virtual*/ void renderShadow(S32 pass);
- /*virtual*/ void prerender();
- /*virtual*/ void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
- /*virtual*/ LLViewerTexture *getTexture();
- /*virtual*/ LLViewerTexture *getDebugTexture();
- /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
+ /*virtual*/ void prerender();
+ /*virtual*/ void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
+ /*virtual*/ LLViewerTexture *getTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
+ /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
- LLPointer<LLViewerTexture> mAlphaRampImagep;
- LLPointer<LLViewerTexture> m2DAlphaRampImagep;
- LLPointer<LLViewerTexture> mAlphaNoiseImagep;
+ LLPointer<LLViewerTexture> mAlphaRampImagep;
+ LLPointer<LLViewerTexture> m2DAlphaRampImagep;
+ LLPointer<LLViewerTexture> mAlphaNoiseImagep;
- static S32 sDetailMode;
- static F32 sDetailScale; // meters per texture
+ static S32 sPBRDetailMode;
+ static F32 sDetailScale; // textures per meter
+ static F32 sPBRDetailScale; // textures per meter
protected:
void boostTerrainDetailTextures();
- void renderSimple();
- void renderOwnership();
+ void renderSimple();
+ void renderOwnership();
- void renderFull2TU();
- void renderFull4TU();
- void renderFullShader();
- void drawLoop();
+ void renderFull2TU();
+ void renderFull4TU();
+ void renderFullShader();
+ void renderFullShaderTextures();
+ void renderFullShaderPBR(BOOL local_materials = false);
+ void drawLoop();
private:
- void hilightParcelOwners();
+ void hilightParcelOwners();
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 7b359c757a..50c4a2c1b3 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpooltree.cpp
* @brief LLDrawPoolTree class implementation
*
* $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$
*/
@@ -44,10 +44,10 @@ S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
- LLFacePool(POOL_TREE),
- mTexturep(texturep)
+ LLFacePool(POOL_TREE),
+ mTexturep(texturep)
{
- mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
+ mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
}
//============================================
@@ -55,11 +55,11 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
//============================================
void LLDrawPoolTree::beginDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
-
- shader = &gDeferredTreeProgram;
- shader->bind();
- shader->setMinimumAlpha(0.5f);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
+
+ shader = &gDeferredTreeProgram;
+ shader->bind();
+ shader->setMinimumAlpha(0.5f);
}
void LLDrawPoolTree::renderDeferred(S32 pass)
@@ -85,17 +85,8 @@ void LLDrawPoolTree::renderDeferred(S32 pass)
{
LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
- if (model_matrix != gGLLastMatrix)
- {
- gGLLastMatrix = model_matrix;
- gGL.loadMatrix(gGLModelView);
- if (model_matrix)
- {
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
- gGL.multMatrix((GLfloat*)model_matrix->mMatrix);
- }
- gPipeline.mMatrixOpCount++;
- }
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ LLRenderPass::applyModelMatrix(model_matrix);
buff->setBuffer();
buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts() - 1, buff->getNumIndices(), 0);
@@ -105,9 +96,9 @@ void LLDrawPoolTree::renderDeferred(S32 pass)
void LLDrawPoolTree::endDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
-
- shader->unbind();
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
+
+ shader->unbind();
}
//============================================
@@ -116,49 +107,49 @@ void LLDrawPoolTree::endDeferredPass(S32 pass)
void LLDrawPoolTree::beginShadowPass(S32 pass)
{
LL_PROFILE_ZONE_SCOPED;
-
- glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
- gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
+
+ glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
+ gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
LLEnvironment& environment = LLEnvironment::instance();
- gDeferredTreeShadowProgram.bind();
+ gDeferredTreeShadowProgram.bind();
gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- gDeferredTreeShadowProgram.setMinimumAlpha(0.5f);
+ gDeferredTreeShadowProgram.setMinimumAlpha(0.5f);
}
void LLDrawPoolTree::renderShadow(S32 pass)
{
- renderDeferred(pass);
+ renderDeferred(pass);
}
void LLDrawPoolTree::endShadowPass(S32 pass)
{
LL_PROFILE_ZONE_SCOPED;
-
- glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
- gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
- gDeferredTreeShadowProgram.unbind();
+
+ glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
+ gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
+ gDeferredTreeShadowProgram.unbind();
}
BOOL LLDrawPoolTree::verify() const
{
- return TRUE;
+ return TRUE;
}
LLViewerTexture *LLDrawPoolTree::getTexture()
{
- return mTexturep;
+ return mTexturep;
}
LLViewerTexture *LLDrawPoolTree::getDebugTexture()
{
- return mTexturep;
+ return mTexturep;
}
LLColor3 LLDrawPoolTree::getDebugColor() const
{
- return LLColor3(1.f, 0.f, 1.f);
+ return LLColor3(1.f, 0.f, 1.f);
}
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 11c47e0d3b..68be354533 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldrawpoolwlsky.cpp
* @brief LLDrawPoolWLSky class implementation
*
* $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$
*/
@@ -33,7 +33,7 @@
#include "llimage.h"
#include "llrender.h"
#include "llatmosphere.h"
-#include "llenvironment.h"
+#include "llenvironment.h"
#include "llglslshader.h"
#include "llgl.h"
@@ -44,6 +44,7 @@
#include "llsky.h"
#include "llvowlsky.h"
#include "llsettingsvo.h"
+#include "llviewercontrol.h"
extern BOOL gCubeSnapshot;
@@ -58,7 +59,7 @@ static LLGLSLShader* moon_shader = NULL;
static float sStarTime;
LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
- LLDrawPool(POOL_WL_SKY)
+ LLDrawPool(POOL_WL_SKY)
{
}
@@ -68,13 +69,13 @@ LLDrawPoolWLSky::~LLDrawPoolWLSky()
LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
{
- return NULL;
+ return NULL;
}
void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
{
- sky_shader = &gDeferredWLSkyProgram;
- cloud_shader = &gDeferredWLCloudProgram;
+ sky_shader = &gDeferredWLSkyProgram;
+ cloud_shader = &gDeferredWLCloudProgram;
sun_shader = &gDeferredWLSunProgram;
@@ -97,34 +98,47 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca
llassert_always(NULL != shader);
gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.pushMatrix();
+
+ //chop off translation
+ if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f)
+ {
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f);
+ }
+ else
+ {
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+ }
+
+
+ // the windlight sky dome works most conveniently in a coordinate system
+ // where Y is up, so permute our basis vectors accordingly.
+ gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
+
+ gGL.scalef(0.333f, 0.333f, 0.333f);
+
+ gGL.translatef(0.f,-camHeightLocal, 0.f);
+
+ // Draw WL Sky
+ shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
- //chop off translation
- if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f)
- {
- gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f);
- }
- else
- {
- gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
- }
-
-
- // the windlight sky dome works most conveniently in a coordinate system
- // where Y is up, so permute our basis vectors accordingly.
- gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
+ gSky.mVOWLSkyp->drawDome();
- gGL.scalef(0.333f, 0.333f, 0.333f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+}
- gGL.translatef(0.f,-camHeightLocal, 0.f);
+extern LLPointer<LLImageGL> gEXRImage;
- // Draw WL Sky
- shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
+static bool use_hdri_sky()
+{
+ static LLCachedControl<F32> hdri_split(gSavedSettings, "RenderHDRISplitScreen", 1.f);
+ static LLCachedControl<bool> irradiance_only(gSavedSettings, "RenderHDRIIrradianceOnly", false);
- gSky.mVOWLSkyp->drawDome();
+ return gCubeSnapshot && (!irradiance_only || !gPipeline.mReflectionMapManager.isRadiancePass()) ? gEXRImage.notNull() : // always use HDRI for reflection probes when available
+ gEXRImage.notNull() ? hdri_split > 0.f : // fallback to EEP sky when split screen is zero
+ false; // no HDRI available, always use EEP sky
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
}
void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
@@ -136,11 +150,36 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
- {
- LLGLSPipelineDepthTestSkyBox sky(true, true);
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ {
+ if (use_hdri_sky())
+ {
+ sky_shader = &gEnvironmentMapProgram;
+ sky_shader->bind();
+ S32 idx = sky_shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP);
+ if (idx > -1)
+ {
+ gGL.getTexUnit(idx)->bind(gEXRImage);
+ }
+
+ static LLCachedControl<F32> hdri_exposure(gSavedSettings, "RenderHDRIExposure", 0.0f);
+ static LLCachedControl<F32> hdri_rotation(gSavedSettings, "RenderHDRIRotation", 0.f);
+ static LLCachedControl<F32> hdri_split(gSavedSettings, "RenderHDRISplitScreen", 1.f);
+ static LLStaticHashedString hdri_split_screen("hdri_split_screen");
+
+ LLMatrix3 rot;
+ rot.setRot(0.f, hdri_rotation*DEG_TO_RAD, 0.f);
+
+ sky_shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, powf(2.f, hdri_exposure));
+ sky_shader->uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, GL_FALSE, (F32*) rot.mMatrix);
+ sky_shader->uniform1f(hdri_split_screen, gCubeSnapshot ? 1.f : hdri_split);
+ }
+ else
+ {
+ sky_shader->bind();
+ }
- sky_shader->bind();
+ LLGLSPipelineDepthTestSkyBox sky(true, true);
sky_shader->uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
@@ -172,43 +211,43 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0);
/// Render the skydome
- renderDome(origin, camHeightLocal, sky_shader);
+ renderDome(origin, camHeightLocal, sky_shader);
- sky_shader->unbind();
+ sky_shader->unbind();
}
}
void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
- if (!gSky.mVOSkyp)
+ if (!gSky.mVOSkyp || use_hdri_sky())
{
return;
}
- LLGLSPipelineBlendSkyBox gls_sky(true, false);
+ LLGLSPipelineBlendSkyBox gls_sky(true, false);
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ 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;
- }
+ // If start_brightness is not set, exit
+ if(star_alpha < 0.001f)
+ {
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
+ return;
+ }
- gDeferredStarProgram.bind();
+ 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(0)->bind(tex_a);
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
blend_factor = 0;
}
@@ -224,40 +263,45 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
gGL.getTexUnit(1)->bind(tex_b);
}
- gGL.pushMatrix();
- gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
- gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
+ gGL.pushMatrix();
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+ gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
if (LLPipeline::sReflectionRender)
{
star_alpha = 1.0f;
}
- gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha);
+ gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha);
sStarTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
gDeferredStarProgram.uniform1f(LLShaderMgr::WATER_TIME, sStarTime);
- gSky.mVOWLSkyp->drawStars();
+ gSky.mVOWLSkyp->drawStars();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredStarProgram.unbind();
- gGL.popMatrix();
+ gGL.popMatrix();
}
void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex())
+ if (use_hdri_sky())
{
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ return;
+ }
- LLGLSPipelineBlendSkyBox pipeline(true, true);
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex())
+ {
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- cloudshader->bind();
+ LLGLSPipelineBlendSkyBox pipeline(true, true);
+
+ cloudshader->bind();
LLPointer<LLViewerTexture> cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
@@ -298,36 +342,36 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
- /// Render the skydome
+ /// Render the skydome
renderDome(camPosLocal, camHeightLocal, cloudshader);
- cloudshader->unbind();
+ cloudshader->unbind();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ }
}
void LLDrawPoolWLSky::renderHeavenlyBodies()
{
- if (!gSky.mVOSkyp) return;
+ if (!gSky.mVOSkyp || use_hdri_sky()) return;
LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.pushMatrix();
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ gGL.pushMatrix();
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
- LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
+ LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
bool can_use_vertex_shaders = gPipeline.shadersLoaded();
bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders();
- if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount())
- {
- LLPointer<LLViewerTexture> tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount())
+ {
+ LLPointer<LLViewerTexture> tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
LLPointer<LLViewerTexture> tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -371,17 +415,17 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
sun_shader->unbind();
}
}
- }
+ }
- face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
+ face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
- if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader)
- {
+ if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader)
+ {
LLViewerTexture* tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
LLViewerTexture* tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
- LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
-
+ LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
+
if (can_use_vertex_shaders && can_use_windlight_shaders && (tex_a || tex_b))
{
moon_shader->bind();
@@ -428,18 +472,16 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
void LLDrawPoolWLSky::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull())
- {
- return;
- }
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull())
+ {
+ return;
+ }
// TODO: remove gSky.mVOSkyp and fold sun/moon into LLVOWLSky
gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
- gGL.setColorMask(true, false);
-
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
if (gPipeline.canUseWindLightShaders())
@@ -456,14 +498,13 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
}
}
- gGL.setColorMask(true, true);
}
LLViewerTexture* LLDrawPoolWLSky::getTexture()
{
- return NULL;
+ return NULL;
}
void LLDrawPoolWLSky::resetDrawOrders()
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index a27a98ff2c..24818241ab 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lldynamictexture.cpp
* @brief Implementation of LLViewerDynamicTexture class
*
* $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$
*/
@@ -30,7 +30,7 @@
// Linden library includes
#include "llglheaders.h"
-#include "llwindow.h" // getPosition()
+#include "llwindow.h" // getPosition()
// Viewer includes
#include "llviewerwindow.h"
@@ -50,16 +50,16 @@ S32 LLViewerDynamicTexture::sNumRenders = 0;
//-----------------------------------------------------------------------------
// LLViewerDynamicTexture()
//-----------------------------------------------------------------------------
-LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) :
- LLViewerTexture(width, height, components, FALSE),
- mClamp(clamp)
+LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) :
+ LLViewerTexture(width, height, components, FALSE),
+ mClamp(clamp)
{
- llassert((1 <= components) && (components <= 4));
+ llassert((1 <= components) && (components <= 4));
- generateGLTexture();
+ generateGLTexture();
- llassert( 0 <= order && order < ORDER_COUNT );
- LLViewerDynamicTexture::sInstances[ order ].insert(this);
+ llassert( 0 <= order && order < ORDER_COUNT );
+ LLViewerDynamicTexture::sInstances[ order ].insert(this);
}
//-----------------------------------------------------------------------------
@@ -67,16 +67,16 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon
//-----------------------------------------------------------------------------
LLViewerDynamicTexture::~LLViewerDynamicTexture()
{
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
- }
+ for( S32 order = 0; order < ORDER_COUNT; order++ )
+ {
+ LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
+ }
}
-//virtual
+//virtual
S8 LLViewerDynamicTexture::getType() const
{
- return LLViewerTexture::DYNAMIC_TEXTURE ;
+ return LLViewerTexture::DYNAMIC_TEXTURE ;
}
//-----------------------------------------------------------------------------
@@ -84,25 +84,25 @@ S8 LLViewerDynamicTexture::getType() const
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::generateGLTexture()
{
- LLViewerTexture::generateGLTexture() ;
- generateGLTexture(-1, 0, 0, FALSE);
+ LLViewerTexture::generateGLTexture() ;
+ generateGLTexture(-1, 0, 0, FALSE);
}
void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
{
- if (mComponents < 1 || mComponents > 4)
- {
- LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL;
- }
-
- LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
- if (internal_format >= 0)
- {
- setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
- }
- createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
- setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
- mGLTexturep->setGLTextureCreated(false);
+ if (mComponents < 1 || mComponents > 4)
+ {
+ LL_ERRS() << "Bad number of components in dynamic texture: " << mComponents << LL_ENDL;
+ }
+
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
+ if (internal_format >= 0)
+ {
+ setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
+ }
+ createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
+ setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
+ mGLTexturep->setGLTextureCreated(false);
}
//-----------------------------------------------------------------------------
@@ -110,7 +110,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum
//-----------------------------------------------------------------------------
BOOL LLViewerDynamicTexture::render()
{
- return FALSE;
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -118,23 +118,25 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
//use the bottom left corner
- mOrigin.set(0, 0);
+ mOrigin.set(0, 0);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // Set up camera
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- mCamera.setOrigin(*camera);
- mCamera.setAxes(*camera);
- mCamera.setAspect(camera->getAspect());
- mCamera.setView(camera->getView());
- mCamera.setNear(camera->getNear());
-
- glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
- if (clear_depth)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- }
+ // Set up camera
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ mCamera.setOrigin(*camera);
+ mCamera.setAxes(*camera);
+ mCamera.setAspect(camera->getAspect());
+ mCamera.setView(camera->getView());
+ mCamera.setNear(camera->getNear());
+
+ glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
+ if (clear_depth)
+ {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
}
//-----------------------------------------------------------------------------
@@ -142,36 +144,36 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::postRender(BOOL success)
{
- {
- if (success)
- {
- if(mGLTexturep.isNull())
- {
- generateGLTexture() ;
- }
- else if(!mGLTexturep->getHasGLTexture())
- {
- generateGLTexture() ;
- }
- else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does.
- {
- generateGLTexture() ;
- }
-
- success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
- }
- }
-
- // restore viewport
- gViewerWindow->setup2DViewport();
-
- // restore camera
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- camera->setOrigin(mCamera);
- camera->setAxes(mCamera);
- camera->setAspect(mCamera.getAspect());
- camera->setViewNoBroadcast(mCamera.getView());
- camera->setNear(mCamera.getNear());
+ {
+ if (success)
+ {
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
+ else if(!mGLTexturep->getHasGLTexture())
+ {
+ generateGLTexture() ;
+ }
+ else if(mGLTexturep->getDiscardLevel() != 0)//do not know how it happens, but regenerate one if it does.
+ {
+ generateGLTexture() ;
+ }
+
+ success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
+ }
+ }
+
+ // restore viewport
+ gViewerWindow->setup2DViewport();
+
+ // restore camera
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ camera->setOrigin(mCamera);
+ camera->setAxes(mCamera);
+ camera->setAspect(mCamera.getAspect());
+ camera->setViewNoBroadcast(mCamera.getView());
+ camera->setNear(mCamera.getNear());
}
//-----------------------------------------------------------------------------
@@ -181,62 +183,68 @@ void LLViewerDynamicTexture::postRender(BOOL success)
//-----------------------------------------------------------------------------
BOOL LLViewerDynamicTexture::updateAllInstances()
{
- sNumRenders = 0;
- if (gGLManager.mIsDisabled)
- {
- return TRUE;
- }
-
- bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- if (use_fbo)
- {
- gPipeline.mBake.bindTarget();
- gPipeline.mBake.clear();
- }
+ sNumRenders = 0;
+ if (gGLManager.mIsDisabled)
+ {
+ return TRUE;
+ }
- LLGLSLShader::unbind();
- LLVertexBuffer::unbind();
-
- BOOL result = FALSE;
- BOOL ret = FALSE ;
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
- iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
- {
- LLViewerDynamicTexture *dynamicTexture = *iter;
- if (dynamicTexture->needsRender())
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- gDepthDirty = TRUE;
-
- gGL.color4f(1,1,1,1);
- dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr);
- dynamicTexture->preRender(); // Must be called outside of startRender()
- result = FALSE;
- if (dynamicTexture->render())
- {
- ret = TRUE ;
- result = TRUE;
- sNumRenders++;
- }
- gGL.flush();
- LLVertexBuffer::unbind();
- dynamicTexture->setBoundTarget(nullptr);
- dynamicTexture->postRender(result);
- }
- }
- }
+ LLRenderTarget& bake_target = gPipeline.mAuxillaryRT.deferredScreen;
- if (use_fbo)
+ if (!bake_target.isComplete())
{
- gPipeline.mBake.flush();
+ llassert(false);
+ return FALSE;
}
+ llassert(bake_target.getWidth() >= LLPipeline::MAX_BAKE_WIDTH);
+ llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH);
+
+ bake_target.bindTarget();
+ bake_target.clear();
+
+ LLGLSLShader::unbind();
+ LLVertexBuffer::unbind();
+
+ BOOL result = FALSE;
+ BOOL ret = FALSE ;
+ for( S32 order = 0; order < ORDER_COUNT; order++ )
+ {
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
+ {
+ LLViewerDynamicTexture *dynamicTexture = *iter;
+ if (dynamicTexture->needsRender())
+ {
+ llassert(dynamicTexture->getFullWidth() <= LLPipeline::MAX_BAKE_WIDTH);
+ llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ gGL.color4f(1,1,1,1);
+ dynamicTexture->setBoundTarget(&bake_target);
+ dynamicTexture->preRender(); // Must be called outside of startRender()
+ result = FALSE;
+ if (dynamicTexture->render())
+ {
+ ret = TRUE ;
+ result = TRUE;
+ sNumRenders++;
+ }
+ gGL.flush();
+ LLVertexBuffer::unbind();
+ dynamicTexture->setBoundTarget(nullptr);
+ dynamicTexture->postRender(result);
+ }
+ }
+ }
+
+ bake_target.flush();
gGL.flush();
- return ret;
+ return ret;
}
//-----------------------------------------------------------------------------
@@ -245,15 +253,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::destroyGL()
{
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
- iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
- {
- LLViewerDynamicTexture *dynamicTexture = *iter;
- dynamicTexture->destroyGLTexture() ;
- }
- }
+ for( S32 order = 0; order < ORDER_COUNT; order++ )
+ {
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
+ {
+ LLViewerDynamicTexture *dynamicTexture = *iter;
+ dynamicTexture->destroyGLTexture() ;
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -262,18 +270,18 @@ void LLViewerDynamicTexture::destroyGL()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::restoreGL()
{
- if (gGLManager.mIsDisabled)
- {
- return ;
- }
-
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
- iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
- {
- LLViewerDynamicTexture *dynamicTexture = *iter;
- dynamicTexture->restoreGLTexture() ;
- }
- }
+ if (gGLManager.mIsDisabled)
+ {
+ return ;
+ }
+
+ for( S32 order = 0; order < ORDER_COUNT; order++ )
+ {
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
+ {
+ LLViewerDynamicTexture *dynamicTexture = *iter;
+ dynamicTexture->restoreGLTexture() ;
+ }
+ }
}
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 98260ec149..0b535e15b0 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -5,21 +5,21 @@
* $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$
*/
@@ -94,7 +94,7 @@ namespace
const std::string KEY_ACTION("action");
const std::string KEY_ACTIONDATA("action_data");
const std::string KEY_EXPERIENCEID("public_id");
- const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format.
+ const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format.
const std::string KEY_PARCELNAME("ParcelName"); // But changing these would also alter the Experience Log requirements.
const std::string KEY_COUNT("Count");
@@ -370,13 +370,13 @@ namespace
virtual ~LLSettingsInjected() {};
typename SETTINGT::ptr_t getSource() const { return this->mSource; }
- void setSource(const typename SETTINGT::ptr_t &source)
+ void setSource(const typename SETTINGT::ptr_t &source)
{
if (source.get() == this) // do not set a source to itself.
return;
- this->mSource = source;
- this->setDirtyFlag(true);
- this->mLastSourceHash = 0;
+ this->mSource = source;
+ this->setDirtyFlag(true);
+ this->mLastSourceHash = 0;
}
virtual bool isDirty() const override { return SETTINGT::isDirty() || (this->mSource->isDirty()); }
@@ -565,7 +565,7 @@ namespace
if (!this->mSource)
return;
- // clears the dirty flag on this object. Need to prevent triggering
+ // clears the dirty flag on this object. Need to prevent triggering
// more calls into this updateSettings
LLSettingsBase::updateSettings();
@@ -824,7 +824,7 @@ const S32 LLEnvironment::NO_TRACK(-1);
const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version
const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups
-const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
+const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01);
@@ -929,9 +929,9 @@ bool LLEnvironment::canEdit() const
return true;
}
-LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const
-{
- LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
if (!psky && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
{
@@ -947,9 +947,9 @@ LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const
return psky;
}
-LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const
+LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const
{
- LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater();
+ LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater();
if (!pwater && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
{
@@ -1235,7 +1235,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
}
}
-
+
if (fixed.second)
{
logEnvironment(env, fixed.second, env_version);
@@ -1531,12 +1531,12 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f
{
if (transition != TRANSITION_INSTANT)
{
- DayInstance::ptr_t trans = std::make_shared<DayTransition>(
- mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
-
- trans->animate();
-
- mCurrentEnvironment = trans;
+ DayInstance::ptr_t trans = std::make_shared<DayTransition>(
+ mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
+
+ trans->animate();
+
+ mCurrentEnvironment = trans;
}
else
{
@@ -1675,8 +1675,6 @@ void LLEnvironment::update(const LLViewerCamera * cam)
updateSettingsUniforms();
- // *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();
@@ -1687,6 +1685,10 @@ void LLEnvironment::update(const LLViewerCamera * cam)
|| shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
{
shaders_iter->mUniformsDirty = TRUE;
+ if (shaders_iter->mRiggedVariant)
+ {
+ shaders_iter->mRiggedVariant->mUniformsDirty = TRUE;
+ }
}
}
}
@@ -1694,12 +1696,12 @@ void LLEnvironment::update(const LLViewerCamera * cam)
void LLEnvironment::updateCloudScroll()
{
- // This is a function of the environment rather than the sky, since it should
+ // 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 rate = mCurrentEnvironment->getSky()->getCloudScrollRate();
@@ -1768,8 +1770,10 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
case LLSD::TypeArray:
{
LLVector4 vect4(value);
+ // always identify as a radiance pass if desaturating irradiance is disabled
+ static LLCachedControl<bool> desaturate_irradiance(gSavedSettings, "RenderDesaturateIrradiance", true);
- if (gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass())
+ if (desaturate_irradiance && gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass())
{ // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color
auto max_vec = [](LLVector4 col)
{
@@ -1782,7 +1786,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
};
switch (it.second.getShaderKey())
- {
+ {
case LLShaderMgr::BLUE_HORIZON:
case LLShaderMgr::BLUE_DENSITY:
vect4 = max_vec(vect4);
@@ -2184,7 +2188,7 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf
query << "&";
}
if (track_no != NO_TRACK)
- {
+ {
query << "trackno=" << track_no;
}
url += query.str();
@@ -2267,7 +2271,7 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen
LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url);
// results that come back may contain the new settings
- LLSD notify;
+ LLSD notify;
LLSD httpResults = result["http_result"];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -2547,7 +2551,7 @@ void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)
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())
@@ -2571,19 +2575,19 @@ void LLEnvironment::handleEnvironmentPush(LLSD &message)
if (action == ACTION_CLEARENVIRONMENT)
- {
+ {
handleEnvironmentPushClear(experience_id, action_data, transition_time);
}
else if (action == ACTION_PUSHFULLENVIRONMENT)
- {
+ {
handleEnvironmentPushFull(experience_id, action_data, transition_time);
}
else if (action == ACTION_PUSHPARTIALENVIRONMENT)
- {
+ {
handleEnvironmentPushPartial(experience_id, action_data, transition_time);
}
else
- {
+ {
LL_WARNS("ENVIRONMENT", "GENERICMESSAGES") << "Unknown environment push action '" << action << "'" << LL_ENDL;
}
}
@@ -2797,9 +2801,9 @@ bool LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
mInitialized = false;
bool changed = psky == nullptr || mSky == nullptr || mSky->getHash() != psky->getHash();
-
+
bool different_sky = mSky != psky;
-
+
mSky = psky;
mSky->mReplaced |= different_sky;
mSky->update();
@@ -2934,7 +2938,7 @@ LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart
mNextInstance(end),
mTransitionTime(time)
{
-
+
}
bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& delta)
@@ -2946,14 +2950,14 @@ bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds&
return changed;
}
-void LLEnvironment::DayTransition::animate()
+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) {
+ [this](LLSettingsBlender::ptr_t blender) {
mBlenderWater.reset();
if (!mBlenderSky && !mBlenderWater)
@@ -2964,7 +2968,7 @@ void LLEnvironment::DayTransition::animate()
// pause probe updates and reset reflection maps on sky change
- gPipeline.mReflectionMapManager.pause();
+ gPipeline.mReflectionMapManager.pause(mTransitionTime);
gPipeline.mReflectionMapManager.reset();
mSky = mStartSky->buildClone();
@@ -3362,8 +3366,8 @@ namespace
return changed;
}
- void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday)
- {
+ void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday)
+ {
mBaseDayInstance = baseday;
if (mSkyExperience.isNull())
@@ -3567,12 +3571,12 @@ namespace
mInjectedSky->setSource(target_sky);
// clear reflection probes and pause updates during sky change
- gPipeline.mReflectionMapManager.pause();
+ gPipeline.mReflectionMapManager.pause(transition);
gPipeline.mReflectionMapManager.reset();
mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(target_sky, start_sky, psky, transition);
mBlenderSky->setOnFinished(
- [this, psky](LLSettingsBlender::ptr_t blender)
+ [this, psky](LLSettingsBlender::ptr_t blender)
{
mBlenderSky.reset();
mInjectedSky->setSource(psky);
@@ -3596,7 +3600,7 @@ namespace
return;
}
if (transition == LLEnvironment::TRANSITION_INSTANT)
- {
+ {
mBlenderWater.reset();
mInjectedWater->setSource(pwater);
}
@@ -3608,7 +3612,7 @@ namespace
mBlenderWater = std::make_shared<LLSettingsBlenderTimeDelta>(scratch_Water, start_Water, pwater, transition);
mBlenderWater->setOnFinished(
- [this, pwater](LLSettingsBlender::ptr_t blender)
+ [this, pwater](LLSettingsBlender::ptr_t blender)
{
mBlenderWater.reset();
mInjectedWater->setSource(pwater);
@@ -3629,7 +3633,7 @@ namespace
LLEnvironment::EnvSelection_t base_env(mBaseDayInstance->getEnvironmentSelection());
LLEnvironment::DayInstance::ptr_t nextbase = LLEnvironment::instance().getSharedEnvironmentInstance();
- if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) ||
+ if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) ||
(!mSkyExperience.isNull() && !mWaterExperience.isNull()))
{ // base instance completely overridden, or not changed no transition will happen
return;
@@ -3661,7 +3665,7 @@ namespace
void DayInjection::checkExperience()
{
if ((!mDayExperience.isNull()) && (mSkyExperience != mDayExperience) && (mWaterExperience != mDayExperience))
- { // There was a day experience but we've replaced it with a water and a sky experience.
+ { // There was a day experience but we've replaced it with a water and a sky experience.
mDayExperience.setNull();
mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 5e2d7f70cf..ccee57cf69 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llface.cpp
* @brief LLFace 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$
*/
@@ -75,49 +75,49 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
/*
For each vertex, given:
- B - binormal
- T - tangent
- N - normal
- P - position
+ B - binormal
+ T - tangent
+ N - normal
+ P - position
The resulting texture coordinate <u,v> is:
- u = 2(B dot P)
- v = 2(T dot P)
+ u = 2(B dot P)
+ v = 2(T dot P)
*/
void planarProjection(LLVector2 &tc, const LLVector4a& normal,
- const LLVector4a &center, const LLVector4a& vec)
-{
- LLVector4a binormal;
- F32 d = normal[0];
-
- if (d >= 0.5f || d <= -0.5f)
- {
- if (d < 0)
- {
- binormal.set(0,-1,0);
- }
- else
- {
- binormal.set(0, 1, 0);
- }
- }
- else
- {
+ const LLVector4a &center, const LLVector4a& vec)
+{
+ LLVector4a binormal;
+ F32 d = normal[0];
+
+ if (d >= 0.5f || d <= -0.5f)
+ {
+ if (d < 0)
+ {
+ binormal.set(0,-1,0);
+ }
+ else
+ {
+ binormal.set(0, 1, 0);
+ }
+ }
+ else
+ {
if (normal[1] > 0)
- {
- binormal.set(-1,0,0);
- }
- else
- {
- binormal.set(1,0,0);
- }
- }
- LLVector4a tangent;
- tangent.setCross3(binormal,normal);
-
- tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f);
- tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);
+ {
+ binormal.set(-1,0,0);
+ }
+ else
+ {
+ binormal.set(1,0,0);
+ }
+ }
+ LLVector4a tangent;
+ tangent.setCross3(binormal,normal);
+
+ tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f);
+ tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);
}
////////////////////
@@ -128,174 +128,174 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,
void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- mLastUpdateTime = gFrameTimeSeconds;
- mLastMoveTime = 0.f;
- mLastSkinTime = gFrameTimeSeconds;
- mVSize = 0.f;
- mPixelArea = 16.f;
- mState = GLOBAL;
- mDrawPoolp = NULL;
- mPoolType = 0;
- mCenterLocal = objp->getPosition();
- mCenterAgent = drawablep->getPositionAgent();
- mDistance = 0.f;
-
- mGeomCount = 0;
- mGeomIndex = 0;
- mIndicesCount = 0;
-
- //special value to indicate uninitialized position
- mIndicesIndex = 0xFFFFFFFF;
-
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- mIndexInTex[i] = 0;
- mTexture[i] = NULL;
- }
-
- mTEOffset = -1;
- mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES;
-
- setDrawable(drawablep);
- mVObjp = objp;
-
- mReferenceIndex = -1;
-
- mTextureMatrix = NULL;
- mDrawInfo = NULL;
-
- mFaceColor = LLColor4(1,0,0,1);
-
- mImportanceToCamera = 0.f ;
- mBoundingSphereRadius = 0.0f ;
-
- mHasMedia = false ;
- mIsMediaAllowed = true;
+ mLastUpdateTime = gFrameTimeSeconds;
+ mLastMoveTime = 0.f;
+ mLastSkinTime = gFrameTimeSeconds;
+ mVSize = 0.f;
+ mPixelArea = 16.f;
+ mState = GLOBAL;
+ mDrawPoolp = NULL;
+ mPoolType = 0;
+ mCenterLocal = objp->getPosition();
+ mCenterAgent = drawablep->getPositionAgent();
+ mDistance = 0.f;
+
+ mGeomCount = 0;
+ mGeomIndex = 0;
+ mIndicesCount = 0;
+
+ //special value to indicate uninitialized position
+ mIndicesIndex = 0xFFFFFFFF;
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ mIndexInTex[i] = 0;
+ mTexture[i] = NULL;
+ }
+
+ mTEOffset = -1;
+ mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES;
+
+ setDrawable(drawablep);
+ mVObjp = objp;
+
+ mReferenceIndex = -1;
+
+ mTextureMatrix = NULL;
+ mDrawInfo = NULL;
+
+ mFaceColor = LLColor4(1,0,0,1);
+
+ mImportanceToCamera = 0.f ;
+ mBoundingSphereRadius = 0.0f ;
+
+ mHasMedia = false ;
+ mIsMediaAllowed = true;
}
void LLFace::destroy()
{
- if (gDebugGL)
- {
- gPipeline.checkReferences(this);
- }
-
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- if(mTexture[i].notNull())
- {
- mTexture[i]->removeFace(i, this) ;
- mTexture[i] = NULL;
- }
- }
-
- if (isState(LLFace::PARTICLE))
- {
- clearState(LLFace::PARTICLE);
- }
-
- if (mDrawPoolp)
- {
- mDrawPoolp->removeFace(this);
- mDrawPoolp = NULL;
- }
-
- if (mTextureMatrix)
- {
- delete mTextureMatrix;
- mTextureMatrix = NULL;
-
- if (mDrawablep)
- {
- LLSpatialGroup* group = mDrawablep->getSpatialGroup();
- if (group)
- {
- group->dirtyGeom();
- gPipeline.markRebuild(group);
- }
- }
- }
-
- setDrawInfo(NULL);
-
- mDrawablep = NULL;
- mVObjp = NULL;
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ if(mTexture[i].notNull())
+ {
+ mTexture[i]->removeFace(i, this) ;
+ mTexture[i] = NULL;
+ }
+ }
+
+ if (isState(LLFace::PARTICLE))
+ {
+ clearState(LLFace::PARTICLE);
+ }
+
+ if (mDrawPoolp)
+ {
+ mDrawPoolp->removeFace(this);
+ mDrawPoolp = NULL;
+ }
+
+ if (mTextureMatrix)
+ {
+ delete mTextureMatrix;
+ mTextureMatrix = NULL;
+
+ if (mDrawablep)
+ {
+ LLSpatialGroup* group = mDrawablep->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
+ }
+ }
+
+ setDrawInfo(NULL);
+
+ mDrawablep = NULL;
+ mVObjp = NULL;
}
void LLFace::setWorldMatrix(const LLMatrix4 &mat)
{
- LL_ERRS() << "Faces on this drawable are not independently modifiable\n" << LL_ENDL;
+ LL_ERRS() << "Faces on this drawable are not independently modifiable\n" << LL_ENDL;
}
void LLFace::setPool(LLFacePool* pool)
{
- mDrawPoolp = pool;
+ mDrawPoolp = pool;
}
void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- if (!new_pool)
- {
- LL_ERRS() << "Setting pool to null!" << LL_ENDL;
- }
-
- if (new_pool != mDrawPoolp)
- {
- // Remove from old pool
- if (mDrawPoolp)
- {
- mDrawPoolp->removeFace(this);
-
- if (mDrawablep)
- {
- gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL);
- }
- }
- mGeomIndex = 0;
-
- // Add to new pool
- if (new_pool)
- {
- new_pool->addFace(this);
- }
- mDrawPoolp = new_pool;
- }
-
- setTexture(texturep) ;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
+
+ if (!new_pool)
+ {
+ LL_ERRS() << "Setting pool to null!" << LL_ENDL;
+ }
+
+ if (new_pool != mDrawPoolp)
+ {
+ // Remove from old pool
+ if (mDrawPoolp)
+ {
+ mDrawPoolp->removeFace(this);
+
+ if (mDrawablep)
+ {
+ gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL);
+ }
+ }
+ mGeomIndex = 0;
+
+ // Add to new pool
+ if (new_pool)
+ {
+ new_pool->addFace(this);
+ }
+ mDrawPoolp = new_pool;
+ }
+
+ setTexture(texturep) ;
}
-void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
+void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
{
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
-
- if(mTexture[ch] == tex)
- {
- return ;
- }
-
- if(mTexture[ch].notNull())
- {
- mTexture[ch]->removeFace(ch, this) ;
- }
-
- if(tex)
- {
- tex->addFace(ch, this) ;
- }
-
- mTexture[ch] = tex ;
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mTexture[ch] == tex)
+ {
+ return ;
+ }
+
+ if(mTexture[ch].notNull())
+ {
+ mTexture[ch]->removeFace(ch, this) ;
+ }
+
+ if(tex)
+ {
+ tex->addFace(ch, this) ;
+ }
+
+ mTexture[ch] = tex ;
}
-void LLFace::setTexture(LLViewerTexture* tex)
+void LLFace::setTexture(LLViewerTexture* tex)
{
- setDiffuseMap(tex);
+ setDiffuseMap(tex);
}
void LLFace::setDiffuseMap(LLViewerTexture* tex)
{
- setTexture(LLRender::DIFFUSE_MAP, tex);
+ setTexture(LLRender::DIFFUSE_MAP, tex);
}
void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex)
@@ -305,278 +305,278 @@ void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex)
void LLFace::setNormalMap(LLViewerTexture* tex)
{
- setTexture(LLRender::NORMAL_MAP, tex);
+ setTexture(LLRender::NORMAL_MAP, tex);
}
void LLFace::setSpecularMap(LLViewerTexture* tex)
{
- setTexture(LLRender::SPECULAR_MAP, tex);
+ setTexture(LLRender::SPECULAR_MAP, tex);
}
void LLFace::dirtyTexture()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
- LLDrawable* drawablep = getDrawable();
+ LLDrawable* drawablep = getDrawable();
- if (mVObjp.notNull() && mVObjp->getVolume())
- {
- for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
- { //dirty texture on an alpha object should be treated as an LoD update
- LLVOVolume* vobj = drawablep->getVOVolume();
- if (vobj)
- {
- vobj->mLODChanged = TRUE;
+ if (mVObjp.notNull() && mVObjp->getVolume())
+ {
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
+ { //dirty texture on an alpha object should be treated as an LoD update
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj)
+ {
+ vobj->mLODChanged = TRUE;
vobj->updateVisualComplexity();
- }
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
- }
- }
- }
+ }
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+ }
+ }
+ }
- gPipeline.markTextured(drawablep);
+ gPipeline.markTextured(drawablep);
}
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- if(mTexture[ch] == new_texture)
- {
- return ;
- }
+ if(mTexture[ch] == new_texture)
+ {
+ return ;
+ }
- if(!new_texture)
- {
- LL_ERRS() << "Can not switch to a null texture." << LL_ENDL;
- return;
- }
+ if(!new_texture)
+ {
+ LL_ERRS() << "Can not switch to a null texture." << LL_ENDL;
+ return;
+ }
- llassert(mTexture[ch].notNull());
+ llassert(mTexture[ch].notNull());
- if (ch == LLRender::DIFFUSE_MAP)
- {
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
- }
+ if (ch == LLRender::DIFFUSE_MAP)
+ {
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ }
- setTexture(ch, new_texture) ;
- dirtyTexture();
+ setTexture(ch, new_texture) ;
+ dirtyTexture();
}
void LLFace::setTEOffset(const S32 te_offset)
{
- mTEOffset = te_offset;
+ mTEOffset = te_offset;
}
void LLFace::setFaceColor(const LLColor4& color)
{
- mFaceColor = color;
- setState(USE_FACE_COLOR);
+ mFaceColor = color;
+ setState(USE_FACE_COLOR);
}
void LLFace::unsetFaceColor()
{
- clearState(USE_FACE_COLOR);
+ clearState(USE_FACE_COLOR);
}
void LLFace::setDrawable(LLDrawable *drawable)
{
- mDrawablep = drawable;
- mXform = &drawable->mXform;
+ mDrawablep = drawable;
+ mXform = &drawable->mXform;
}
void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)
{
- if (align)
- {
- //allocate vertices in blocks of 4 for alignment
- num_vertices = (num_vertices + 0x3) & ~0x3;
- }
-
- if (mGeomCount != num_vertices ||
- mIndicesCount != num_indices)
- {
- mGeomCount = num_vertices;
- mIndicesCount = num_indices;
- mVertexBuffer = NULL;
- }
-
- llassert(verify());
+ if (align)
+ {
+ //allocate vertices in blocks of 4 for alignment
+ num_vertices = (num_vertices + 0x3) & ~0x3;
+ }
+
+ if (mGeomCount != num_vertices ||
+ mIndicesCount != num_indices)
+ {
+ mGeomCount = num_vertices;
+ mIndicesCount = num_indices;
+ mVertexBuffer = NULL;
+ }
+
+ llassert(verify());
}
-void LLFace::setGeomIndex(U16 idx)
-{
- if (mGeomIndex != idx)
- {
- mGeomIndex = idx;
- mVertexBuffer = NULL;
- }
+void LLFace::setGeomIndex(U16 idx)
+{
+ if (mGeomIndex != idx)
+ {
+ mGeomIndex = idx;
+ mVertexBuffer = NULL;
+ }
}
void LLFace::setTextureIndex(U8 index)
{
- if (index != mTextureIndex)
- {
- mTextureIndex = index;
-
- if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES)
- {
- mDrawablep->setState(LLDrawable::REBUILD_POSITION);
- }
- else
- {
- if (mDrawInfo && !mDrawInfo->mTextureList.empty())
- {
- LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL;
- }
- }
- }
+ if (index != mTextureIndex)
+ {
+ mTextureIndex = index;
+
+ if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES)
+ {
+ mDrawablep->setState(LLDrawable::REBUILD_POSITION);
+ }
+ else
+ {
+ if (mDrawInfo && !mDrawInfo->mTextureList.empty())
+ {
+ LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL;
+ }
+ }
+ }
}
-void LLFace::setIndicesIndex(S32 idx)
-{
- if (mIndicesIndex != idx)
- {
- mIndicesIndex = idx;
- mVertexBuffer = NULL;
- }
+void LLFace::setIndicesIndex(S32 idx)
+{
+ if (mIndicesIndex != idx)
+ {
+ mIndicesIndex = idx;
+ mVertexBuffer = NULL;
+ }
}
-
+
//============================================================================
U16 LLFace::getGeometryAvatar(
- LLStrider<LLVector3> &vertices,
- LLStrider<LLVector3> &normals,
- LLStrider<LLVector2> &tex_coords,
- LLStrider<F32> &vertex_weights,
- LLStrider<LLVector4> &clothing_weights)
+ LLStrider<LLVector3> &vertices,
+ LLStrider<LLVector3> &normals,
+ LLStrider<LLVector2> &tex_coords,
+ LLStrider<F32> &vertex_weights,
+ LLStrider<LLVector4> &clothing_weights)
{
- if (mVertexBuffer.notNull())
- {
- mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount);
- mVertexBuffer->getNormalStrider (normals, mGeomIndex, mGeomCount);
- mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex, mGeomCount);
- mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount);
- mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount);
- }
-
- return mGeomIndex;
+ if (mVertexBuffer.notNull())
+ {
+ mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount);
+ mVertexBuffer->getNormalStrider (normals, mGeomIndex, mGeomCount);
+ mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex, mGeomCount);
+ mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount);
+ mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount);
+ }
+
+ return mGeomIndex;
}
U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
- LLStrider<LLVector2> &tex_coords, LLStrider<U16> &indicesp)
+ LLStrider<LLVector2> &tex_coords, LLStrider<U16> &indicesp)
{
- if (mVertexBuffer.notNull())
- {
- mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount);
- if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
- {
- mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount);
- }
- if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0))
- {
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
- }
-
- mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
- }
-
- return mGeomIndex;
+ if (mVertexBuffer.notNull())
+ {
+ mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount);
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
+ {
+ mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount);
+ }
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0))
+ {
+ mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+ }
+
+ mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
+ }
+
+ return mGeomIndex;
}
void LLFace::updateCenterAgent()
{
- if (mDrawablep->isActive())
- {
- mCenterAgent = mCenterLocal * getRenderMatrix();
- }
- else
- {
- mCenterAgent = mCenterLocal;
- }
+ if (mDrawablep->isActive())
+ {
+ mCenterAgent = mCenterLocal * getRenderMatrix();
+ }
+ else
+ {
+ mCenterAgent = mCenterLocal;
+ }
}
void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL)
- {
- return;
- }
-
- mDrawablep->getSpatialGroup()->rebuildGeom();
- mDrawablep->getSpatialGroup()->rebuildMesh();
-
- if(mVertexBuffer.isNull())
- {
- return;
- }
-
- if (mGeomCount > 0 && mIndicesCount > 0)
- {
- gGL.getTexUnit(0)->bind(imagep);
-
- gGL.pushMatrix();
- if (mDrawablep->isActive())
- {
- gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix);
- }
- else
- {
- gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
- }
-
- gGL.diffuseColor4fv(color.mV);
-
- if (mDrawablep->isState(LLDrawable::RIGGED))
- {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
+
+ if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL)
+ {
+ return;
+ }
+
+ mDrawablep->getSpatialGroup()->rebuildGeom();
+ mDrawablep->getSpatialGroup()->rebuildMesh();
+
+ if(mVertexBuffer.isNull())
+ {
+ return;
+ }
+
+ if (mGeomCount > 0 && mIndicesCount > 0)
+ {
+ gGL.getTexUnit(0)->bind(imagep);
+
+ gGL.pushMatrix();
+ if (mDrawablep->isActive())
+ {
+ gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix);
+ }
+ else
+ {
+ gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
+ }
+
+ gGL.diffuseColor4fv(color.mV);
+
+ if (mDrawablep->isState(LLDrawable::RIGGED))
+ {
#if 0 // TODO -- there is no way this won't destroy our GL machine as implemented, rewrite it to not rely on software skinning
- LLVOVolume* volume = mDrawablep->getVOVolume();
- if (volume)
- {
- LLRiggedVolume* rigged = volume->getRiggedVolume();
- if (rigged)
- {
+ LLVOVolume* volume = mDrawablep->getVOVolume();
+ if (volume)
+ {
+ LLRiggedVolume* rigged = volume->getRiggedVolume();
+ if (rigged)
+ {
// called when selecting a face during edit of a mesh object
- LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.f, -1.f);
- gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
- const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset());
- LLVertexBuffer::unbind();
- glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions);
- if (vol_face.mTexCoords)
- {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
- }
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- }
+ LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.f, -1.f);
+ gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
+ const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset());
+ LLVertexBuffer::unbind();
+ glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions);
+ if (vol_face.mTexCoords)
+ {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
+ }
+ gGL.syncMatrices();
+ glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
#endif
- }
- else
- {
- // cheaters sometimes prosper...
- //
- mVertexBuffer->setBuffer();
- mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
- }
-
- gGL.popMatrix();
- }
+ }
+ else
+ {
+ // cheaters sometimes prosper...
+ //
+ mVertexBuffer->setBuffer();
+ mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
+ }
+
+ gGL.popMatrix();
+ }
}
void renderFace(LLDrawable* drawable, LLFace *face)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
LLVOVolume* vobj = drawable->getVOVolume();
if (vobj)
@@ -646,234 +646,234 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
void LLFace::setDrawInfo(LLDrawInfo* draw_info)
{
- mDrawInfo = draw_info;
+ mDrawInfo = draw_info;
}
void LLFace::printDebugInfo() const
{
- LLFacePool *poolp = getPool();
- LL_INFOS() << "Object: " << getViewerObject()->mID << LL_ENDL;
- if (getDrawable())
- {
- LL_INFOS() << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << LL_ENDL;
- }
- if (getTexture())
- {
- LL_INFOS() << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "No texture: " << LL_ENDL;
- }
-
- LL_INFOS() << "Face: " << this << LL_ENDL;
- LL_INFOS() << "State: " << getState() << LL_ENDL;
- LL_INFOS() << "Geom Index Data:" << LL_ENDL;
- LL_INFOS() << "--------------------" << LL_ENDL;
- LL_INFOS() << "GI: " << mGeomIndex << " Count:" << mGeomCount << LL_ENDL;
- LL_INFOS() << "Face Index Data:" << LL_ENDL;
- LL_INFOS() << "--------------------" << LL_ENDL;
- LL_INFOS() << "II: " << mIndicesIndex << " Count:" << mIndicesCount << LL_ENDL;
- LL_INFOS() << LL_ENDL;
-
- if (poolp)
- {
- poolp->printDebugInfo();
-
- S32 pool_references = 0;
- for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin();
- iter != poolp->mReferences.end(); iter++)
- {
- LLFace *facep = *iter;
- if (facep == this)
- {
- LL_INFOS() << "Pool reference: " << pool_references << LL_ENDL;
- pool_references++;
- }
- }
-
- if (pool_references != 1)
- {
- LL_INFOS() << "Incorrect number of pool references!" << LL_ENDL;
- }
- }
+ LLFacePool *poolp = getPool();
+ LL_INFOS() << "Object: " << getViewerObject()->mID << LL_ENDL;
+ if (getDrawable())
+ {
+ LL_INFOS() << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << LL_ENDL;
+ }
+ if (getTexture())
+ {
+ LL_INFOS() << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "No texture: " << LL_ENDL;
+ }
+
+ LL_INFOS() << "Face: " << this << LL_ENDL;
+ LL_INFOS() << "State: " << getState() << LL_ENDL;
+ LL_INFOS() << "Geom Index Data:" << LL_ENDL;
+ LL_INFOS() << "--------------------" << LL_ENDL;
+ LL_INFOS() << "GI: " << mGeomIndex << " Count:" << mGeomCount << LL_ENDL;
+ LL_INFOS() << "Face Index Data:" << LL_ENDL;
+ LL_INFOS() << "--------------------" << LL_ENDL;
+ LL_INFOS() << "II: " << mIndicesIndex << " Count:" << mIndicesCount << LL_ENDL;
+ LL_INFOS() << LL_ENDL;
+
+ if (poolp)
+ {
+ poolp->printDebugInfo();
+
+ S32 pool_references = 0;
+ for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin();
+ iter != poolp->mReferences.end(); iter++)
+ {
+ LLFace *facep = *iter;
+ if (facep == this)
+ {
+ LL_INFOS() << "Pool reference: " << pool_references << LL_ENDL;
+ pool_references++;
+ }
+ }
+
+ if (pool_references != 1)
+ {
+ LL_INFOS() << "Incorrect number of pool references!" << LL_ENDL;
+ }
+ }
#if 0
- LL_INFOS() << "Indices:" << LL_ENDL;
- LL_INFOS() << "--------------------" << LL_ENDL;
-
- const U32 *indicesp = getRawIndices();
- S32 indices_count = getIndicesCount();
- S32 geom_start = getGeomStart();
-
- for (S32 i = 0; i < indices_count; i++)
- {
- LL_INFOS() << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << LL_ENDL;
- }
- LL_INFOS() << LL_ENDL;
-
- LL_INFOS() << "Vertices:" << LL_ENDL;
- LL_INFOS() << "--------------------" << LL_ENDL;
- for (S32 i = 0; i < mGeomCount; i++)
- {
- LL_INFOS() << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << LL_ENDL;
- }
- LL_INFOS() << LL_ENDL;
+ LL_INFOS() << "Indices:" << LL_ENDL;
+ LL_INFOS() << "--------------------" << LL_ENDL;
+
+ const U32 *indicesp = getRawIndices();
+ S32 indices_count = getIndicesCount();
+ S32 geom_start = getGeomStart();
+
+ for (S32 i = 0; i < indices_count; i++)
+ {
+ LL_INFOS() << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << LL_ENDL;
+ }
+ LL_INFOS() << LL_ENDL;
+
+ LL_INFOS() << "Vertices:" << LL_ENDL;
+ LL_INFOS() << "--------------------" << LL_ENDL;
+ for (S32 i = 0; i < mGeomCount; i++)
+ {
+ LL_INFOS() << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << LL_ENDL;
+ }
+ LL_INFOS() << LL_ENDL;
#endif
}
// Transform the texture coordinates for this face.
static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT)
{
- // New, good way
- F32 s = tex_coord.mV[0];
- F32 t = tex_coord.mV[1];
+ // New, good way
+ F32 s = tex_coord.mV[0];
+ F32 t = tex_coord.mV[1];
- // Texture transforms are done about the center of the face.
- s -= 0.5;
- t -= 0.5;
+ // Texture transforms are done about the center of the face.
+ s -= 0.5;
+ t -= 0.5;
- // Handle rotation
- F32 temp = s;
- s = s * cosAng + t * sinAng;
- t = -temp * sinAng + t * cosAng;
+ // Handle rotation
+ F32 temp = s;
+ s = s * cosAng + t * sinAng;
+ t = -temp * sinAng + t * cosAng;
- // Then scale
- s *= magS;
- t *= magT;
+ // Then scale
+ s *= magS;
+ t *= magT;
- // Then offset
- s += offS + 0.5f;
- t += offT + 0.5f;
+ // Then offset
+ s += offS + 0.5f;
+ t += offT + 0.5f;
- tex_coord.mV[0] = s;
- tex_coord.mV[1] = t;
+ tex_coord.mV[0] = s;
+ tex_coord.mV[1] = t;
}
// Transform the texture coordinates for this face.
-static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale)
+static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale)
{
- //tex coord is two coords, <s0, t0, s1, t1>
- LLVector4a st;
-
- // Texture transforms are done about the center of the face.
- st.setAdd(tex_coord, trans);
-
- // Handle rotation
- LLVector4a rot_st;
-
- // <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng>
- LLVector4a s0;
- s0.splat(st, 0);
- LLVector4a s1;
- s1.splat(st, 2);
- LLVector4a ss;
- ss.setSelectWithMask(mask, s1, s0);
-
- LLVector4a a;
- a.setMul(rot0, ss);
-
- // <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng>
- LLVector4a t0;
- t0.splat(st, 1);
- LLVector4a t1;
- t1.splat(st, 3);
- LLVector4a tt;
- tt.setSelectWithMask(mask, t1, t0);
-
- LLVector4a b;
- b.setMul(rot1, tt);
-
- st.setAdd(a,b);
-
- // Then scale
- st.mul(scale);
-
- // Then offset
- tex_coord.setAdd(st, offset);
+ //tex coord is two coords, <s0, t0, s1, t1>
+ LLVector4a st;
+
+ // Texture transforms are done about the center of the face.
+ st.setAdd(tex_coord, trans);
+
+ // Handle rotation
+ LLVector4a rot_st;
+
+ // <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng>
+ LLVector4a s0;
+ s0.splat(st, 0);
+ LLVector4a s1;
+ s1.splat(st, 2);
+ LLVector4a ss;
+ ss.setSelectWithMask(mask, s1, s0);
+
+ LLVector4a a;
+ a.setMul(rot0, ss);
+
+ // <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng>
+ LLVector4a t0;
+ t0.splat(st, 1);
+ LLVector4a t1;
+ t1.splat(st, 3);
+ LLVector4a tt;
+ tt.setSelectWithMask(mask, t1, t0);
+
+ LLVector4a b;
+ b.setMul(rot1, tt);
+
+ st.setAdd(a,b);
+
+ // Then scale
+ st.mul(scale);
+
+ // Then offset
+ tex_coord.setAdd(st, offset);
}
bool less_than_max_mag(const LLVector4a& vec)
{
- LLVector4a MAX_MAG;
- MAX_MAG.splat(1024.f*1024.f);
-
- LLVector4a val;
- val.setAbs(vec);
+ LLVector4a MAX_MAG;
+ MAX_MAG.splat(1024.f*1024.f);
- S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7;
+ LLVector4a val;
+ val.setAbs(vec);
- return lt == 0x7;
+ S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7;
+
+ return lt == 0x7;
}
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat_vert_in, BOOL global_volume)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- //get bounding box
- if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
- {
- if (f >= volume.getNumVolumeFaces())
- {
- LL_WARNS() << "Generating bounding box for invalid face index!" << LL_ENDL;
- f = 0;
- }
-
- const LLVolumeFace &face = volume.getVolumeFace(f);
-
- LL_DEBUGS("RiggedBox") << "updating extents for face " << f
- << " starting extents " << mExtents[0] << ", " << mExtents[1]
- << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1]
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
+
+ //get bounding box
+ if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
+ {
+ if (f >= volume.getNumVolumeFaces())
+ {
+ LL_WARNS() << "Generating bounding box for invalid face index!" << LL_ENDL;
+ f = 0;
+ }
+
+ const LLVolumeFace &face = volume.getVolumeFace(f);
+
+ LL_DEBUGS("RiggedBox") << "updating extents for face " << f
+ << " starting extents " << mExtents[0] << ", " << mExtents[1]
+ << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1]
<< " num verts " << face.mNumVertices << LL_ENDL;
// MAINT-8264 - stray vertices, especially in low LODs, cause bounding box errors.
- if (face.mNumVertices < 3)
+ if (face.mNumVertices < 3)
{
- LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices "
+ LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices "
<< face.mNumVertices << " " << face.mNumIndices << " " << face.mWeights << LL_ENDL;
return FALSE;
}
-
- //VECTORIZE THIS
- LLMatrix4a mat_vert;
- mat_vert.loadu(mat_vert_in);
+
+ //VECTORIZE THIS
+ LLMatrix4a mat_vert;
+ mat_vert.loadu(mat_vert_in);
LLVector4a new_extents[2];
- llassert(less_than_max_mag(face.mExtents[0]));
- llassert(less_than_max_mag(face.mExtents[1]));
+ llassert(less_than_max_mag(face.mExtents[0]));
+ llassert(less_than_max_mag(face.mExtents[1]));
- matMulBoundBox(mat_vert, face.mExtents, mExtents);
+ matMulBoundBox(mat_vert, face.mExtents, mExtents);
- LL_DEBUGS("RiggedBox") << "updated extents for face " << f
+ LL_DEBUGS("RiggedBox") << "updated extents for face " << f
<< " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL;
- if (!mDrawablep->isActive())
- { // Shift position for region
- LLVector4a offset;
- offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
- mExtents[0].add(offset);
- mExtents[1].add(offset);
- LL_DEBUGS("RiggedBox") << "updating extents for face " << f
+ if (!mDrawablep->isActive())
+ { // Shift position for region
+ LLVector4a offset;
+ offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
+ mExtents[0].add(offset);
+ mExtents[1].add(offset);
+ LL_DEBUGS("RiggedBox") << "updating extents for face " << f
<< " not active, added offset " << offset << LL_ENDL;
- }
+ }
- LL_DEBUGS("RiggedBox") << "updated extents for face " << f
+ LL_DEBUGS("RiggedBox") << "updated extents for face " << f
<< " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL;
- LLVector4a t;
- t.setAdd(mExtents[0],mExtents[1]);
- t.mul(0.5f);
+ LLVector4a t;
+ t.setAdd(mExtents[0],mExtents[1]);
+ t.mul(0.5f);
- mCenterLocal.set(t.getF32ptr());
+ mCenterLocal.set(t.getF32ptr());
- t.setSub(mExtents[1],mExtents[0]);
- mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
+ t.setSub(mExtents[1],mExtents[0]);
+ mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
- updateCenterAgent();
- }
+ updateCenterAgent();
+ }
- return TRUE;
+ return TRUE;
}
@@ -885,113 +885,113 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
// with the implications.
LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)
{
- LLVector2 tc = surface_coord;
-
- const LLTextureEntry *tep = getTextureEntry();
-
- if (tep == NULL)
- {
- // can't do much without the texture entry
- return surface_coord;
- }
-
- //VECTORIZE THIS
- // see if we have a non-default mapping
+ LLVector2 tc = surface_coord;
+
+ const LLTextureEntry *tep = getTextureEntry();
+
+ if (tep == NULL)
+ {
+ // can't do much without the texture entry
+ return surface_coord;
+ }
+
+ //VECTORIZE THIS
+ // see if we have a non-default mapping
U8 texgen = getTextureEntry()->getTexGen();
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
-
- LLVector4a volume_position;
- LLVector3 v_position(position.getF32ptr());
-
- volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);
-
- if (!mDrawablep->getVOVolume()->isVolumeGlobal())
- {
- LLVector4a scale;
- scale.load3(mVObjp->getScale().mV);
- volume_position.mul(scale);
- }
-
- LLVector4a volume_normal;
- LLVector3 v_normal(normal.getF32ptr());
- volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);
- volume_normal.normalize3fast();
-
- if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
- {
- planarProjection(tc, volume_normal, center, volume_position);
- }
- }
-
- if (mTextureMatrix) // if we have a texture matrix, use it
- {
- LLVector3 tc3(tc);
- tc3 = tc3 * *mTextureMatrix;
- tc = LLVector2(tc3);
- }
-
- else // otherwise use the texture entry parameters
- {
- xform(tc, cos(tep->getRotation()), sin(tep->getRotation()),
- tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT);
- }
-
-
- return tc;
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
+
+ LLVector4a volume_position;
+ LLVector3 v_position(position.getF32ptr());
+
+ volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);
+
+ if (!mDrawablep->getVOVolume()->isVolumeGlobal())
+ {
+ LLVector4a scale;
+ scale.load3(mVObjp->getScale().mV);
+ volume_position.mul(scale);
+ }
+
+ LLVector4a volume_normal;
+ LLVector3 v_normal(normal.getF32ptr());
+ volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);
+ volume_normal.normalize3fast();
+
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ planarProjection(tc, volume_normal, center, volume_position);
+ }
+ }
+
+ if (mTextureMatrix) // if we have a texture matrix, use it
+ {
+ LLVector3 tc3(tc);
+ tc3 = tc3 * *mTextureMatrix;
+ tc = LLVector2(tc3);
+ }
+
+ else // otherwise use the texture entry parameters
+ {
+ xform(tc, cos(tep->getRotation()), sin(tep->getRotation()),
+ tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT);
+ }
+
+
+ return tc;
}
// Returns scale compared to default texgen, and face orientation as calculated
// by planarProjection(). This is needed to match planar texgen parameters.
void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const
{
- const LLMatrix4& vol_mat = getWorldMatrix();
- const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
- if (! (vf.mNormals && vf.mTangents))
- {
- return;
- }
- const LLVector4a& normal4a = *vf.mNormals;
- const LLVector4a& tangent = *vf.mTangents;
-
- LLVector4a binormal4a;
- binormal4a.setCross3(normal4a, tangent);
- binormal4a.mul(tangent.getF32ptr()[3]);
-
- LLVector2 projected_binormal;
- planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
- projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
- *scale = projected_binormal.length();
- // rotate binormal to match what planarProjection() thinks it is,
- // then find rotation from that:
- projected_binormal.normalize();
- F32 ang = acos(projected_binormal.mV[VY]);
- ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang;
-
- //VECTORIZE THIS
- LLVector3 binormal(binormal4a.getF32ptr());
- LLVector3 normal(normal4a.getF32ptr());
- binormal.rotVec(ang, normal);
- LLQuaternion local_rot( binormal % normal, binormal, normal );
- *face_rot = local_rot * vol_mat.quaternion();
- *face_pos = vol_mat.getTranslation();
+ const LLMatrix4& vol_mat = getWorldMatrix();
+ const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
+ if (! (vf.mNormals && vf.mTangents))
+ {
+ return;
+ }
+ const LLVector4a& normal4a = *vf.mNormals;
+ const LLVector4a& tangent = *vf.mTangents;
+
+ LLVector4a binormal4a;
+ binormal4a.setCross3(normal4a, tangent);
+ binormal4a.mul(tangent.getF32ptr()[3]);
+
+ LLVector2 projected_binormal;
+ planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
+ projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
+ *scale = projected_binormal.length();
+ // rotate binormal to match what planarProjection() thinks it is,
+ // then find rotation from that:
+ projected_binormal.normalize();
+ F32 ang = acos(projected_binormal.mV[VY]);
+ ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang;
+
+ //VECTORIZE THIS
+ LLVector3 binormal(binormal4a.getF32ptr());
+ LLVector3 normal(normal4a.getF32ptr());
+ binormal.rotVec(ang, normal);
+ LLQuaternion local_rot( binormal % normal, binormal, normal );
+ *face_rot = local_rot * vol_mat.quaternion();
+ *face_pos = vol_mat.getTranslation();
}
// Returns the necessary texture transform to align this face's TE to align_to's TE
-bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset,
- LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const
+bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset,
+ LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const
{
- if (!align_to)
- {
- return false;
- }
- const LLTextureEntry *orig_tep = align_to->getTextureEntry();
- if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) ||
- (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
- {
- return false;
- }
+ if (!align_to)
+ {
+ return false;
+ }
+ const LLTextureEntry *orig_tep = align_to->getTextureEntry();
+ if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) ||
+ (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
+ {
+ return false;
+ }
F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f;
@@ -1037,55 +1037,55 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
break;
}
- LLVector3 orig_pos, this_pos;
- LLQuaternion orig_face_rot, this_face_rot;
- F32 orig_proj_scale, this_proj_scale;
- align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale);
- getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale);
-
- // The rotation of "this face's" texture:
- LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot;
- LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot;
- F32 x_ang, y_ang, z_ang;
- this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang);
- *res_st_rot = z_ang;
-
- // Offset and scale of "this face's" texture:
- LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot;
- LLVector3 st_scale(map_scaleS, map_scaleT, 1.f);
- st_scale *= orig_proj_scale;
- centers_dist.scaleVec(st_scale);
- LLVector2 orig_st_offset(map_offsS, map_offsT);
-
- *res_st_offset = orig_st_offset + (LLVector2)centers_dist;
- res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX];
- res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY];
-
- st_scale /= this_proj_scale;
- *res_st_scale = (LLVector2)st_scale;
- return true;
+ LLVector3 orig_pos, this_pos;
+ LLQuaternion orig_face_rot, this_face_rot;
+ F32 orig_proj_scale, this_proj_scale;
+ align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale);
+ getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale);
+
+ // The rotation of "this face's" texture:
+ LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot;
+ LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot;
+ F32 x_ang, y_ang, z_ang;
+ this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang);
+ *res_st_rot = z_ang;
+
+ // Offset and scale of "this face's" texture:
+ LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot;
+ LLVector3 st_scale(map_scaleS, map_scaleT, 1.f);
+ st_scale *= orig_proj_scale;
+ centers_dist.scaleVec(st_scale);
+ LLVector2 orig_st_offset(map_offsS, map_offsT);
+
+ *res_st_offset = orig_st_offset + (LLVector2)centers_dist;
+ res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX];
+ res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY];
+
+ st_scale /= this_proj_scale;
+ *res_st_scale = (LLVector2)st_scale;
+ return true;
}
void LLFace::updateRebuildFlags()
{
- if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
- { //this rebuild is zero overhead (direct consequence of some change that affects this face)
- mLastUpdateTime = gFrameTimeSeconds;
- }
- else
- { //this rebuild is overhead (side effect of some change that does not affect this face)
- mLastMoveTime = gFrameTimeSeconds;
- }
+ if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
+ { //this rebuild is zero overhead (direct consequence of some change that affects this face)
+ mLastUpdateTime = gFrameTimeSeconds;
+ }
+ else
+ { //this rebuild is overhead (side effect of some change that does not affect this face)
+ mLastMoveTime = gFrameTimeSeconds;
+ }
}
bool LLFace::canRenderAsMask()
{
- const LLTextureEntry* te = getTextureEntry();
- if( !te || !getViewerObject() || !getTexture() )
- {
- return false;
- }
+ const LLTextureEntry* te = getTextureEntry();
+ if( !te || !getViewerObject() || !getTexture() )
+ {
+ return false;
+ }
if (te->getGLTFRenderMaterial())
{
@@ -1102,45 +1102,45 @@ bool LLFace::canRenderAsMask()
return false;
}
-
- LLMaterial* mat = te->getMaterialParams();
- if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
- {
- return false;
- }
-
- if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha
- (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
- getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)
- {
- if (getViewerObject()->isHUDAttachment() || te->getFullbright())
- { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe
- return LLPipeline::sAutoMaskAlphaNonDeferred;
- }
- else
- {
- return LLPipeline::sAutoMaskAlphaDeferred;
- }
- }
-
- return false;
+
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ {
+ return false;
+ }
+
+ if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha
+ (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
+ getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)
+ {
+ if (getViewerObject()->isHUDAttachment() || te->getFullbright())
+ { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe
+ return LLPipeline::sAutoMaskAlphaNonDeferred;
+ }
+ else
+ {
+ return LLPipeline::sAutoMaskAlphaDeferred;
+ }
+ }
+
+ return false;
}
//helper function for pushing primitives for transform shaders and cleaning up
//uninitialized data on the tail, plus tracking number of expected primitives
void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
{
- if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping
- {
- //push source primitives
- buff->drawArrays(LLRender::POINTS, 0, source_count);
- U32 tail = dest_count-source_count;
- for (U32 i = 0; i < tail; ++i)
- { //copy last source primitive into each element in tail
- buff->drawArrays(LLRender::POINTS, source_count-1, 1);
- }
- gPipeline.mTransformFeedbackPrimitives += dest_count;
- }
+ if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping
+ {
+ //push source primitives
+ buff->drawArrays(LLRender::POINTS, 0, source_count);
+ U32 tail = dest_count-source_count;
+ for (U32 i = 0; i < tail; ++i)
+ { //copy last source primitive into each element in tail
+ buff->drawArrays(LLRender::POINTS, source_count-1, 1);
+ }
+ gPipeline.mTransformFeedbackPrimitives += dest_count;
+ }
}
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
@@ -1152,7 +1152,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool no_debug_assert)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- llassert(verify());
+ llassert(verify());
if (face_index < 0 || face_index >= volume.getNumVolumeFaces())
{
@@ -1170,163 +1170,163 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool rigged = isState(RIGGED);
const LLVolumeFace &vf = volume.getVolumeFace(face_index);
- S32 num_vertices = (S32)vf.mNumVertices;
- S32 num_indices = (S32) vf.mNumIndices;
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
- {
- updateRebuildFlags();
- }
-
- if (mVertexBuffer.notNull())
- {
- if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
- {
- if (gDebugGL)
- {
- LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
- LL_WARNS() << "Indices Count: " << mIndicesCount
- << " VF Num Indices: " << num_indices
- << " Indices Index: " << mIndicesIndex
- << " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL;
- LL_WARNS() << " Face Index: " << face_index
- << " Pool Type: " << mPoolType << LL_ENDL;
- llassert(no_debug_assert);
- }
- return FALSE;
- }
-
- if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
- {
- if (gDebugGL)
- {
- LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
- llassert(no_debug_assert);
- }
- return FALSE;
- }
- }
-
- LLStrider<LLVector3> vert;
- LLStrider<LLVector2> tex_coords0;
- LLStrider<LLVector2> tex_coords1;
- LLStrider<LLVector2> tex_coords2;
- LLStrider<LLVector3> norm;
- LLStrider<LLColor4U> colors;
- LLStrider<LLVector3> tangent;
- LLStrider<U16> indicesp;
- LLStrider<LLVector4> wght;
-
- BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
-
- BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal();
- LLVector3 scale;
- if (global_volume)
- {
- scale.setVec(1,1,1);
- }
- else
- {
- scale = mVObjp->getScale();
- }
-
- bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
- bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
- bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
- bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
- bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
- bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
-
- const LLTextureEntry *tep = mVObjp->getTE(face_index);
- const U8 bump_code = tep ? tep->getBumpmap() : 0;
-
- BOOL is_static = mDrawablep->isStatic();
- BOOL is_global = is_static;
-
- LLVector3 center_sum(0.f, 0.f, 0.f);
-
- if (is_global)
- {
- setState(GLOBAL);
- }
- else
- {
- clearState(GLOBAL);
- }
-
- LLColor4U color = tep->getColor();
+ S32 num_vertices = (S32)vf.mNumVertices;
+ S32 num_indices = (S32) vf.mNumIndices;
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
+ {
+ updateRebuildFlags();
+ }
+
+ if (mVertexBuffer.notNull())
+ {
+ if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
+ {
+ if (gDebugGL)
+ {
+ LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
+ LL_WARNS() << "Indices Count: " << mIndicesCount
+ << " VF Num Indices: " << num_indices
+ << " Indices Index: " << mIndicesIndex
+ << " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL;
+ LL_WARNS() << " Face Index: " << face_index
+ << " Pool Type: " << mPoolType << LL_ENDL;
+ llassert(no_debug_assert);
+ }
+ return FALSE;
+ }
+
+ if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
+ {
+ if (gDebugGL)
+ {
+ LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
+ llassert(no_debug_assert);
+ }
+ return FALSE;
+ }
+ }
+
+ LLStrider<LLVector3> vert;
+ LLStrider<LLVector2> tex_coords0;
+ LLStrider<LLVector2> tex_coords1;
+ LLStrider<LLVector2> tex_coords2;
+ LLStrider<LLVector3> norm;
+ LLStrider<LLColor4U> colors;
+ LLStrider<LLVector3> tangent;
+ LLStrider<U16> indicesp;
+ LLStrider<LLVector4> wght;
+
+ BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
+
+ BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal();
+ LLVector3 scale;
+ if (global_volume)
+ {
+ scale.setVec(1,1,1);
+ }
+ else
+ {
+ scale = mVObjp->getScale();
+ }
+
+ bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
+ bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
+ bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
+ bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
+ bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
+ bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
+ bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
+
+ const LLTextureEntry *tep = mVObjp->getTE(face_index);
+ const U8 bump_code = tep ? tep->getBumpmap() : 0;
+
+ BOOL is_static = mDrawablep->isStatic();
+ BOOL is_global = is_static;
+
+ LLVector3 center_sum(0.f, 0.f, 0.f);
+
+ if (is_global)
+ {
+ setState(GLOBAL);
+ }
+ else
+ {
+ clearState(GLOBAL);
+ }
+
+ LLColor4U color = tep->getColor();
if (tep->getGLTFRenderMaterial())
{
color = tep->getGLTFRenderMaterial()->mBaseColor;
}
- if (rebuild_color)
- { //decide if shiny goes in alpha channel of color
- if (tep &&
- !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny
- {
- LLMaterial* mat = tep->getMaterialParams().get();
-
- bool shiny_in_alpha = false;
-
- //store shiny in alpha if we don't have a specular map
- if (!mat || mat->getSpecularID().isNull())
- {
- shiny_in_alpha = true;
- }
-
- if (shiny_in_alpha)
- {
- static const GLfloat SHININESS_TO_ALPHA[4] =
- {
- 0.0000f,
- 0.25f,
- 0.5f,
- 0.75f
- };
-
- llassert(tep->getShiny() <= 3);
- color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255);
- }
- }
- }
-
- // INDICES
- if (full_rebuild)
- {
+ if (rebuild_color)
+ { //decide if shiny goes in alpha channel of color
+ if (tep &&
+ !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny
+ {
+ LLMaterial* mat = tep->getMaterialParams().get();
+
+ bool shiny_in_alpha = false;
+
+ //store shiny in alpha if we don't have a specular map
+ if (!mat || mat->getSpecularID().isNull())
+ {
+ shiny_in_alpha = true;
+ }
+
+ if (shiny_in_alpha)
+ {
+ static const GLfloat SHININESS_TO_ALPHA[4] =
+ {
+ 0.0000f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+
+ llassert(tep->getShiny() <= 3);
+ color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255);
+ }
+ }
+ }
+
+ // INDICES
+ if (full_rebuild)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices");
- mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
-
- volatile __m128i* dst = (__m128i*) indicesp.get();
- __m128i* src = (__m128i*) vf.mIndices;
- __m128i offset = _mm_set1_epi16(index_offset);
+ mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
- S32 end = num_indices/8;
+ volatile __m128i* dst = (__m128i*) indicesp.get();
+ __m128i* src = (__m128i*) vf.mIndices;
+ __m128i offset = _mm_set1_epi16(index_offset);
- for (S32 i = 0; i < end; i++)
- {
- __m128i res = _mm_add_epi16(src[i], offset);
- _mm_storeu_si128((__m128i*) dst++, res);
- }
+ S32 end = num_indices/8;
+
+ for (S32 i = 0; i < end; i++)
+ {
+ __m128i res = _mm_add_epi16(src[i], offset);
+ _mm_storeu_si128((__m128i*) dst++, res);
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices tail");
- U16* idx = (U16*) dst;
-
- for (S32 i = end*8; i < num_indices; ++i)
- {
- *idx++ = vf.mIndices[i]+index_offset;
- }
- }
- }
+ U16* idx = (U16*) dst;
+ for (S32 i = end*8; i < num_indices; ++i)
+ {
+ *idx++ = vf.mIndices[i]+index_offset;
+ }
+ }
+ }
+
LLMaterial* mat = tep->getMaterialParams().get();
LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
- F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
+ F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
constexpr S32 XFORM_NONE = 0;
constexpr S32 XFORM_BLINNPHONG_COLOR = 1;
@@ -1391,7 +1391,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
}
-
+
const LLMeshSkinInfo* skin = nullptr;
LLMatrix4a mat_vert;
LLMatrix4a mat_normal;
@@ -1431,334 +1431,334 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- {
- //if it's not fullbright and has no normals, bake sunlight based on face normal
- //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
- // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
+ {
+ //if it's not fullbright and has no normals, bake sunlight based on face normal
+ //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
+ // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- if (rebuild_tcoord)
- {
+ if (rebuild_tcoord)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tcoord");
-
- //bump setup
- LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
- LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
- LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
-
- LLQuaternion bump_quat;
- if (mDrawablep->isActive())
- {
- bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
- }
-
- if (bump_code)
- {
- mVObjp->getVolume()->genTangents(face_index);
- F32 offset_multiple;
- switch( bump_code )
- {
- case BE_NO_BUMP:
- offset_multiple = 0.f;
- break;
- case BE_BRIGHTNESS:
- case BE_DARKNESS:
- if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
- {
- // Offset by approximately one texel
- S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
- S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
- max_size <<= cur_discard;
- const F32 ARTIFICIAL_OFFSET = 2.f;
- offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
- }
- else
- {
- offset_multiple = 1.f/256;
- }
- break;
-
- default: // Standard bumpmap textures. Assumed to be 256x256
- offset_multiple = 1.f / 256;
- break;
- }
-
- F32 s_scale = 1.f;
- F32 t_scale = 1.f;
- if( tep )
- {
- tep->getScale( &s_scale, &t_scale );
- }
- // Use the nudged south when coming from above sun angle, such
- // 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.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);
- bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
- }
-
- U8 texgen = getTextureEntry()->getTexGen();
- if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- { //planar texgen needs binormals
- mVObjp->getVolume()->genTangents(face_index);
- }
-
- U8 tex_mode = 0;
-
- bool tex_anim = false;
-
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
-
- if (vobj->mTextureAnimp)
- { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
- tex_anim = true;
- }
-
- if (isState(TEXTURE_ANIM))
- {
- if (!tex_mode)
- {
- clearState(TEXTURE_ANIM);
- }
- else
- {
- os = ot = 0.f;
- r = 0.f;
- cos_ang = 1.f;
- sin_ang = 0.f;
- ms = mt = 1.f;
+
+ //bump setup
+ LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
+ LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
+ LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
+
+ LLQuaternion bump_quat;
+ if (mDrawablep->isActive())
+ {
+ bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+ }
+
+ if (bump_code)
+ {
+ mVObjp->getVolume()->genTangents(face_index);
+ F32 offset_multiple;
+ switch( bump_code )
+ {
+ case BE_NO_BUMP:
+ offset_multiple = 0.f;
+ break;
+ case BE_BRIGHTNESS:
+ case BE_DARKNESS:
+ if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
+ {
+ // Offset by approximately one texel
+ S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
+ S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
+ max_size <<= cur_discard;
+ const F32 ARTIFICIAL_OFFSET = 2.f;
+ offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
+ }
+ else
+ {
+ offset_multiple = 1.f/256;
+ }
+ break;
+
+ default: // Standard bumpmap textures. Assumed to be 256x256
+ offset_multiple = 1.f / 256;
+ break;
+ }
+
+ F32 s_scale = 1.f;
+ F32 t_scale = 1.f;
+ if( tep )
+ {
+ tep->getScale( &s_scale, &t_scale );
+ }
+ // Use the nudged south when coming from above sun angle, such
+ // 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.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);
+ bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
+ }
+
+ U8 texgen = getTextureEntry()->getTexGen();
+ if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ { //planar texgen needs binormals
+ mVObjp->getVolume()->genTangents(face_index);
+ }
+
+ U8 tex_mode = 0;
+
+ bool tex_anim = false;
+
+ LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
+ tex_mode = vobj->mTexAnimMode;
+
+ if (vobj->mTextureAnimp)
+ { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
+ tex_anim = true;
+ }
+
+ if (isState(TEXTURE_ANIM))
+ {
+ if (!tex_mode)
+ {
+ clearState(TEXTURE_ANIM);
+ }
+ else
+ {
+ os = ot = 0.f;
+ r = 0.f;
+ cos_ang = 1.f;
+ sin_ang = 0.f;
+ ms = mt = 1.f;
xforms = XFORM_NONE;
- }
+ }
- if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
- { //don't override texture transform during tc bake
- tex_mode = 0;
- }
- }
+ if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
+ { //don't override texture transform during tc bake
+ tex_mode = 0;
+ }
+ }
- LLVector4a scalea;
- scalea.load3(scale.mV);
+ LLVector4a scalea;
+ scalea.load3(scale.mV);
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
-
- if ((mat || gltf_mat) && !do_bump)
- {
- do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
- || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
- }
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
+ if ((mat || gltf_mat) && !do_bump)
+ {
+ do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
+ || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
+ }
+
// For GLTF materials: Transforms will be applied later
- bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat;
+ bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat;
- if (!do_bump)
- { //not bump mapped, might be able to do a cheap update
- mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);
+ if (!do_bump)
+ { //not bump mapped, might be able to do a cheap update
+ mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);
- if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
- {
+ if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen");
- if (!do_tex_mat)
- {
- if (xforms == XFORM_NONE)
- {
+ if (!do_tex_mat)
+ {
+ if (xforms == XFORM_NONE)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1");
- S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
- }
- else
- {
+ S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
+ }
+ else
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 2");
- F32* dst = (F32*) tex_coords0.get();
- LLVector4a* src = (LLVector4a*) vf.mTexCoords;
-
- LLVector4a trans;
- trans.splat(-0.5f);
-
- LLVector4a rot0;
- rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
-
- LLVector4a rot1;
- rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
-
- LLVector4a scale;
- scale.set(ms, mt, ms, mt);
-
- LLVector4a offset;
- offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
-
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<2>();
- mask.setElement<3>();
-
- U32 count = num_vertices/2 + num_vertices%2;
-
- for (S32 i = 0; i < count; i++)
- {
- LLVector4a res = *src++;
- xform4a(res, trans, mask, rot0, rot1, offset, scale);
- res.store4a(dst);
- dst += 4;
- }
- }
- }
- else
- { //do tex mat, no texgen, no bump
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
-
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- *tex_coords0++ = tc;
- }
- }
- }
- else
- { //no bump, tex gen planar
+ F32* dst = (F32*) tex_coords0.get();
+ LLVector4a* src = (LLVector4a*) vf.mTexCoords;
+
+ LLVector4a trans;
+ trans.splat(-0.5f);
+
+ LLVector4a rot0;
+ rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
+
+ LLVector4a rot1;
+ rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
+
+ LLVector4a scale;
+ scale.set(ms, mt, ms, mt);
+
+ LLVector4a offset;
+ offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<2>();
+ mask.setElement<3>();
+
+ U32 count = num_vertices/2 + num_vertices%2;
+
+ for (S32 i = 0; i < count; i++)
+ {
+ LLVector4a res = *src++;
+ xform4a(res, trans, mask, rot0, rot1, offset, scale);
+ res.store4a(dst);
+ dst += 4;
+ }
+ }
+ }
+ else
+ { //do tex mat, no texgen, no bump
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ *tex_coords0++ = tc;
+ }
+ }
+ }
+ else
+ { //no bump, tex gen planar
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen planar");
- if (do_tex_mat)
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
-
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
-
- *tex_coords0++ = tc;
- }
- }
- else if (xforms != XFORM_NONE)
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
-
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
-
- *tex_coords0++ = tc;
- }
- }
- else
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
-
- *tex_coords0++ = tc;
- }
- }
- }
- }
- else
- { //bump mapped or has material, just do the whole expensive loop
+ if (do_tex_mat)
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
+
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+
+ *tex_coords0++ = tc;
+ }
+ }
+ else if (xforms != XFORM_NONE)
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
+
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+
+ *tex_coords0++ = tc;
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
+
+ *tex_coords0++ = tc;
+ }
+ }
+ }
+ }
+ else
+ { //bump mapped or has material, just do the whole expensive loop
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen default");
- std::vector<LLVector2> bump_tc;
-
- if (mat && !mat->getNormalID().isNull())
- { //writing out normal and specular texture coordinates, not bump offsets
- do_bump = false;
- }
+ std::vector<LLVector2> bump_tc;
+
+ if (mat && !mat->getNormalID().isNull())
+ { //writing out normal and specular texture coordinates, not bump offsets
+ do_bump = false;
+ }
- LLStrider<LLVector2> dst;
+ LLStrider<LLVector2> dst;
- for (U32 ch = 0; ch < 3; ++ch)
- {
+ for (U32 ch = 0; ch < 3; ++ch)
+ {
S32 xform_channel = XFORM_NONE;
- switch (ch)
- {
- case 0:
+ switch (ch)
+ {
+ case 0:
xform_channel = XFORM_BLINNPHONG_COLOR;
- mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount);
- break;
- case 1:
+ mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount);
+ break;
+ case 1:
xform_channel = XFORM_BLINNPHONG_NORMAL;
- if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
- {
- mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount);
- if (mat && !tex_anim)
- {
- r = mat->getNormalRotation();
- mat->getNormalOffset(os, ot);
- mat->getNormalRepeat(ms, mt);
-
- cos_ang = cos(r);
- sin_ang = sin(r);
-
- }
- }
- else
- {
- continue;
- }
- break;
- case 2:
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
+ {
+ mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount);
+ if (mat && !tex_anim)
+ {
+ r = mat->getNormalRotation();
+ mat->getNormalOffset(os, ot);
+ mat->getNormalRepeat(ms, mt);
+
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+
+ }
+ }
+ else
+ {
+ continue;
+ }
+ break;
+ case 2:
xform_channel = XFORM_BLINNPHONG_SPECULAR;
- if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
- {
- mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount);
- if (mat && !tex_anim)
- {
- r = mat->getSpecularRotation();
- mat->getSpecularOffset(os, ot);
- mat->getSpecularRepeat(ms, mt);
-
- cos_ang = cos(r);
- sin_ang = sin(r);
- }
- }
- else
- {
- continue;
- }
- break;
- }
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
+ {
+ mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount);
+ if (mat && !tex_anim)
+ {
+ r = mat->getSpecularRotation();
+ mat->getSpecularOffset(os, ot);
+ mat->getSpecularRepeat(ms, mt);
+
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+ }
+ }
+ else
+ {
+ continue;
+ }
+ break;
+ }
const bool do_xform = (xforms & xform_channel) != XFORM_NONE;
-
+
for (S32 i = 0; i < num_vertices; i++)
- {
+ {
LLVector2 tc(vf.mTexCoords[i]);
-
+
LLVector4a& norm = vf.mNormals[i];
-
+
LLVector4a& center = *(vf.mCenter);
-
+
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a vec = vf.mPositions[i];
-
+
vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
planarProjection(tc, norm, center, vec);
- }
+ }
}
if (tex_mode && mTextureMatrix)
@@ -1779,239 +1779,239 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bump_tc.push_back(tc);
}
}
- }
-
- if ((!mat && !gltf_mat) && do_bump)
- {
- mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount);
+ }
+ if ((!mat && !gltf_mat) && do_bump)
+ {
+ mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount);
+
mVObjp->getVolume()->genTangents(face_index);
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a tangent = vf.mTangents[i];
-
- LLVector4a binorm;
- binorm.setCross3(vf.mNormals[i], tangent);
- binorm.mul(tangent.getF32ptr()[3]);
-
- LLMatrix4a tangent_to_object;
- tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
- LLVector4a t;
- tangent_to_object.rotate(binormal_dir, t);
- LLVector4a binormal;
- mat_normal.rotate(t, binormal);
-
- //VECTORIZE THIS
- if (mDrawablep->isActive())
- {
- LLVector3 t;
- t.set(binormal.getF32ptr());
- t *= bump_quat;
- binormal.load3(t.mV);
- }
-
- binormal.normalize3fast();
-
- LLVector2 tc = bump_tc[i];
- tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
-
- *tex_coords1++ = tc;
- }
- }
- }
- }
-
- if (rebuild_pos)
- {
- LLVector4a* src = vf.mPositions;
-
- //_mm_prefetch((char*)src, _MM_HINT_T0);
-
- LLVector4a* end = src+num_vertices;
- //LLVector4a* end_64 = end-4;
-
- llassert(num_vertices > 0);
-
- mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount);
-
-
- F32* dst = (F32*) vert.get();
- F32* end_f32 = dst+mGeomCount*4;
-
- //_mm_prefetch((char*)dst, _MM_HINT_NTA);
- //_mm_prefetch((char*)src, _MM_HINT_NTA);
-
- //_mm_prefetch((char*)dst, _MM_HINT_NTA);
-
-
- LLVector4a res0; //,res1,res2,res3;
-
- LLVector4a texIdx;
-
- S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
-
- F32 val = 0.f;
- S32* vp = (S32*) &val;
- *vp = index;
-
- llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
-
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<3>();
-
- texIdx.set(0,0,0,val);
-
- LLVector4a tmp;
-
-
- while (src < end)
- {
- mat_vert.affineTransform(*src++, res0);
- tmp.setSelectWithMask(mask, texIdx, res0);
- tmp.store4a((F32*) dst);
- dst += 4;
- }
-
- while (dst < end_f32)
- {
- res0.store4a((F32*) dst);
- dst += 4;
- }
- }
-
- if (rebuild_normal)
- {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector4a tangent = vf.mTangents[i];
+
+ LLVector4a binorm;
+ binorm.setCross3(vf.mNormals[i], tangent);
+ binorm.mul(tangent.getF32ptr()[3]);
+
+ LLMatrix4a tangent_to_object;
+ tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
+ LLVector4a t;
+ tangent_to_object.rotate(binormal_dir, t);
+ LLVector4a binormal;
+ mat_normal.rotate(t, binormal);
+
+ //VECTORIZE THIS
+ if (mDrawablep->isActive())
+ {
+ LLVector3 t;
+ t.set(binormal.getF32ptr());
+ t *= bump_quat;
+ binormal.load3(t.mV);
+ }
+
+ binormal.normalize3fast();
+
+ LLVector2 tc = bump_tc[i];
+ tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
+
+ *tex_coords1++ = tc;
+ }
+ }
+ }
+ }
+
+ if (rebuild_pos)
+ {
+ LLVector4a* src = vf.mPositions;
+
+ //_mm_prefetch((char*)src, _MM_HINT_T0);
+
+ LLVector4a* end = src+num_vertices;
+ //LLVector4a* end_64 = end-4;
+
+ llassert(num_vertices > 0);
+
+ mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount);
+
+
+ F32* dst = (F32*) vert.get();
+ F32* end_f32 = dst+mGeomCount*4;
+
+ //_mm_prefetch((char*)dst, _MM_HINT_NTA);
+ //_mm_prefetch((char*)src, _MM_HINT_NTA);
+
+ //_mm_prefetch((char*)dst, _MM_HINT_NTA);
+
+
+ LLVector4a res0; //,res1,res2,res3;
+
+ LLVector4a texIdx;
+
+ S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
+
+ F32 val = 0.f;
+ S32* vp = (S32*) &val;
+ *vp = index;
+
+ llassert(index < LLGLSLShader::sIndexedTextureChannels);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ texIdx.set(0,0,0,val);
+
+ LLVector4a tmp;
+
+
+ while (src < end)
+ {
+ mat_vert.affineTransform(*src++, res0);
+ tmp.setSelectWithMask(mask, texIdx, res0);
+ tmp.store4a((F32*) dst);
+ dst += 4;
+ }
+
+ while (dst < end_f32)
+ {
+ res0.store4a((F32*) dst);
+ dst += 4;
+ }
+ }
+
+ if (rebuild_normal)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - normal");
- mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount);
- F32* normals = (F32*) norm.get();
- LLVector4a* src = vf.mNormals;
- LLVector4a* end = src+num_vertices;
-
- while (src < end)
- {
- LLVector4a normal;
- mat_normal.rotate(*src++, normal);
- normal.store4a(normals);
- normals += 4;
- }
- }
-
- if (rebuild_tangent)
- {
+ mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount);
+ F32* normals = (F32*) norm.get();
+ LLVector4a* src = vf.mNormals;
+ LLVector4a* end = src+num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a normal;
+ mat_normal.rotate(*src++, normal);
+ normal.store4a(normals);
+ normals += 4;
+ }
+ }
+
+ if (rebuild_tangent)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tangent");
- mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount);
- F32* tangents = (F32*) tangent.get();
-
+ mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount);
+ F32* tangents = (F32*) tangent.get();
+
mVObjp->getVolume()->genTangents(face_index);
-
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<3>();
-
- LLVector4a* src = vf.mTangents;
- LLVector4a* end = vf.mTangents +num_vertices;
-
- while (src < end)
- {
- LLVector4a tangent_out;
- mat_normal.rotate(*src, tangent_out);
- tangent_out.setSelectWithMask(mask, *src, tangent_out);
- tangent_out.store4a(tangents);
-
- src++;
- tangents += 4;
- }
- }
-
- if (rebuild_weights && vf.mWeights)
- {
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ LLVector4a* src = vf.mTangents;
+ LLVector4a* end = vf.mTangents +num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a tangent_out;
+ mat_normal.rotate(*src, tangent_out);
+ tangent_out.setSelectWithMask(mask, *src, tangent_out);
+ tangent_out.store4a(tangents);
+
+ src++;
+ tangents += 4;
+ }
+ }
+
+ if (rebuild_weights && vf.mWeights)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - weight");
- mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount);
- F32* weights = (F32*) wght.get();
- LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
- }
+ mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount);
+ F32* weights = (F32*) wght.get();
+ LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
+ }
- if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
- {
+ if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - color");
- mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);
-
- LLVector4a src;
-
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = color.asRGBA();
-
- src.loadua((F32*) vec);
-
- F32* dst = (F32*) colors.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
-
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
- }
-
- if (rebuild_emissive)
- {
+ mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);
+
+ LLVector4a src;
+
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = color.asRGBA();
+
+ src.loadua((F32*) vec);
+
+ F32* dst = (F32*) colors.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
+
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
+ }
+
+ if (rebuild_emissive)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - emissive");
- LLStrider<LLColor4U> emissive;
- mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount);
-
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
-
- LLVector4a src;
-
-
- LLColor4U glow4u = LLColor4U(0,0,0,glow);
-
- U32 glow32 = glow4u.asRGBA();
-
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = glow32;
-
- src.loadua((F32*) vec);
-
- F32* dst = (F32*) emissive.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
-
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
- }
- }
-
- if (rebuild_tcoord)
- {
- mTexExtents[0].setVec(0,0);
- mTexExtents[1].setVec(1,1);
- xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
- xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
-
- F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ;
- F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ;
- mTexExtents[0][0] *= es ;
- mTexExtents[1][0] *= es ;
- mTexExtents[0][1] *= et ;
- mTexExtents[1][1] *= et ;
- }
-
-
- return TRUE;
+ LLStrider<LLColor4U> emissive;
+ mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount);
+
+ U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+
+ LLVector4a src;
+
+
+ LLColor4U glow4u = LLColor4U(0,0,0,glow);
+
+ U32 glow32 = glow4u.asRGBA();
+
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+
+ src.loadua((F32*) vec);
+
+ F32* dst = (F32*) emissive.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
+
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
+ }
+ }
+
+ if (rebuild_tcoord)
+ {
+ mTexExtents[0].setVec(0,0);
+ mTexExtents[1].setVec(1,1);
+ xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
+ xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
+
+ F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ;
+ F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ;
+ mTexExtents[0][0] *= es ;
+ mTexExtents[1][0] *= es ;
+ mTexExtents[0][1] *= et ;
+ mTexExtents[1][1] *= et ;
+ }
+
+
+ return TRUE;
}
void LLFace::renderIndexed()
@@ -2024,18 +2024,18 @@ void LLFace::renderIndexed()
}
//check if the face has a media
-BOOL LLFace::hasMedia() const
+BOOL LLFace::hasMedia() const
{
- if(mHasMedia)
- {
- return TRUE ;
- }
- if(mTexture[LLRender::DIFFUSE_MAP].notNull())
- {
- return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
- }
-
- return FALSE ; //no media.
+ if(mHasMedia)
+ {
+ return TRUE ;
+ }
+ if(mTexture[LLRender::DIFFUSE_MAP].notNull())
+ {
+ return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
+ }
+
+ return FALSE ; //no media.
}
const F32 LEAST_IMPORTANCE = 0.05f ;
@@ -2043,65 +2043,65 @@ const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
void LLFace::resetVirtualSize()
{
- setVirtualSize(0.f);
- mImportanceToCamera = 0.f;
+ setVirtualSize(0.f);
+ mImportanceToCamera = 0.f;
}
F32 LLFace::getTextureVirtualSize()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- F32 radius;
- F32 cos_angle_to_view_dir;
- BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
-
- if (mPixelArea < F_ALMOST_ZERO || !in_frustum)
- {
- setVirtualSize(0.f) ;
- return 0.f;
- }
-
- //get area of circle in texture space
- LLVector2 tdim = mTexExtents[1] - mTexExtents[0];
- F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
- if (texel_area <= 0)
- {
- // Probably animated, use default
- texel_area = 1.f;
- }
-
- F32 face_area;
- if (mVObjp->isSculpted() && texel_area > 1.f)
- {
- //sculpts can break assumptions about texel area
- face_area = mPixelArea;
- }
- else
- {
- //apply texel area to face area to get accurate ratio
- //face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
- face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
- }
-
- face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;
- if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
- {
- if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
- {
- face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
- }
- }
-
- setVirtualSize(face_area) ;
-
- return face_area;
+ F32 radius;
+ F32 cos_angle_to_view_dir;
+ BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
+
+ if (mPixelArea < F_ALMOST_ZERO || !in_frustum)
+ {
+ setVirtualSize(0.f) ;
+ return 0.f;
+ }
+
+ //get area of circle in texture space
+ LLVector2 tdim = mTexExtents[1] - mTexExtents[0];
+ F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
+ if (texel_area <= 0)
+ {
+ // Probably animated, use default
+ texel_area = 1.f;
+ }
+
+ F32 face_area;
+ if (mVObjp->isSculpted() && texel_area > 1.f)
+ {
+ //sculpts can break assumptions about texel area
+ face_area = mPixelArea;
+ }
+ else
+ {
+ //apply texel area to face area to get accurate ratio
+ //face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
+ face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
+ }
+
+ face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;
+ if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
+ {
+ if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
+ {
+ face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
+ }
+ }
+
+ setVirtualSize(face_area) ;
+
+ return face_area;
}
BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- //VECTORIZE THIS
- //get area of circle around face
+ //VECTORIZE THIS
+ //get area of circle around face
LLVector4a center;
LLVector4a size;
@@ -2127,237 +2127,237 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
center.load3(getPositionAgent().mV);
size.setSub(mExtents[1], mExtents[0]);
}
- size.mul(0.5f);
-
- LLViewerCamera* camera = LLViewerCamera::getInstance();
-
- F32 size_squared = size.dot3(size).getF32();
- LLVector4a lookAt;
- LLVector4a t;
- t.load3(camera->getOrigin().mV);
- lookAt.setSub(center, t);
-
- F32 dist = lookAt.getLength3().getF32();
- dist = llmax(dist-size.getLength3().getF32(), 0.001f);
- //ramp down distance for nearby objects
- if (dist < 16.f)
- {
- dist /= 16.f;
- dist *= dist;
- dist *= 16.f;
- }
-
- lookAt.normalize3fast() ;
-
- //get area of circle around node
- F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
- radius = app_angle*LLDrawable::sCurPixelAngle;
- mPixelArea = radius*radius * 3.14159f;
- LLVector4a x_axis;
- x_axis.load3(camera->getXAxis().mV);
- cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
-
- //if has media, check if the face is out of the view frustum.
- if(hasMedia())
- {
- if(!camera->AABBInFrustum(center, size))
- {
- mImportanceToCamera = 0.f ;
- return false ;
- }
- if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum
- {
- cos_angle_to_view_dir = 1.0f ;
- }
- else
- {
- LLVector4a d;
- d.setSub(lookAt, x_axis);
-
- if(dist * dist * d.dot3(d) < size_squared)
- {
- cos_angle_to_view_dir = 1.0f ;
- }
- }
- }
-
- if(dist < mBoundingSphereRadius) //camera is very close
- {
- cos_angle_to_view_dir = 1.0f ;
- mImportanceToCamera = 1.0f ;
- }
- else
- {
- mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
- }
-
- return true ;
+ size.mul(0.5f);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ F32 size_squared = size.dot3(size).getF32();
+ LLVector4a lookAt;
+ LLVector4a t;
+ t.load3(camera->getOrigin().mV);
+ lookAt.setSub(center, t);
+
+ F32 dist = lookAt.getLength3().getF32();
+ dist = llmax(dist-size.getLength3().getF32(), 0.001f);
+ //ramp down distance for nearby objects
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
+
+ lookAt.normalize3fast() ;
+
+ //get area of circle around node
+ F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
+ radius = app_angle*LLDrawable::sCurPixelAngle;
+ mPixelArea = radius*radius * 3.14159f;
+ LLVector4a x_axis;
+ x_axis.load3(camera->getXAxis().mV);
+ cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
+
+ //if has media, check if the face is out of the view frustum.
+ if(hasMedia())
+ {
+ if(!camera->AABBInFrustum(center, size))
+ {
+ mImportanceToCamera = 0.f ;
+ return false ;
+ }
+ if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum
+ {
+ cos_angle_to_view_dir = 1.0f ;
+ }
+ else
+ {
+ LLVector4a d;
+ d.setSub(lookAt, x_axis);
+
+ if(dist * dist * d.dot3(d) < size_squared)
+ {
+ cos_angle_to_view_dir = 1.0f ;
+ }
+ }
+ }
+
+ if(dist < mBoundingSphereRadius) //camera is very close
+ {
+ cos_angle_to_view_dir = 1.0f ;
+ mImportanceToCamera = 1.0f ;
+ }
+ else
+ {
+ mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
+ }
+
+ return true ;
}
//the projection of the face partially overlaps with the screen
F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius )
{
- F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()) ;
- F32 center_angle = acosf(cos_angle_to_view_dir) ;
- F32 d = center_angle * LLDrawable::sCurPixelAngle ;
-
- if(d + radius > screen_radius + 5.f)
- {
- //----------------------------------------------
- //calculate the intersection area of two circles
- //F32 radius_square = radius * radius ;
- //F32 d_square = d * d ;
- //F32 screen_radius_square = screen_radius * screen_radius ;
- //face_area =
- // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) +
- // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) -
- // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ;
- //----------------------------------------------
-
- //the above calculation is too expensive
- //the below is a good estimation: bounding box of the bounding sphere:
- F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
- alpha = llclamp(alpha, 0.f, 1.f) ;
- return alpha * alpha ;
- }
- return 1.0f ;
+ F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()) ;
+ F32 center_angle = acosf(cos_angle_to_view_dir) ;
+ F32 d = center_angle * LLDrawable::sCurPixelAngle ;
+
+ if(d + radius > screen_radius + 5.f)
+ {
+ //----------------------------------------------
+ //calculate the intersection area of two circles
+ //F32 radius_square = radius * radius ;
+ //F32 d_square = d * d ;
+ //F32 screen_radius_square = screen_radius * screen_radius ;
+ //face_area =
+ // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) +
+ // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) -
+ // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ;
+ //----------------------------------------------
+
+ //the above calculation is too expensive
+ //the below is a good estimation: bounding box of the bounding sphere:
+ F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
+ alpha = llclamp(alpha, 0.f, 1.f) ;
+ return alpha * alpha ;
+ }
+ return 1.0f ;
}
const S8 FACE_IMPORTANCE_LEVEL = 4 ;
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight}
- {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ;
+ {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ;
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight}
- {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ;
+ {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ;
-//static
+//static
F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
{
- F32 importance = 0.f ;
-
- if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() &&
- dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0])
- {
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- F32 camera_moving_speed = camera->getAverageSpeed() ;
- F32 camera_angular_speed = camera->getAverageAngularSpeed();
-
- if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f)
- {
- //if camera moves or rotates too fast, ignore the importance factor
- return 0.f ;
- }
-
- S32 i = 0 ;
- for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);
- i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
- F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ;
-
- for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ;
- i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
- importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ;
- }
-
- return importance ;
+ F32 importance = 0.f ;
+
+ if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() &&
+ dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0])
+ {
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ F32 camera_moving_speed = camera->getAverageSpeed() ;
+ F32 camera_angular_speed = camera->getAverageAngularSpeed();
+
+ if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f)
+ {
+ //if camera moves or rotates too fast, ignore the importance factor
+ return 0.f ;
+ }
+
+ S32 i = 0 ;
+ for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);
+ i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
+ F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ;
+
+ for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ;
+ i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
+ importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ;
+ }
+
+ return importance ;
}
-//static
+//static
F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area)
{
- if(pixel_area > LLViewerTexture::sMaxSmallImageSize)
- {
- if(importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
- {
- static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ;
- pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ;
- }
- else if(pixel_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
- {
- if(importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
- {
- pixel_area = LLViewerTexture::sMinLargeImageSize ;
- }
- }
- }
-
- return pixel_area ;
+ if(pixel_area > LLViewerTexture::sMaxSmallImageSize)
+ {
+ if(importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
+ {
+ static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ;
+ pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ;
+ }
+ else if(pixel_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
+ {
+ if(importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
+ {
+ pixel_area = LLViewerTexture::sMinLargeImageSize ;
+ }
+ }
+ }
+
+ return pixel_area ;
}
BOOL LLFace::verify(const U32* indices_array) const
{
- BOOL ok = TRUE;
-
- if( mVertexBuffer.isNull() )
- { //no vertex buffer, face is implicitly valid
- return TRUE;
- }
-
- // First, check whether the face data fits within the pool's range.
- if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())
- {
- ok = FALSE;
- LL_INFOS() << "Face references invalid vertices!" << LL_ENDL;
- }
-
- S32 indices_count = (S32)getIndicesCount();
-
- if (!indices_count)
- {
- return TRUE;
- }
-
- if (indices_count > LL_MAX_INDICES_COUNT)
- {
- ok = FALSE;
- LL_INFOS() << "Face has bogus indices count" << LL_ENDL;
- }
-
- if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices())
- {
- ok = FALSE;
- LL_INFOS() << "Face references invalid indices!" << LL_ENDL;
- }
+ BOOL ok = TRUE;
+
+ if( mVertexBuffer.isNull() )
+ { //no vertex buffer, face is implicitly valid
+ return TRUE;
+ }
+
+ // First, check whether the face data fits within the pool's range.
+ if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())
+ {
+ ok = FALSE;
+ LL_INFOS() << "Face references invalid vertices!" << LL_ENDL;
+ }
+
+ S32 indices_count = (S32)getIndicesCount();
+
+ if (!indices_count)
+ {
+ return TRUE;
+ }
+
+ if (indices_count > LL_MAX_INDICES_COUNT)
+ {
+ ok = FALSE;
+ LL_INFOS() << "Face has bogus indices count" << LL_ENDL;
+ }
+
+ if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices())
+ {
+ ok = FALSE;
+ LL_INFOS() << "Face references invalid indices!" << LL_ENDL;
+ }
#if 0
- S32 geom_start = getGeomStart();
- S32 geom_count = mGeomCount;
-
- const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices();
-
- for (S32 i = 0; i < indices_count; i++)
- {
- S32 delta = indicesp[i] - geom_start;
- if (0 > delta)
- {
- LL_WARNS() << "Face index too low!" << LL_ENDL;
- LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << LL_ENDL;
- ok = FALSE;
- }
- else if (delta >= geom_count)
- {
- LL_WARNS() << "Face index too high!" << LL_ENDL;
- LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << LL_ENDL;
- ok = FALSE;
- }
- }
+ S32 geom_start = getGeomStart();
+ S32 geom_count = mGeomCount;
+
+ const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices();
+
+ for (S32 i = 0; i < indices_count; i++)
+ {
+ S32 delta = indicesp[i] - geom_start;
+ if (0 > delta)
+ {
+ LL_WARNS() << "Face index too low!" << LL_ENDL;
+ LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << LL_ENDL;
+ ok = FALSE;
+ }
+ else if (delta >= geom_count)
+ {
+ LL_WARNS() << "Face index too high!" << LL_ENDL;
+ LL_INFOS() << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << LL_ENDL;
+ ok = FALSE;
+ }
+ }
#endif
- if (!ok)
- {
- printDebugInfo();
- }
- return ok;
+ if (!ok)
+ {
+ printDebugInfo();
+ }
+ return ok;
}
void LLFace::setViewerObject(LLViewerObject* objp)
{
- mVObjp = objp;
+ mVObjp = objp;
}
const LLMatrix4& LLFace::getRenderMatrix() const
{
- return mDrawablep->getRenderMatrix();
+ return mDrawablep->getRenderMatrix();
}
//============================================================================
@@ -2365,78 +2365,78 @@ const LLMatrix4& LLFace::getRenderMatrix() const
S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
{
- if (!mGeomCount)
- {
- return -1;
- }
-
- // llassert(mGeomIndex >= 0);
- mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);
- return mGeomIndex;
+ if (!mGeomCount)
+ {
+ return -1;
+ }
+
+ // llassert(mGeomIndex >= 0);
+ mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);
+ return mGeomIndex;
}
-S32 LLFace::getIndices(LLStrider<U16> &indicesp)
+S32 LLFace::getIndices(LLStrider<U16> &indicesp)
{
- mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
- llassert(indicesp[0] != indicesp[1]);
- return mIndicesIndex;
+ mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
+ llassert(indicesp[0] != indicesp[1]);
+ return mIndicesIndex;
}
LLVector3 LLFace::getPositionAgent() const
{
- if (mDrawablep->isStatic())
- {
- return mCenterAgent;
- }
- else
- {
- return mCenterLocal * getRenderMatrix();
- }
+ if (mDrawablep->isStatic())
+ {
+ return mCenterAgent;
+ }
+ else
+ {
+ return mCenterLocal * getRenderMatrix();
+ }
}
LLViewerTexture* LLFace::getTexture(U32 ch) const
{
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- return mTexture[ch] ;
+ return mTexture[ch] ;
}
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
{
- if (buffer)
- {
- LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize());
- }
-
- if (mVertexBuffer)
- {
- LLSculptIDSize::instance().dec(mDrawablep);
- }
-
- mVertexBuffer = buffer;
- llassert(verify());
+ if (buffer)
+ {
+ LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize());
+ }
+
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
+
+ mVertexBuffer = buffer;
+ llassert(verify());
}
void LLFace::clearVertexBuffer()
{
- if (mVertexBuffer)
- {
- LLSculptIDSize::instance().dec(mDrawablep);
- }
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
- mVertexBuffer = NULL;
+ mVertexBuffer = NULL;
}
S32 LLFace::getRiggedIndex(U32 type) const
{
- if (mRiggedIndex.empty())
- {
- return -1;
- }
+ if (mRiggedIndex.empty())
+ {
+ return -1;
+ }
- llassert(type < mRiggedIndex.size());
+ llassert(type < mRiggedIndex.size());
- return mRiggedIndex[type];
+ return mRiggedIndex[type];
}
U64 LLFace::getSkinHash()
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 99139e6528..9fff505c2a 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfeaturemanager.cpp
* @brief LLFeatureManager class implementation
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -71,12 +71,12 @@ const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
#if 0 // consuming code in #if 0 below
#endif
LLFeatureInfo::LLFeatureInfo(const std::string& name, const BOOL available, const F32 level)
- : mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
+ : mValid(TRUE), mName(name), mAvailable(available), mRecommendedLevel(level)
{
}
LLFeatureList::LLFeatureList(const std::string& name)
- : mName(name)
+ : mName(name)
{
}
@@ -86,293 +86,293 @@ LLFeatureList::~LLFeatureList()
void LLFeatureList::addFeature(const std::string& name, const BOOL available, const F32 level)
{
- if (mFeatures.count(name))
- {
- LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL;
- }
+ if (mFeatures.count(name))
+ {
+ LL_WARNS("RenderInit") << "LLFeatureList::Attempting to add preexisting feature " << name << LL_ENDL;
+ }
- LLFeatureInfo fi(name, available, level);
+ LLFeatureInfo fi(name, available, level);
LL_DEBUGS_ONCE("RenderInit") << "Feature '" << name << "' "
<< (available ? "" : "not " ) << "available"
<< " at " << level
<< LL_ENDL;
- mFeatures[name] = fi;
+ mFeatures[name] = fi;
}
BOOL LLFeatureList::isFeatureAvailable(const std::string& name)
{
- if (mFeatures.count(name))
- {
- return mFeatures[name].mAvailable;
- }
-
- LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL;
-
- // changing this to TRUE so you have to explicitly disable
- // something for it to be disabled
- return TRUE;
+ if (mFeatures.count(name))
+ {
+ return mFeatures[name].mAvailable;
+ }
+
+ LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list!" << LL_ENDL;
+
+ // changing this to TRUE so you have to explicitly disable
+ // something for it to be disabled
+ return TRUE;
}
F32 LLFeatureList::getRecommendedValue(const std::string& name)
{
- if (mFeatures.count(name) && isFeatureAvailable(name))
- {
+ if (mFeatures.count(name) && isFeatureAvailable(name))
+ {
LL_DEBUGS_ONCE("RenderInit") << "Setting '" << name << "' to recommended value " << mFeatures[name].mRecommendedLevel << LL_ENDL;
- return mFeatures[name].mRecommendedLevel;
- }
+ return mFeatures[name].mRecommendedLevel;
+ }
- LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL;
- return 0;
+ LL_WARNS_ONCE("RenderInit") << "Feature " << name << " not on feature list or not available!" << LL_ENDL;
+ return 0;
}
BOOL LLFeatureList::maskList(LLFeatureList &mask)
{
- LL_DEBUGS_ONCE() << "Masking with " << mask.mName << LL_ENDL;
- //
- // Lookup the specified feature mask, and overlay it on top of the
- // current feature mask.
- //
-
- LLFeatureInfo mask_fi;
-
- feature_map_t::iterator feature_it;
- for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it)
- {
- mask_fi = feature_it->second;
- //
- // Look for the corresponding feature
- //
- if (!mFeatures.count(mask_fi.mName))
- {
- LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL;
- continue;
- }
-
- LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName];
- if (mask_fi.mAvailable && !cur_fi.mAvailable)
- {
- LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL;
- continue;
- }
- cur_fi.mAvailable = mask_fi.mAvailable;
- cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel);
- LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName
- << " Feature " << mask_fi.mName
- << " Mask: " << mask_fi.mRecommendedLevel
- << " Now: " << cur_fi.mRecommendedLevel << LL_ENDL;
- }
-
- LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl;
- // Will conditionally call dump only if the above message will be logged, thanks
- // to it being wrapped by the LL_DEBUGS and LL_ENDL macros.
- dump();
- LL_CONT << LL_ENDL;
-
- return TRUE;
+ LL_DEBUGS_ONCE() << "Masking with " << mask.mName << LL_ENDL;
+ //
+ // Lookup the specified feature mask, and overlay it on top of the
+ // current feature mask.
+ //
+
+ LLFeatureInfo mask_fi;
+
+ feature_map_t::iterator feature_it;
+ for (feature_it = mask.mFeatures.begin(); feature_it != mask.mFeatures.end(); ++feature_it)
+ {
+ mask_fi = feature_it->second;
+ //
+ // Look for the corresponding feature
+ //
+ if (!mFeatures.count(mask_fi.mName))
+ {
+ LL_WARNS("RenderInit") << "Feature " << mask_fi.mName << " in mask not in top level!" << LL_ENDL;
+ continue;
+ }
+
+ LLFeatureInfo &cur_fi = mFeatures[mask_fi.mName];
+ if (mask_fi.mAvailable && !cur_fi.mAvailable)
+ {
+ LL_WARNS("RenderInit") << "Mask attempting to reenabling disabled feature, ignoring " << cur_fi.mName << LL_ENDL;
+ continue;
+ }
+ cur_fi.mAvailable = mask_fi.mAvailable;
+ cur_fi.mRecommendedLevel = llmin(cur_fi.mRecommendedLevel, mask_fi.mRecommendedLevel);
+ LL_DEBUGS("RenderInit") << "Feature mask " << mask.mName
+ << " Feature " << mask_fi.mName
+ << " Mask: " << mask_fi.mRecommendedLevel
+ << " Now: " << cur_fi.mRecommendedLevel << LL_ENDL;
+ }
+
+ LL_DEBUGS("RenderInit") << "After applying mask " << mask.mName << std::endl;
+ // Will conditionally call dump only if the above message will be logged, thanks
+ // to it being wrapped by the LL_DEBUGS and LL_ENDL macros.
+ dump();
+ LL_CONT << LL_ENDL;
+
+ return TRUE;
}
void LLFeatureList::dump()
{
- LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL;
-
- LLFeatureInfo fi;
- feature_map_t::iterator feature_it;
- for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it)
- {
- fi = feature_it->second;
- LL_DEBUGS("RenderInit") << "With " << mName << " feature " << fi.mName << " " << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL;
- }
+ LL_DEBUGS("RenderInit") << "Feature list: " << mName << LL_ENDL;
+
+ LLFeatureInfo fi;
+ feature_map_t::iterator feature_it;
+ for (feature_it = mFeatures.begin(); feature_it != mFeatures.end(); ++feature_it)
+ {
+ fi = feature_it->second;
+ LL_DEBUGS("RenderInit") << "With " << mName << " feature " << fi.mName << " " << fi.mAvailable << ":" << fi.mRecommendedLevel << LL_ENDL;
+ }
}
static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of
- ("Low")
- ("LowMid")
- ("Mid")
- ("MidHigh")
- ("High")
- ("HighUltra")
- ("Ultra")
+ ("Low")
+ ("LowMid")
+ ("Mid")
+ ("MidHigh")
+ ("High")
+ ("HighUltra")
+ ("Ultra")
;
U32 LLFeatureManager::getMaxGraphicsLevel() const
{
- return sGraphicsLevelNames.size() - 1;
+ return sGraphicsLevelNames.size() - 1;
}
bool LLFeatureManager::isValidGraphicsLevel(U32 level) const
{
- return (level <= getMaxGraphicsLevel());
+ return (level <= getMaxGraphicsLevel());
}
std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const
{
- if (isValidGraphicsLevel(level))
- {
- return sGraphicsLevelNames[level];
- }
- return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
- << getMaxGraphicsLevel());
+ if (isValidGraphicsLevel(level))
+ {
+ return sGraphicsLevelNames[level];
+ }
+ return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
+ << getMaxGraphicsLevel());
}
S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const
{
- const std::string FixedFunction("FixedFunction");
- std::string rname(name);
- if (LLStringUtil::endsWith(rname, FixedFunction))
- {
- // chop off any "FixedFunction" suffix
- rname = rname.substr(0, rname.length() - FixedFunction.length());
- }
- for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
- {
- if (sGraphicsLevelNames[i] == rname)
- {
- return i;
- }
- }
- return -1;
+ const std::string FixedFunction("FixedFunction");
+ std::string rname(name);
+ if (LLStringUtil::endsWith(rname, FixedFunction))
+ {
+ // chop off any "FixedFunction" suffix
+ rname = rname.substr(0, rname.length() - FixedFunction.length());
+ }
+ for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
+ {
+ if (sGraphicsLevelNames[i] == rname)
+ {
+ return i;
+ }
+ }
+ return -1;
}
LLFeatureList *LLFeatureManager::findMask(const std::string& name)
{
- if (mMaskList.count(name))
- {
- return mMaskList[name];
- }
+ if (mMaskList.count(name))
+ {
+ return mMaskList[name];
+ }
- return NULL;
+ return NULL;
}
BOOL LLFeatureManager::maskFeatures(const std::string& name)
{
- LLFeatureList *maskp = findMask(name);
- if (!maskp)
- {
- LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL;
- return FALSE;
- }
- LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL;
- return maskList(*maskp);
+ LLFeatureList *maskp = findMask(name);
+ if (!maskp)
+ {
+ LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL;
+ return FALSE;
+ }
+ LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL;
+ return maskList(*maskp);
}
bool LLFeatureManager::loadFeatureTables()
{
- // *TODO - if I or anyone else adds something else to the skipped list
- // make this data driven. Put it in the feature table and parse it
- // correctly
- mSkippedFeatures.insert("RenderAnisotropic");
- mSkippedFeatures.insert("RenderGamma");
- mSkippedFeatures.insert("RenderVBOEnable");
- mSkippedFeatures.insert("RenderFogRatio");
+ // *TODO - if I or anyone else adds something else to the skipped list
+ // make this data driven. Put it in the feature table and parse it
+ // correctly
+ mSkippedFeatures.insert("RenderAnisotropic");
+ mSkippedFeatures.insert("RenderGamma");
+ mSkippedFeatures.insert("RenderVBOEnable");
+ mSkippedFeatures.insert("RenderFogRatio");
- // first table is install with app
- std::string app_path = gDirUtilp->getAppRODataDir();
- app_path += gDirUtilp->getDirDelimiter();
+ // first table is install with app
+ std::string app_path = gDirUtilp->getAppRODataDir();
+ app_path += gDirUtilp->getDirDelimiter();
- std::string filename;
- filename = FEATURE_TABLE_FILENAME;
+ std::string filename;
+ filename = FEATURE_TABLE_FILENAME;
- app_path += filename;
+ app_path += filename;
- bool parse_ok = parseFeatureTable(app_path);
+ bool parse_ok = parseFeatureTable(app_path);
- return parse_ok;
+ return parse_ok;
}
bool LLFeatureManager::parseFeatureTable(std::string filename)
{
- LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
-
- llifstream file;
- std::string name;
- U32 version;
-
- cleanupFeatureTables(); // in case an earlier attempt left partial results
- file.open(filename.c_str()); /*Flawfinder: ignore*/
-
- if (!file)
- {
- LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL;
- return FALSE;
- }
-
- // Check file version
- file >> name;
- if (name != "version")
- {
- LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
- return false;
- }
- file >> version;
-
- mTableVersion = version;
- LL_INFOS("RenderInit") << "Found feature table version " << version << LL_ENDL;
-
- LLFeatureList *flp = NULL;
- bool parse_ok = true;
- while (parse_ok && file >> name )
- {
- char buffer[MAX_STRING]; /*Flawfinder: ignore*/
-
- if (name.substr(0,2) == "//")
- {
- // This is a comment.
- file.getline(buffer, MAX_STRING);
- continue;
- }
-
- if (name == "list")
- {
- LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
- if (flp)
- {
- flp->dump();
- }
- else
- {
- LL_CONT << "No current list";
- }
- LL_CONT << LL_ENDL;
-
- // It's a new mask, create it.
- file >> name;
- if (!mMaskList.count(name))
- {
+ LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
+
+ llifstream file;
+ std::string name;
+ U32 version;
+
+ cleanupFeatureTables(); // in case an earlier attempt left partial results
+ file.open(filename.c_str()); /*Flawfinder: ignore*/
+
+ if (!file)
+ {
+ LL_WARNS("RenderInit") << "Unable to open feature table " << filename << LL_ENDL;
+ return FALSE;
+ }
+
+ // Check file version
+ file >> name;
+ if (name != "version")
+ {
+ LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
+ return false;
+ }
+ file >> version;
+
+ mTableVersion = version;
+ LL_INFOS("RenderInit") << "Found feature table version " << version << LL_ENDL;
+
+ LLFeatureList *flp = NULL;
+ bool parse_ok = true;
+ while (parse_ok && file >> name )
+ {
+ char buffer[MAX_STRING]; /*Flawfinder: ignore*/
+
+ if (name.substr(0,2) == "//")
+ {
+ // This is a comment.
+ file.getline(buffer, MAX_STRING);
+ continue;
+ }
+
+ if (name == "list")
+ {
+ LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
+ if (flp)
+ {
+ flp->dump();
+ }
+ else
+ {
+ LL_CONT << "No current list";
+ }
+ LL_CONT << LL_ENDL;
+
+ // It's a new mask, create it.
+ file >> name;
+ if (!mMaskList.count(name))
+ {
flp = new LLFeatureList(name);
mMaskList[name] = flp;
}
else
{
- LL_WARNS("RenderInit") << "Overriding mask '" << name << "'; this is invalid!" << LL_ENDL;
- parse_ok = false;
- }
- }
- else
- {
- if (flp)
- {
+ LL_WARNS("RenderInit") << "Overriding mask '" << name << "'; this is invalid!" << LL_ENDL;
+ parse_ok = false;
+ }
+ }
+ else
+ {
+ if (flp)
+ {
S32 available;
F32 recommended;
file >> available >> recommended;
flp->addFeature(name, available, recommended);
}
- else
- {
- LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
- parse_ok = false;
- }
- }
- }
- file.close();
-
- if (!parse_ok)
- {
- LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
- cleanupFeatureTables();
- }
-
- return parse_ok;
+ else
+ {
+ LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
+ parse_ok = false;
+ }
+ }
+ }
+ file.close();
+
+ if (!parse_ok)
+ {
+ LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
+ cleanupFeatureTables();
+ }
+
+ return parse_ok;
}
F32 gpu_benchmark();
@@ -382,9 +382,9 @@ F32 gpu_benchmark();
F32 logExceptionBenchmark()
{
// FIXME: gpu_benchmark uses many C++ classes on the stack to control state.
- // SEH exceptions with our current exception handling options do not call
+ // SEH exceptions with our current exception handling options do not call
// destructors for these classes, resulting in an undefined state should
- // this handler be invoked.
+ // this handler be invoked.
F32 gbps = -1;
__try
{
@@ -406,25 +406,25 @@ F32 logExceptionBenchmark()
bool LLFeatureManager::loadGPUClass()
{
- if (!gSavedSettings.getBOOL("SkipBenchmark"))
- {
- F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
- //get memory bandwidth from benchmark
- F32 gbps;
- try
- {
+ if (!gSavedSettings.getBOOL("SkipBenchmark"))
+ {
+ F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
+ //get memory bandwidth from benchmark
+ F32 gbps;
+ try
+ {
#if LL_WINDOWS
- gbps = logExceptionBenchmark();
+ gbps = logExceptionBenchmark();
#else
- gbps = gpu_benchmark();
+ gbps = gpu_benchmark();
#endif
- }
- catch (const std::exception& e)
- {
- gbps = -1.f;
- LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
- }
-
+ }
+ catch (const std::exception& e)
+ {
+ gbps = -1.f;
+ LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
+ }
+
mGPUMemoryBandwidth = gbps;
// bias by CPU speed
@@ -433,36 +433,36 @@ bool LLFeatureManager::loadGPUClass()
F32 cpu_bias = llclamp(cpu_mhz / cpu_basis_mhz, 0.5f, 1.f);
gbps *= cpu_bias;
- if (gbps < 0.f)
- { //couldn't bench, default to Low
- #if LL_DARWIN
- //GLVersion is misleading on OSX, just default to class 3 if we can't bench
- LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
- mGPUClass = GPU_CLASS_3;
- #else
- mGPUClass = GPU_CLASS_0;
- #endif
- }
- else if (gbps <= class1_gbps)
- {
- mGPUClass = GPU_CLASS_1;
- }
- else if (gbps <= class1_gbps *2.f)
- {
- mGPUClass = GPU_CLASS_2;
- }
- else if (gbps <= class1_gbps*4.f)
- {
- mGPUClass = GPU_CLASS_3;
- }
- else if (gbps <= class1_gbps*8.f)
- {
- mGPUClass = GPU_CLASS_4;
- }
- else
- {
- mGPUClass = GPU_CLASS_5;
- }
+ if (gbps < 0.f)
+ { //couldn't bench, default to Low
+ #if LL_DARWIN
+ //GLVersion is misleading on OSX, just default to class 3 if we can't bench
+ LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
+ mGPUClass = GPU_CLASS_3;
+ #else
+ mGPUClass = GPU_CLASS_0;
+ #endif
+ }
+ else if (gbps <= class1_gbps)
+ {
+ mGPUClass = GPU_CLASS_1;
+ }
+ else if (gbps <= class1_gbps *2.f)
+ {
+ mGPUClass = GPU_CLASS_2;
+ }
+ else if (gbps <= class1_gbps*4.f)
+ {
+ mGPUClass = GPU_CLASS_3;
+ }
+ else if (gbps <= class1_gbps*8.f)
+ {
+ mGPUClass = GPU_CLASS_4;
+ }
+ else
+ {
+ mGPUClass = GPU_CLASS_5;
+ }
#if LL_WINDOWS
const F32Gigabytes MIN_PHYSICAL_MEMORY(2);
@@ -475,118 +475,118 @@ bool LLFeatureManager::loadGPUClass()
mGPUClass = (EGPUClass)(mGPUClass - 1);
}
#endif //LL_WINDOWS
- } //end if benchmark
- else
- {
- //setting says don't benchmark MAINT-7558
+ } //end if benchmark
+ else
+ {
+ //setting says don't benchmark MAINT-7558
LL_WARNS("RenderInit") << "Setting 'SkipBenchmark' is true; defaulting to class 1 (may be required for some GPUs)" << LL_ENDL;
+
+ mGPUClass = GPU_CLASS_1;
+ }
- mGPUClass = GPU_CLASS_1;
- }
-
- // defaults
- mGPUString = gGLManager.getRawGLString();
- mGPUSupported = TRUE;
+ // defaults
+ mGPUString = gGLManager.getRawGLString();
+ mGPUSupported = TRUE;
- return true; // indicates that a gpu value was established
+ return true; // indicates that a gpu value was established
}
void LLFeatureManager::cleanupFeatureTables()
{
- std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
- mMaskList.clear();
+ std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
+ mMaskList.clear();
}
void LLFeatureManager::initSingleton()
{
- // load the tables
- loadFeatureTables();
+ // load the tables
+ loadFeatureTables();
- // get the gpu class
- loadGPUClass();
+ // get the gpu class
+ loadGPUClass();
- // apply the base masks, so we know if anything is disabled
- applyBaseMasks();
+ // apply the base masks, so we know if anything is disabled
+ applyBaseMasks();
}
void LLFeatureManager::applyRecommendedSettings()
{
- // apply saved settings
- // cap the level at 2 (high)
- U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
-
- LL_INFOS("RenderInit") << "Applying Recommended Features for level " << level << LL_ENDL;
-
- setGraphicsLevel(level, false);
- gSavedSettings.setU32("RenderQualityPerformance", level);
-
- // now apply the tweaks to draw distance
- // these are double negatives, because feature masks only work by
- // downgrading values, so i needed to make a true value go to false
- // for certain cards, thus the awkward name, "Disregard..."
- if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance"))
- {
- gSavedSettings.setF32("RenderFarClip", 96.0f);
- }
- else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance"))
- {
- gSavedSettings.setF32("RenderFarClip", 128.0f);
- }
+ // apply saved settings
+ // cap the level at 2 (high)
+ U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
+
+ LL_INFOS("RenderInit") << "Applying Recommended Features for level " << level << LL_ENDL;
+
+ setGraphicsLevel(level, false);
+ gSavedSettings.setU32("RenderQualityPerformance", level);
+
+ // now apply the tweaks to draw distance
+ // these are double negatives, because feature masks only work by
+ // downgrading values, so i needed to make a true value go to false
+ // for certain cards, thus the awkward name, "Disregard..."
+ if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance"))
+ {
+ gSavedSettings.setF32("RenderFarClip", 96.0f);
+ }
+ else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance"))
+ {
+ gSavedSettings.setF32("RenderFarClip", 128.0f);
+ }
}
void LLFeatureManager::applyFeatures(bool skipFeatures)
{
- // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt
+ // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt
#ifndef LL_RELEASE_FOR_DOWNLOAD
- dump();
+ dump();
#endif
- // scroll through all of these and set their corresponding control value
- for(feature_map_t::iterator mIt = mFeatures.begin();
- mIt != mFeatures.end();
- ++mIt)
- {
- // skip features you want to skip
- // do this for when you don't want to change certain settings
- if(skipFeatures)
- {
- if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end())
- {
- continue;
- }
- }
-
- // get the control setting
- LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
- if(ctrl == NULL)
- {
- LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
- continue;
- }
-
- // handle all the different types
- if(ctrl->isType(TYPE_BOOLEAN))
- {
- gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first));
- }
- else if (ctrl->isType(TYPE_S32))
- {
- gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first));
- }
- else if (ctrl->isType(TYPE_U32))
- {
- gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first));
- }
- else if (ctrl->isType(TYPE_F32))
- {
- gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first));
- }
- else
- {
- LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
- }
- }
+ // scroll through all of these and set their corresponding control value
+ for(feature_map_t::iterator mIt = mFeatures.begin();
+ mIt != mFeatures.end();
+ ++mIt)
+ {
+ // skip features you want to skip
+ // do this for when you don't want to change certain settings
+ if(skipFeatures)
+ {
+ if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end())
+ {
+ continue;
+ }
+ }
+
+ // get the control setting
+ LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
+ if(ctrl == NULL)
+ {
+ LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
+ continue;
+ }
+
+ // handle all the different types
+ if(ctrl->isType(TYPE_BOOLEAN))
+ {
+ gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first));
+ }
+ else if (ctrl->isType(TYPE_S32))
+ {
+ gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first));
+ }
+ else if (ctrl->isType(TYPE_U32))
+ {
+ gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first));
+ }
+ else if (ctrl->isType(TYPE_F32))
+ {
+ gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first));
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
+ }
+ }
}
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
@@ -609,65 +609,69 @@ void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
void LLFeatureManager::applyBaseMasks()
{
- // reapply masks
- mFeatures.clear();
-
- LLFeatureList* maskp = findMask("all");
- if(maskp == NULL)
- {
- LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL;
- return;
- }
-
- mFeatures = maskp->getFeatures();
-
- // mask class
- if (mGPUClass >= 0 && mGPUClass < 6)
- {
- const char* class_table[] =
- {
- "Class0",
- "Class1",
- "Class2",
- "Class3",
- "Class4",
- "Class5",
- };
-
- LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
- maskFeatures(class_table[mGPUClass]);
- }
- else
- {
- LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL;
- maskFeatures("Unknown");
- }
-
- // now all those wacky ones
- if (gGLManager.mIsNVIDIA)
- {
- maskFeatures("NVIDIA");
- }
- if (gGLManager.mIsAMD)
- {
- maskFeatures("AMD");
- }
- if (gGLManager.mIsIntel)
- {
- maskFeatures("Intel");
- }
- if (gGLManager.mGLVersion < 3.f)
- {
- maskFeatures("OpenGLPre30");
- }
- if (gGLManager.mNumTextureImageUnits <= 8)
- {
- maskFeatures("TexUnit8orLess");
- }
- if (gGLManager.mVRAM > 512)
- {
- maskFeatures("VRAMGT512");
- }
+ // reapply masks
+ mFeatures.clear();
+
+ LLFeatureList* maskp = findMask("all");
+ if(maskp == NULL)
+ {
+ LL_WARNS("RenderInit") << "AHH! No \"all\" in feature table!" << LL_ENDL;
+ return;
+ }
+
+ mFeatures = maskp->getFeatures();
+
+ // mask class
+ if (mGPUClass >= 0 && mGPUClass < 6)
+ {
+ const char* class_table[] =
+ {
+ "Class0",
+ "Class1",
+ "Class2",
+ "Class3",
+ "Class4",
+ "Class5",
+ };
+
+ LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
+ maskFeatures(class_table[mGPUClass]);
+ }
+ else
+ {
+ LL_INFOS("RenderInit") << "Setting GPU Class to Unknown" << LL_ENDL;
+ maskFeatures("Unknown");
+ }
+
+ // now all those wacky ones
+ if (gGLManager.mIsNVIDIA)
+ {
+ maskFeatures("NVIDIA");
+ }
+ if (gGLManager.mIsAMD)
+ {
+ maskFeatures("AMD");
+ }
+ if (gGLManager.mIsIntel)
+ {
+ maskFeatures("Intel");
+ }
+ if (gGLManager.mGLVersion < 3.f)
+ {
+ maskFeatures("OpenGLPre30");
+ }
+ if (gGLManager.mNumTextureImageUnits <= 8)
+ {
+ maskFeatures("TexUnit8orLess");
+ }
+ if (gGLManager.mNumTextureImageUnits <= 16)
+ {
+ maskFeatures("TexUnit16orLess");
+ }
+ if (gGLManager.mVRAM > 512)
+ {
+ maskFeatures("VRAMGT512");
+ }
if (gGLManager.mVRAM < 2048)
{
maskFeatures("VRAMLT2GB");
@@ -677,79 +681,79 @@ void LLFeatureManager::applyBaseMasks()
maskFeatures("GL3");
}
- // now mask by gpu string
- // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
- std::string gpustr = mGPUString;
- for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter)
- {
- if (*iter == ' ')
- {
- *iter = '_';
- }
- }
-
- //LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL;
- maskFeatures(gpustr);
-
- if (isSafe())
- {
- maskFeatures("safe");
- }
+ // now mask by gpu string
+ // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
+ std::string gpustr = mGPUString;
+ for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter)
+ {
+ if (*iter == ' ')
+ {
+ *iter = '_';
+ }
+ }
+
+ //LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL;
+ maskFeatures(gpustr);
+
+ if (isSafe())
+ {
+ maskFeatures("safe");
+ }
}
LLSD LLFeatureManager::getRecommendedSettingsMap()
{
- // Create the map and fill it with the hardware recommended settings.
- // It's needed to create an initial Default graphics preset (MAINT-6435).
- // The process is similar to the one LLFeatureManager::applyRecommendedSettings() does.
-
- LLSD map(LLSD::emptyMap());
-
- U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
- LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL;
-
- std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low");
-
- maskFeatures(features);
-
- LLControlVariable* ctrl = gSavedSettings.getControl("RenderQualityPerformance"); // include the quality value for correct preset loading
- map["RenderQualityPerformance"]["Value"] = (LLSD::Integer)level;
- map["RenderQualityPerformance"]["Comment"] = ctrl->getComment();;
- map["RenderQualityPerformance"]["Persist"] = 1;
- map["RenderQualityPerformance"]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
-
-
-
- for (feature_map_t::iterator mIt = mFeatures.begin(); mIt != mFeatures.end(); ++mIt)
- {
- LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
- if (ctrl == NULL)
- {
- LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
- continue;
- }
-
- if (ctrl->isType(TYPE_BOOLEAN))
- {
- map[mIt->first]["Value"] = (LLSD::Boolean)getRecommendedValue(mIt->first);
- }
- else if (ctrl->isType(TYPE_S32) || ctrl->isType(TYPE_U32))
- {
- map[mIt->first]["Value"] = (LLSD::Integer)getRecommendedValue(mIt->first);
- }
- else if (ctrl->isType(TYPE_F32))
- {
- map[mIt->first]["Value"] = (LLSD::Real)getRecommendedValue(mIt->first);
- }
- else
- {
- LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
- continue;
- }
- map[mIt->first]["Comment"] = ctrl->getComment();;
- map[mIt->first]["Persist"] = 1;
- map[mIt->first]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
- }
-
- return map;
+ // Create the map and fill it with the hardware recommended settings.
+ // It's needed to create an initial Default graphics preset (MAINT-6435).
+ // The process is similar to the one LLFeatureManager::applyRecommendedSettings() does.
+
+ LLSD map(LLSD::emptyMap());
+
+ U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
+ LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL;
+
+ std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low");
+
+ maskFeatures(features);
+
+ LLControlVariable* ctrl = gSavedSettings.getControl("RenderQualityPerformance"); // include the quality value for correct preset loading
+ map["RenderQualityPerformance"]["Value"] = (LLSD::Integer)level;
+ map["RenderQualityPerformance"]["Comment"] = ctrl->getComment();;
+ map["RenderQualityPerformance"]["Persist"] = 1;
+ map["RenderQualityPerformance"]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
+
+
+
+ for (feature_map_t::iterator mIt = mFeatures.begin(); mIt != mFeatures.end(); ++mIt)
+ {
+ LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
+ if (ctrl == NULL)
+ {
+ LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
+ continue;
+ }
+
+ if (ctrl->isType(TYPE_BOOLEAN))
+ {
+ map[mIt->first]["Value"] = (LLSD::Boolean)getRecommendedValue(mIt->first);
+ }
+ else if (ctrl->isType(TYPE_S32) || ctrl->isType(TYPE_U32))
+ {
+ map[mIt->first]["Value"] = (LLSD::Integer)getRecommendedValue(mIt->first);
+ }
+ else if (ctrl->isType(TYPE_F32))
+ {
+ map[mIt->first]["Value"] = (LLSD::Real)getRecommendedValue(mIt->first);
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
+ continue;
+ }
+ map[mIt->first]["Comment"] = ctrl->getComment();;
+ map[mIt->first]["Persist"] = 1;
+ map[mIt->first]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
+ }
+
+ return map;
}
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index aa89a19aed..1dd1dbabbe 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -34,18 +34,19 @@
#include "llshadermgr.h"
#include "pipeline.h"
+//static
+LLFetchedGLTFMaterial LLFetchedGLTFMaterial::sDefault;
+
LLFetchedGLTFMaterial::LLFetchedGLTFMaterial()
: LLGLTFMaterial()
, mExpectedFlusTime(0.f)
- , mActive(true)
- , mFetching(false)
{
}
LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
{
-
+
}
LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
@@ -78,7 +79,14 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
{
// dividing the alpha cutoff by transparency here allows the shader to compare against
// the alpha value of the texture without needing the transparency value
- min_alpha = mAlphaCutoff/mBaseColor.mV[3];
+ if (mBaseColor.mV[3] > 0.f)
+ {
+ min_alpha = mAlphaCutoff / mBaseColor.mV[3];
+ }
+ else
+ {
+ min_alpha = 1024.f;
+ }
}
shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
}
@@ -242,10 +250,11 @@ void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> material_co
materialCompleteCallbacks.push_back(material_complete);
}
-void LLFetchedGLTFMaterial::materialComplete()
+void LLFetchedGLTFMaterial::materialComplete(bool success)
{
llassert(mFetching);
mFetching = false;
+ mFetchSuccess = success;
for (std::function<void()> material_complete : materialCompleteCallbacks)
{
@@ -254,55 +263,3 @@ void LLFetchedGLTFMaterial::materialComplete()
materialCompleteCallbacks.clear();
materialCompleteCallbacks.shrink_to_fit();
}
-
-LLPointer<LLViewerFetchedTexture> LLFetchedGLTFMaterial::getUITexture()
-{
- if (mFetching)
- {
- return nullptr;
- }
-
- auto fetch_texture_for_ui = [](LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
- {
- if (id.notNull())
- {
- if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
- {
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if (obj)
- {
- LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
- img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
- }
-
- }
- else
- {
- img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
- }
- if (img)
- {
- img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
- img->forceToSaveRawImage(0);
- }
- };
-
- fetch_texture_for_ui(mBaseColorTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
- fetch_texture_for_ui(mNormalTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
- fetch_texture_for_ui(mMetallicRoughnessTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
- fetch_texture_for_ui(mEmissiveTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
-
- if ((mBaseColorTexture && (mBaseColorTexture->getRawImageLevel() != 0)) ||
- (mNormalTexture && (mNormalTexture->getRawImageLevel() != 0)) ||
- (mMetallicRoughnessTexture && (mMetallicRoughnessTexture->getRawImageLevel() != 0)) ||
- (mEmissiveTexture && (mEmissiveTexture->getRawImageLevel() != 0)))
- {
- return nullptr;
- }
-
- // *HACK: Use one of the PBR texture components as the preview texture for now
- mPreviewTexture = mBaseColorTexture;
-
- return mPreviewTexture;
-}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 3352438660..7550c75b45 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -40,6 +40,8 @@ public:
virtual ~LLFetchedGLTFMaterial();
LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
+ // LLGLTFMaterial::operator== is defined, but LLFetchedGLTFMaterial::operator== is not.
+ bool operator==(const LLGLTFMaterial& rhs) const = delete;
// If this material is loaded, fire the given function
void onMaterialComplete(std::function<void()> material_complete);
@@ -49,8 +51,7 @@ public:
void bind(LLViewerTexture* media_tex = nullptr);
bool isFetching() const { return mFetching; }
-
- LLPointer<LLViewerFetchedTexture> getUITexture();
+ bool isLoaded() const { return !mFetching && mFetchSuccess; }
void addTextureEntry(LLTextureEntry* te) override;
void removeTextureEntry(LLTextureEntry* te) override;
@@ -65,18 +66,18 @@ public:
std::set<LLTextureEntry*> mTextureEntires;
- // Texture used for previewing the material in the UI
- LLPointer<LLViewerFetchedTexture> mPreviewTexture;
-
+ // default material for when assets don't have one
+ static LLFetchedGLTFMaterial sDefault;
protected:
// Lifetime management
-
+
void materialBegin();
- void materialComplete();
+ void materialComplete(bool success);
F64 mExpectedFlusTime; // since epoch in seconds
- bool mActive;
- bool mFetching;
+ bool mActive = true;
+ bool mFetching = false;
+ bool mFetchSuccess = false;
std::vector<std::function<void()>> materialCompleteCallbacks;
};
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index bfdede37bc..b82172c506 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfilepicker.cpp
* @brief OS-specific file picker
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,7 +34,7 @@
#include "llframetimer.h"
#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llwindow.h" // beforeDialog()
+#include "llwindow.h" // beforeDialog()
#if LL_SDL
#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers
@@ -61,6 +61,7 @@ LLFilePicker LLFilePicker::sInstance;
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
+#define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0"
#define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
@@ -75,149 +76,149 @@ LLFilePicker LLFilePicker::sInstance;
// Implementation
//
LLFilePicker::LLFilePicker()
- : mCurrentFile(0),
- mLocked(false)
+ : mCurrentFile(0),
+ mLocked(false)
{
- reset();
+ reset();
#if LL_WINDOWS
- mOFN.lStructSize = sizeof(OPENFILENAMEW);
- mOFN.hwndOwner = NULL; // Set later
- mOFN.hInstance = NULL;
- mOFN.lpstrCustomFilter = NULL;
- mOFN.nMaxCustFilter = 0;
- mOFN.lpstrFile = NULL; // set in open and close
- mOFN.nMaxFile = LL_MAX_PATH;
- mOFN.lpstrFileTitle = NULL;
- mOFN.nMaxFileTitle = 0;
- mOFN.lpstrInitialDir = NULL;
- mOFN.lpstrTitle = NULL;
- mOFN.Flags = 0; // set in open and close
- mOFN.nFileOffset = 0;
- mOFN.nFileExtension = 0;
- mOFN.lpstrDefExt = NULL;
- mOFN.lCustData = 0L;
- mOFN.lpfnHook = NULL;
- mOFN.lpTemplateName = NULL;
- mFilesW[0] = '\0';
+ mOFN.lStructSize = sizeof(OPENFILENAMEW);
+ mOFN.hwndOwner = NULL; // Set later
+ mOFN.hInstance = NULL;
+ mOFN.lpstrCustomFilter = NULL;
+ mOFN.nMaxCustFilter = 0;
+ mOFN.lpstrFile = NULL; // set in open and close
+ mOFN.nMaxFile = LL_MAX_PATH;
+ mOFN.lpstrFileTitle = NULL;
+ mOFN.nMaxFileTitle = 0;
+ mOFN.lpstrInitialDir = NULL;
+ mOFN.lpstrTitle = NULL;
+ mOFN.Flags = 0; // set in open and close
+ mOFN.nFileOffset = 0;
+ mOFN.nFileExtension = 0;
+ mOFN.lpstrDefExt = NULL;
+ mOFN.lCustData = 0L;
+ mOFN.lpfnHook = NULL;
+ mOFN.lpTemplateName = NULL;
+ mFilesW[0] = '\0';
#elif LL_DARWIN
- mPickOptions = 0;
+ mPickOptions = 0;
#endif
}
LLFilePicker::~LLFilePicker()
{
- // nothing
+ // nothing
}
-// utility function to check if access to local file system via file browser
+// utility function to check if access to local file system via file browser
// is enabled and if not, tidy up and indicate we're not allowed to do this.
bool LLFilePicker::check_local_file_access_enabled()
{
- // if local file browsing is turned off, return without opening dialog
- bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
- if ( ! local_file_system_browsing_enabled )
- {
- mFiles.clear();
- return false;
- }
-
- return true;
+ // if local file browsing is turned off, return without opening dialog
+ bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
+ if ( ! local_file_system_browsing_enabled )
+ {
+ mFiles.clear();
+ return false;
+ }
+
+ return true;
}
const std::string LLFilePicker::getFirstFile()
{
- mCurrentFile = 0;
- return getNextFile();
+ mCurrentFile = 0;
+ return getNextFile();
}
const std::string LLFilePicker::getNextFile()
{
- if (mCurrentFile >= getFileCount())
- {
- mLocked = false;
- return std::string();
- }
- else
- {
- return mFiles[mCurrentFile++];
- }
+ if (mCurrentFile >= getFileCount())
+ {
+ mLocked = false;
+ return std::string();
+ }
+ else
+ {
+ return mFiles[mCurrentFile++];
+ }
}
const std::string LLFilePicker::getCurFile()
{
- if (mCurrentFile >= getFileCount())
- {
- mLocked = false;
- return std::string();
- }
- else
- {
- return mFiles[mCurrentFile];
- }
+ if (mCurrentFile >= getFileCount())
+ {
+ mLocked = false;
+ return std::string();
+ }
+ else
+ {
+ return mFiles[mCurrentFile];
+ }
}
void LLFilePicker::reset()
{
- mLocked = false;
- mFiles.clear();
- mCurrentFile = 0;
+ mLocked = false;
+ mFiles.clear();
+ mCurrentFile = 0;
}
#if LL_WINDOWS
BOOL LLFilePicker::setupFilter(ELoadFilter filter)
{
- BOOL res = TRUE;
- switch (filter)
- {
+ BOOL res = TRUE;
+ switch (filter)
+ {
case FFLOAD_ALL:
case FFLOAD_EXE:
- mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \
- SOUND_FILTER \
- IMAGE_FILTER \
- ANIM_FILTER \
- MATERIAL_FILTER \
- L"\0";
- break;
- case FFLOAD_WAV:
- mOFN.lpstrFilter = SOUND_FILTER \
- L"\0";
- break;
- case FFLOAD_IMAGE:
- mOFN.lpstrFilter = IMAGE_FILTER \
- L"\0";
- break;
- case FFLOAD_ANIM:
- mOFN.lpstrFilter = ANIM_FILTER \
- L"\0";
- break;
- case FFLOAD_GLTF:
- mOFN.lpstrFilter = GLTF_FILTER \
- L"\0";
- break;
- case FFLOAD_COLLADA:
- mOFN.lpstrFilter = COLLADA_FILTER \
- L"\0";
- break;
- case FFLOAD_XML:
- mOFN.lpstrFilter = XML_FILTER \
- L"\0";
- break;
- case FFLOAD_SLOBJECT:
- mOFN.lpstrFilter = SLOBJECT_FILTER \
- L"\0";
- break;
- case FFLOAD_RAW:
- mOFN.lpstrFilter = RAW_FILTER \
- L"\0";
- break;
- case FFLOAD_MODEL:
- mOFN.lpstrFilter = MODEL_FILTER \
- L"\0";
- break;
+ mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \
+ SOUND_FILTER \
+ IMAGE_FILTER \
+ ANIM_FILTER \
+ MATERIAL_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_WAV:
+ mOFN.lpstrFilter = SOUND_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_IMAGE:
+ mOFN.lpstrFilter = IMAGE_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_ANIM:
+ mOFN.lpstrFilter = ANIM_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_GLTF:
+ mOFN.lpstrFilter = GLTF_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_COLLADA:
+ mOFN.lpstrFilter = COLLADA_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_XML:
+ mOFN.lpstrFilter = XML_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_SLOBJECT:
+ mOFN.lpstrFilter = SLOBJECT_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_RAW:
+ mOFN.lpstrFilter = RAW_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_MODEL:
+ mOFN.lpstrFilter = MODEL_FILTER \
+ L"\0";
+ break;
case FFLOAD_MATERIAL:
mOFN.lpstrFilter = MATERIAL_FILTER \
L"\0";
@@ -228,70 +229,74 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
IMAGE_FILTER \
L"\0";
break;
- case FFLOAD_SCRIPT:
- mOFN.lpstrFilter = SCRIPT_FILTER \
+ case FFLOAD_HDRI:
+ mOFN.lpstrFilter = HDRI_FILTER \
L"\0";
break;
- case FFLOAD_DICTIONARY:
- mOFN.lpstrFilter = DICTIONARY_FILTER \
- L"\0";
- break;
- default:
- res = FALSE;
- break;
- }
- return res;
+ case FFLOAD_SCRIPT:
+ mOFN.lpstrFilter = SCRIPT_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_DICTIONARY:
+ mOFN.lpstrFilter = DICTIONARY_FILTER \
+ L"\0";
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+ return res;
}
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
{
- if( mLocked )
- {
- return FALSE;
- }
- BOOL success = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- // don't provide default file selection
- mFilesW[0] = '\0';
-
- mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
- mOFN.lpstrFile = mFilesW;
- mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE;
- mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ;
- mOFN.nFilterIndex = 1;
-
- setupFilter(filter);
-
- if (blocking)
- {
- // Modal, so pause agent
- send_agent_pause();
- }
-
- reset();
-
- // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
- success = GetOpenFileName(&mOFN);
- if (success)
- {
- std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
- mFiles.push_back(filename);
- }
-
- if (blocking)
- {
- send_agent_resume();
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- }
-
- return success;
+ if( mLocked )
+ {
+ return FALSE;
+ }
+ BOOL success = FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ // don't provide default file selection
+ mFilesW[0] = '\0';
+
+ mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
+ mOFN.lpstrFile = mFilesW;
+ mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE;
+ mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ;
+ mOFN.nFilterIndex = 1;
+
+ setupFilter(filter);
+
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
+ reset();
+
+ // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
+ success = GetOpenFileName(&mOFN);
+ if (success)
+ {
+ std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
+ mFiles.push_back(filename);
+ }
+
+ if (blocking)
+ {
+ send_agent_resume();
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ }
+
+ return success;
}
BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
@@ -305,79 +310,79 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
{
- if( mLocked )
- {
- return FALSE;
- }
- BOOL success = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- // don't provide default file selection
- mFilesW[0] = '\0';
-
- mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
- mOFN.lpstrFile = mFilesW;
- mOFN.nFilterIndex = 1;
- mOFN.nMaxFile = FILENAME_BUFFER_SIZE;
- mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR |
- OFN_EXPLORER | OFN_ALLOWMULTISELECT;
-
- setupFilter(filter);
-
- reset();
-
- if (blocking)
- {
- // Modal, so pause agent
- send_agent_pause();
- }
-
- // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
- success = GetOpenFileName(&mOFN); // pauses until ok or cancel.
- if( success )
- {
- // The getopenfilename api doesn't tell us if we got more than
- // one file, so we have to test manually by checking string
- // lengths.
- if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/
- {
- std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
- mFiles.push_back(filename);
- }
- else
- {
- mLocked = true;
- WCHAR* tptrw = mFilesW;
- std::string dirname;
- while(1)
- {
- if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0'
- break;
- if (*tptrw == 0)
- tptrw++; // shouldn't happen?
- std::string filename = utf16str_to_utf8str(llutf16string(tptrw));
- if (dirname.empty())
- dirname = filename + "\\";
- else
- mFiles.push_back(dirname + filename);
- tptrw += wcslen(tptrw);
- }
- }
- }
-
- if (blocking)
- {
- send_agent_resume();
- }
-
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- return success;
+ if( mLocked )
+ {
+ return FALSE;
+ }
+ BOOL success = FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ // don't provide default file selection
+ mFilesW[0] = '\0';
+
+ mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
+ mOFN.lpstrFile = mFilesW;
+ mOFN.nFilterIndex = 1;
+ mOFN.nMaxFile = FILENAME_BUFFER_SIZE;
+ mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR |
+ OFN_EXPLORER | OFN_ALLOWMULTISELECT;
+
+ setupFilter(filter);
+
+ reset();
+
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
+ // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
+ success = GetOpenFileName(&mOFN); // pauses until ok or cancel.
+ if( success )
+ {
+ // The getopenfilename api doesn't tell us if we got more than
+ // one file, so we have to test manually by checking string
+ // lengths.
+ if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/
+ {
+ std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
+ mFiles.push_back(filename);
+ }
+ else
+ {
+ mLocked = true;
+ WCHAR* tptrw = mFilesW;
+ std::string dirname;
+ while(1)
+ {
+ if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0'
+ break;
+ if (*tptrw == 0)
+ tptrw++; // shouldn't happen?
+ std::string filename = utf16str_to_utf8str(llutf16string(tptrw));
+ if (dirname.empty())
+ dirname = filename + "\\";
+ else
+ mFiles.push_back(dirname + filename);
+ tptrw += wcslen(tptrw);
+ }
+ }
+ }
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
+
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ return success;
}
BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
@@ -391,222 +396,222 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
{
- if( mLocked )
- {
- return FALSE;
- }
- BOOL success = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- mOFN.lpstrFile = mFilesW;
- if (!filename.empty())
- {
- llutf16string tstring = utf8str_to_utf16str(filename);
- wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/
- else
- {
- mFilesW[0] = '\0';
- }
- mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
-
- switch( filter )
- {
- case FFSAVE_ALL:
- mOFN.lpstrDefExt = NULL;
- mOFN.lpstrFilter =
- L"All Files (*.*)\0*.*\0" \
- L"WAV Sounds (*.wav)\0*.wav\0" \
- L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \
- L"\0";
- break;
- case FFSAVE_WAV:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"wav";
- mOFN.lpstrFilter =
- L"WAV Sounds (*.wav)\0*.wav\0" \
- L"\0";
- break;
- case FFSAVE_TGA:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"tga";
- mOFN.lpstrFilter =
- L"Targa Images (*.tga)\0*.tga\0" \
- L"\0";
- break;
- case FFSAVE_BMP:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"bmp";
- mOFN.lpstrFilter =
- L"Bitmap Images (*.bmp)\0*.bmp\0" \
- L"\0";
- break;
- case FFSAVE_PNG:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"png";
- mOFN.lpstrFilter =
- L"PNG Images (*.png)\0*.png\0" \
- L"\0";
- break;
- case FFSAVE_TGAPNG:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- //PNG by default
- }
- mOFN.lpstrDefExt = L"png";
- mOFN.lpstrFilter =
- L"PNG Images (*.png)\0*.png\0" \
- L"Targa Images (*.tga)\0*.tga\0" \
- L"\0";
- break;
-
- case FFSAVE_JPEG:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"jpg";
- mOFN.lpstrFilter =
- L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \
- L"\0";
- break;
- case FFSAVE_AVI:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"avi";
- mOFN.lpstrFilter =
- L"AVI Movie File (*.avi)\0*.avi\0" \
- L"\0";
- break;
- case FFSAVE_ANIM:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"xaf";
- mOFN.lpstrFilter =
- L"XAF Anim File (*.xaf)\0*.xaf\0" \
- L"\0";
- break;
- case FFSAVE_GLTF:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"glb";
- mOFN.lpstrFilter =
- L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \
- L"\0";
- break;
- case FFSAVE_XML:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
-
- mOFN.lpstrDefExt = L"xml";
- mOFN.lpstrFilter =
- L"XML File (*.xml)\0*.xml\0" \
- L"\0";
- break;
- case FFSAVE_COLLADA:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"collada";
- mOFN.lpstrFilter =
- L"COLLADA File (*.collada)\0*.collada\0" \
- L"\0";
- break;
- case FFSAVE_RAW:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
- }
- mOFN.lpstrDefExt = L"raw";
- mOFN.lpstrFilter = RAW_FILTER \
- L"\0";
- break;
- case FFSAVE_J2C:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE);
- }
- mOFN.lpstrDefExt = L"j2c";
- mOFN.lpstrFilter =
- L"Compressed Images (*.j2c)\0*.j2c\0" \
- L"\0";
- break;
- case FFSAVE_SCRIPT:
- if (filename.empty())
- {
- wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE);
- }
- mOFN.lpstrDefExt = L"txt";
- mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0";
- break;
- default:
- return FALSE;
- }
-
-
- mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE;
- mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
-
- reset();
-
- if (blocking)
- {
- // Modal, so pause agent
- send_agent_pause();
- }
-
- {
- // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
- try
- {
- success = GetSaveFileName(&mOFN);
- if (success)
- {
- std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
- mFiles.push_back(filename);
- }
- }
- catch (...)
- {
- LOG_UNHANDLED_EXCEPTION("");
- }
- gKeyboard->resetKeys();
- }
-
- if (blocking)
- {
- send_agent_resume();
- }
-
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- return success;
+ if( mLocked )
+ {
+ return FALSE;
+ }
+ BOOL success = FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ mOFN.lpstrFile = mFilesW;
+ if (!filename.empty())
+ {
+ llutf16string tstring = utf8str_to_utf16str(filename);
+ wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/
+ else
+ {
+ mFilesW[0] = '\0';
+ }
+ mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
+
+ switch( filter )
+ {
+ case FFSAVE_ALL:
+ mOFN.lpstrDefExt = NULL;
+ mOFN.lpstrFilter =
+ L"All Files (*.*)\0*.*\0" \
+ L"WAV Sounds (*.wav)\0*.wav\0" \
+ L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \
+ L"\0";
+ break;
+ case FFSAVE_WAV:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"wav";
+ mOFN.lpstrFilter =
+ L"WAV Sounds (*.wav)\0*.wav\0" \
+ L"\0";
+ break;
+ case FFSAVE_TGA:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"tga";
+ mOFN.lpstrFilter =
+ L"Targa Images (*.tga)\0*.tga\0" \
+ L"\0";
+ break;
+ case FFSAVE_BMP:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"bmp";
+ mOFN.lpstrFilter =
+ L"Bitmap Images (*.bmp)\0*.bmp\0" \
+ L"\0";
+ break;
+ case FFSAVE_PNG:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"png";
+ mOFN.lpstrFilter =
+ L"PNG Images (*.png)\0*.png\0" \
+ L"\0";
+ break;
+ case FFSAVE_TGAPNG:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ //PNG by default
+ }
+ mOFN.lpstrDefExt = L"png";
+ mOFN.lpstrFilter =
+ L"PNG Images (*.png)\0*.png\0" \
+ L"Targa Images (*.tga)\0*.tga\0" \
+ L"\0";
+ break;
+
+ case FFSAVE_JPEG:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"jpg";
+ mOFN.lpstrFilter =
+ L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \
+ L"\0";
+ break;
+ case FFSAVE_AVI:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"avi";
+ mOFN.lpstrFilter =
+ L"AVI Movie File (*.avi)\0*.avi\0" \
+ L"\0";
+ break;
+ case FFSAVE_ANIM:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"xaf";
+ mOFN.lpstrFilter =
+ L"XAF Anim File (*.xaf)\0*.xaf\0" \
+ L"\0";
+ break;
+ case FFSAVE_GLTF:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"glb";
+ mOFN.lpstrFilter =
+ L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \
+ L"\0";
+ break;
+ case FFSAVE_XML:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+
+ mOFN.lpstrDefExt = L"xml";
+ mOFN.lpstrFilter =
+ L"XML File (*.xml)\0*.xml\0" \
+ L"\0";
+ break;
+ case FFSAVE_COLLADA:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"collada";
+ mOFN.lpstrFilter =
+ L"COLLADA File (*.collada)\0*.collada\0" \
+ L"\0";
+ break;
+ case FFSAVE_RAW:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"raw";
+ mOFN.lpstrFilter = RAW_FILTER \
+ L"\0";
+ break;
+ case FFSAVE_J2C:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE);
+ }
+ mOFN.lpstrDefExt = L"j2c";
+ mOFN.lpstrFilter =
+ L"Compressed Images (*.j2c)\0*.j2c\0" \
+ L"\0";
+ break;
+ case FFSAVE_SCRIPT:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE);
+ }
+ mOFN.lpstrDefExt = L"txt";
+ mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0";
+ break;
+ default:
+ return FALSE;
+ }
+
+
+ mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE;
+ mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
+
+ reset();
+
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
+ {
+ // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
+ try
+ {
+ success = GetSaveFileName(&mOFN);
+ if (success)
+ {
+ std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
+ mFiles.push_back(filename);
+ }
+ }
+ catch (...)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ gKeyboard->resetKeys();
+ }
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
+
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ return success;
}
BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
@@ -663,6 +668,8 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
allowedv->push_back("gltf");
allowedv->push_back("glb");
break;
+ case FFLOAD_HDRI:
+ allowedv->push_back("exr");
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
@@ -685,25 +692,25 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
LL_WARNS() << "Unsupported format." << LL_ENDL;
}
- return allowedv;
+ return allowedv;
}
-bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
+bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
{
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return false;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return false;
+ }
+
+ gViewerWindow->getWindow()->beforeDialog();
+
std::unique_ptr<std::vector<std::string>> allowed_types = navOpenFilterProc(filter);
-
+
std::unique_ptr<std::vector<std::string>> filev = doLoadDialog(allowed_types.get(),
mPickOptions);
- gViewerWindow->getWindow()->afterDialog();
+ gViewerWindow->getWindow()->afterDialog();
if (filev && filev->size() > 0)
@@ -711,8 +718,8 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
mFiles.insert(mFiles.end(), filev->begin(), filev->end());
return true;
}
-
- return false;
+
+ return false;
}
bool LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter,
@@ -724,14 +731,14 @@ bool LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter,
{
return false;
}
-
+
std::unique_ptr<std::vector<std::string>> allowed_types=navOpenFilterProc(filter);
-
+
doLoadDialogModeless(allowed_types.get(),
mPickOptions,
callback,
userdata);
-
+
return true;
}
@@ -785,13 +792,13 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension,
creator = "\?\?\?\?";
extension = "glb";
break;
-
+
case LLFilePicker::FFSAVE_XML:
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "xml";
break;
-
+
case LLFilePicker::FFSAVE_RAW:
type = "\?\?\?\?";
creator = "\?\?\?\?";
@@ -803,13 +810,13 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension,
creator = "prvw";
extension = "j2c";
break;
-
+
case LLFilePicker::FFSAVE_SCRIPT:
type = "LSL ";
creator = "\?\?\?\?";
extension = "lsl";
break;
-
+
case LLFilePicker::FFSAVE_ALL:
default:
type = "\?\?\?\?";
@@ -819,34 +826,34 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension,
}
}
-bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
+bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
{
- // Setup the type, creator, and extension
- std::string extension, type, creator;
-
+ // Setup the type, creator, and extension
+ std::string extension, type, creator;
+
set_nav_save_data(filter, extension, type, creator);
-
+
std::string namestring = filename;
if (namestring.empty()) namestring="Untitled";
+
+ gViewerWindow->getWindow()->beforeDialog();
- gViewerWindow->getWindow()->beforeDialog();
-
- // Run the dialog
- std::unique_ptr<std::string> filev = doSaveDialog(&namestring,
+ // Run the dialog
+ std::unique_ptr<std::string> filev = doSaveDialog(&namestring,
&type,
&creator,
&extension,
mPickOptions);
- gViewerWindow->getWindow()->afterDialog();
+ gViewerWindow->getWindow()->afterDialog();
- if ( filev && !filev->empty() )
- {
+ if ( filev && !filev->empty() )
+ {
mFiles.push_back(*filev);
- return true;
+ return true;
}
-
- return false;
+
+ return false;
}
bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter,
@@ -856,9 +863,9 @@ bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter,
{
// Setup the type, creator, and extension
std::string extension, type, creator;
-
+
set_nav_save_data(filter, extension, type, creator);
-
+
std::string namestring = filename;
if (namestring.empty()) namestring="Untitled";
@@ -875,57 +882,57 @@ bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter,
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
{
- if( mLocked )
- return FALSE;
-
- BOOL success = FALSE;
+ if( mLocked )
+ return FALSE;
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
+ BOOL success = FALSE;
- reset();
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+ reset();
+
mPickOptions &= ~F_MULTIPLE;
mPickOptions |= F_FILE;
-
- if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
+
+ if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
{
mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY );
mPickOptions &= ~F_FILE;
}
- if (filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
- {
+ if (filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
+ {
mPickOptions |= F_NAV_SUPPORT;
- }
-
- if (blocking) // always true for linux/mac
- {
- // Modal, so pause agent
- send_agent_pause();
- }
-
-
- success = doNavChooseDialog(filter);
-
- if (success)
- {
- if (!getFileCount())
- success = false;
- }
-
- if (blocking)
- {
- send_agent_resume();
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- }
-
- return success;
+ }
+
+ if (blocking) // always true for linux/mac
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
+
+ success = doNavChooseDialog(filter);
+
+ if (success)
+ {
+ if (!getFileCount())
+ success = false;
+ }
+
+ if (blocking)
+ {
+ send_agent_resume();
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ }
+
+ return success;
}
@@ -943,10 +950,10 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
}
reset();
-
+
mPickOptions &= ~F_MULTIPLE;
mPickOptions |= F_FILE;
-
+
if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
{
@@ -964,47 +971,47 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
{
- if( mLocked )
- return FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
+ if( mLocked )
+ return FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
BOOL success = FALSE;
- reset();
-
+ reset();
+
mPickOptions |= F_FILE;
mPickOptions |= F_MULTIPLE;
- if (blocking) // always true for linux/mac
- {
- // Modal, so pause agent
- send_agent_pause();
- }
-
- success = doNavChooseDialog(filter);
-
- if (blocking)
- {
- send_agent_resume();
- }
-
- if (success)
- {
- if (!getFileCount())
- success = false;
- if (getFileCount() > 1)
- mLocked = true;
- }
-
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- return success;
+ if (blocking) // always true for linux/mac
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
+
+ success = doNavChooseDialog(filter);
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
+
+ if (success)
+ {
+ if (!getFileCount())
+ success = false;
+ if (getFileCount() > 1)
+ mLocked = true;
+ }
+
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ return success;
}
@@ -1022,7 +1029,7 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
}
reset();
-
+
mPickOptions |= F_FILE;
mPickOptions |= F_MULTIPLE;
@@ -1033,42 +1040,42 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
{
- if( mLocked )
- return false;
- BOOL success = false;
+ if( mLocked )
+ return false;
+ BOOL success = false;
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return false;
- }
-
- reset();
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return false;
+ }
+ reset();
+
mPickOptions &= ~F_MULTIPLE;
- if (blocking)
- {
- // Modal, so pause agent
- send_agent_pause();
- }
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
success = doNavSaveDialog(filter, filename);
if (success)
- {
- if (!getFileCount())
- success = false;
- }
-
- if (blocking)
- {
- send_agent_resume();
- }
-
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- return success;
+ {
+ if (!getFileCount())
+ success = false;
+ }
+
+ if (blocking)
+ {
+ send_agent_resume();
+ }
+
+ // Account for the fact that the app has been stalled.
+ LLFrameTimer::updateFrameTime();
+ return success;
}
BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
@@ -1078,7 +1085,7 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
{
if( mLocked )
return false;
-
+
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
@@ -1086,7 +1093,7 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
}
reset();
-
+
mPickOptions &= ~F_MULTIPLE;
return doNavSaveDialogModeless(filter, filename, callback, userdata);
@@ -1100,414 +1107,414 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
// static
void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data)
{
- // We need to run g_filename_to_utf8 in the user's locale
- std::string saved_locale(setlocale(LC_ALL, NULL));
- setlocale(LC_ALL, "");
-
- LLFilePicker* picker = (LLFilePicker*) user_data;
- GError *error = NULL;
- gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
- -1, NULL, NULL, &error);
- if (error)
- {
- // *FIXME.
- // This condition should really be notified to the user, e.g.
- // through a message box. Just logging it is inappropriate.
-
- // g_filename_display_name is ideal, but >= glib 2.6, so:
- // a hand-rolled hacky makeASCII which disallows control chars
- std::string display_name;
- for (const gchar *str = (const gchar *)data; *str; str++)
- {
- display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?');
- }
- LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL;
- }
-
- if (filename_utf8)
- {
- picker->mFiles.push_back(std::string(filename_utf8));
- LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL;
- g_free(filename_utf8);
- }
-
- setlocale(LC_ALL, saved_locale.c_str());
+ // We need to run g_filename_to_utf8 in the user's locale
+ std::string saved_locale(setlocale(LC_ALL, NULL));
+ setlocale(LC_ALL, "");
+
+ LLFilePicker* picker = (LLFilePicker*) user_data;
+ GError *error = NULL;
+ gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
+ -1, NULL, NULL, &error);
+ if (error)
+ {
+ // *FIXME.
+ // This condition should really be notified to the user, e.g.
+ // through a message box. Just logging it is inappropriate.
+
+ // g_filename_display_name is ideal, but >= glib 2.6, so:
+ // a hand-rolled hacky makeASCII which disallows control chars
+ std::string display_name;
+ for (const gchar *str = (const gchar *)data; *str; str++)
+ {
+ display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?');
+ }
+ LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL;
+ }
+
+ if (filename_utf8)
+ {
+ picker->mFiles.push_back(std::string(filename_utf8));
+ LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL;
+ g_free(filename_utf8);
+ }
+
+ setlocale(LC_ALL, saved_locale.c_str());
}
// static
void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data)
{
- LLFilePicker* picker = (LLFilePicker*)user_data;
-
- LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL;
-
- if (response == GTK_RESPONSE_ACCEPT)
- {
- GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
- g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data);
- g_slist_foreach(file_list, (GFunc)g_free, NULL);
- g_slist_free (file_list);
- }
-
- // let's save the extension of the last added file(considering current filter)
- GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
- if(gfilter)
- {
- std::string filter = gtk_file_filter_get_name(gfilter);
-
- if(filter == LLTrans::getString("png_image_files"))
- {
- picker->mCurrentExtension = ".png";
- }
- else if(filter == LLTrans::getString("targa_image_files"))
- {
- picker->mCurrentExtension = ".tga";
- }
- }
-
- // set the default path for this usage context.
- const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
- if (cur_folder != NULL)
- {
- picker->mContextToPathMap[picker->mCurContextName] = cur_folder;
- }
-
- gtk_widget_destroy(widget);
- gtk_main_quit();
+ LLFilePicker* picker = (LLFilePicker*)user_data;
+
+ LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL;
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
+ g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data);
+ g_slist_foreach(file_list, (GFunc)g_free, NULL);
+ g_slist_free (file_list);
+ }
+
+ // let's save the extension of the last added file(considering current filter)
+ GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
+ if(gfilter)
+ {
+ std::string filter = gtk_file_filter_get_name(gfilter);
+
+ if(filter == LLTrans::getString("png_image_files"))
+ {
+ picker->mCurrentExtension = ".png";
+ }
+ else if(filter == LLTrans::getString("targa_image_files"))
+ {
+ picker->mCurrentExtension = ".tga";
+ }
+ }
+
+ // set the default path for this usage context.
+ const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
+ if (cur_folder != NULL)
+ {
+ picker->mContextToPathMap[picker->mCurContextName] = cur_folder;
+ }
+
+ gtk_widget_destroy(widget);
+ gtk_main_quit();
}
GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
{
#ifndef LL_MESA_HEADLESS
- if (LLWindowSDL::ll_try_gtk_init())
- {
- GtkWidget *win = NULL;
- GtkFileChooserAction pickertype =
- is_save?
- (is_folder?
- GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER :
- GTK_FILE_CHOOSER_ACTION_SAVE) :
- (is_folder?
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
- GTK_FILE_CHOOSER_ACTION_OPEN);
-
- win = gtk_file_chooser_dialog_new(NULL, NULL,
- pickertype,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- is_folder ?
- GTK_STOCK_APPLY :
- (is_save ?
- GTK_STOCK_SAVE :
- GTK_STOCK_OPEN),
- GTK_RESPONSE_ACCEPT,
- (gchar *)NULL);
- mCurContextName = context;
-
- // get the default path for this usage context if it's been
- // seen before.
- std::map<std::string,std::string>::iterator
- this_path = mContextToPathMap.find(context);
- if (this_path != mContextToPathMap.end())
- {
- gtk_file_chooser_set_current_folder
- (GTK_FILE_CHOOSER(win),
- this_path->second.c_str());
- }
+ if (LLWindowSDL::ll_try_gtk_init())
+ {
+ GtkWidget *win = NULL;
+ GtkFileChooserAction pickertype =
+ is_save?
+ (is_folder?
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER :
+ GTK_FILE_CHOOSER_ACTION_SAVE) :
+ (is_folder?
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+
+ win = gtk_file_chooser_dialog_new(NULL, NULL,
+ pickertype,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ is_folder ?
+ GTK_STOCK_APPLY :
+ (is_save ?
+ GTK_STOCK_SAVE :
+ GTK_STOCK_OPEN),
+ GTK_RESPONSE_ACCEPT,
+ (gchar *)NULL);
+ mCurContextName = context;
+
+ // get the default path for this usage context if it's been
+ // seen before.
+ std::map<std::string,std::string>::iterator
+ this_path = mContextToPathMap.find(context);
+ if (this_path != mContextToPathMap.end())
+ {
+ gtk_file_chooser_set_current_folder
+ (GTK_FILE_CHOOSER(win),
+ this_path->second.c_str());
+ }
# if LL_X11
- // Make GTK tell the window manager to associate this
- // dialog with our non-GTK raw X11 window, which should try
- // to keep it on top etc.
- Window XWindowID = LLWindowSDL::get_SDL_XWindowID();
- if (None != XWindowID)
- {
- gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
- GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID);
- gdk_window_set_transient_for(GTK_WIDGET(win)->window,
- gdkwin);
- }
- else
- {
- LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL;
- }
+ // Make GTK tell the window manager to associate this
+ // dialog with our non-GTK raw X11 window, which should try
+ // to keep it on top etc.
+ Window XWindowID = LLWindowSDL::get_SDL_XWindowID();
+ if (None != XWindowID)
+ {
+ gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin
+ GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID);
+ gdk_window_set_transient_for(GTK_WIDGET(win)->window,
+ gdkwin);
+ }
+ else
+ {
+ LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL;
+ }
# endif //LL_X11
- g_signal_connect (GTK_FILE_CHOOSER(win),
- "response",
- G_CALLBACK(LLFilePicker::chooser_responder),
- this);
+ g_signal_connect (GTK_FILE_CHOOSER(win),
+ "response",
+ G_CALLBACK(LLFilePicker::chooser_responder),
+ this);
- gtk_window_set_modal(GTK_WINDOW(win), TRUE);
+ gtk_window_set_modal(GTK_WINDOW(win), TRUE);
- /* GTK 2.6: if (is_folder)
- gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win),
- TRUE); */
+ /* GTK 2.6: if (is_folder)
+ gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win),
+ TRUE); */
- return GTK_WINDOW(win);
- }
- else
- {
- return NULL;
- }
+ return GTK_WINDOW(win);
+ }
+ else
+ {
+ return NULL;
+ }
#else
- return NULL;
+ return NULL;
#endif //LL_MESA_HEADLESS
}
static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
- GtkWindow *picker,
- std::string filtername)
-{
- gtk_file_filter_set_name(gfilter, filtername.c_str());
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter);
- GtkFileFilter *allfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(allfilter, "*");
- gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str());
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter);
- gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter);
+ GtkWindow *picker,
+ std::string filtername)
+{
+ gtk_file_filter_set_name(gfilter, filtername.c_str());
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+ gfilter);
+ GtkFileFilter *allfilter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(allfilter, "*");
+ gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str());
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter);
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter);
}
static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker,
- std::string pattern,
- std::string filtername)
+ std::string pattern,
+ std::string filtername)
{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, pattern.c_str());
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
+ GtkFileFilter *gfilter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(gfilter, pattern.c_str());
+ add_common_filters_to_gtkchooser(gfilter, picker, filtername);
+ return filtername;
}
static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker,
- std::string mime,
- std::string filtername)
+ std::string mime,
+ std::string filtername)
{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_mime_type(gfilter, mime.c_str());
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
+ GtkFileFilter *gfilter = gtk_file_filter_new();
+ gtk_file_filter_add_mime_type(gfilter, mime.c_str());
+ add_common_filters_to_gtkchooser(gfilter, picker, filtername);
+ return filtername;
}
static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker)
{
- return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav",
- LLTrans::getString("sound_files") + " (*.wav)");
+ return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav",
+ LLTrans::getString("sound_files") + " (*.wav)");
}
static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker)
{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, "*.bvh");
- gtk_file_filter_add_pattern(gfilter, "*.anim");
- std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)";
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
+ GtkFileFilter *gfilter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(gfilter, "*.bvh");
+ gtk_file_filter_add_pattern(gfilter, "*.anim");
+ std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)";
+ add_common_filters_to_gtkchooser(gfilter, picker, filtername);
+ return filtername;
}
static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker)
{
- return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml",
- LLTrans::getString("xml_files") + " (*.xml)");
+ return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml",
+ LLTrans::getString("xml_files") + " (*.xml)");
}
static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker)
{
- return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae",
- LLTrans::getString("scene_files") + " (*.dae)");
+ return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae",
+ LLTrans::getString("scene_files") + " (*.dae)");
}
static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
{
- GtkFileFilter *gfilter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(gfilter, "*.tga");
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str());
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str());
- gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str());
- std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)";
- add_common_filters_to_gtkchooser(gfilter, picker, filtername);
- return filtername;
+ GtkFileFilter *gfilter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(gfilter, "*.tga");
+ gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str());
+ gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str());
+ gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str());
+ std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)";
+ add_common_filters_to_gtkchooser(gfilter, picker, filtername);
+ return filtername;
}
-
+
static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
{
- return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
- LLTrans::getString("script_files") + " (*.lsl)");
+ return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
+ LLTrans::getString("script_files") + " (*.lsl)");
}
static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
{
- return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
- LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
+ return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
+ LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
}
static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
{
- GtkFileFilter *gfilter_tga = gtk_file_filter_new();
- GtkFileFilter *gfilter_png = gtk_file_filter_new();
-
- gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
- gtk_file_filter_add_mime_type(gfilter_png, "image/png");
- std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
- gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
- gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
-
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter_png);
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
- gfilter_tga);
- return caption;
+ GtkFileFilter *gfilter_tga = gtk_file_filter_new();
+ GtkFileFilter *gfilter_png = gtk_file_filter_new();
+
+ gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
+ gtk_file_filter_add_mime_type(gfilter_png, "image/png");
+ std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
+ gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
+ gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
+
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+ gfilter_png);
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+ gfilter_tga);
+ return caption;
}
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )
{
- BOOL rtn = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
- reset();
-
- GtkWindow* picker = buildFilePicker(true, false, "savefile");
-
- if (picker)
- {
- std::string suggest_name = "untitled";
- std::string suggest_ext = "";
- std::string caption = LLTrans::getString("save_file_verb") + " ";
- switch (filter)
- {
- case FFSAVE_WAV:
- caption += add_wav_filter_to_gtkchooser(picker);
- suggest_ext = ".wav";
- break;
- case FFSAVE_TGA:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)");
- suggest_ext = ".tga";
- break;
- case FFSAVE_BMP:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)");
- suggest_ext = ".bmp";
- break;
- case FFSAVE_PNG:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
- suggest_ext = ".png";
- break;
- case FFSAVE_TGAPNG:
- caption += add_save_texture_filter_to_gtkchooser(picker);
- suggest_ext = ".png";
- break;
- case FFSAVE_AVI:
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "video/x-msvideo",
- LLTrans::getString("avi_movie_file") + " (*.avi)");
- suggest_ext = ".avi";
- break;
- case FFSAVE_ANIM:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)");
- suggest_ext = ".xaf";
- break;
- case FFSAVE_XML:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)");
- suggest_ext = ".xml";
- break;
- case FFSAVE_RAW:
- caption += add_simple_pattern_filter_to_gtkchooser
- (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)");
- suggest_ext = ".raw";
- break;
- case FFSAVE_J2C:
- // *TODO: Should this be 'image/j2c' ?
- caption += add_simple_mime_filter_to_gtkchooser
- (picker, "images/jp2",
- LLTrans::getString("compressed_image_files") + " (*.j2c)");
- suggest_ext = ".j2c";
- break;
- case FFSAVE_SCRIPT:
- caption += add_script_filter_to_gtkchooser(picker);
- suggest_ext = ".lsl";
- break;
- default:;
- break;
- }
-
- gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
-
- if (filename.empty())
- {
- suggest_name += suggest_ext;
-
- gtk_file_chooser_set_current_name
- (GTK_FILE_CHOOSER(picker),
- suggest_name.c_str());
- }
- else
- {
- gtk_file_chooser_set_current_name
- (GTK_FILE_CHOOSER(picker), filename.c_str());
- }
-
- gtk_widget_show_all(GTK_WIDGET(picker));
-
- gtk_main();
-
- rtn = (getFileCount() == 1);
-
- if(rtn && filter == FFSAVE_TGAPNG)
- {
- std::string selected_file = mFiles.back();
- mFiles.pop_back();
- mFiles.push_back(selected_file + mCurrentExtension);
- }
- }
-
- gViewerWindow->getWindow()->afterDialog();
-
- return rtn;
+ BOOL rtn = FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ gViewerWindow->getWindow()->beforeDialog();
+
+ reset();
+
+ GtkWindow* picker = buildFilePicker(true, false, "savefile");
+
+ if (picker)
+ {
+ std::string suggest_name = "untitled";
+ std::string suggest_ext = "";
+ std::string caption = LLTrans::getString("save_file_verb") + " ";
+ switch (filter)
+ {
+ case FFSAVE_WAV:
+ caption += add_wav_filter_to_gtkchooser(picker);
+ suggest_ext = ".wav";
+ break;
+ case FFSAVE_TGA:
+ caption += add_simple_pattern_filter_to_gtkchooser
+ (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)");
+ suggest_ext = ".tga";
+ break;
+ case FFSAVE_BMP:
+ caption += add_simple_mime_filter_to_gtkchooser
+ (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)");
+ suggest_ext = ".bmp";
+ break;
+ case FFSAVE_PNG:
+ caption += add_simple_mime_filter_to_gtkchooser
+ (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
+ suggest_ext = ".png";
+ break;
+ case FFSAVE_TGAPNG:
+ caption += add_save_texture_filter_to_gtkchooser(picker);
+ suggest_ext = ".png";
+ break;
+ case FFSAVE_AVI:
+ caption += add_simple_mime_filter_to_gtkchooser
+ (picker, "video/x-msvideo",
+ LLTrans::getString("avi_movie_file") + " (*.avi)");
+ suggest_ext = ".avi";
+ break;
+ case FFSAVE_ANIM:
+ caption += add_simple_pattern_filter_to_gtkchooser
+ (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)");
+ suggest_ext = ".xaf";
+ break;
+ case FFSAVE_XML:
+ caption += add_simple_pattern_filter_to_gtkchooser
+ (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)");
+ suggest_ext = ".xml";
+ break;
+ case FFSAVE_RAW:
+ caption += add_simple_pattern_filter_to_gtkchooser
+ (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)");
+ suggest_ext = ".raw";
+ break;
+ case FFSAVE_J2C:
+ // *TODO: Should this be 'image/j2c' ?
+ caption += add_simple_mime_filter_to_gtkchooser
+ (picker, "images/jp2",
+ LLTrans::getString("compressed_image_files") + " (*.j2c)");
+ suggest_ext = ".j2c";
+ break;
+ case FFSAVE_SCRIPT:
+ caption += add_script_filter_to_gtkchooser(picker);
+ suggest_ext = ".lsl";
+ break;
+ default:;
+ break;
+ }
+
+ gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
+
+ if (filename.empty())
+ {
+ suggest_name += suggest_ext;
+
+ gtk_file_chooser_set_current_name
+ (GTK_FILE_CHOOSER(picker),
+ suggest_name.c_str());
+ }
+ else
+ {
+ gtk_file_chooser_set_current_name
+ (GTK_FILE_CHOOSER(picker), filename.c_str());
+ }
+
+ gtk_widget_show_all(GTK_WIDGET(picker));
+
+ gtk_main();
+
+ rtn = (getFileCount() == 1);
+
+ if(rtn && filter == FFSAVE_TGAPNG)
+ {
+ std::string selected_file = mFiles.back();
+ mFiles.pop_back();
+ mFiles.push_back(selected_file + mCurrentExtension);
+ }
+ }
+
+ gViewerWindow->getWindow()->afterDialog();
+
+ return rtn;
}
BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
{
- BOOL rtn = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- gViewerWindow->getWindow()->beforeDialog();
-
- reset();
-
- GtkWindow* picker = buildFilePicker(false, false, "openfile");
-
- if (picker)
- {
- std::string caption = LLTrans::getString("load_file_verb") + " ";
- std::string filtername = "";
- switch (filter)
- {
- case FFLOAD_WAV:
- filtername = add_wav_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_ANIM:
- filtername = add_anim_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_XML:
- filtername = add_xml_filter_to_gtkchooser(picker);
- break;
+ BOOL rtn = FALSE;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ gViewerWindow->getWindow()->beforeDialog();
+
+ reset();
+
+ GtkWindow* picker = buildFilePicker(false, false, "openfile");
+
+ if (picker)
+ {
+ std::string caption = LLTrans::getString("load_file_verb") + " ";
+ std::string filtername = "";
+ switch (filter)
+ {
+ case FFLOAD_WAV:
+ filtername = add_wav_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_ANIM:
+ filtername = add_anim_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_XML:
+ filtername = add_xml_filter_to_gtkchooser(picker);
+ break;
case FFLOAD_GLTF:
filtername = dead_code_should_blow_up_here(picker);
break;
@@ -1515,64 +1522,64 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
filtername = add_collada_filter_to_gtkchooser(picker);
break;
case FFLOAD_IMAGE:
- filtername = add_imageload_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_SCRIPT:
- filtername = add_script_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_DICTIONARY:
- filtername = add_dictionary_filter_to_gtkchooser(picker);
- break;
- default:;
- break;
- }
-
- caption += filtername;
-
- gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
-
- gtk_widget_show_all(GTK_WIDGET(picker));
- gtk_main();
-
- rtn = (getFileCount() == 1);
- }
-
- gViewerWindow->getWindow()->afterDialog();
-
- return rtn;
+ filtername = add_imageload_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_SCRIPT:
+ filtername = add_script_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_DICTIONARY:
+ filtername = add_dictionary_filter_to_gtkchooser(picker);
+ break;
+ default:;
+ break;
+ }
+
+ caption += filtername;
+
+ gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
+
+ gtk_widget_show_all(GTK_WIDGET(picker));
+ gtk_main();
+
+ rtn = (getFileCount() == 1);
+ }
+
+ gViewerWindow->getWindow()->afterDialog();
+
+ return rtn;
}
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
- BOOL rtn = FALSE;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
+ BOOL rtn = FALSE;
- gViewerWindow->getWindow()->beforeDialog();
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
- reset();
+ gViewerWindow->getWindow()->beforeDialog();
- GtkWindow* picker = buildFilePicker(false, false, "openfile");
+ reset();
+
+ GtkWindow* picker = buildFilePicker(false, false, "openfile");
- if (picker)
- {
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker),
- TRUE);
+ if (picker)
+ {
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker),
+ TRUE);
- gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str());
+ gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str());
- gtk_widget_show_all(GTK_WIDGET(picker));
- gtk_main();
- rtn = !mFiles.empty();
- }
+ gtk_widget_show_all(GTK_WIDGET(picker));
+ gtk_main();
+ rtn = !mFiles.empty();
+ }
- gViewerWindow->getWindow()->afterDialog();
+ gViewerWindow->getWindow()->afterDialog();
- return rtn;
+ return rtn;
}
# else // LL_GTK
@@ -1582,23 +1589,23 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )
{
- // if local file browsing is turned off, return without opening dialog
- // (Even though this is a stub, I think we still should not return anything at all)
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- reset();
-
- LL_INFOS() << "getSaveFile suggested filename is [" << filename
- << "]" << LL_ENDL;
- if (!filename.empty())
- {
- mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename);
- return TRUE;
- }
- return FALSE;
+ // if local file browsing is turned off, return without opening dialog
+ // (Even though this is a stub, I think we still should not return anything at all)
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ reset();
+
+ LL_INFOS() << "getSaveFile suggested filename is [" << filename
+ << "]" << LL_ENDL;
+ if (!filename.empty())
+ {
+ mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename);
+ return TRUE;
+ }
+ return FALSE;
}
BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
@@ -1612,27 +1619,27 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
{
- // if local file browsing is turned off, return without opening dialog
- // (Even though this is a stub, I think we still should not return anything at all)
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- reset();
-
- // HACK: Static filenames for 'open' until we implement filepicker
- std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload";
- switch (filter)
- {
- case FFLOAD_WAV: filename += ".wav"; break;
- case FFLOAD_IMAGE: filename += ".tga"; break;
- case FFLOAD_ANIM: filename += ".bvh"; break;
- default: break;
- }
- mFiles.push_back(filename);
- LL_INFOS() << "getOpenFile: Will try to open file: " << filename << LL_ENDL;
- return TRUE;
+ // if local file browsing is turned off, return without opening dialog
+ // (Even though this is a stub, I think we still should not return anything at all)
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ reset();
+
+ // HACK: Static filenames for 'open' until we implement filepicker
+ std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload";
+ switch (filter)
+ {
+ case FFLOAD_WAV: filename += ".wav"; break;
+ case FFLOAD_IMAGE: filename += ".tga"; break;
+ case FFLOAD_ANIM: filename += ".bvh"; break;
+ default: break;
+ }
+ mFiles.push_back(filename);
+ LL_INFOS() << "getOpenFile: Will try to open file: " << filename << LL_ENDL;
+ return TRUE;
}
BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
@@ -1645,15 +1652,15 @@ BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
- // if local file browsing is turned off, return without opening dialog
- // (Even though this is a stub, I think we still should not return anything at all)
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- reset();
- return FALSE;
+ // if local file browsing is turned off, return without opening dialog
+ // (Even though this is a stub, I think we still should not return anything at all)
+ if ( check_local_file_access_enabled() == false )
+ {
+ return FALSE;
+ }
+
+ reset();
+ return FALSE;
}
BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
@@ -1670,20 +1677,20 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
{
- reset();
- return FALSE;
+ reset();
+ return FALSE;
}
BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
{
- reset();
- return FALSE;
+ reset();
+ return FALSE;
}
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
- reset();
- return FALSE;
+ reset();
+ return FALSE;
}
#endif // LL_LINUX
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 7149ced34a..891c0c0482 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfilepicker.h
* @brief OS-specific file picker
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -64,118 +64,119 @@ extern "C" {
class LLFilePicker
{
#ifdef LL_GTK
- friend class LLDirPicker;
- friend void chooser_responder(GtkWidget *, gint, gpointer);
+ friend class LLDirPicker;
+ friend void chooser_responder(GtkWidget *, gint, gpointer);
#endif // LL_GTK
public:
- // calling this before main() is undefined
- static LLFilePicker& instance( void ) { return sInstance; }
-
- enum ELoadFilter
- {
- FFLOAD_ALL = 1,
- FFLOAD_WAV = 2,
- FFLOAD_IMAGE = 3,
- FFLOAD_ANIM = 4,
- FFLOAD_GLTF = 5,
- FFLOAD_XML = 6,
- FFLOAD_SLOBJECT = 7,
- FFLOAD_RAW = 8,
- FFLOAD_MODEL = 9,
- FFLOAD_COLLADA = 10,
- FFLOAD_SCRIPT = 11,
- FFLOAD_DICTIONARY = 12,
+ // calling this before main() is undefined
+ static LLFilePicker& instance( void ) { return sInstance; }
+
+ enum ELoadFilter
+ {
+ FFLOAD_ALL = 1,
+ FFLOAD_WAV = 2,
+ FFLOAD_IMAGE = 3,
+ FFLOAD_ANIM = 4,
+ FFLOAD_GLTF = 5,
+ FFLOAD_XML = 6,
+ FFLOAD_SLOBJECT = 7,
+ FFLOAD_RAW = 8,
+ FFLOAD_MODEL = 9,
+ FFLOAD_COLLADA = 10,
+ FFLOAD_SCRIPT = 11,
+ FFLOAD_DICTIONARY = 12,
FFLOAD_DIRECTORY = 13, // To call from lldirpicker.
FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
FFLOAD_MATERIAL = 15,
FFLOAD_MATERIAL_TEXTURE = 16,
- };
-
- enum ESaveFilter
- {
- FFSAVE_ALL = 1,
- FFSAVE_WAV = 3,
- FFSAVE_TGA = 4,
- FFSAVE_BMP = 5,
- FFSAVE_AVI = 6,
- FFSAVE_ANIM = 7,
- FFSAVE_GLTF = 8,
- FFSAVE_XML = 9,
- FFSAVE_COLLADA = 10,
- FFSAVE_RAW = 11,
- FFSAVE_J2C = 12,
- FFSAVE_PNG = 13,
- FFSAVE_JPEG = 14,
- FFSAVE_SCRIPT = 15,
- FFSAVE_TGAPNG = 16
- };
-
- // open the dialog. This is a modal operation
- BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true);
+ FFLOAD_HDRI = 17,
+ };
+
+ enum ESaveFilter
+ {
+ FFSAVE_ALL = 1,
+ FFSAVE_WAV = 3,
+ FFSAVE_TGA = 4,
+ FFSAVE_BMP = 5,
+ FFSAVE_AVI = 6,
+ FFSAVE_ANIM = 7,
+ FFSAVE_GLTF = 8,
+ FFSAVE_XML = 9,
+ FFSAVE_COLLADA = 10,
+ FFSAVE_RAW = 11,
+ FFSAVE_J2C = 12,
+ FFSAVE_PNG = 13,
+ FFSAVE_JPEG = 14,
+ FFSAVE_SCRIPT = 15,
+ FFSAVE_TGAPNG = 16
+ };
+
+ // open the dialog. This is a modal operation
+ BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true);
BOOL getSaveFileModeless(ESaveFilter filter,
const std::string& filename,
void (*callback)(bool, std::string&, void*),
void *userdata);
- BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
+ BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
// Todo: implement getOpenFileModeless and getMultipleOpenFilesModeless
// for windows and use directly instead of ugly LLFilePickerThread
BOOL getOpenFileModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata); // MAC only.
- BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
+ BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
BOOL getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata ); // MAC only
- // Get the filename(s) found. getFirstFile() sets the pointer to
- // the start of the structure and allows the start of iteration.
- const std::string getFirstFile();
-
- // getNextFile() increments the internal representation and
- // returns the next file specified by the user. Returns NULL when
- // no more files are left. Further calls to getNextFile() are
- // undefined.
- const std::string getNextFile();
+ // Get the filename(s) found. getFirstFile() sets the pointer to
+ // the start of the structure and allows the start of iteration.
+ const std::string getFirstFile();
- // This utility function extracts the current file name without
- // doing any incrementing.
- const std::string getCurFile();
+ // getNextFile() increments the internal representation and
+ // returns the next file specified by the user. Returns NULL when
+ // no more files are left. Further calls to getNextFile() are
+ // undefined.
+ const std::string getNextFile();
- // Returns the index of the current file.
- S32 getCurFileNum() const { return mCurrentFile; }
+ // This utility function extracts the current file name without
+ // doing any incrementing.
+ const std::string getCurFile();
- S32 getFileCount() const { return (S32)mFiles.size(); }
+ // Returns the index of the current file.
+ S32 getCurFileNum() const { return mCurrentFile; }
- // see lldir.h : getBaseFileName and getDirName to extract base or directory names
+ S32 getFileCount() const { return (S32)mFiles.size(); }
- // clear any lists of buffers or whatever, and make sure the file
- // picker isn't locked.
- void reset();
+ // see lldir.h : getBaseFileName and getDirName to extract base or directory names
+
+ // clear any lists of buffers or whatever, and make sure the file
+ // picker isn't locked.
+ void reset();
private:
- enum
- {
- SINGLE_FILENAME_BUFFER_SIZE = 1024,
- //FILENAME_BUFFER_SIZE = 65536
- FILENAME_BUFFER_SIZE = 65000
- };
-
- // utility function to check if access to local file system via file browser
- // is enabled and if not, tidy up and indicate we're not allowed to do this.
- bool check_local_file_access_enabled();
-
+ enum
+ {
+ SINGLE_FILENAME_BUFFER_SIZE = 1024,
+ //FILENAME_BUFFER_SIZE = 65536
+ FILENAME_BUFFER_SIZE = 65000
+ };
+
+ // utility function to check if access to local file system via file browser
+ // is enabled and if not, tidy up and indicate we're not allowed to do this.
+ bool check_local_file_access_enabled();
+
#if LL_WINDOWS
- OPENFILENAMEW mOFN; // for open and save dialogs
- WCHAR mFilesW[FILENAME_BUFFER_SIZE];
+ OPENFILENAMEW mOFN; // for open and save dialogs
+ WCHAR mFilesW[FILENAME_BUFFER_SIZE];
- BOOL setupFilter(ELoadFilter filter);
+ BOOL setupFilter(ELoadFilter filter);
#endif
#if LL_DARWIN
S32 mPickOptions;
- std::vector<std::string> mFileVector;
-
- bool doNavChooseDialog(ELoadFilter filter);
- bool doNavChooseDialogModeless(ELoadFilter filter,
+ std::vector<std::string> mFileVector;
+
+ bool doNavChooseDialog(ELoadFilter filter);
+ bool doNavChooseDialogModeless(ELoadFilter filter,
void (*callback)(bool, std::vector<std::string>&, void*),
void *userdata);
- bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
+ bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
std::unique_ptr<std::vector<std::string>> navOpenFilterProc(ELoadFilter filter);
bool doNavSaveDialogModeless(ESaveFilter filter,
const std::string& filename,
@@ -184,31 +185,31 @@ private:
#endif
#if LL_GTK
- static void add_to_selectedfiles(gpointer data, gpointer user_data);
- static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data);
- // we remember the last path that was accessed for a particular usage
- std::map <std::string, std::string> mContextToPathMap;
- std::string mCurContextName;
- // we also remember the extension of the last added file.
- std::string mCurrentExtension;
+ static void add_to_selectedfiles(gpointer data, gpointer user_data);
+ static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data);
+ // we remember the last path that was accessed for a particular usage
+ std::map <std::string, std::string> mContextToPathMap;
+ std::string mCurContextName;
+ // we also remember the extension of the last added file.
+ std::string mCurrentExtension;
#endif
- std::vector<std::string> mFiles;
- S32 mCurrentFile;
- bool mLocked;
-
- static LLFilePicker sInstance;
+ std::vector<std::string> mFiles;
+ S32 mCurrentFile;
+ bool mLocked;
+ static LLFilePicker sInstance;
+
protected:
#if LL_GTK
GtkWindow* buildFilePicker(bool is_save, bool is_folder,
- std::string context = "generic");
+ std::string context = "generic");
#endif
public:
- // don't call these directly please.
- LLFilePicker();
- ~LLFilePicker();
+ // don't call these directly please.
+ LLFilePicker();
+ ~LLFilePicker();
};
#endif
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 8f83c39520..2a5106f79e 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfloaterimagepreview.cpp
* @brief LLFloaterImagePreview class implementation
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,6 +34,7 @@
#include "llimagepng.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -64,23 +65,23 @@
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
-const S32 PREVIEW_VPAD = -24 + 35; // yuk, hard coded
+const S32 PREVIEW_VPAD = -24 + 35; // yuk, hard coded
const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16 + 35;
const S32 PREVIEW_TEXTURE_HEIGHT = 320;
//-----------------------------------------------------------------------------
// LLFloaterImagePreview()
//-----------------------------------------------------------------------------
-LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) :
- LLFloaterNameDesc(filename),
+LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) :
+ LLFloaterNameDesc(filename),
- mAvatarPreview(NULL),
- mSculptedPreview(NULL),
- mLastMouseX(0),
- mLastMouseY(0),
- mImagep(NULL)
+ mAvatarPreview(NULL),
+ mSculptedPreview(NULL),
+ mLastMouseX(0),
+ mLastMouseY(0),
+ mImagep(NULL)
{
- loadImage(mFilenameAndPath);
+ loadImage(mFilenameAndPath);
}
//-----------------------------------------------------------------------------
@@ -88,33 +89,33 @@ LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) :
//-----------------------------------------------------------------------------
BOOL LLFloaterImagePreview::postBuild()
{
- if (!LLFloaterNameDesc::postBuild())
- {
- return FALSE;
- }
-
- LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- if (iface)
- {
- iface->selectFirstItem();
- }
- childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this);
-
- mPreviewRect.set(PREVIEW_HPAD,
- PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
- getRect().getWidth() - PREVIEW_HPAD,
- PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
-
- getChildView("bad_image_text")->setVisible(FALSE);
-
- if (mRawImagep.notNull() && gAgent.getRegion() != NULL)
- {
- mAvatarPreview = new LLImagePreviewAvatar(256, 256);
- mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE);
-
- mSculptedPreview = new LLImagePreviewSculpted(256, 256);
- mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
+ if (!LLFloaterNameDesc::postBuild())
+ {
+ return FALSE;
+ }
+
+ LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
+ if (iface)
+ {
+ iface->selectFirstItem();
+ }
+ childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this);
+
+ mPreviewRect.set(PREVIEW_HPAD,
+ PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
+ getRect().getWidth() - PREVIEW_HPAD,
+ PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
+
+ getChildView("bad_image_text")->setVisible(FALSE);
+
+ if (mRawImagep.notNull() && gAgent.getRegion() != NULL)
+ {
+ mAvatarPreview = new LLImagePreviewAvatar(256, 256);
+ mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE);
+
+ mSculptedPreview = new LLImagePreviewSculpted(256, 256);
+ mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
{
@@ -124,24 +125,33 @@ BOOL LLFloaterImagePreview::postBuild()
check_box->setEnabled(TRUE);
check_box->setControlVariable(gSavedSettings.getControl("LosslessJ2CUpload"));
}
- }
- else
- {
- mAvatarPreview = NULL;
- mSculptedPreview = NULL;
- getChildView("bad_image_text")->setVisible(TRUE);
- getChildView("clothing_type_combo")->setEnabled(FALSE);
- getChildView("ok_btn")->setEnabled(FALSE);
-
- if(!mImageLoadError.empty())
- {
- getChild<LLUICtrl>("bad_image_text")->setValue(mImageLoadError.c_str());
- }
- }
+ }
+ else
+ {
+ mAvatarPreview = NULL;
+ mSculptedPreview = NULL;
+ getChildView("bad_image_text")->setVisible(TRUE);
+ getChildView("clothing_type_combo")->setEnabled(FALSE);
+ getChildView("ok_btn")->setEnabled(FALSE);
+
+ if(!mImageLoadError.empty())
+ {
+ getChild<LLUICtrl>("bad_image_text")->setValue(mImageLoadError.c_str());
+ }
+ }
+
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+
+ return TRUE;
+}
- getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
- return TRUE;
+//-----------------------------------------------------------------------------
+// getExpectedUploadCost()
+//-----------------------------------------------------------------------------
+S32 LLFloaterImagePreview::getExpectedUploadCost() const
+{
+ return LLAgentBenefitsMgr::current().getTextureUploadCost(mRawImagep);
}
//-----------------------------------------------------------------------------
@@ -149,70 +159,70 @@ BOOL LLFloaterImagePreview::postBuild()
//-----------------------------------------------------------------------------
LLFloaterImagePreview::~LLFloaterImagePreview()
{
- clearAllPreviewTextures();
+ clearAllPreviewTextures();
- mRawImagep = NULL;
- mImagep = NULL ;
+ mRawImagep = NULL;
+ mImagep = NULL ;
}
-//static
+//static
//-----------------------------------------------------------------------------
// onPreviewTypeCommit()
//-----------------------------------------------------------------------------
-void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
+void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
{
- LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata;
-
- if (!fp->mAvatarPreview || !fp->mSculptedPreview)
- {
- return;
- }
-
- S32 which_mode = 0;
-
- LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo");
- if (iface)
- {
- which_mode = iface->getFirstSelectedIndex();
- }
-
- switch(which_mode)
- {
- case 0:
- break;
- case 1:
- fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE);
- break;
- case 2:
- fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE);
- break;
- case 3:
- fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE);
- break;
- case 4:
- fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE);
- break;
- case 5:
- fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE);
- break;
- case 6:
- fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
- break;
- case 7:
- fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
- break;
- case 8:
- fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE);
- break;
- case 9:
- fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f);
- break;
- default:
- break;
- }
-
- fp->mAvatarPreview->refresh();
- fp->mSculptedPreview->refresh();
+ LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata;
+
+ if (!fp->mAvatarPreview || !fp->mSculptedPreview)
+ {
+ return;
+ }
+
+ S32 which_mode = 0;
+
+ LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo");
+ if (iface)
+ {
+ which_mode = iface->getFirstSelectedIndex();
+ }
+
+ switch(which_mode)
+ {
+ case 0:
+ break;
+ case 1:
+ fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE);
+ break;
+ case 2:
+ fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE);
+ break;
+ case 3:
+ fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE);
+ break;
+ case 4:
+ fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE);
+ break;
+ case 5:
+ fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE);
+ break;
+ case 6:
+ fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
+ break;
+ case 7:
+ fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
+ break;
+ case 8:
+ fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE);
+ break;
+ case 9:
+ fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f);
+ break;
+ default:
+ break;
+ }
+
+ fp->mAvatarPreview->refresh();
+ fp->mSculptedPreview->refresh();
}
@@ -221,16 +231,16 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdat
//-----------------------------------------------------------------------------
void LLFloaterImagePreview::clearAllPreviewTextures()
{
- if (mAvatarPreview)
- {
- mAvatarPreview->clearPreviewTexture("mHairMesh0");
- mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
- mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
- mAvatarPreview->clearPreviewTexture("mHeadMesh0");
- mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
- mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
- mAvatarPreview->clearPreviewTexture("mSkirtMesh0");
- }
+ if (mAvatarPreview)
+ {
+ mAvatarPreview->clearPreviewTexture("mHairMesh0");
+ mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
+ mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
+ mAvatarPreview->clearPreviewTexture("mHeadMesh0");
+ mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
+ mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
+ mAvatarPreview->clearPreviewTexture("mSkirtMesh0");
+ }
}
//-----------------------------------------------------------------------------
@@ -238,92 +248,92 @@ void LLFloaterImagePreview::clearAllPreviewTextures()
//-----------------------------------------------------------------------------
void LLFloaterImagePreview::draw()
{
- LLFloater::draw();
- LLRect r = getRect();
-
- if (mRawImagep.notNull())
- {
- LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- U32 selected = 0;
- if (iface)
- selected = iface->getFirstSelectedIndex();
-
- if (selected <= 0)
- {
- gl_rect_2d_checkerboard(mPreviewRect);
-
- if(mImagep.notNull())
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
- }
- else
- {
- mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ;
-
- gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ;
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
- stop_glerror();
-
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- if (mAvatarPreview)
- {
- mAvatarPreview->setTexture(mImagep->getTexName());
- mSculptedPreview->setTexture(mImagep->getTexName());
- }
- }
-
- gGL.color3f(1.f, 1.f, 1.f);
- gGL.begin( LLRender::QUADS );
- {
- gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
- gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
- }
- gGL.end();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- stop_glerror();
- }
- else
- {
- if ((mAvatarPreview) && (mSculptedPreview))
- {
- gGL.color3f(1.f, 1.f, 1.f);
-
- if (selected == 9)
- {
- gGL.getTexUnit(0)->bind(mSculptedPreview);
- }
- else
- {
- gGL.getTexUnit(0)->bind(mAvatarPreview);
- }
-
- gGL.begin( LLRender::QUADS );
- {
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
- }
- gGL.end();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
- }
+ LLFloater::draw();
+ LLRect r = getRect();
+
+ if (mRawImagep.notNull())
+ {
+ LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
+ U32 selected = 0;
+ if (iface)
+ selected = iface->getFirstSelectedIndex();
+
+ if (selected <= 0)
+ {
+ gl_rect_2d_checkerboard(mPreviewRect);
+
+ if(mImagep.notNull())
+ {
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
+ }
+ else
+ {
+ mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ;
+
+ gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ;
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
+ stop_glerror();
+
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ if (mAvatarPreview)
+ {
+ mAvatarPreview->setTexture(mImagep->getTexName());
+ mSculptedPreview->setTexture(mImagep->getTexName());
+ }
+ }
+
+ gGL.color3f(1.f, 1.f, 1.f);
+ gGL.begin( LLRender::QUADS );
+ {
+ gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ }
+ gGL.end();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ stop_glerror();
+ }
+ else
+ {
+ if ((mAvatarPreview) && (mSculptedPreview))
+ {
+ gGL.color3f(1.f, 1.f, 1.f);
+
+ if (selected == 9)
+ {
+ gGL.getTexUnit(0)->bind(mSculptedPreview);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(mAvatarPreview);
+ }
+
+ gGL.begin( LLRender::QUADS );
+ {
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ }
+ gGL.end();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
}
@@ -332,56 +342,56 @@ void LLFloaterImagePreview::draw()
//-----------------------------------------------------------------------------
bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
{
- std::string exten = gDirUtilp->getExtension(src_filename);
- U32 codec = LLImageBase::getCodecFromExtension(exten);
-
- LLImageDimensionsInfo image_info;
- if (!image_info.load(src_filename,codec))
- {
- mImageLoadError = image_info.getLastError();
- return false;
- }
-
- S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
- S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
-
- if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
- {
- LLStringUtil::format_map_t args;
- args["WIDTH"] = llformat("%d", max_width);
- args["HEIGHT"] = llformat("%d", max_height);
-
- mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
- return false;
- }
-
- // Load the image
- LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
- if (image.isNull())
- {
- return false;
- }
- if (!image->load(src_filename))
- {
- return false;
- }
- // Decompress or expand it in a raw image structure
- LLPointer<LLImageRaw> raw_image = new LLImageRaw;
- if (!image->decode(raw_image, 0.0f))
- {
- return false;
- }
- // Check the image constraints
- if ((image->getComponents() != 3) && (image->getComponents() != 4))
- {
- image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
- return false;
- }
-
- raw_image->biasedScaleToPowerOfTwo(1024);
- mRawImagep = raw_image;
-
- return true;
+ std::string exten = gDirUtilp->getExtension(src_filename);
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+ LLImageDimensionsInfo image_info;
+ if (!image_info.load(src_filename,codec))
+ {
+ mImageLoadError = image_info.getLastError();
+ return false;
+ }
+
+ S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
+ S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
+
+ if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
+ {
+ LLStringUtil::format_map_t args;
+ args["WIDTH"] = llformat("%d", max_width);
+ args["HEIGHT"] = llformat("%d", max_height);
+
+ mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
+ return false;
+ }
+
+ // Load the image
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
+ if (image.isNull())
+ {
+ return false;
+ }
+ if (!image->load(src_filename))
+ {
+ return false;
+ }
+ // Decompress or expand it in a raw image structure
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+ if (!image->decode(raw_image, 0.0f))
+ {
+ return false;
+ }
+ // Check the image constraints
+ if ((image->getComponents() != 3) && (image->getComponents() != 4))
+ {
+ image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
+ return false;
+ }
+
+ raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ mRawImagep = raw_image;
+
+ return true;
}
//-----------------------------------------------------------------------------
@@ -389,17 +399,17 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
//-----------------------------------------------------------------------------
BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (mPreviewRect.pointInRect(x, y))
- {
- bringToFront( x, y );
- gFocusMgr.setMouseCapture(this);
- gViewerWindow->hideCursor();
- mLastMouseX = x;
- mLastMouseY = y;
- return TRUE;
- }
-
- return LLFloater::handleMouseDown(x, y, mask);
+ if (mPreviewRect.pointInRect(x, y))
+ {
+ bringToFront( x, y );
+ gFocusMgr.setMouseCapture(this);
+ gViewerWindow->hideCursor();
+ mLastMouseX = x;
+ mLastMouseY = y;
+ return TRUE;
+ }
+
+ return LLFloater::handleMouseDown(x, y, mask);
}
//-----------------------------------------------------------------------------
@@ -407,9 +417,9 @@ BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
//-----------------------------------------------------------------------------
BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask)
{
- gFocusMgr.setMouseCapture(FALSE);
- gViewerWindow->showCursor();
- return LLFloater::handleMouseUp(x, y, mask);
+ gFocusMgr.setMouseCapture(FALSE);
+ gViewerWindow->showCursor();
+ return LLFloater::handleMouseUp(x, y, mask);
}
//-----------------------------------------------------------------------------
@@ -417,119 +427,119 @@ BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask)
//-----------------------------------------------------------------------------
BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
{
- MASK local_mask = mask & ~MASK_ALT;
-
- if (mAvatarPreview && hasMouseCapture())
- {
- if (local_mask == MASK_PAN)
- {
- // pan here
- LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- if (iface && iface->getFirstSelectedIndex() <= 0)
- {
- mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(),
- (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight());
- }
- else
- {
- mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
- mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
- }
- }
- else if (local_mask == MASK_ORBIT)
- {
- F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
- F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
-
- mAvatarPreview->rotate(yaw_radians, pitch_radians);
- mSculptedPreview->rotate(yaw_radians, pitch_radians);
- }
- else
- {
- LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- if (iface && iface->getFirstSelectedIndex() <= 0)
- {
- F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f;
- mPreviewImageRect.stretch(zoom_amt);
- }
- else
- {
- F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
- F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
-
- mAvatarPreview->rotate(yaw_radians, 0.f);
- mAvatarPreview->zoom(zoom_amt);
- mSculptedPreview->rotate(yaw_radians, 0.f);
- mSculptedPreview->zoom(zoom_amt);
- }
- }
-
- LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- if (iface && iface->getFirstSelectedIndex() <= 0)
- {
- if (mPreviewImageRect.getWidth() > 1.f)
- {
- mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f);
- }
- else if (mPreviewImageRect.getWidth() < 0.1f)
- {
- mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f);
- }
-
- if (mPreviewImageRect.getHeight() > 1.f)
- {
- mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f);
- }
- else if (mPreviewImageRect.getHeight() < 0.1f)
- {
- mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f);
- }
-
- if (mPreviewImageRect.mLeft < 0.f)
- {
- mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f);
- }
- else if (mPreviewImageRect.mRight > 1.f)
- {
- mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f);
- }
-
- if (mPreviewImageRect.mBottom < 0.f)
- {
- mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom);
- }
- else if (mPreviewImageRect.mTop > 1.f)
- {
- mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop);
- }
- }
- else
- {
- mAvatarPreview->refresh();
- mSculptedPreview->refresh();
- }
-
- LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY);
- }
-
- if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview)
- {
- return LLFloater::handleHover(x, y, mask);
- }
- else if (local_mask == MASK_ORBIT)
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
- }
- else if (local_mask == MASK_PAN)
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
- }
- else
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
- }
-
- return TRUE;
+ MASK local_mask = mask & ~MASK_ALT;
+
+ if (mAvatarPreview && hasMouseCapture())
+ {
+ if (local_mask == MASK_PAN)
+ {
+ // pan here
+ LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
+ if (iface && iface->getFirstSelectedIndex() <= 0)
+ {
+ mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(),
+ (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight());
+ }
+ else
+ {
+ mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
+ mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
+ }
+ }
+ else if (local_mask == MASK_ORBIT)
+ {
+ F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
+ F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
+
+ mAvatarPreview->rotate(yaw_radians, pitch_radians);
+ mSculptedPreview->rotate(yaw_radians, pitch_radians);
+ }
+ else
+ {
+ LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
+ if (iface && iface->getFirstSelectedIndex() <= 0)
+ {
+ F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f;
+ mPreviewImageRect.stretch(zoom_amt);
+ }
+ else
+ {
+ F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
+ F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
+
+ mAvatarPreview->rotate(yaw_radians, 0.f);
+ mAvatarPreview->zoom(zoom_amt);
+ mSculptedPreview->rotate(yaw_radians, 0.f);
+ mSculptedPreview->zoom(zoom_amt);
+ }
+ }
+
+ LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
+ if (iface && iface->getFirstSelectedIndex() <= 0)
+ {
+ if (mPreviewImageRect.getWidth() > 1.f)
+ {
+ mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f);
+ }
+ else if (mPreviewImageRect.getWidth() < 0.1f)
+ {
+ mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f);
+ }
+
+ if (mPreviewImageRect.getHeight() > 1.f)
+ {
+ mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f);
+ }
+ else if (mPreviewImageRect.getHeight() < 0.1f)
+ {
+ mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f);
+ }
+
+ if (mPreviewImageRect.mLeft < 0.f)
+ {
+ mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f);
+ }
+ else if (mPreviewImageRect.mRight > 1.f)
+ {
+ mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f);
+ }
+
+ if (mPreviewImageRect.mBottom < 0.f)
+ {
+ mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom);
+ }
+ else if (mPreviewImageRect.mTop > 1.f)
+ {
+ mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop);
+ }
+ }
+ else
+ {
+ mAvatarPreview->refresh();
+ mSculptedPreview->refresh();
+ }
+
+ LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY);
+ }
+
+ if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview)
+ {
+ return LLFloater::handleHover(x, y, mask);
+ }
+ else if (local_mask == MASK_ORBIT)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
+ }
+ else if (local_mask == MASK_PAN)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
+ }
+ else
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
+ }
+
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -537,16 +547,16 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
//-----------------------------------------------------------------------------
BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (mPreviewRect.pointInRect(x, y) && mAvatarPreview)
- {
- mAvatarPreview->zoom((F32)clicks * -0.2f);
- mAvatarPreview->refresh();
+ if (mPreviewRect.pointInRect(x, y) && mAvatarPreview)
+ {
+ mAvatarPreview->zoom((F32)clicks * -0.2f);
+ mAvatarPreview->refresh();
- mSculptedPreview->zoom((F32)clicks * -0.2f);
- mSculptedPreview->refresh();
- }
+ mSculptedPreview->zoom((F32)clicks * -0.2f);
+ mSculptedPreview->refresh();
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -555,7 +565,7 @@ BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
// static
void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handler)
{
- gViewerWindow->showCursor();
+ gViewerWindow->showCursor();
}
@@ -564,63 +574,63 @@ void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handl
//-----------------------------------------------------------------------------
LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
{
- mNeedsUpdate = TRUE;
- mTargetJoint = NULL;
- mTargetMesh = NULL;
- mCameraDistance = 0.f;
- mCameraYaw = 0.f;
- mCameraPitch = 0.f;
- mCameraZoom = 1.f;
-
- mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
- mDummyAvatar->mSpecialRenderMode = 2;
-
- mTextureName = 0;
+ mNeedsUpdate = TRUE;
+ mTargetJoint = NULL;
+ mTargetMesh = NULL;
+ mCameraDistance = 0.f;
+ mCameraYaw = 0.f;
+ mCameraPitch = 0.f;
+ mCameraZoom = 1.f;
+
+ mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
+ mDummyAvatar->mSpecialRenderMode = 2;
+
+ mTextureName = 0;
}
LLImagePreviewAvatar::~LLImagePreviewAvatar()
{
- mDummyAvatar->markDead();
+ mDummyAvatar->markDead();
}
//virtual
S8 LLImagePreviewAvatar::getType() const
{
- return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_AVATAR ;
+ return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_AVATAR ;
}
-void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)
-{
- mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);
- // clear out existing test mesh
- if (mTargetMesh)
- {
- mTargetMesh->setTestTexture(0);
- }
-
- if (male)
- {
- mDummyAvatar->setVisualParamWeight( "male", 1.f );
- mDummyAvatar->updateVisualParams();
- mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
- }
- else
- {
- mDummyAvatar->setVisualParamWeight( "male", 0.f );
- mDummyAvatar->updateVisualParams();
- mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
- }
- mDummyAvatar->mRoot->setVisible(FALSE, TRUE);
-
- mTargetMesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
- mTargetMesh->setTestTexture(mTextureName);
- mTargetMesh->setVisible(TRUE, FALSE);
- mCameraDistance = distance;
- mCameraZoom = 1.f;
- mCameraPitch = 0.f;
- mCameraYaw = 0.f;
- mCameraOffset.clearVec();
+void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)
+{
+ mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);
+ // clear out existing test mesh
+ if (mTargetMesh)
+ {
+ mTargetMesh->setTestTexture(0);
+ }
+
+ if (male)
+ {
+ mDummyAvatar->setVisualParamWeight( "male", 1.f );
+ mDummyAvatar->updateVisualParams();
+ mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
+ }
+ else
+ {
+ mDummyAvatar->setVisualParamWeight( "male", 0.f );
+ mDummyAvatar->updateVisualParams();
+ mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
+ }
+ mDummyAvatar->mRoot->setVisible(FALSE, TRUE);
+
+ mTargetMesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
+ mTargetMesh->setTestTexture(mTextureName);
+ mTargetMesh->setVisible(TRUE, FALSE);
+ mCameraDistance = distance;
+ mCameraZoom = 1.f;
+ mCameraPitch = 0.f;
+ mCameraYaw = 0.f;
+ mCameraOffset.clearVec();
}
//-----------------------------------------------------------------------------
@@ -628,15 +638,15 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const
//-----------------------------------------------------------------------------
void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
{
- if (mDummyAvatar)
- {
- LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
- // clear out existing test mesh
- if (mesh)
- {
- mesh->setTestTexture(0);
- }
- }
+ if (mDummyAvatar)
+ {
+ LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
+ // clear out existing test mesh
+ if (mesh)
+ {
+ mesh->setTestTexture(0);
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -644,82 +654,82 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
//-----------------------------------------------------------------------------
BOOL LLImagePreviewAvatar::render()
{
- mNeedsUpdate = FALSE;
- LLVOAvatar* avatarp = mDummyAvatar;
-
- gGL.pushUIMatrix();
- gGL.loadUIIdentity();
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
-
- LLGLSUIDefault def;
- gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
-
- gUIProgram.bind();
-
- gl_rect_2d_simple( mFullWidth, mFullHeight );
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- gGL.flush();
- LLVector3 target_pos = mTargetJoint->getWorldPosition();
-
- LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
- LLQuaternion(mCameraYaw, LLVector3::z_axis);
-
- LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot;
- LLViewerCamera::getInstance()->setOriginAndLookAt(
- target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
- LLVector3::z_axis, // up
- target_pos + (mCameraOffset * av_rot) ); // point of interest
-
- stop_glerror();
-
- LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight);
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
-
- LLVertexBuffer::unbind();
- avatarp->updateLOD();
-
- if (avatarp->mDrawable.notNull())
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
- // make sure alpha=0 shows avatar material color
- LLGLDisable no_blend(GL_BLEND);
-
- LLFace* face = avatarp->mDrawable->getFace(0);
- if (face)
- {
- LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
- gPipeline.enableLightsPreview();
- avatarPoolp->renderAvatars(avatarp); // renders only one avatar
- }
- }
-
- gGL.popUIMatrix();
- gGL.color4f(1,1,1,1);
- return TRUE;
+ mNeedsUpdate = FALSE;
+ LLVOAvatar* avatarp = mDummyAvatar;
+
+ gGL.pushUIMatrix();
+ gGL.loadUIIdentity();
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+
+ LLGLSUIDefault def;
+ gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+
+ gUIProgram.bind();
+
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.flush();
+ LLVector3 target_pos = mTargetJoint->getWorldPosition();
+
+ LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
+ LLQuaternion(mCameraYaw, LLVector3::z_axis);
+
+ LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot;
+ LLViewerCamera::getInstance()->setOriginAndLookAt(
+ target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos + (mCameraOffset * av_rot) ); // point of interest
+
+ stop_glerror();
+
+ LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight);
+ LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
+
+ LLVertexBuffer::unbind();
+ avatarp->updateLOD();
+
+ if (avatarp->mDrawable.notNull())
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
+ // make sure alpha=0 shows avatar material color
+ LLGLDisable no_blend(GL_BLEND);
+
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ gPipeline.enableLightsPreview();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
+ }
+
+ gGL.popUIMatrix();
+ gGL.color4f(1,1,1,1);
+ return TRUE;
}
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
void LLImagePreviewAvatar::refresh()
-{
- mNeedsUpdate = TRUE;
+{
+ mNeedsUpdate = TRUE;
}
//-----------------------------------------------------------------------------
@@ -727,9 +737,9 @@ void LLImagePreviewAvatar::refresh()
//-----------------------------------------------------------------------------
void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians)
{
- mCameraYaw = mCameraYaw + yaw_radians;
+ mCameraYaw = mCameraYaw + yaw_radians;
- mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
+ mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
}
//-----------------------------------------------------------------------------
@@ -737,13 +747,13 @@ void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians)
//-----------------------------------------------------------------------------
void LLImagePreviewAvatar::zoom(F32 zoom_amt)
{
- mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
+ mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
}
void LLImagePreviewAvatar::pan(F32 right, F32 up)
{
- mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
- mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
}
@@ -753,19 +763,19 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up)
LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
{
- mNeedsUpdate = TRUE;
- mCameraDistance = 0.f;
- mCameraYaw = 0.f;
- mCameraPitch = 0.f;
- mCameraZoom = 1.f;
- mTextureName = 0;
-
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE);
- volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_SPHERE);
-
- F32 const HIGHEST_LOD = 4.0f;
- mVolume = new LLVolume(volume_params, HIGHEST_LOD);
+ mNeedsUpdate = TRUE;
+ mCameraDistance = 0.f;
+ mCameraYaw = 0.f;
+ mCameraPitch = 0.f;
+ mCameraZoom = 1.f;
+ mTextureName = 0;
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE);
+ volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_SPHERE);
+
+ F32 const HIGHEST_LOD = 4.0f;
+ mVolume = new LLVolume(volume_params, HIGHEST_LOD);
}
@@ -776,67 +786,67 @@ LLImagePreviewSculpted::~LLImagePreviewSculpted()
//virtual
S8 LLImagePreviewSculpted::getType() const
{
- return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_SCULPTED ;
+ return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_SCULPTED ;
}
void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
-{
- mCameraDistance = distance;
- mCameraZoom = 1.f;
- mCameraPitch = 0.f;
- mCameraYaw = 0.f;
- mCameraOffset.clearVec();
-
- if (imagep)
- {
- mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
- }
-
- const LLVolumeFace &vf = mVolume->getVolumeFace(0);
- U32 num_indices = vf.mNumIndices;
- U32 num_vertices = vf.mNumVertices;
-
- mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
- if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices))
- {
- LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to"
- << num_vertices << " vertices and "
- << num_indices << " indices" << LL_ENDL;
- // We are likely to crash on getTexCoord0Strider()
- }
-
- LLStrider<LLVector3> vertex_strider;
- LLStrider<LLVector3> normal_strider;
- LLStrider<LLVector2> tc_strider;
- LLStrider<U16> index_strider;
-
- mVertexBuffer->getVertexStrider(vertex_strider);
- mVertexBuffer->getNormalStrider(normal_strider);
- mVertexBuffer->getTexCoord0Strider(tc_strider);
- mVertexBuffer->getIndexStrider(index_strider);
-
- // build vertices and normals
- LLStrider<LLVector3> pos;
- pos = (LLVector3*) vf.mPositions; pos.setStride(16);
- LLStrider<LLVector3> norm;
- norm = (LLVector3*) vf.mNormals; norm.setStride(16);
- LLStrider<LLVector2> tc;
- tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
-
- for (U32 i = 0; i < num_vertices; i++)
- {
- *(vertex_strider++) = *pos++;
- LLVector3 normal = *norm++;
- normal.normalize();
- *(normal_strider++) = normal;
- *(tc_strider++) = *tc++;
- }
-
- // build indices
- for (U16 i = 0; i < num_indices; i++)
- {
- *(index_strider++) = vf.mIndices[i];
- }
+{
+ mCameraDistance = distance;
+ mCameraZoom = 1.f;
+ mCameraPitch = 0.f;
+ mCameraYaw = 0.f;
+ mCameraOffset.clearVec();
+
+ if (imagep)
+ {
+ mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
+ }
+
+ const LLVolumeFace &vf = mVolume->getVolumeFace(0);
+ U32 num_indices = vf.mNumIndices;
+ U32 num_vertices = vf.mNumVertices;
+
+ mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
+ if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices))
+ {
+ LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to"
+ << num_vertices << " vertices and "
+ << num_indices << " indices" << LL_ENDL;
+ // We are likely to crash on getTexCoord0Strider()
+ }
+
+ LLStrider<LLVector3> vertex_strider;
+ LLStrider<LLVector3> normal_strider;
+ LLStrider<LLVector2> tc_strider;
+ LLStrider<U16> index_strider;
+
+ mVertexBuffer->getVertexStrider(vertex_strider);
+ mVertexBuffer->getNormalStrider(normal_strider);
+ mVertexBuffer->getTexCoord0Strider(tc_strider);
+ mVertexBuffer->getIndexStrider(index_strider);
+
+ // build vertices and normals
+ LLStrider<LLVector3> pos;
+ pos = (LLVector3*) vf.mPositions; pos.setStride(16);
+ LLStrider<LLVector3> norm;
+ norm = (LLVector3*) vf.mNormals; norm.setStride(16);
+ LLStrider<LLVector2> tc;
+ tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
+
+ for (U32 i = 0; i < num_vertices; i++)
+ {
+ *(vertex_strider++) = *pos++;
+ LLVector3 normal = *norm++;
+ normal.normalize();
+ *(normal_strider++) = normal;
+ *(tc_strider++) = *tc++;
+ }
+
+ // build indices
+ for (U16 i = 0; i < num_indices; i++)
+ {
+ *(index_strider++) = vf.mIndices[i];
+ }
mVertexBuffer->unmapBuffer();
}
@@ -847,82 +857,82 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
//-----------------------------------------------------------------------------
BOOL LLImagePreviewSculpted::render()
{
- mNeedsUpdate = FALSE;
- LLGLSUIDefault def;
- LLGLDisable no_blend(GL_BLEND);
- LLGLEnable cull(GL_CULL_FACE);
- LLGLDepthTest depth(GL_TRUE);
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+ mNeedsUpdate = FALSE;
+ LLGLSUIDefault def;
+ LLGLDisable no_blend(GL_BLEND);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLDepthTest depth(GL_TRUE);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
- gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- gUIProgram.bind();
+ gUIProgram.bind();
- gl_rect_2d_simple( mFullWidth, mFullHeight );
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ LLVector3 target_pos(0, 0, 0);
- glClear(GL_DEPTH_BUFFER_BIT);
+ LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
+ LLQuaternion(mCameraYaw, LLVector3::z_axis);
- LLVector3 target_pos(0, 0, 0);
+ LLQuaternion av_rot = camera_rot;
+ LLViewerCamera::getInstance()->setOriginAndLookAt(
+ target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos + (mCameraOffset * av_rot) ); // point of interest
- LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
- LLQuaternion(mCameraYaw, LLVector3::z_axis);
+ stop_glerror();
- LLQuaternion av_rot = camera_rot;
- LLViewerCamera::getInstance()->setOriginAndLookAt(
- target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
- LLVector3::z_axis, // up
- target_pos + (mCameraOffset * av_rot) ); // point of interest
+ LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight);
+ LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
- stop_glerror();
+ const LLVolumeFace &vf = mVolume->getVolumeFace(0);
+ U32 num_indices = vf.mNumIndices;
+
+ gPipeline.enableLightsAvatar();
- LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight);
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
+ gObjectPreviewProgram.bind();
+ gPipeline.enableLightsPreview();
- const LLVolumeFace &vf = mVolume->getVolumeFace(0);
- U32 num_indices = vf.mNumIndices;
+ gGL.pushMatrix();
+ const F32 SCALE = 1.25f;
+ gGL.scalef(SCALE, SCALE, SCALE);
+ const F32 BRIGHTNESS = 0.9f;
+ gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
- gPipeline.enableLightsAvatar();
+ mVertexBuffer->setBuffer();
+ mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
- gObjectPreviewProgram.bind();
- gPipeline.enableLightsPreview();
+ gGL.popMatrix();
- gGL.pushMatrix();
- const F32 SCALE = 1.25f;
- gGL.scalef(SCALE, SCALE, SCALE);
- const F32 BRIGHTNESS = 0.9f;
- gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+ gObjectPreviewProgram.unbind();
- mVertexBuffer->setBuffer();
- mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
-
- gGL.popMatrix();
-
- gObjectPreviewProgram.unbind();
-
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
void LLImagePreviewSculpted::refresh()
-{
- mNeedsUpdate = TRUE;
+{
+ mNeedsUpdate = TRUE;
}
//-----------------------------------------------------------------------------
@@ -930,9 +940,9 @@ void LLImagePreviewSculpted::refresh()
//-----------------------------------------------------------------------------
void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians)
{
- mCameraYaw = mCameraYaw + yaw_radians;
+ mCameraYaw = mCameraYaw + yaw_radians;
- mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
+ mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
}
//-----------------------------------------------------------------------------
@@ -940,11 +950,11 @@ void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians)
//-----------------------------------------------------------------------------
void LLImagePreviewSculpted::zoom(F32 zoom_amt)
{
- mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
+ mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
}
void LLImagePreviewSculpted::pan(F32 right, F32 up)
{
- mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
- mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
}
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index 9e764e4972..426dd926ae 100644
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfloaterimagepreview.h
* @brief LLFloaterImagePreview class definition
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -43,102 +43,104 @@ class LLVolume;
class LLImagePreviewSculpted : public LLViewerDynamicTexture
{
protected:
- virtual ~LLImagePreviewSculpted();
+ virtual ~LLImagePreviewSculpted();
public:
- LLImagePreviewSculpted(S32 width, S32 height);
+ LLImagePreviewSculpted(S32 width, S32 height);
- /*virtual*/ S8 getType() const ;
+ S8 getType() const override;
- void setPreviewTarget(LLImageRaw *imagep, F32 distance);
- void setTexture(U32 name) { mTextureName = name; }
+ void setPreviewTarget(LLImageRaw *imagep, F32 distance);
+ void setTexture(U32 name) { mTextureName = name; }
- BOOL render();
- void refresh();
- void rotate(F32 yaw_radians, F32 pitch_radians);
- void zoom(F32 zoom_amt);
- void pan(F32 right, F32 up);
- virtual BOOL needsRender() { return mNeedsUpdate; }
+ BOOL render() override;
+ void refresh();
+ void rotate(F32 yaw_radians, F32 pitch_radians);
+ void zoom(F32 zoom_amt);
+ void pan(F32 right, F32 up);
+ virtual BOOL needsRender() override { return mNeedsUpdate; }
protected:
- BOOL mNeedsUpdate;
- U32 mTextureName;
- F32 mCameraDistance;
- F32 mCameraYaw;
- F32 mCameraPitch;
- F32 mCameraZoom;
- LLVector3 mCameraOffset;
- LLPointer<LLVolume> mVolume;
- LLPointer<LLVertexBuffer> mVertexBuffer;
+ BOOL mNeedsUpdate;
+ U32 mTextureName;
+ F32 mCameraDistance;
+ F32 mCameraYaw;
+ F32 mCameraPitch;
+ F32 mCameraZoom;
+ LLVector3 mCameraOffset;
+ LLPointer<LLVolume> mVolume;
+ LLPointer<LLVertexBuffer> mVertexBuffer;
};
class LLImagePreviewAvatar : public LLViewerDynamicTexture
{
protected:
- virtual ~LLImagePreviewAvatar();
+ virtual ~LLImagePreviewAvatar();
public:
- LLImagePreviewAvatar(S32 width, S32 height);
+ LLImagePreviewAvatar(S32 width, S32 height);
- /*virtual*/ S8 getType() const ;
+ S8 getType() const override;
- void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male);
- void setTexture(U32 name) { mTextureName = name; }
- void clearPreviewTexture(const std::string& mesh_name);
+ void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male);
+ void setTexture(U32 name) { mTextureName = name; }
+ void clearPreviewTexture(const std::string& mesh_name);
- BOOL render();
- void refresh();
- void rotate(F32 yaw_radians, F32 pitch_radians);
- void zoom(F32 zoom_amt);
- void pan(F32 right, F32 up);
- virtual BOOL needsRender() { return mNeedsUpdate; }
+ BOOL render() override;
+ void refresh();
+ void rotate(F32 yaw_radians, F32 pitch_radians);
+ void zoom(F32 zoom_amt);
+ void pan(F32 right, F32 up);
+ virtual BOOL needsRender() override { return mNeedsUpdate; }
protected:
- BOOL mNeedsUpdate;
- LLJoint* mTargetJoint;
- LLViewerJointMesh* mTargetMesh;
- F32 mCameraDistance;
- F32 mCameraYaw;
- F32 mCameraPitch;
- F32 mCameraZoom;
- LLVector3 mCameraOffset;
- LLPointer<LLVOAvatar> mDummyAvatar;
- U32 mTextureName;
+ BOOL mNeedsUpdate;
+ LLJoint* mTargetJoint;
+ LLViewerJointMesh* mTargetMesh;
+ F32 mCameraDistance;
+ F32 mCameraYaw;
+ F32 mCameraPitch;
+ F32 mCameraZoom;
+ LLVector3 mCameraOffset;
+ LLPointer<LLVOAvatar> mDummyAvatar;
+ U32 mTextureName;
};
class LLFloaterImagePreview : public LLFloaterNameDesc
{
public:
- LLFloaterImagePreview(const std::string& filename);
- virtual ~LLFloaterImagePreview();
+ LLFloaterImagePreview(const std::string& filename);
+ virtual ~LLFloaterImagePreview();
- virtual BOOL postBuild();
+ BOOL postBuild() override;
- BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- BOOL handleHover(S32 x, S32 y, MASK mask);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ S32 getExpectedUploadCost() const override;
+
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override;
- static void onMouseCaptureLostImagePreview(LLMouseHandler*);
+ static void onMouseCaptureLostImagePreview(LLMouseHandler*);
- void clearAllPreviewTextures();
+ void clearAllPreviewTextures();
protected:
- static void onPreviewTypeCommit(LLUICtrl*,void*);
- void draw();
- bool loadImage(const std::string& filename);
-
- LLPointer<LLImageRaw> mRawImagep;
- LLPointer<LLImagePreviewAvatar> mAvatarPreview;
- LLPointer<LLImagePreviewSculpted> mSculptedPreview;
- S32 mLastMouseX;
- S32 mLastMouseY;
- LLRect mPreviewRect;
- LLRectf mPreviewImageRect;
- LLPointer<LLViewerTexture> mImagep ;
-
- std::string mImageLoadError;
+ static void onPreviewTypeCommit(LLUICtrl*,void*);
+ void draw() override;
+ bool loadImage(const std::string& filename);
+
+ LLPointer<LLImageRaw> mRawImagep;
+ LLPointer<LLImagePreviewAvatar> mAvatarPreview;
+ LLPointer<LLImagePreviewSculpted> mSculptedPreview;
+ S32 mLastMouseX;
+ S32 mLastMouseY;
+ LLRect mPreviewRect;
+ LLRectf mPreviewImageRect;
+ LLPointer<LLViewerTexture> mImagep ;
+
+ std::string mImageLoadError;
};
#endif // LL_LLFLOATERIMAGEPREVIEW_H
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 148da6912a..cf3b512fab 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfloaternamedesc.h
* @brief LLFloaterNameDesc class definition
*
* $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$
*/
@@ -39,46 +39,46 @@ class LLRadioGroup;
class LLFloaterNameDesc : public LLFloater
{
public:
- LLFloaterNameDesc(const LLSD& filename);
- virtual ~LLFloaterNameDesc();
- virtual BOOL postBuild();
-
- void onBtnOK();
- void onBtnCancel();
- void doCommit();
-
- S32 getExpectedUploadCost() const;
+ LLFloaterNameDesc(const LLSD& filename);
+ virtual ~LLFloaterNameDesc();
+ virtual BOOL postBuild();
+
+ void onBtnOK();
+ void onBtnCancel();
+ void doCommit();
+ virtual S32 getExpectedUploadCost() const;
+
protected:
- virtual void onCommit();
+ virtual void onCommit();
protected:
- BOOL mIsAudio;
- bool mIsText;
+ BOOL mIsAudio;
+ bool mIsText;
- std::string mFilenameAndPath;
- std::string mFilename;
+ std::string mFilenameAndPath;
+ std::string mFilename;
};
class LLFloaterSoundPreview : public LLFloaterNameDesc
{
public:
- LLFloaterSoundPreview(const LLSD& filename );
- virtual BOOL postBuild();
+ LLFloaterSoundPreview(const LLSD& filename );
+ virtual BOOL postBuild();
};
class LLFloaterAnimPreview : public LLFloaterNameDesc
{
public:
- LLFloaterAnimPreview(const LLSD& filename );
- virtual BOOL postBuild();
+ LLFloaterAnimPreview(const LLSD& filename );
+ virtual BOOL postBuild();
};
class LLFloaterScriptPreview : public LLFloaterNameDesc
{
public:
- LLFloaterScriptPreview(const LLSD& filename );
- virtual BOOL postBuild();
+ LLFloaterScriptPreview(const LLSD& filename );
+ virtual BOOL postBuild();
};
#endif // LL_LLFLOATERNAMEDESC_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index ef81cb549f..9ce7a07ee4 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfloaterregioninfo.cpp
* @author Aaron Brashears
* @brief Implementation of the region info and controls floater and panels.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -50,18 +50,19 @@
#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
-#include "llbutton.h"
+#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llclipboard.h"
#include "llcombobox.h"
#include "llestateinfomodel.h"
#include "llfilepicker.h"
-#include "llfloatergodtools.h" // for send_sim_wide_deletes()
+#include "llfloatergodtools.h" // for send_sim_wide_deletes()
#include "llfloatertopobjects.h" // added to fix SL-32336
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloatertelehub.h"
+#include "llgltfmateriallist.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
#include "llnamelistctrl.h"
@@ -86,7 +87,6 @@
#include "llviewerstats.h"
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
-#include "llvlcomposition.h"
#include "lltrans.h"
#include "llagentui.h"
#include "llmeshrepository.h"
@@ -100,7 +100,6 @@
#include "llavatarnamecache.h"
#include "llenvironment.h"
-const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
const U32 MAX_LISTED_NAMES = 100;
@@ -114,70 +113,70 @@ const U32 MAX_LISTED_NAMES = 100;
class LLDispatchEstateUpdateInfo : public LLDispatchHandler
{
public:
- LLDispatchEstateUpdateInfo() {}
- virtual ~LLDispatchEstateUpdateInfo() {}
- virtual bool operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings);
+ LLDispatchEstateUpdateInfo() {}
+ virtual ~LLDispatchEstateUpdateInfo() {}
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings);
};
class LLDispatchSetEstateAccess : public LLDispatchHandler
{
public:
- LLDispatchSetEstateAccess() {}
- virtual ~LLDispatchSetEstateAccess() {}
- virtual bool operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings);
+ LLDispatchSetEstateAccess() {}
+ virtual ~LLDispatchSetEstateAccess() {}
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings);
};
class LLDispatchSetEstateExperience : public LLDispatchHandler
{
public:
- virtual bool operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings);
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings);
- static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
+ static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
};
/*
void unpack_request_params(
- LLMessageSystem* msg,
- LLDispatcher::sparam_t& strings,
- LLDispatcher::iparam_t& integers)
-{
- char str_buf[MAX_STRING];
- S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData);
- S32 i;
- for (i = 0; i < str_count; ++i)
- {
- // we treat the SParam as binary data (since it might be an
- // LLUUID in compressed form which may have embedded \0's,)
- str_buf[0] = '\0';
- S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam);
- if (data_size >= 0)
- {
- msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam,
- str_buf, data_size, i, MAX_STRING - 1);
- strings.push_back(std::string(str_buf, data_size));
- }
- }
-
- U32 int_buf;
- S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData);
- for (i = 0; i < int_count; ++i)
- {
- msg->getU32("IntegerData", "IParam", int_buf, i);
- integers.push_back(int_buf);
- }
+ LLMessageSystem* msg,
+ LLDispatcher::sparam_t& strings,
+ LLDispatcher::iparam_t& integers)
+{
+ char str_buf[MAX_STRING];
+ S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData);
+ S32 i;
+ for (i = 0; i < str_count; ++i)
+ {
+ // we treat the SParam as binary data (since it might be an
+ // LLUUID in compressed form which may have embedded \0's,)
+ str_buf[0] = '\0';
+ S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam);
+ if (data_size >= 0)
+ {
+ msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam,
+ str_buf, data_size, i, MAX_STRING - 1);
+ strings.push_back(std::string(str_buf, data_size));
+ }
+ }
+
+ U32 int_buf;
+ S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData);
+ for (i = 0; i < int_count; ++i)
+ {
+ msg->getU32("IntegerData", "IParam", int_buf, i);
+ integers.push_back(int_buf);
+ }
}
*/
@@ -229,75 +228,75 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice;
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
- : LLFloater(seed),
+ : LLFloater(seed),
mEnvironmentPanel(NULL),
mRegionChangedCallback()
{}
BOOL LLFloaterRegionInfo::postBuild()
{
- mTab = getChild<LLTabContainer>("region_panels");
- mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2));
-
- // contruct the panels
- LLPanelRegionInfo* panel;
- panel = new LLPanelEstateInfo;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_estate.xml");
- mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
-
- panel = new LLPanelEstateAccess;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_access.xml");
- mTab->addTabPanel(panel);
-
- panel = new LLPanelEstateCovenant;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_covenant.xml");
- mTab->addTabPanel(panel);
-
- panel = new LLPanelRegionGeneralInfo;
- mInfoPanels.push_back(panel);
- panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub", boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel));
- panel->buildFromFile("panel_region_general.xml");
- mTab->addTabPanel(panel);
-
- panel = new LLPanelRegionTerrainInfo;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_terrain.xml");
- mTab->addTabPanel(panel);
+ mTab = getChild<LLTabContainer>("region_panels");
+ mTab->setCommitCallback(boost::bind(&LLFloaterRegionInfo::onTabSelected, this, _2));
+
+ // contruct the panels
+ LLPanelRegionInfo* panel;
+ panel = new LLPanelEstateInfo;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_estate.xml");
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
+
+ panel = new LLPanelEstateAccess;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_access.xml");
+ mTab->addTabPanel(panel);
+
+ panel = new LLPanelEstateCovenant;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_covenant.xml");
+ mTab->addTabPanel(panel);
+
+ panel = new LLPanelRegionGeneralInfo;
+ mInfoPanels.push_back(panel);
+ panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub", boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel));
+ panel->buildFromFile("panel_region_general.xml");
+ mTab->addTabPanel(panel);
+
+ panel = new LLPanelRegionTerrainInfo;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_terrain.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);
- panel->buildFromFile("panel_region_debug.xml");
- mTab->addTabPanel(panel);
-
- if(gDisconnected)
- {
- return TRUE;
- }
+ panel = new LLPanelRegionDebugInfo;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_debug.xml");
+ mTab->addTabPanel(panel);
- if(!gAgent.getRegionCapability("RegionExperiences").empty())
- {
- panel = new LLPanelRegionExperiences;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_experiences.xml");
- mTab->addTabPanel(panel);
- }
+ if(gDisconnected)
+ {
+ return TRUE;
+ }
- gMessageSystem->setHandlerFunc(
- "EstateOwnerMessage",
- &processEstateOwnerRequest);
+ if(!gAgent.getRegionCapability("RegionExperiences").empty())
+ {
+ panel = new LLPanelRegionExperiences;
+ mInfoPanels.push_back(panel);
+ panel->buildFromFile("panel_region_experiences.xml");
+ mTab->addTabPanel(panel);
+ }
+
+ gMessageSystem->setHandlerFunc(
+ "EstateOwnerMessage",
+ &processEstateOwnerRequest);
- // Request region info when agent region changes.
- mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this));
+ // Request region info when agent region changes.
+ mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this));
- return TRUE;
+ return TRUE;
}
LLFloaterRegionInfo::~LLFloaterRegionInfo()
@@ -310,26 +309,26 @@ LLFloaterRegionInfo::~LLFloaterRegionInfo()
void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
- if(gDisconnected)
- {
- disableTabCtrls();
- return;
- }
- refreshFromRegion(gAgent.getRegion());
- requestRegionInfo();
+ if(gDisconnected)
+ {
+ disableTabCtrls();
+ return;
+ }
+ refreshFromRegion(gAgent.getRegion());
+ requestRegionInfo();
- if (!mGodLevelChangeSlot.connected())
- {
- mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1));
- }
+ if (!mGodLevelChangeSlot.connected())
+ {
+ mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1));
+ }
}
void LLFloaterRegionInfo::onClose(bool app_quitting)
{
- if (mGodLevelChangeSlot.connected())
- {
- mGodLevelChangeSlot.disconnect();
- }
+ if (mGodLevelChangeSlot.connected())
+ {
+ mGodLevelChangeSlot.disconnect();
+ }
}
void LLFloaterRegionInfo::onRegionChanged()
@@ -340,359 +339,368 @@ void LLFloaterRegionInfo::onRegionChanged()
}
}
-// static
void LLFloaterRegionInfo::requestRegionInfo()
{
- LLTabContainer* tab = findChild<LLTabContainer>("region_panels");
- if (tab)
- {
- tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+ LLTabContainer* tab = findChild<LLTabContainer>("region_panels");
+ if (tab)
+ {
+ tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
tab->getChild<LLPanel>("Access")->setCtrlsEnabled(FALSE);
- }
+ }
- // Must allow anyone to request the RegionInfo data
- // so non-owners/non-gods can see the values.
- // Therefore can't use an EstateOwnerMessage JC
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("RequestRegionInfo");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- gAgent.sendReliableMessage();
+ // Must allow anyone to request the RegionInfo data
+ // so non-owners/non-gods can see the values.
+ // Therefore can't use an EstateOwnerMessage JC
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("RequestRegionInfo");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ gAgent.sendReliableMessage();
}
// static
void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
{
- static LLDispatcher dispatch;
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if(!floater)
- {
- return;
- }
-
- if (!estate_dispatch_initialized)
- {
- LLPanelEstateInfo::initDispatch(dispatch);
- }
-
- LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
-
- // unpack the message
- std::string request;
- LLUUID invoice;
- LLDispatcher::sparam_t strings;
- LLDispatcher::unpackMessage(msg, request, invoice, strings);
- if(invoice != getLastInvoice())
- {
- LL_WARNS() << "Mismatched Estate message: " << request << LL_ENDL;
- return;
- }
-
- //dispatch the message
- dispatch.dispatch(request, invoice, strings);
-
- if (panel)
- {
- panel->updateControls(gAgent.getRegion());
- }
+ static LLDispatcher dispatch;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if(!floater)
+ {
+ return;
+ }
+
+ if (!estate_dispatch_initialized)
+ {
+ LLPanelEstateInfo::initDispatch(dispatch);
+ }
+
+ LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
+
+ // unpack the message
+ std::string request;
+ LLUUID invoice;
+ LLDispatcher::sparam_t strings;
+ LLDispatcher::unpackMessage(msg, request, invoice, strings);
+ if(invoice != getLastInvoice())
+ {
+ LL_WARNS() << "Mismatched Estate message: " << request << LL_ENDL;
+ return;
+ }
+
+ //dispatch the message
+ dispatch.dispatch(request, invoice, strings);
+
+ if (panel)
+ {
+ panel->updateControls(gAgent.getRegion());
+ }
}
// static
void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
{
- LLPanel* panel;
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if(!floater)
- {
- return;
- }
+ LLPanel* panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if(!floater)
+ {
+ 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();
- BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
-
- // *TODO: Replace parsing msg with accessing the region info model.
- LLRegionInfoModel& region_info = LLRegionInfoModel::instance();
-
- // extract message
- std::string sim_name;
- std::string sim_type = LLTrans::getString("land_type_unknown");
- U64 region_flags;
- U8 agent_limit;
- S32 hard_agent_limit;
- F32 object_bonus_factor;
- U8 sim_access;
- F32 water_height;
- F32 terrain_raise_limit;
- F32 terrain_lower_limit;
- BOOL use_estate_sun;
- F32 sun_hour;
- msg->getString("RegionInfo", "SimName", sim_name);
- msg->getU8("RegionInfo", "MaxAgents", agent_limit);
- msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit);
- msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
- msg->getU8("RegionInfo", "SimAccess", sim_access);
- msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
- msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit);
- msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit);
- msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun);
- // actually the "last set" sun hour, not the current sun hour. JC
- msg->getF32("RegionInfo", "SunHour", sun_hour);
- // the only reasonable way to decide if we actually have any data is to
- // check to see if any of these fields have nonzero sizes
- if (msg->getSize("RegionInfo2", "ProductSKU") > 0 ||
- msg->getSize("RegionInfo2", "ProductName") > 0)
- {
- msg->getString("RegionInfo2", "ProductName", sim_type);
- LLTrans::findString(sim_type, sim_type); // try localizing sim product name
- }
-
- if (msg->has(_PREHASH_RegionInfo3))
- {
- msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags);
- }
- else
- {
- U32 flags = 0;
- msg->getU32("RegionInfo", "RegionFlags", flags);
- region_flags = flags;
- }
-
- if (msg->has(_PREHASH_RegionInfo5))
- {
- F32 chat_whisper_range;
- F32 chat_normal_range;
- F32 chat_shout_range;
- F32 chat_whisper_offset;
- F32 chat_normal_offset;
- F32 chat_shout_offset;
- U32 chat_flags;
-
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range);
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range);
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range);
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset);
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset);
- msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset);
- msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags);
-
- LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range
- << " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset
- << " chat flags: " << chat_flags << LL_ENDL;
- }
-
- // GENERAL PANEL
- panel = tab->getChild<LLPanel>("General");
- panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
- panel->getChild<LLUICtrl>("region_type")->setValue(LLSD(sim_type));
- panel->getChild<LLUICtrl>("version_channel_text")->setValue(gLastVersionChannel);
-
- panel->getChild<LLUICtrl>("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE );
- panel->getChild<LLUICtrl>("allow_parcel_changes_check")->setValue((region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("block_parcel_search_check")->setValue((region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE );
- panel->getChild<LLUICtrl>("agent_limit_spin")->setValue(LLSD((F32)agent_limit) );
- panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
- panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
-
- panel->getChild<LLSpinCtrl>("agent_limit_spin")->setMaxValue(hard_agent_limit);
-
- LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral();
- if (panel)
- {
- panel_general->setObjBonusFactor(object_bonus_factor);
- }
-
- // detect teen grid for maturity
-
- U32 parent_estate_id;
- msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id);
- BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that
- panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid));
- panel->setCtrlsEnabled(allow_modify);
-
-
- // DEBUG PANEL
- panel = tab->getChild<LLPanel>("Debug");
-
- panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
- panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) );
- panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) );
- panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );
- panel->setCtrlsEnabled(allow_modify);
-
- // TERRAIN PANEL
- panel = tab->getChild<LLPanel>("Terrain");
-
- panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
- panel->getChild<LLUICtrl>("water_height_spin")->setValue(region_info.mWaterHeight);
- panel->getChild<LLUICtrl>("terrain_raise_spin")->setValue(region_info.mTerrainRaiseLimit);
- panel->getChild<LLUICtrl>("terrain_lower_spin")->setValue(region_info.mTerrainLowerLimit);
-
- panel->setCtrlsEnabled(allow_modify);
-
- if (floater->getVisible())
- {
- // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message
- // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed'
- floater->refreshFromRegion(gAgent.getRegion());
- } // else will rerequest on onOpen either way
+ // 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();
+ BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
+
+ // *TODO: Replace parsing msg with accessing the region info model.
+ LLRegionInfoModel& region_info = LLRegionInfoModel::instance();
+
+ // extract message
+ std::string sim_name;
+ std::string sim_type = LLTrans::getString("land_type_unknown");
+ U64 region_flags;
+ U8 agent_limit;
+ S32 hard_agent_limit;
+ F32 object_bonus_factor;
+ U8 sim_access;
+ F32 water_height;
+ F32 terrain_raise_limit;
+ F32 terrain_lower_limit;
+ BOOL use_estate_sun;
+ F32 sun_hour;
+ msg->getString("RegionInfo", "SimName", sim_name);
+ msg->getU8("RegionInfo", "MaxAgents", agent_limit);
+ msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit);
+ msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
+ msg->getU8("RegionInfo", "SimAccess", sim_access);
+ msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
+ msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit);
+ msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit);
+ msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun);
+ // actually the "last set" sun hour, not the current sun hour. JC
+ msg->getF32("RegionInfo", "SunHour", sun_hour);
+ // the only reasonable way to decide if we actually have any data is to
+ // check to see if any of these fields have nonzero sizes
+ if (msg->getSize("RegionInfo2", "ProductSKU") > 0 ||
+ msg->getSize("RegionInfo2", "ProductName") > 0)
+ {
+ msg->getString("RegionInfo2", "ProductName", sim_type);
+ LLTrans::findString(sim_type, sim_type); // try localizing sim product name
+ }
+
+ if (msg->has(_PREHASH_RegionInfo3))
+ {
+ msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32("RegionInfo", "RegionFlags", flags);
+ region_flags = flags;
+ }
+
+ if (msg->has(_PREHASH_RegionInfo5))
+ {
+ F32 chat_whisper_range;
+ F32 chat_normal_range;
+ F32 chat_shout_range;
+ F32 chat_whisper_offset;
+ F32 chat_normal_offset;
+ F32 chat_shout_offset;
+ U32 chat_flags;
+
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range);
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range);
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range);
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset);
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset);
+ msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset);
+ msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags);
+
+ LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range
+ << " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset
+ << " chat flags: " << chat_flags << LL_ENDL;
+ }
+
+ // GENERAL PANEL
+ panel = tab->getChild<LLPanel>("General");
+ panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
+ panel->getChild<LLUICtrl>("region_type")->setValue(LLSD(sim_type));
+ panel->getChild<LLUICtrl>("version_channel_text")->setValue(gLastVersionChannel);
+
+ panel->getChild<LLUICtrl>("block_terraform_check")->setValue((region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("block_fly_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("block_fly_over_check")->setValue((region_flags & REGION_FLAGS_BLOCK_FLYOVER) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("allow_damage_check")->setValue((region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("restrict_pushobject")->setValue((region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("allow_land_resell_check")->setValue((region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE );
+ panel->getChild<LLUICtrl>("allow_parcel_changes_check")->setValue((region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("block_parcel_search_check")->setValue((region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE );
+ panel->getChild<LLUICtrl>("agent_limit_spin")->setValue(LLSD((F32)agent_limit) );
+ panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
+ panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
+
+ panel->getChild<LLSpinCtrl>("agent_limit_spin")->setMaxValue(hard_agent_limit);
+
+ LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral();
+ if (panel)
+ {
+ panel_general->setObjBonusFactor(object_bonus_factor);
+ }
+
+ // detect teen grid for maturity
+
+ U32 parent_estate_id;
+ msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id);
+ BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that
+ panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid));
+ panel->setCtrlsEnabled(allow_modify);
+
+
+ // DEBUG PANEL
+ panel = tab->getChild<LLPanel>("Debug");
+
+ panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
+ panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) );
+ panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) );
+ panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );
+ panel->setCtrlsEnabled(allow_modify);
+
+ // TERRAIN PANEL
+ panel = tab->getChild<LLPanel>("Terrain");
+
+ panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
+ panel->getChild<LLUICtrl>("water_height_spin")->setValue(region_info.mWaterHeight);
+ panel->getChild<LLUICtrl>("terrain_raise_spin")->setValue(region_info.mTerrainRaiseLimit);
+ panel->getChild<LLUICtrl>("terrain_lower_spin")->setValue(region_info.mTerrainLowerLimit);
+
+ panel->setCtrlsEnabled(allow_modify);
+
+ if (floater->getVisible())
+ {
+ // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message
+ // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed'
+ floater->refreshFromRegion(gAgent.getRegion());
+ } // else will rerequest on onOpen either way
}
// static
LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
- return panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
+ return panel;
}
// static
LLPanelEstateAccess* LLFloaterRegionInfo::getPanelAccess()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild<LLPanel>("Access");
- return panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild<LLPanel>("Access");
+ return panel;
}
// static
LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant");
- return panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant");
+ return panel;
}
// static
LLPanelRegionGeneralInfo* LLFloaterRegionInfo::getPanelGeneral()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- LLPanelRegionGeneralInfo* panel = (LLPanelRegionGeneralInfo*)tab->getChild<LLPanel>("General");
- return panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelRegionGeneralInfo* panel = (LLPanelRegionGeneralInfo*)tab->getChild<LLPanel>("General");
+ return panel;
}
// static
LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- LLPanelRegionEnvironment* panel = (LLPanelRegionEnvironment*)tab->getChild<LLPanel>("panel_env_info");
- return panel;
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelRegionEnvironment* panel = (LLPanelRegionEnvironment*)tab->getChild<LLPanel>("panel_env_info");
+ return panel;
+}
+
+LLTerrainMaterials::Type material_type_from_ctrl(LLCheckBoxCtrl* ctrl)
+{
+ return ctrl->get() ? LLTerrainMaterials::Type::PBR : LLTerrainMaterials::Type::TEXTURE;
+}
+
+void material_type_to_ctrl(LLCheckBoxCtrl* ctrl, LLTerrainMaterials::Type new_type)
+{
+ ctrl->set(new_type == LLTerrainMaterials::Type::PBR);
}
// static
LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater)
- {
- llassert(floater);
- return NULL;
- }
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater)
+ {
+ llassert(floater);
+ return NULL;
+ }
- LLTabContainer* tab_container = floater->getChild<LLTabContainer>("region_panels");
- LLPanelRegionTerrainInfo* panel =
- dynamic_cast<LLPanelRegionTerrainInfo*>(tab_container->getChild<LLPanel>("Terrain"));
- llassert(panel);
- return panel;
+ LLTabContainer* tab_container = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelRegionTerrainInfo* panel =
+ dynamic_cast<LLPanelRegionTerrainInfo*>(tab_container->getChild<LLPanel>("Terrain"));
+ llassert(panel);
+ return panel;
}
LLPanelRegionExperiences* LLFloaterRegionInfo::getPanelExperiences()
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (!floater) return NULL;
- LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
- return (LLPanelRegionExperiences*)tab->getChild<LLPanel>("Experiences");
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ return (LLPanelRegionExperiences*)tab->getChild<LLPanel>("Experiences");
}
void LLFloaterRegionInfo::disableTabCtrls()
{
- LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
+ LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
- tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("panel_env_info")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Access")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("panel_env_info")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Access")->setCtrlsEnabled(FALSE);
}
void LLFloaterRegionInfo::onTabSelected(const LLSD& param)
{
- LLPanel* active_panel = getChild<LLPanel>(param.asString());
- active_panel->onOpen(LLSD());
+ LLPanel* active_panel = getChild<LLPanel>(param.asString());
+ active_panel->onOpen(LLSD());
}
void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
{
- if (!region)
- {
- return;
- }
+ if (!region)
+ {
+ return;
+ }
- // call refresh from region on all panels
- for (const auto& infoPanel : mInfoPanels)
- {
- infoPanel->refreshFromRegion(region);
- }
- mEnvironmentPanel->refreshFromRegion(region);
+ // call refresh from region on all panels
+ for (const auto& infoPanel : mInfoPanels)
+ {
+ infoPanel->refreshFromRegion(region);
+ }
+ mEnvironmentPanel->refreshFromRegion(region);
}
// public
void LLFloaterRegionInfo::refresh()
{
- for(info_panels_t::iterator iter = mInfoPanels.begin();
- iter != mInfoPanels.end(); ++iter)
- {
- (*iter)->refresh();
- }
+ for(info_panels_t::iterator iter = mInfoPanels.begin();
+ iter != mInfoPanels.end(); ++iter)
+ {
+ (*iter)->refresh();
+ }
mEnvironmentPanel->refresh();
}
void LLFloaterRegionInfo::enableTopButtons()
{
- getChildView("top_colliders_btn")->setEnabled(true);
- getChildView("top_scripts_btn")->setEnabled(true);
+ getChildView("top_colliders_btn")->setEnabled(true);
+ getChildView("top_scripts_btn")->setEnabled(true);
}
void LLFloaterRegionInfo::disableTopButtons()
{
- getChildView("top_colliders_btn")->setEnabled(false);
- getChildView("top_scripts_btn")->setEnabled(false);
+ getChildView("top_colliders_btn")->setEnabled(false);
+ getChildView("top_scripts_btn")->setEnabled(false);
}
void LLFloaterRegionInfo::onGodLevelChange(U8 god_level)
{
- LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
- if (floater && floater->getVisible())
- {
- refreshFromRegion(gAgent.getRegion());
- }
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (floater && floater->getVisible())
+ {
+ refreshFromRegion(gAgent.getRegion());
+ }
}
///----------------------------------------------------------------------------
@@ -704,58 +712,58 @@ void LLFloaterRegionInfo::onGodLevelChange(U8 god_level)
//
LLPanelRegionInfo::LLPanelRegionInfo()
- : LLPanel()
+ : LLPanel()
{
}
void LLPanelRegionInfo::onBtnSet()
{
- if (sendUpdate())
- {
- disableButton("apply_btn");
- }
+ if (sendUpdate())
+ {
+ disableButton("apply_btn");
+ }
}
void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl)
{
- updateChild(ctrl); // virtual function
+ updateChild(ctrl); // virtual function
}
// Enables the "set" button if it is not already enabled
void LLPanelRegionInfo::onChangeAnything()
{
- enableButton("apply_btn");
- refresh();
+ enableButton("apply_btn");
+ refresh();
}
// static
// Enables set button on change to line editor
void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data)
{
- LLPanelRegionInfo* panel = dynamic_cast<LLPanelRegionInfo*>(caller->getParent());
- if(panel)
- {
- panel->enableButton("apply_btn");
- panel->refresh();
- }
+ LLPanelRegionInfo* panel = dynamic_cast<LLPanelRegionInfo*>(caller->getParent());
+ if(panel)
+ {
+ panel->enableButton("apply_btn");
+ panel->refresh();
+ }
}
// virtual
BOOL LLPanelRegionInfo::postBuild()
{
- // If the panel has an Apply button, set a callback for it.
- LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
- if (apply_btn)
- {
- apply_btn->setCommitCallback(boost::bind(&LLPanelRegionInfo::onBtnSet, this));
- }
+ // If the panel has an Apply button, set a callback for it.
+ LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
+ if (apply_btn)
+ {
+ apply_btn->setCommitCallback(boost::bind(&LLPanelRegionInfo::onBtnSet, this));
+ }
- refresh();
- return TRUE;
+ refresh();
+ return TRUE;
}
-// virtual
+// virtual
void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr)
{
}
@@ -763,64 +771,64 @@ void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr)
// virtual
bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region)
{
- if (region) mHost = region->getHost();
- return true;
+ if (region) mHost = region->getHost();
+ return true;
}
void LLPanelRegionInfo::sendEstateOwnerMessage(
- LLMessageSystem* msg,
- const std::string& request,
- const LLUUID& invoice,
- const strings_t& strings)
-{
- LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL;
- msg->newMessage("EstateOwnerMessage");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
- msg->nextBlock("MethodData");
- msg->addString("Method", request);
- msg->addUUID("Invoice", invoice);
- if(strings.empty())
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", NULL);
- }
- else
- {
- strings_t::const_iterator it = strings.begin();
- strings_t::const_iterator end = strings.end();
- for(; it != end; ++it)
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", *it);
- }
- }
- msg->sendReliable(mHost);
+ LLMessageSystem* msg,
+ const std::string& request,
+ const LLUUID& invoice,
+ const strings_t& strings)
+{
+ LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL;
+ msg->newMessage("EstateOwnerMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+ msg->nextBlock("MethodData");
+ msg->addString("Method", request);
+ msg->addUUID("Invoice", invoice);
+ if(strings.empty())
+ {
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", NULL);
+ }
+ else
+ {
+ strings_t::const_iterator it = strings.begin();
+ strings_t::const_iterator end = strings.end();
+ for(; it != end; ++it)
+ {
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", *it);
+ }
+ }
+ msg->sendReliable(mHost);
}
void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable)
{
- LLView* button = findChildView(btn_name);
- if (button) button->setEnabled(enable);
+ LLView* button = findChildView(btn_name);
+ if (button) button->setEnabled(enable);
}
void LLPanelRegionInfo::disableButton(const std::string& btn_name)
{
- LLView* button = findChildView(btn_name);
- if (button) button->setEnabled(FALSE);
+ LLView* button = findChildView(btn_name);
+ if (button) button->setEnabled(FALSE);
}
void LLPanelRegionInfo::initCtrl(const std::string& name)
{
- getChild<LLUICtrl>(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this));
+ getChild<LLUICtrl>(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this));
}
void LLPanelRegionInfo::onClickManageTelehub()
{
- LLFloaterReg::hideInstance("region_info");
- LLFloaterReg::showInstance("telehubs");
+ LLFloaterReg::hideInstance("region_info");
+ LLFloaterReg::showInstance("telehubs");
}
/////////////////////////////////////////////////////////////////////////////
@@ -828,181 +836,181 @@ void LLPanelRegionInfo::onClickManageTelehub()
//
bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
{
- BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
- setCtrlsEnabled(allow_modify);
- getChildView("apply_btn")->setEnabled(FALSE);
- getChildView("access_text")->setEnabled(allow_modify);
- // getChildView("access_combo")->setEnabled(allow_modify);
- // now set in processRegionInfo for teen grid detection
- getChildView("kick_btn")->setEnabled(allow_modify);
- getChildView("kick_all_btn")->setEnabled(allow_modify);
- getChildView("im_btn")->setEnabled(allow_modify);
- getChildView("manage_telehub_btn")->setEnabled(allow_modify);
+ BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
+ setCtrlsEnabled(allow_modify);
+ getChildView("apply_btn")->setEnabled(FALSE);
+ getChildView("access_text")->setEnabled(allow_modify);
+ // getChildView("access_combo")->setEnabled(allow_modify);
+ // now set in processRegionInfo for teen grid detection
+ getChildView("kick_btn")->setEnabled(allow_modify);
+ getChildView("kick_all_btn")->setEnabled(allow_modify);
+ getChildView("im_btn")->setEnabled(allow_modify);
+ getChildView("manage_telehub_btn")->setEnabled(allow_modify);
- // Data gets filled in by processRegionInfo
+ // Data gets filled in by processRegionInfo
- return LLPanelRegionInfo::refreshFromRegion(region);
+ return LLPanelRegionInfo::refreshFromRegion(region);
}
BOOL LLPanelRegionGeneralInfo::postBuild()
{
- // Enable the "Apply" button if something is changed. JC
- initCtrl("block_terraform_check");
- initCtrl("block_fly_check");
- initCtrl("block_fly_over_check");
- initCtrl("allow_damage_check");
- initCtrl("allow_land_resell_check");
- initCtrl("allow_parcel_changes_check");
- initCtrl("agent_limit_spin");
- initCtrl("object_bonus_spin");
- initCtrl("access_combo");
- initCtrl("restrict_pushobject");
- initCtrl("block_parcel_search_check");
-
- childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this));
- childSetAction("kick_all_btn", onClickKickAll, this);
- childSetAction("im_btn", onClickMessage, this);
-// childSetAction("manage_telehub_btn", onClickManageTelehub, this);
-
- LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
- if (apply_btn)
- {
- apply_btn->setCommitCallback(boost::bind(&LLPanelRegionGeneralInfo::onBtnSet, this));
- }
-
- refresh();
- return TRUE;
+ // Enable the "Apply" button if something is changed. JC
+ initCtrl("block_terraform_check");
+ initCtrl("block_fly_check");
+ initCtrl("block_fly_over_check");
+ initCtrl("allow_damage_check");
+ initCtrl("allow_land_resell_check");
+ initCtrl("allow_parcel_changes_check");
+ initCtrl("agent_limit_spin");
+ initCtrl("object_bonus_spin");
+ initCtrl("access_combo");
+ initCtrl("restrict_pushobject");
+ initCtrl("block_parcel_search_check");
+
+ childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this));
+ childSetAction("kick_all_btn", onClickKickAll, this);
+ childSetAction("im_btn", onClickMessage, this);
+// childSetAction("manage_telehub_btn", onClickManageTelehub, this);
+
+ LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
+ if (apply_btn)
+ {
+ apply_btn->setCommitCallback(boost::bind(&LLPanelRegionGeneralInfo::onBtnSet, this));
+ }
+
+ refresh();
+ return TRUE;
}
void LLPanelRegionGeneralInfo::onBtnSet()
{
- if(mObjBonusFactor == getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal())
- {
- if (sendUpdate())
- {
- disableButton("apply_btn");
- }
- }
- else
- {
- LLNotificationsUtil::add("ChangeObjectBonusFactor", LLSD(), LLSD(), boost::bind(&LLPanelRegionGeneralInfo::onChangeObjectBonus, this, _1, _2));
- }
+ if(mObjBonusFactor == getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal())
+ {
+ if (sendUpdate())
+ {
+ disableButton("apply_btn");
+ }
+ }
+ else
+ {
+ LLNotificationsUtil::add("ChangeObjectBonusFactor", LLSD(), LLSD(), boost::bind(&LLPanelRegionGeneralInfo::onChangeObjectBonus, this, _1, _2));
+ }
}
bool LLPanelRegionGeneralInfo::onChangeObjectBonus(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- if (sendUpdate())
- {
- disableButton("apply_btn");
- }
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ if (sendUpdate())
+ {
+ disableButton("apply_btn");
+ }
+ }
+ return false;
}
void LLPanelRegionGeneralInfo::onClickKick()
{
- LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKick" << LL_ENDL;
+ LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKick" << LL_ENDL;
- // this depends on the grandparent view being a floater
- // in order to set up floater dependency
+ // this depends on the grandparent view being a floater
+ // in order to set up floater dependency
LLView * button = findChild<LLButton>("kick_btn");
- LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1),
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1),
FALSE, TRUE, FALSE, parent_floater->getName(), button);
- if (child_floater)
- {
- parent_floater->addDependentFloater(child_floater);
- }
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids)
{
- if (ids.empty()) return;
- if(ids[0].notNull())
- {
- strings_t strings;
- // [0] = our agent id
- // [1] = target agent id
- std::string buffer;
- gAgent.getID().toString(buffer);
- strings.push_back(buffer);
+ if (ids.empty()) return;
+ if(ids[0].notNull())
+ {
+ strings_t strings;
+ // [0] = our agent id
+ // [1] = target agent id
+ std::string buffer;
+ gAgent.getID().toString(buffer);
+ strings.push_back(buffer);
- ids[0].toString(buffer);
- strings.push_back(strings_t::value_type(buffer));
+ ids[0].toString(buffer);
+ strings.push_back(strings_t::value_type(buffer));
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings);
- }
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings);
+ }
}
// static
void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata)
{
- LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKickAll" << LL_ENDL;
- LLNotificationsUtil::add("KickUsersFromRegion",
- LLSD(),
- LLSD(),
- boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
+ LL_INFOS() << "LLPanelRegionGeneralInfo::onClickKickAll" << LL_ENDL;
+ LLNotificationsUtil::add("KickUsersFromRegion",
+ LLSD(),
+ LLSD(),
+ boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
}
bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- strings_t strings;
- // [0] = our agent id
- std::string buffer;
- gAgent.getID().toString(buffer);
- strings.push_back(buffer);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ strings_t strings;
+ // [0] = our agent id
+ std::string buffer;
+ gAgent.getID().toString(buffer);
+ strings.push_back(buffer);
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- // historical message name
- sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
- }
- return false;
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ // historical message name
+ sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
+ }
+ return false;
}
// static
void LLPanelRegionGeneralInfo::onClickMessage(void* userdata)
{
- LL_INFOS() << "LLPanelRegionGeneralInfo::onClickMessage" << LL_ENDL;
- LLNotificationsUtil::add("MessageRegion",
- LLSD(),
- LLSD(),
- boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
+ LL_INFOS() << "LLPanelRegionGeneralInfo::onClickMessage" << LL_ENDL;
+ LLNotificationsUtil::add("MessageRegion",
+ LLSD(),
+ LLSD(),
+ boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
}
// static
bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
{
- if(LLNotificationsUtil::getSelectedOption(notification, response) != 0) return false;
-
- std::string text = response["message"].asString();
- if (text.empty()) return false;
-
- LL_INFOS() << "Message to everyone: " << text << LL_ENDL;
- strings_t strings;
- // [0] grid_x, unused here
- // [1] grid_y, unused here
- // [2] agent_id of sender
- // [3] sender name
- // [4] message
- strings.push_back("-1");
- strings.push_back("-1");
- std::string buffer;
- gAgent.getID().toString(buffer);
- strings.push_back(buffer);
- std::string name;
- LLAgentUI::buildFullname(name);
- strings.push_back(strings_t::value_type(name));
- strings.push_back(strings_t::value_type(text));
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
- return false;
+ if(LLNotificationsUtil::getSelectedOption(notification, response) != 0) return false;
+
+ std::string text = response["message"].asString();
+ if (text.empty()) return false;
+
+ LL_INFOS() << "Message to everyone: " << text << LL_ENDL;
+ strings_t strings;
+ // [0] grid_x, unused here
+ // [1] grid_y, unused here
+ // [2] agent_id of sender
+ // [3] sender name
+ // [4] message
+ strings.push_back("-1");
+ strings.push_back("-1");
+ std::string buffer;
+ gAgent.getID().toString(buffer);
+ strings.push_back(buffer);
+ std::string name;
+ LLAgentUI::buildFullname(name);
+ strings.push_back(strings_t::value_type(name));
+ strings.push_back(strings_t::value_type(text));
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
+ return false;
}
// setregioninfo
@@ -1018,74 +1026,74 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
// strings[9] = 'Y' - block parcel search, 'N' - allow
BOOL LLPanelRegionGeneralInfo::sendUpdate()
{
- LL_INFOS() << "LLPanelRegionGeneralInfo::sendUpdate()" << LL_ENDL;
-
- // First try using a Cap. If that fails use the old method.
- LLSD body;
- std::string url = gAgent.getRegionCapability("DispatchRegionInfo");
- if (!url.empty())
- {
- body["block_terraform"] = getChild<LLUICtrl>("block_terraform_check")->getValue();
- body["block_fly"] = getChild<LLUICtrl>("block_fly_check")->getValue();
- body["block_fly_over"] = getChild<LLUICtrl>("block_fly_over_check")->getValue();
- body["allow_damage"] = getChild<LLUICtrl>("allow_damage_check")->getValue();
- body["allow_land_resell"] = getChild<LLUICtrl>("allow_land_resell_check")->getValue();
- body["agent_limit"] = getChild<LLUICtrl>("agent_limit_spin")->getValue();
- body["prim_bonus"] = getChild<LLUICtrl>("object_bonus_spin")->getValue();
- body["sim_access"] = getChild<LLUICtrl>("access_combo")->getValue();
- body["restrict_pushobject"] = getChild<LLUICtrl>("restrict_pushobject")->getValue();
- body["allow_parcel_changes"] = getChild<LLUICtrl>("allow_parcel_changes_check")->getValue();
- body["block_parcel_search"] = getChild<LLUICtrl>("block_parcel_search_check")->getValue();
+ LL_INFOS() << "LLPanelRegionGeneralInfo::sendUpdate()" << LL_ENDL;
+
+ // First try using a Cap. If that fails use the old method.
+ LLSD body;
+ std::string url = gAgent.getRegionCapability("DispatchRegionInfo");
+ if (!url.empty())
+ {
+ body["block_terraform"] = getChild<LLUICtrl>("block_terraform_check")->getValue();
+ body["block_fly"] = getChild<LLUICtrl>("block_fly_check")->getValue();
+ body["block_fly_over"] = getChild<LLUICtrl>("block_fly_over_check")->getValue();
+ body["allow_damage"] = getChild<LLUICtrl>("allow_damage_check")->getValue();
+ body["allow_land_resell"] = getChild<LLUICtrl>("allow_land_resell_check")->getValue();
+ body["agent_limit"] = getChild<LLUICtrl>("agent_limit_spin")->getValue();
+ body["prim_bonus"] = getChild<LLUICtrl>("object_bonus_spin")->getValue();
+ body["sim_access"] = getChild<LLUICtrl>("access_combo")->getValue();
+ body["restrict_pushobject"] = getChild<LLUICtrl>("restrict_pushobject")->getValue();
+ body["allow_parcel_changes"] = getChild<LLUICtrl>("allow_parcel_changes_check")->getValue();
+ body["block_parcel_search"] = getChild<LLUICtrl>("block_parcel_search_check")->getValue();
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
"Region info update posted.", "Region info update not posted.");
- }
- else
- {
- strings_t strings;
- std::string buffer;
+ }
+ else
+ {
+ strings_t strings;
+ std::string buffer;
- buffer = llformat("%s", (getChild<LLUICtrl>("block_terraform_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("block_terraform_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%s", (getChild<LLUICtrl>("block_fly_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("block_fly_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%s", (getChild<LLUICtrl>("allow_damage_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("allow_damage_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%s", (getChild<LLUICtrl>("allow_land_resell_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("allow_land_resell_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- F32 value = (F32)getChild<LLUICtrl>("agent_limit_spin")->getValue().asReal();
- buffer = llformat("%f", value);
- strings.push_back(strings_t::value_type(buffer));
+ F32 value = (F32)getChild<LLUICtrl>("agent_limit_spin")->getValue().asReal();
+ buffer = llformat("%f", value);
+ strings.push_back(strings_t::value_type(buffer));
- value = (F32)getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal();
- buffer = llformat("%f", value);
- strings.push_back(strings_t::value_type(buffer));
+ value = (F32)getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal();
+ buffer = llformat("%f", value);
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%d", getChild<LLUICtrl>("access_combo")->getValue().asInteger());
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%d", getChild<LLUICtrl>("access_combo")->getValue().asInteger());
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%s", (getChild<LLUICtrl>("restrict_pushobject")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("restrict_pushobject")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- buffer = llformat("%s", (getChild<LLUICtrl>("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(strings_t::value_type(buffer));
+ buffer = llformat("%s", (getChild<LLUICtrl>("allow_parcel_changes_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(strings_t::value_type(buffer));
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings);
- }
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings);
+ }
- // if we changed access levels, tell user about it
- LLViewerRegion* region = gAgent.getRegion();
- if (region && (getChild<LLUICtrl>("access_combo")->getValue().asInteger() != region->getSimAccess()) )
- {
- LLNotificationsUtil::add("RegionMaturityChange");
- }
+ // if we changed access levels, tell user about it
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && (getChild<LLUICtrl>("access_combo")->getValue().asInteger() != region->getSimAccess()) )
+ {
+ LLNotificationsUtil::add("RegionMaturityChange");
+ }
- return TRUE;
+ return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
@@ -1093,375 +1101,670 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
/////////////////////////////////////////////////////////////////////////////
BOOL LLPanelRegionDebugInfo::postBuild()
{
- LLPanelRegionInfo::postBuild();
- initCtrl("disable_scripts_check");
- initCtrl("disable_collisions_check");
- initCtrl("disable_physics_check");
+ LLPanelRegionInfo::postBuild();
+ initCtrl("disable_scripts_check");
+ initCtrl("disable_collisions_check");
+ initCtrl("disable_physics_check");
- childSetAction("choose_avatar_btn", boost::bind(&LLPanelRegionDebugInfo::onClickChooseAvatar, this));
- childSetAction("return_btn", onClickReturn, this);
- childSetAction("top_colliders_btn", onClickTopColliders, this);
- childSetAction("top_scripts_btn", onClickTopScripts, this);
- childSetAction("restart_btn", onClickRestart, this);
- childSetAction("cancel_restart_btn", onClickCancelRestart, this);
- childSetAction("region_debug_console_btn", onClickDebugConsole, this);
+ childSetAction("choose_avatar_btn", boost::bind(&LLPanelRegionDebugInfo::onClickChooseAvatar, this));
+ childSetAction("return_btn", onClickReturn, this);
+ childSetAction("top_colliders_btn", onClickTopColliders, this);
+ childSetAction("top_scripts_btn", onClickTopScripts, this);
+ childSetAction("restart_btn", onClickRestart, this);
+ childSetAction("cancel_restart_btn", onClickCancelRestart, this);
+ childSetAction("region_debug_console_btn", onClickDebugConsole, this);
- return TRUE;
+ return TRUE;
}
// virtual
bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region)
{
- BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
- setCtrlsEnabled(allow_modify);
- getChildView("apply_btn")->setEnabled(FALSE);
- getChildView("target_avatar_name")->setEnabled(FALSE);
-
- getChildView("choose_avatar_btn")->setEnabled(allow_modify);
- getChildView("return_scripts")->setEnabled(allow_modify && !mTargetAvatar.isNull());
- getChildView("return_other_land")->setEnabled(allow_modify && !mTargetAvatar.isNull());
- getChildView("return_estate_wide")->setEnabled(allow_modify && !mTargetAvatar.isNull());
- getChildView("return_btn")->setEnabled(allow_modify && !mTargetAvatar.isNull());
- getChildView("top_colliders_btn")->setEnabled(allow_modify);
- getChildView("top_scripts_btn")->setEnabled(allow_modify);
- getChildView("restart_btn")->setEnabled(allow_modify);
- getChildView("cancel_restart_btn")->setEnabled(allow_modify);
- getChildView("region_debug_console_btn")->setEnabled(allow_modify);
-
- return LLPanelRegionInfo::refreshFromRegion(region);
+ BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
+ setCtrlsEnabled(allow_modify);
+ getChildView("apply_btn")->setEnabled(FALSE);
+ getChildView("target_avatar_name")->setEnabled(FALSE);
+
+ getChildView("choose_avatar_btn")->setEnabled(allow_modify);
+ getChildView("return_scripts")->setEnabled(allow_modify && !mTargetAvatar.isNull());
+ getChildView("return_other_land")->setEnabled(allow_modify && !mTargetAvatar.isNull());
+ getChildView("return_estate_wide")->setEnabled(allow_modify && !mTargetAvatar.isNull());
+ getChildView("return_btn")->setEnabled(allow_modify && !mTargetAvatar.isNull());
+ getChildView("top_colliders_btn")->setEnabled(allow_modify);
+ getChildView("top_scripts_btn")->setEnabled(allow_modify);
+ getChildView("restart_btn")->setEnabled(allow_modify);
+ getChildView("cancel_restart_btn")->setEnabled(allow_modify);
+ getChildView("region_debug_console_btn")->setEnabled(allow_modify);
+
+ return LLPanelRegionInfo::refreshFromRegion(region);
}
// virtual
BOOL LLPanelRegionDebugInfo::sendUpdate()
{
- LL_INFOS() << "LLPanelRegionDebugInfo::sendUpdate" << LL_ENDL;
- strings_t strings;
- std::string buffer;
+ LL_INFOS() << "LLPanelRegionDebugInfo::sendUpdate" << LL_ENDL;
+ strings_t strings;
+ std::string buffer;
- buffer = llformat("%s", (getChild<LLUICtrl>("disable_scripts_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(buffer);
+ buffer = llformat("%s", (getChild<LLUICtrl>("disable_scripts_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(buffer);
- buffer = llformat("%s", (getChild<LLUICtrl>("disable_collisions_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(buffer);
+ buffer = llformat("%s", (getChild<LLUICtrl>("disable_collisions_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(buffer);
- buffer = llformat("%s", (getChild<LLUICtrl>("disable_physics_check")->getValue().asBoolean() ? "Y" : "N"));
- strings.push_back(buffer);
+ buffer = llformat("%s", (getChild<LLUICtrl>("disable_physics_check")->getValue().asBoolean() ? "Y" : "N"));
+ strings.push_back(buffer);
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings);
- return TRUE;
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings);
+ return TRUE;
}
void LLPanelRegionDebugInfo::onClickChooseAvatar()
{
LLView * button = findChild<LLButton>("choose_avatar_btn");
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2),
+ LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2),
FALSE, TRUE, FALSE, parent_floater->getName(), button);
- if (child_floater)
- {
- parent_floater->addDependentFloater(child_floater);
- }
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
- if (ids.empty() || names.empty()) return;
- mTargetAvatar = ids[0];
- getChild<LLUICtrl>("target_avatar_name")->setValue(LLSD(names[0].getCompleteName()));
- refreshFromRegion( gAgent.getRegion() );
+ if (ids.empty() || names.empty()) return;
+ mTargetAvatar = ids[0];
+ getChild<LLUICtrl>("target_avatar_name")->setValue(LLSD(names[0].getCompleteName()));
+ refreshFromRegion( gAgent.getRegion() );
}
// static
void LLPanelRegionDebugInfo::onClickReturn(void* data)
{
- LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
- if (panelp->mTargetAvatar.isNull()) return;
-
- LLSD args;
- args["USER_NAME"] = panelp->getChild<LLUICtrl>("target_avatar_name")->getValue().asString();
- LLSD payload;
- payload["avatar_id"] = panelp->mTargetAvatar;
-
- U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
-
- if (panelp->getChild<LLUICtrl>("return_scripts")->getValue().asBoolean())
- {
- flags |= SWD_SCRIPTED_ONLY;
- }
-
- if (panelp->getChild<LLUICtrl>("return_other_land")->getValue().asBoolean())
- {
- flags |= SWD_OTHERS_LAND_ONLY;
- }
- payload["flags"] = int(flags);
- payload["return_estate_wide"] = panelp->getChild<LLUICtrl>("return_estate_wide")->getValue().asBoolean();
- LLNotificationsUtil::add("EstateObjectReturn", args, payload,
- boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2));
+ LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
+ if (panelp->mTargetAvatar.isNull()) return;
+
+ LLSD args;
+ args["USER_NAME"] = panelp->getChild<LLUICtrl>("target_avatar_name")->getValue().asString();
+ LLSD payload;
+ payload["avatar_id"] = panelp->mTargetAvatar;
+
+ U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
+
+ if (panelp->getChild<LLUICtrl>("return_scripts")->getValue().asBoolean())
+ {
+ flags |= SWD_SCRIPTED_ONLY;
+ }
+
+ if (panelp->getChild<LLUICtrl>("return_other_land")->getValue().asBoolean())
+ {
+ flags |= SWD_OTHERS_LAND_ONLY;
+ }
+ payload["flags"] = int(flags);
+ payload["return_estate_wide"] = panelp->getChild<LLUICtrl>("return_estate_wide")->getValue().asBoolean();
+ LLNotificationsUtil::add("EstateObjectReturn", args, payload,
+ boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2));
}
bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return false;
-
- LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID();
- if (!target_avatar.isNull())
- {
- U32 flags = notification["payload"]["flags"].asInteger();
- bool return_estate_wide = notification["payload"]["return_estate_wide"];
- if (return_estate_wide)
- {
- // send as estate message - routed by spaceserver to all regions in estate
- strings_t strings;
- strings.push_back(llformat("%d", flags));
- strings.push_back(target_avatar.asString());
-
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-
- sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
- }
- else
- {
- // send to this simulator only
- send_sim_wide_deletes(target_avatar, flags);
- }
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return false;
+
+ LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID();
+ if (!target_avatar.isNull())
+ {
+ U32 flags = notification["payload"]["flags"].asInteger();
+ bool return_estate_wide = notification["payload"]["return_estate_wide"];
+ if (return_estate_wide)
+ {
+ // send as estate message - routed by spaceserver to all regions in estate
+ strings_t strings;
+ strings.push_back(llformat("%d", flags));
+ strings.push_back(target_avatar.asString());
+
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+
+ sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
+ }
+ else
+ {
+ // send to this simulator only
+ send_sim_wide_deletes(target_avatar, flags);
+ }
+ }
+ return false;
}
// static
void LLPanelRegionDebugInfo::onClickTopColliders(void* data)
{
- LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
- strings_t strings;
- strings.push_back("1"); // one physics step
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
- if(!instance) return;
- LLFloaterReg::showInstance("top_objects");
- instance->clearList();
- instance->disableRefreshBtn();
+ LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
+ strings_t strings;
+ strings.push_back("1"); // one physics step
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+ LLFloaterReg::showInstance("top_objects");
+ instance->clearList();
+ instance->disableRefreshBtn();
- self->getChildView("top_colliders_btn")->setEnabled(false);
- self->getChildView("top_scripts_btn")->setEnabled(false);
+ self->getChildView("top_colliders_btn")->setEnabled(false);
+ self->getChildView("top_scripts_btn")->setEnabled(false);
- self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings);
+ self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings);
}
// static
void LLPanelRegionDebugInfo::onClickTopScripts(void* data)
{
- LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
- strings_t strings;
- strings.push_back("6"); // top 5 scripts
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
- if(!instance) return;
- LLFloaterReg::showInstance("top_objects");
- instance->clearList();
- instance->disableRefreshBtn();
+ LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
+ strings_t strings;
+ strings.push_back("6"); // top 5 scripts
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+ LLFloaterReg::showInstance("top_objects");
+ instance->clearList();
+ instance->disableRefreshBtn();
- self->getChildView("top_colliders_btn")->setEnabled(false);
- self->getChildView("top_scripts_btn")->setEnabled(false);
+ self->getChildView("top_colliders_btn")->setEnabled(false);
+ self->getChildView("top_scripts_btn")->setEnabled(false);
- self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings);
+ self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings);
}
// static
void LLPanelRegionDebugInfo::onClickRestart(void* data)
{
- LLNotificationsUtil::add("ConfirmRestart", LLSD(), LLSD(),
- boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2));
+ LLNotificationsUtil::add("ConfirmRestart", LLSD(), LLSD(),
+ boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2));
}
bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return false;
- strings_t strings;
- strings.push_back("120");
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
- return false;
+ strings_t strings;
+ strings.push_back("120");
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
+ return false;
}
// static
void LLPanelRegionDebugInfo::onClickCancelRestart(void* data)
{
- LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
- strings_t strings;
- strings.push_back("-1");
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
+ LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
+ strings_t strings;
+ strings.push_back("-1");
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
}
// static
void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
{
- LLFloaterReg::showInstance("region_debug_console");
+ LLFloaterReg::showInstance("region_debug_console");
}
-BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
+bool LLPanelRegionTerrainInfo::validateTextureSizes()
{
- static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
- for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
+ if (mMaterialTypeCtrl)
{
- std::string buffer;
- buffer = llformat("texture_detail_%d", i);
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(buffer);
- if (!texture_ctrl) continue;
+ const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl);
+ const bool is_material_selected = material_type == LLTerrainMaterials::Type::PBR;
+ if (is_material_selected) { return true; }
+ }
+
+ bool valid = true;
+ static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
+ const S32 max_terrain_texture_size = (S32)max_texture_resolution;
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i];
+ if (!texture_ctrl) continue;
+
+ LLUUID image_asset_id = texture_ctrl->getImageAssetID();
+ LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ S32 components = img->getComponents();
+ // Must ask for highest resolution version's width. JC
+ S32 width = img->getFullWidth();
+ S32 height = img->getFullHeight();
- LLUUID image_asset_id = texture_ctrl->getImageAssetID();
- LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
- S32 components = img->getComponents();
- // Must ask for highest resolution version's width. JC
- S32 width = img->getFullWidth();
- S32 height = img->getFullHeight();
+ //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL;
- //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL;
+ if (components != 3 && components != 4)
+ {
+ LLSD args;
+ args["TEXTURE_NUM"] = i+1;
+ args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = max_terrain_texture_size;
+ LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
+ valid = false;
+ continue;
+ }
- if (components != 3)
+ if (components == 4)
{
- LLSD args;
- args["TEXTURE_NUM"] = i+1;
- args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
- args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
- LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
- return FALSE;
+ if (!img->hasSavedRawImage())
+ {
+ // Raw image isn't loaded yet
+ // Assume it's invalid due to presence of alpha channel
+ LLSD args;
+ args["TEXTURE_NUM"] = i+1;
+ args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ LLNotificationsUtil::add("InvalidTerrainAlphaNotFullyLoaded", args);
+ valid = false;
+ }
+ else
+ {
+ // Slower path: Calculate alpha from raw image pixels (not needed
+ // for GLTF materials, which use alphaMode to determine
+ // transparency)
+ // Raw image is pretty much guaranteed to be saved due to the texture swatches
+ LLImageRaw* raw = img->getSavedRawImage();
+ if (raw->checkHasTransparentPixels())
+ {
+ LLSD args;
+ args["TEXTURE_NUM"] = i+1;
+ LLNotificationsUtil::add("InvalidTerrainAlpha", args);
+ valid = false;
+ }
+ LL_WARNS() << "Terrain texture image in slot " << i << " with ID " << image_asset_id << " has alpha channel, but pixels are opaque. Is alpha being optimized away in the texture uploader?" << LL_ENDL;
+ }
}
- if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
+ if (width > max_terrain_texture_size || height > max_terrain_texture_size)
+ {
+
+ LLSD args;
+ args["TEXTURE_NUM"] = i+1;
+ args["TEXTURE_SIZE_X"] = width;
+ args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = max_terrain_texture_size;
+ LLNotificationsUtil::add("InvalidTerrainSize", args);
+ valid = false;
+ }
+ }
+
+ return valid;
+}
+
+bool LLPanelRegionTerrainInfo::validateMaterials()
+{
+ if (mMaterialTypeCtrl)
+ {
+ const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl);
+ const bool is_texture_selected = material_type == LLTerrainMaterials::Type::TEXTURE;
+ if (is_texture_selected) { return true; }
+ }
+
+ // *TODO: If/when we implement additional GLTF extensions, they may not be
+ // compatible with our GLTF terrain implementation. We may want to disallow
+ // materials with some features from being set on terrain, if their
+ // implementation on terrain is not compliant with the spec:
+ // - KHR_materials_transmission: Probably OK?
+ // - KHR_materials_ior: Probably OK?
+ // - KHR_materials_volume: Likely incompatible, as our terrain
+ // heightmaps cannot currently be described as finite enclosed
+ // volumes.
+ // See also LLGLTFMaterial
+#ifdef LL_WINDOWS
+ llassert(sizeof(LLGLTFMaterial) == 232);
+#endif
+
+ bool valid = true;
+ for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i];
+ if (!material_ctrl) { continue; }
+
+ const LLUUID& material_asset_id = material_ctrl->getImageAssetID();
+ llassert(material_asset_id.notNull());
+ if (material_asset_id.isNull()) { return false; }
+ const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id);
+ if (!material->isLoaded())
{
+ if (material->isFetching())
+ {
+ LLSD args;
+ args["MATERIAL_NUM"] = i + 1;
+ LLNotificationsUtil::add("InvalidTerrainMaterialNotLoaded", args);
+ }
+ else // Loading failed
+ {
+ LLSD args;
+ args["MATERIAL_NUM"] = i + 1;
+ LLNotificationsUtil::add("InvalidTerrainMaterialLoadFailed", args);
+ }
+ valid = false;
+ continue;
+ }
+ if (material->mDoubleSided)
+ {
LLSD args;
- args["TEXTURE_NUM"] = i+1;
- args["TEXTURE_SIZE_X"] = width;
- args["TEXTURE_SIZE_Y"] = height;
- args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
- LLNotificationsUtil::add("InvalidTerrainSize", args);
- return FALSE;
-
+ args["MATERIAL_NUM"] = i + 1;
+ LLNotificationsUtil::add("InvalidTerrainMaterialDoubleSided", args);
+ valid = false;
+ }
+ if (material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE && material->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ LLSD args;
+ args["MATERIAL_NUM"] = i + 1;
+ const char* alpha_mode = material->getAlphaMode();
+ args["MATERIAL_ALPHA_MODE"] = alpha_mode;
+ LLNotificationsUtil::add("InvalidTerrainMaterialAlphaMode", args);
+ valid = false;
}
}
- return TRUE;
+ return valid;
}
BOOL LLPanelRegionTerrainInfo::validateTextureHeights()
{
- for (S32 i = 0; i < CORNER_COUNT; ++i)
- {
- std::string low = llformat("height_start_spin_%d", i);
- std::string high = llformat("height_range_spin_%d", i);
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ std::string low = llformat("height_start_spin_%d", i);
+ std::string high = llformat("height_range_spin_%d", i);
- if (getChild<LLUICtrl>(low)->getValue().asReal() > getChild<LLUICtrl>(high)->getValue().asReal())
- {
- return FALSE;
- }
- }
+ if (getChild<LLUICtrl>(low)->getValue().asReal() > getChild<LLUICtrl>(high)->getValue().asReal())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// LLPanelRegionTerrainInfo
/////////////////////////////////////////////////////////////////////////////
+
+LLPanelRegionTerrainInfo::LLPanelRegionTerrainInfo()
+: LLPanelRegionInfo()
+{
+ const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures();
+ for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ mLastSetTextures[i] = default_textures[i];
+ }
+ for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ mLastSetMaterials[i] = BLANK_MATERIAL_ASSET_ID;
+ }
+}
+
// Initialize statics
BOOL LLPanelRegionTerrainInfo::postBuild()
{
- LLPanelRegionInfo::postBuild();
+ LLPanelRegionInfo::postBuild();
+
+ initCtrl("water_height_spin");
+ initCtrl("terrain_raise_spin");
+ initCtrl("terrain_lower_spin");
- initCtrl("water_height_spin");
- initCtrl("terrain_raise_spin");
- initCtrl("terrain_lower_spin");
+ mMaterialTypeCtrl = findChild<LLCheckBoxCtrl>("terrain_material_type");
+ if (mMaterialTypeCtrl) { mMaterialTypeCtrl->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); }
- std::string buffer;
- for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
+ std::string buffer;
+
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ buffer = llformat("texture_detail_%d", i);
+ initCtrl(buffer);
+ mTextureDetailCtrl[i] = findChild<LLTextureCtrl>(buffer);
+ }
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ buffer = llformat("material_detail_%d", i);
+ initCtrl(buffer);
+ mMaterialDetailCtrl[i] = findChild<LLTextureCtrl>(buffer);
+ }
+
+ for(S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ buffer = llformat("height_start_spin_%d", i);
+ initCtrl(buffer);
+ buffer = llformat("height_range_spin_%d", i);
+ initCtrl(buffer);
+ }
+
+ childSetAction("download_raw_btn", onClickDownloadRaw, this);
+ childSetAction("upload_raw_btn", onClickUploadRaw, this);
+ childSetAction("bake_terrain_btn", onClickBakeTerrain, this);
+
+ mAskedTextureHeights = false;
+ mConfirmedTextureHeights = false;
+
+ return LLPanelRegionInfo::postBuild();
+}
+
+void LLPanelRegionTerrainInfo::onSelectMaterialType()
+{
+ updateForMaterialType();
+ onChangeAnything();
+}
+
+void LLPanelRegionTerrainInfo::updateForMaterialType()
+{
+ if (!mMaterialTypeCtrl) { return; }
+ const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl);
+ const bool show_texture_controls = material_type == LLTerrainMaterials::Type::TEXTURE;
+ const bool show_material_controls = material_type == LLTerrainMaterials::Type::PBR;
+
+ // Toggle visibility of correct swatches
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
{
- buffer = llformat("texture_detail_%d", i);
- initCtrl(buffer);
+ LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i];
+ if (texture_ctrl)
+ {
+ texture_ctrl->setVisible(show_texture_controls);
+ }
}
-
- for(S32 i = 0; i < CORNER_COUNT; ++i)
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
{
- buffer = llformat("height_start_spin_%d", i);
- initCtrl(buffer);
- buffer = llformat("height_range_spin_%d", i);
- initCtrl(buffer);
+ LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i];
+ if (material_ctrl)
+ {
+ material_ctrl->setVisible(show_material_controls);
+ }
}
- childSetAction("download_raw_btn", onClickDownloadRaw, this);
- childSetAction("upload_raw_btn", onClickUploadRaw, this);
- childSetAction("bake_terrain_btn", onClickBakeTerrain, this);
-
- mAskedTextureHeights = false;
- mConfirmedTextureHeights = false;
+ // Toggle visibility of labels
+ LLUICtrl* texture_label = findChild<LLUICtrl>("detail_texture_text");
+ if (texture_label) { texture_label->setVisible(show_texture_controls); }
+ LLUICtrl* material_label = findChild<LLUICtrl>("detail_material_text");
+ if (material_label) { material_label->setVisible(show_material_controls); }
- return LLPanelRegionInfo::postBuild();
+ // Toggle visibility of documentation labels for terrain blending ranges
+ const std::vector<std::string> doc_suffixes { "5", "10", "11" };
+ std::string buffer;
+ for (const std::string& suffix : doc_suffixes)
+ {
+ buffer = "height_text_lbl" + suffix;
+ LLUICtrl* texture_doc_label = findChild<LLUICtrl>(buffer);
+ if (texture_doc_label) { texture_doc_label->setVisible(show_texture_controls); }
+ buffer += "_material";
+ LLUICtrl* material_doc_label = findChild<LLUICtrl>(buffer);
+ if (material_doc_label) { material_doc_label->setVisible(show_material_controls); }
+ }
}
// virtual
bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
{
- BOOL owner_or_god = gAgent.isGodlike()
- || (region && (region->getOwner() == gAgent.getID()));
- BOOL owner_or_god_or_manager = owner_or_god
- || (region && region->isEstateManager());
- setCtrlsEnabled(owner_or_god_or_manager);
+ BOOL owner_or_god = gAgent.isGodlike()
+ || (region && (region->getOwner() == gAgent.getID()));
+ BOOL owner_or_god_or_manager = owner_or_god
+ || (region && region->isEstateManager());
+ setCtrlsEnabled(owner_or_god_or_manager);
- getChildView("apply_btn")->setEnabled(FALSE);
+ getChildView("apply_btn")->setEnabled(FALSE);
- if (region)
- {
- getChild<LLUICtrl>("region_text")->setValue(LLSD(region->getName()));
+ if (region)
+ {
+ getChild<LLUICtrl>("region_text")->setValue(LLSD(region->getName()));
+
+ LLVLComposition* compp = region->getComposition();
+
+ static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+
+ const bool textures_ready = compp->texturesReady(false, false);
+ const bool materials_ready = feature_pbr_terrain_enabled && compp->materialsReady(false, false);
+
+ bool set_texture_swatches;
+ bool set_material_swatches;
+ bool reset_texture_swatches;
+ bool reset_material_swatches;
+ LLTerrainMaterials::Type material_type;
+ if (!textures_ready && !materials_ready)
+ {
+ // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set
+ // the IDs on both pickers for now.
+ material_type = LLTerrainMaterials::Type::TEXTURE;
+ set_texture_swatches = true;
+ set_material_swatches = true;
+ reset_texture_swatches = false;
+ reset_material_swatches = false;
+ }
+ else
+ {
+ material_type = compp->getMaterialType();
+ set_texture_swatches = material_type == LLTerrainMaterials::Type::TEXTURE;
+ set_material_swatches = !set_texture_swatches;
+ reset_texture_swatches = !set_texture_swatches;
+ reset_material_swatches = !set_material_swatches;
+ }
- LLVLComposition* compp = region->getComposition();
- LLTextureCtrl* texture_ctrl;
- std::string buffer;
- for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
+ if (mMaterialTypeCtrl)
{
- buffer = llformat("texture_detail_%d", i);
- texture_ctrl = getChild<LLTextureCtrl>(buffer);
- if(texture_ctrl)
+ material_type_to_ctrl(mMaterialTypeCtrl, material_type);
+ updateForMaterialType();
+ mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled);
+ }
+
+ if (set_texture_swatches)
+ {
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
{
- LL_DEBUGS() << "Detail Texture " << i << ": "
- << compp->getDetailTextureID(i) << LL_ENDL;
- LLUUID tmp_id(compp->getDetailTextureID(i));
- texture_ctrl->setImageAssetID(tmp_id);
+ LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i];
+ if(asset_ctrl)
+ {
+ LL_DEBUGS("Terrain", "Texture") << "Detail Texture " << i << ": "
+ << compp->getDetailAssetID(i) << LL_ENDL;
+ LLUUID tmp_id(compp->getDetailAssetID(i));
+ asset_ctrl->setImageAssetID(tmp_id);
+ }
}
}
-
- for(S32 i = 0; i < CORNER_COUNT; ++i)
+ if (set_material_swatches)
{
- buffer = llformat("height_start_spin_%d", i);
- getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getStartHeight(i)));
- buffer = llformat("height_range_spin_%d", i);
- getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getHeightRange(i)));
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i];
+ if(asset_ctrl)
+ {
+ LL_DEBUGS("Terrain", "Material") << "Detail Material " << i << ": "
+ << compp->getDetailAssetID(i) << LL_ENDL;
+ LLUUID tmp_id(compp->getDetailAssetID(i));
+ asset_ctrl->setImageAssetID(tmp_id);
+ }
+ }
+ }
+ if (reset_texture_swatches)
+ {
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ LL_DEBUGS("Terrain", "Texture") << "Reset Texture swatch " << i
+ << LL_ENDL;
+ LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i];
+ if(asset_ctrl)
+ {
+ asset_ctrl->setImageAssetID(mLastSetTextures[i]);
+ }
+ }
+ }
+ if (reset_material_swatches)
+ {
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ LL_DEBUGS("Terrain", "Material") << "Reset Material swatch " << i
+ << LL_ENDL;
+ LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i];
+ if(asset_ctrl)
+ {
+ asset_ctrl->setImageAssetID(mLastSetMaterials[i]);
+ }
+ }
}
- }
- else
- {
- LL_DEBUGS() << "no region set" << LL_ENDL;
- getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
- }
- getChildView("download_raw_btn")->setEnabled(owner_or_god);
- getChildView("upload_raw_btn")->setEnabled(owner_or_god);
- getChildView("bake_terrain_btn")->setEnabled(owner_or_god);
+ std::string buffer;
+ for(S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ buffer = llformat("height_start_spin_%d", i);
+ getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getStartHeight(i)));
+ buffer = llformat("height_range_spin_%d", i);
+ getChild<LLUICtrl>(buffer)->setValue(LLSD(compp->getHeightRange(i)));
+ }
+ }
+ else
+ {
+ LL_DEBUGS() << "no region set" << LL_ENDL;
+ getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
+ }
+
+ // Update visibility of terrain swatches, etc
+ refresh();
- return LLPanelRegionInfo::refreshFromRegion(region);
+ getChildView("download_raw_btn")->setEnabled(owner_or_god);
+ getChildView("upload_raw_btn")->setEnabled(owner_or_god);
+ getChildView("bake_terrain_btn")->setEnabled(owner_or_god);
+
+ return LLPanelRegionInfo::refreshFromRegion(region);
}
// virtual
BOOL LLPanelRegionTerrainInfo::sendUpdate()
{
- LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL;
+ LL_INFOS() << "LLPanelRegionTerrainInfo::sendUpdate" << LL_ENDL;
+
+ // Make sure user hasn't chosen wacky textures.
+ if (!validateTextureSizes())
+ {
+ return FALSE;
+ }
+
+ // Prevent applying unsupported alpha blend/double-sided materials
+ if (!validateMaterials())
+ {
+ return FALSE;
+ }
+
+ // Check if terrain Elevation Ranges are correct
+ if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights())
+ {
+ if (!mAskedTextureHeights)
+ {
+ LLNotificationsUtil::add("ConfirmTextureHeights", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackTextureHeights, this, _1, _2));
+ mAskedTextureHeights = true;
+ return FALSE;
+ }
+ else if (!mConfirmedTextureHeights)
+ {
+ return FALSE;
+ }
+ }
+
std::string buffer;
strings_t strings;
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
@@ -1478,182 +1781,180 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate()
// =======================================
// Assemble and send texturedetail message
- // Make sure user hasn't chosen wacky textures.
- if (!validateTextureSizes())
- {
- return FALSE;
- }
+ std::string id_str;
+ LLMessageSystem* msg = gMessageSystem;
- // Check if terrain Elevation Ranges are correct
- if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights())
+ // Send either material IDs instead of texture IDs depending on
+ // material_type - they both occupy the same slot.
+ const LLTerrainMaterials::Type material_type = mMaterialTypeCtrl ? material_type_from_ctrl(mMaterialTypeCtrl) : LLTerrainMaterials::Type::TEXTURE;
+ for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
{
- if (!mAskedTextureHeights)
+ LLTextureCtrl* asset_ctrl;
+ if (material_type == LLTerrainMaterials::Type::PBR)
{
- LLNotificationsUtil::add("ConfirmTextureHeights", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackTextureHeights, this, _1, _2));
- mAskedTextureHeights = true;
- return FALSE;
+ asset_ctrl = mMaterialDetailCtrl[i];
}
- else if (!mConfirmedTextureHeights)
+ else
{
- return FALSE;
+ asset_ctrl = mTextureDetailCtrl[i];
}
- }
- LLTextureCtrl* texture_ctrl;
- std::string id_str;
- LLMessageSystem* msg = gMessageSystem;
+ if (!asset_ctrl) { continue; }
- for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
- {
- buffer = llformat("texture_detail_%d", i);
- texture_ctrl = getChild<LLTextureCtrl>(buffer);
- if(texture_ctrl)
+ LLUUID tmp_id(asset_ctrl->getImageAssetID());
+ tmp_id.toString(id_str);
+ buffer = llformat("%d %s", i, id_str.c_str());
+ strings.push_back(buffer);
+
+ // Store asset for later terrain editing
+ if (material_type == LLTerrainMaterials::Type::PBR)
{
- LLUUID tmp_id(texture_ctrl->getImageAssetID());
- tmp_id.toString(id_str);
- buffer = llformat("%d %s", i, id_str.c_str());
- strings.push_back(buffer);
+ mLastSetMaterials[i] = tmp_id;
+ }
+ else
+ {
+ mLastSetTextures[i] = tmp_id;
}
}
- sendEstateOwnerMessage(msg, "texturedetail", invoice, strings);
- strings.clear();
+ sendEstateOwnerMessage(msg, "texturedetail", invoice, strings);
+ strings.clear();
- // ========================================
- // Assemble and send textureheights message
+ // ========================================
+ // Assemble and send textureheights message
- for(S32 i = 0; i < CORNER_COUNT; ++i)
- {
- buffer = llformat("height_start_spin_%d", i);
- std::string buffer2 = llformat("height_range_spin_%d", i);
- std::string buffer3 = llformat("%d %f %f", i, (F32)getChild<LLUICtrl>(buffer)->getValue().asReal(), (F32)getChild<LLUICtrl>(buffer2)->getValue().asReal());
- strings.push_back(buffer3);
- }
- sendEstateOwnerMessage(msg, "textureheights", invoice, strings);
- strings.clear();
+ for(S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ buffer = llformat("height_start_spin_%d", i);
+ std::string buffer2 = llformat("height_range_spin_%d", i);
+ std::string buffer3 = llformat("%d %f %f", i, (F32)getChild<LLUICtrl>(buffer)->getValue().asReal(), (F32)getChild<LLUICtrl>(buffer2)->getValue().asReal());
+ strings.push_back(buffer3);
+ }
+ sendEstateOwnerMessage(msg, "textureheights", invoice, strings);
+ strings.clear();
- // ========================================
- // Send texturecommit message
+ // ========================================
+ // Send texturecommit message
- sendEstateOwnerMessage(msg, "texturecommit", invoice, strings);
+ sendEstateOwnerMessage(msg, "texturecommit", invoice, strings);
- return TRUE;
+ return TRUE;
}
bool LLPanelRegionTerrainInfo::callbackTextureHeights(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0) // ok
- {
- mConfirmedTextureHeights = true;
- }
- else if (option == 1) // cancel
- {
- mConfirmedTextureHeights = false;
- }
- else if (option == 2) // don't ask
- {
- gSavedSettings.setBOOL("RegionCheckTextureHeights", FALSE);
- mConfirmedTextureHeights = true;
- }
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // ok
+ {
+ mConfirmedTextureHeights = true;
+ }
+ else if (option == 1) // cancel
+ {
+ mConfirmedTextureHeights = false;
+ }
+ else if (option == 2) // don't ask
+ {
+ gSavedSettings.setBOOL("RegionCheckTextureHeights", FALSE);
+ mConfirmedTextureHeights = true;
+ }
- onBtnSet();
+ onBtnSet();
- mAskedTextureHeights = false;
- return false;
+ mAskedTextureHeights = false;
+ return false;
}
// static
void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data)
{
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw"))
- {
- LL_WARNS() << "No file" << LL_ENDL;
- return;
- }
- std::string filepath = picker.getFirstFile();
- gXferManager->expectFileForRequest(filepath);
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw"))
+ {
+ LL_WARNS() << "No file" << LL_ENDL;
+ return;
+ }
+ std::string filepath = picker.getFirstFile();
+ gXferManager->expectFileForRequest(filepath);
- LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
- strings_t strings;
- strings.push_back("download filename");
- strings.push_back(filepath);
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
+ LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
+ strings_t strings;
+ strings.push_back("download filename");
+ strings.push_back(filepath);
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
}
// static
void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data)
{
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW))
- {
- LL_WARNS() << "No file" << LL_ENDL;
- return;
- }
- std::string filepath = picker.getFirstFile();
- gXferManager->expectFileForTransfer(filepath);
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW))
+ {
+ LL_WARNS() << "No file" << LL_ENDL;
+ return;
+ }
+ std::string filepath = picker.getFirstFile();
+ gXferManager->expectFileForTransfer(filepath);
- LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
- strings_t strings;
- strings.push_back("upload filename");
- strings.push_back(filepath);
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
+ LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
+ strings_t strings;
+ strings.push_back("upload filename");
+ strings.push_back(filepath);
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
- LLNotificationsUtil::add("RawUploadStarted");
+ LLNotificationsUtil::add("RawUploadStarted");
}
// static
void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data)
{
- LLNotificationsUtil::add("ConfirmBakeTerrain", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2));
+ LLNotificationsUtil::add("ConfirmBakeTerrain", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2));
}
bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return false;
- strings_t strings;
- strings.push_back("bake");
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
+ strings_t strings;
+ strings.push_back("bake");
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
- return false;
+ return false;
}
/////////////////////////////////////////////////////////////////////////////
// LLPanelEstateInfo
//
-LLPanelEstateInfo::LLPanelEstateInfo()
-: LLPanelRegionInfo(),
- mEstateID(0) // invalid
+LLPanelEstateInfo::LLPanelEstateInfo()
+: LLPanelRegionInfo(),
+ mEstateID(0) // invalid
{
- LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
- estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
- estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
+ LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+ estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
+ estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
}
// static
void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch)
{
- std::string name;
-
- name.assign("estateupdateinfo");
- static LLDispatchEstateUpdateInfo estate_update_info;
- dispatch.addHandler(name, &estate_update_info);
+ std::string name;
+
+ name.assign("estateupdateinfo");
+ static LLDispatchEstateUpdateInfo estate_update_info;
+ dispatch.addHandler(name, &estate_update_info);
- name.assign("setaccess");
- static LLDispatchSetEstateAccess set_access;
- dispatch.addHandler(name, &set_access);
+ name.assign("setaccess");
+ static LLDispatchSetEstateAccess set_access;
+ dispatch.addHandler(name, &set_access);
- name.assign("setexperience");
- static LLDispatchSetEstateExperience set_experience;
- dispatch.addHandler(name, &set_experience);
+ name.assign("setexperience");
+ static LLDispatchSetEstateExperience set_experience;
+ dispatch.addHandler(name, &set_experience);
- estate_dispatch_initialized = true;
+ estate_dispatch_initialized = true;
}
//---------------------------------------------------------------------------
@@ -1662,49 +1963,49 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch)
void LLPanelEstateInfo::onClickKickUser()
{
- // this depends on the grandparent view being a floater
- // in order to set up floater dependency
+ // this depends on the grandparent view being a floater
+ // in order to set up floater dependency
LLView * button = findChild<LLButton>("kick_user_from_estate_btn");
- LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1),
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1),
FALSE, TRUE, FALSE, parent_floater->getName(), button);
- if (child_floater)
- {
- parent_floater->addDependentFloater(child_floater);
- }
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids)
{
- if (ids.empty()) return;
-
- //Bring up a confirmation dialog
- LLSD args;
- args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString();
- LLSD payload;
- payload["agent_id"] = ids[0];
- LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2));
+ if (ids.empty()) return;
+
+ //Bring up a confirmation dialog
+ LLSD args;
+ args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString();
+ LLSD payload;
+ payload["agent_id"] = ids[0];
+ LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2));
}
bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch(option)
- {
- case 0:
- {
- //Kick User
- strings_t strings;
- strings.push_back(notification["payload"]["agent_id"].asString());
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0:
+ {
+ //Kick User
+ strings_t strings;
+ strings.push_back(notification["payload"]["agent_id"].asString());
- sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings);
- break;
- }
- default:
- break;
- }
- return false;
+ sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings);
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
}
//---------------------------------------------------------------------------
@@ -1715,270 +2016,270 @@ bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& re
//---------------------------------------------------------------------------
std::string all_estates_text()
{
- LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
- if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")";
-
- LLStringUtil::format_map_t args;
- std::string owner = panel->getOwnerName();
-
- LLViewerRegion* region = gAgent.getRegion();
- if (gAgent.isGodlike())
- {
- args["[OWNER]"] = owner.c_str();
- return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args);
- }
- else if (region && region->getOwner() == gAgent.getID())
- {
- return LLTrans::getString("RegionInfoAllEstatesYouOwn");
- }
- else if (region && region->isEstateManager())
- {
- args["[OWNER]"] = owner.c_str();
- return LLTrans::getString("RegionInfoAllEstatesYouManage", args);
- }
- else
- {
- return "(" + LLTrans::getString("RegionInfoError") + ")";
- }
+ LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
+ if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")";
+
+ LLStringUtil::format_map_t args;
+ std::string owner = panel->getOwnerName();
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (gAgent.isGodlike())
+ {
+ args["[OWNER]"] = owner.c_str();
+ return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args);
+ }
+ else if (region && region->getOwner() == gAgent.getID())
+ {
+ return LLTrans::getString("RegionInfoAllEstatesYouOwn");
+ }
+ else if (region && region->isEstateManager())
+ {
+ args["[OWNER]"] = owner.c_str();
+ return LLTrans::getString("RegionInfoAllEstatesYouManage", args);
+ }
+ else
+ {
+ return "(" + LLTrans::getString("RegionInfoError") + ")";
+ }
}
// static
bool LLPanelEstateInfo::isLindenEstate()
{
- U32 estate_id = LLEstateInfoModel::instance().getID();
- return (estate_id <= ESTATE_LAST_LINDEN);
+ U32 estate_id = LLEstateInfoModel::instance().getID();
+ return (estate_id <= ESTATE_LAST_LINDEN);
}
struct LLEstateAccessChangeInfo
{
- LLEstateAccessChangeInfo(const LLSD& sd)
- {
- mDialogName = sd["dialog_name"].asString();
- mOperationFlag = (U32)sd["operation"].asInteger();
- LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray();
- for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray();
- id_it != end_it;
- ++id_it)
- {
- mAgentOrGroupIDs.push_back(id_it->asUUID());
- }
- }
-
- const LLSD asLLSD() const
- {
- LLSD sd;
- sd["name"] = mDialogName;
- sd["operation"] = (S32)mOperationFlag;
- for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i)
- {
- sd["allowed_ids"].append(mAgentOrGroupIDs[i]);
- if (mAgentNames.size() > i)
- {
- sd["allowed_names"].append(mAgentNames[i].asLLSD());
- }
- }
- return sd;
- }
-
- U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc.
- std::string mDialogName;
- uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change
- std::vector<LLAvatarName> mAgentNames; // Optional list of the agent names for notifications
+ LLEstateAccessChangeInfo(const LLSD& sd)
+ {
+ mDialogName = sd["dialog_name"].asString();
+ mOperationFlag = (U32)sd["operation"].asInteger();
+ LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray();
+ for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray();
+ id_it != end_it;
+ ++id_it)
+ {
+ mAgentOrGroupIDs.push_back(id_it->asUUID());
+ }
+ }
+
+ const LLSD asLLSD() const
+ {
+ LLSD sd;
+ sd["name"] = mDialogName;
+ sd["operation"] = (S32)mOperationFlag;
+ for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i)
+ {
+ sd["allowed_ids"].append(mAgentOrGroupIDs[i]);
+ if (mAgentNames.size() > i)
+ {
+ sd["allowed_names"].append(mAgentNames[i].asLLSD());
+ }
+ }
+ return sd;
+ }
+
+ U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc.
+ std::string mDialogName;
+ uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change
+ std::vector<LLAvatarName> mAgentNames; // Optional list of the agent names for notifications
};
// static
void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name)
{
- LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
- if (panelp)
- {
- panelp->setOwnerName(name);
- }
+ LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
+ if (panelp)
+ {
+ panelp->setOwnerName(name);
+ }
}
// static
void LLPanelEstateInfo::updateEstateName(const std::string& name)
{
- LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
- if (panelp)
- {
- panelp->getChildRef<LLTextBox>("estate_name").setText(name);
- }
+ LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
+ if (panelp)
+ {
+ panelp->getChildRef<LLTextBox>("estate_name").setText(name);
+ }
}
void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
{
- BOOL god = gAgent.isGodlike();
- BOOL owner = (region && (region->getOwner() == gAgent.getID()));
- BOOL manager = (region && region->isEstateManager());
- setCtrlsEnabled(god || owner || manager);
-
- getChildView("apply_btn")->setEnabled(FALSE);
+ BOOL god = gAgent.isGodlike();
+ BOOL owner = (region && (region->getOwner() == gAgent.getID()));
+ BOOL manager = (region && region->isEstateManager());
+ setCtrlsEnabled(god || owner || manager);
+
+ getChildView("apply_btn")->setEnabled(FALSE);
getChildView("estate_owner")->setEnabled(TRUE);
- getChildView("message_estate_btn")->setEnabled(god || owner || manager);
- getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
+ getChildView("message_estate_btn")->setEnabled(god || owner || manager);
+ getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
- refresh();
+ refresh();
}
bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region)
{
- updateControls(region);
+ updateControls(region);
+
+ // let the parent class handle the general data collection.
+ bool rv = LLPanelRegionInfo::refreshFromRegion(region);
- // let the parent class handle the general data collection.
- bool rv = LLPanelRegionInfo::refreshFromRegion(region);
+ // We want estate info. To make sure it works across region
+ // boundaries and multiple packets, we add a serial number to the
+ // integers and track against that on update.
+ strings_t strings;
+ //integers_t integers;
+ //LLFloaterRegionInfo::incrementSerial();
+ LLFloaterRegionInfo::nextInvoice();
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate();
- // We want estate info. To make sure it works across region
- // boundaries and multiple packets, we add a serial number to the
- // integers and track against that on update.
- strings_t strings;
- //integers_t integers;
- //LLFloaterRegionInfo::incrementSerial();
- LLFloaterRegionInfo::nextInvoice();
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate();
+
+ sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings);
+ refresh();
- sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings);
-
- refresh();
-
- return rv;
+ return rv;
}
void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl)
{
- // Ensure appropriate state of the management ui.
- updateControls(gAgent.getRegion());
+ // Ensure appropriate state of the management ui.
+ updateControls(gAgent.getRegion());
}
bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg)
{
- LL_INFOS() << "LLPanelEstateInfo::estateUpdate()" << LL_ENDL;
- return false;
+ LL_INFOS() << "LLPanelEstateInfo::estateUpdate()" << LL_ENDL;
+ return false;
}
BOOL LLPanelEstateInfo::postBuild()
{
- // set up the callbacks for the generic controls
- initCtrl("externally_visible_radio");
- initCtrl("allow_direct_teleport");
- initCtrl("limit_payment");
- initCtrl("limit_age_verified");
+ // set up the callbacks for the generic controls
+ initCtrl("externally_visible_radio");
+ initCtrl("allow_direct_teleport");
+ initCtrl("limit_payment");
+ initCtrl("limit_age_verified");
initCtrl("limit_bots");
- initCtrl("voice_chat_check");
+ initCtrl("voice_chat_check");
initCtrl("parcel_access_override");
- childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this));
- childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this));
+ childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this));
+ childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this));
- getChild<LLUICtrl>("parcel_access_override")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAccessOverride, this));
+ getChild<LLUICtrl>("parcel_access_override")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAccessOverride, this));
- getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
- return LLPanelRegionInfo::postBuild();
+ return LLPanelRegionInfo::postBuild();
}
void LLPanelEstateInfo::refresh()
{
- // Disable access restriction controls if they make no sense.
- bool public_access = ("estate_public_access" == getChild<LLUICtrl>("externally_visible_radio")->getValue().asString());
+ // Disable access restriction controls if they make no sense.
+ bool public_access = ("estate_public_access" == getChild<LLUICtrl>("externally_visible_radio")->getValue().asString());
- getChildView("Only Allow")->setEnabled(public_access);
- getChildView("limit_payment")->setEnabled(public_access);
- getChildView("limit_age_verified")->setEnabled(public_access);
+ getChildView("Only Allow")->setEnabled(public_access);
+ getChildView("limit_payment")->setEnabled(public_access);
+ getChildView("limit_age_verified")->setEnabled(public_access);
getChildView("limit_bots")->setEnabled(public_access);
- // if this is set to false, then the limit fields are meaningless and should be turned off
- if (public_access == false)
- {
- getChild<LLUICtrl>("limit_payment")->setValue(false);
- getChild<LLUICtrl>("limit_age_verified")->setValue(false);
+ // if this is set to false, then the limit fields are meaningless and should be turned off
+ if (public_access == false)
+ {
+ getChild<LLUICtrl>("limit_payment")->setValue(false);
+ getChild<LLUICtrl>("limit_age_verified")->setValue(false);
getChild<LLUICtrl>("limit_bots")->setValue(false);
- }
+ }
}
void LLPanelEstateInfo::refreshFromEstate()
{
- const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+ const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
- getChild<LLUICtrl>("estate_name")->setValue(estate_info.getName());
- setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString());
+ getChild<LLUICtrl>("estate_name")->setValue(estate_info.getName());
+ setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString());
- getChild<LLUICtrl>("externally_visible_radio")->setValue(estate_info.getIsExternallyVisible() ? "estate_public_access" : "estate_restricted_access");
- getChild<LLUICtrl>("voice_chat_check")->setValue(estate_info.getAllowVoiceChat());
- getChild<LLUICtrl>("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport());
- getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
- getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
+ getChild<LLUICtrl>("externally_visible_radio")->setValue(estate_info.getIsExternallyVisible() ? "estate_public_access" : "estate_restricted_access");
+ getChild<LLUICtrl>("voice_chat_check")->setValue(estate_info.getAllowVoiceChat());
+ getChild<LLUICtrl>("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport());
+ getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
+ getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride());
getChild<LLUICtrl>("limit_bots")->setValue(estate_info.getDenyScriptedAgents());
- // Ensure appriopriate state of the management UI
- updateControls(gAgent.getRegion());
- refresh();
+ // Ensure appriopriate state of the management UI
+ updateControls(gAgent.getRegion());
+ refresh();
}
BOOL LLPanelEstateInfo::sendUpdate()
{
- LL_INFOS() << "LLPanelEsateInfo::sendUpdate()" << LL_ENDL;
+ LL_INFOS() << "LLPanelEsateInfo::sendUpdate()" << LL_ENDL;
- LLNotification::Params params("ChangeLindenEstate");
- params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
+ LLNotification::Params params("ChangeLindenEstate");
+ params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
- if (isLindenEstate())
- {
- // trying to change reserved estate, warn
- LLNotifications::instance().add(params);
- }
- else
- {
- // for normal estates, just make the change
- LLNotifications::instance().forceResponse(params, 0);
- }
- return TRUE;
+ if (isLindenEstate())
+ {
+ // trying to change reserved estate, warn
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ // for normal estates, just make the change
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ return TRUE;
}
bool LLPanelEstateInfo::callbackChangeLindenEstate(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.setUseFixedSun(false); // we don't support fixed sun estates anymore
- estate_info.setIsExternallyVisible("estate_public_access" == getChild<LLUICtrl>("externally_visible_radio")->getValue().asString());
- estate_info.setAllowDirectTeleport(getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean());
- estate_info.setDenyAnonymous(getChild<LLUICtrl>("limit_payment")->getValue().asBoolean());
- estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
- estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0:
+ {
+ LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+ // update model
+ estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore
+ estate_info.setIsExternallyVisible("estate_public_access" == getChild<LLUICtrl>("externally_visible_radio")->getValue().asString());
+ estate_info.setAllowDirectTeleport(getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean());
+ estate_info.setDenyAnonymous(getChild<LLUICtrl>("limit_payment")->getValue().asBoolean());
+ 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());
estate_info.setDenyScriptedAgents(getChild<LLUICtrl>("limit_bots")->getValue().asBoolean());
// JIGGLYPUFF
//estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
- // send the update to sim
- estate_info.sendEstateInfo();
- }
-
- // we don't want to do this because we'll get it automatically from the sim
- // after the spaceserver processes it
-// else
-// {
-// // caps method does not automatically send this info
-// LLFloaterRegionInfo::requestRegionInfo();
-// }
- break;
- case 1:
- default:
- // do nothing
- break;
- }
- return false;
+ // send the update to sim
+ estate_info.sendEstateInfo();
+ }
+
+ // we don't want to do this because we'll get it automatically from the sim
+ // after the spaceserver processes it
+// else
+// {
+// // caps method does not automatically send this info
+// LLFloaterRegionInfo::requestRegionInfo();
+// }
+ break;
+ case 1:
+ default:
+ // do nothing
+ break;
+ }
+ return false;
}
@@ -1988,326 +2289,326 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
// IParam[0] = serial
void LLPanelEstateInfo::getEstateOwner()
{
- // TODO -- disable the panel
- // and call this function whenever we cross a region boundary
- // re-enable when owner matches, and get new estate info
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_EstateOwnerRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ // TODO -- disable the panel
+ // and call this function whenever we cross a region boundary
+ // re-enable when owner matches, and get new estate info
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_EstateOwnerRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->nextBlockFast(_PREHASH_RequestData);
- msg->addStringFast(_PREHASH_Request, "getowner");
+ msg->nextBlockFast(_PREHASH_RequestData);
+ msg->addStringFast(_PREHASH_Request, "getowner");
- // we send an empty string so that the variable block is not empty
- msg->nextBlockFast(_PREHASH_StringData);
- msg->addStringFast(_PREHASH_SParam, "");
+ // we send an empty string so that the variable block is not empty
+ msg->nextBlockFast(_PREHASH_StringData);
+ msg->addStringFast(_PREHASH_SParam, "");
- msg->nextBlockFast(_PREHASH_IntegerData);
- msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial());
+ msg->nextBlockFast(_PREHASH_IntegerData);
+ msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial());
- gAgent.sendMessage();
+ gAgent.sendMessage();
}
*/
const std::string LLPanelEstateInfo::getOwnerName() const
{
- return getChild<LLUICtrl>("estate_owner")->getValue().asString();
+ return getChild<LLUICtrl>("estate_owner")->getValue().asString();
}
void LLPanelEstateInfo::setOwnerName(const std::string& name)
{
- getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name));
+ getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name));
}
// static
void LLPanelEstateInfo::onClickMessageEstate(void* userdata)
{
- LL_INFOS() << "LLPanelEstateInfo::onClickMessageEstate" << LL_ENDL;
- LLNotificationsUtil::add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2));
+ LL_INFOS() << "LLPanelEstateInfo::onClickMessageEstate" << LL_ENDL;
+ LLNotificationsUtil::add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2));
}
bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- std::string text = response["message"].asString();
- if(option != 0) return false;
- if(text.empty()) return false;
- LL_INFOS() << "Message to everyone: " << text << LL_ENDL;
- strings_t strings;
- //integers_t integers;
- std::string name;
- LLAgentUI::buildFullname(name);
- strings.push_back(strings_t::value_type(name));
- strings.push_back(strings_t::value_type(text));
- LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ std::string text = response["message"].asString();
+ if(option != 0) return false;
+ if(text.empty()) return false;
+ LL_INFOS() << "Message to everyone: " << text << LL_ENDL;
+ strings_t strings;
+ //integers_t integers;
+ std::string name;
+ LLAgentUI::buildFullname(name);
+ strings.push_back(strings_t::value_type(name));
+ strings.push_back(strings_t::value_type(text));
+ LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+ sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
+ return false;
}
void LLPanelEstateInfo::onChangeAccessOverride()
{
- if (!getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean())
- {
- LLNotificationsUtil::add("EstateParcelAccessOverride");
- }
+ if (!getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean())
+ {
+ LLNotificationsUtil::add("EstateParcelAccessOverride");
+ }
}
LLPanelEstateCovenant::LLPanelEstateCovenant()
- :
- mCovenantID(LLUUID::null),
- mAssetStatus(ASSET_ERROR)
+ :
+ mCovenantID(LLUUID::null),
+ mAssetStatus(ASSET_ERROR)
{
}
-// virtual
+// virtual
bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
{
- LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
- if (region_name)
- {
- region_name->setText(region->getName());
- }
-
- LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
- if (resellable_clause)
- {
- if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
- {
- resellable_clause->setText(getString("can_not_resell"));
- }
- else
- {
- resellable_clause->setText(getString("can_resell"));
- }
- }
-
- LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
- if (changeable_clause)
- {
- if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
- {
- changeable_clause->setText(getString("can_change"));
- }
- else
- {
- changeable_clause->setText(getString("can_not_change"));
- }
- }
-
- LLTextBox* region_maturity = getChild<LLTextBox>("region_maturity_text");
- if (region_maturity)
- {
- region_maturity->setText(region->getSimAccessString());
- }
-
- LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text");
- region_landtype->setText(region->getLocalizedSimProductName());
+ LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
+ if (region_name)
+ {
+ region_name->setText(region->getName());
+ }
+
+ LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
+ if (resellable_clause)
+ {
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
+ {
+ resellable_clause->setText(getString("can_not_resell"));
+ }
+ else
+ {
+ resellable_clause->setText(getString("can_resell"));
+ }
+ }
+
+ LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
+ if (changeable_clause)
+ {
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
+ {
+ changeable_clause->setText(getString("can_change"));
+ }
+ else
+ {
+ changeable_clause->setText(getString("can_not_change"));
+ }
+ }
+
+ LLTextBox* region_maturity = getChild<LLTextBox>("region_maturity_text");
+ if (region_maturity)
+ {
+ region_maturity->setText(region->getSimAccessString());
+ }
+
+ LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text");
+ region_landtype->setText(region->getLocalizedSimProductName());
getChild<LLButton>("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate()));
-
- // let the parent class handle the general data collection.
- bool rv = LLPanelRegionInfo::refreshFromRegion(region);
- LLMessageSystem *msg = gMessageSystem;
- msg->newMessage("EstateCovenantRequest");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
- msg->sendReliable(region->getHost());
- return rv;
-}
-
-// virtual
+
+ // let the parent class handle the general data collection.
+ bool rv = LLPanelRegionInfo::refreshFromRegion(region);
+ LLMessageSystem *msg = gMessageSystem;
+ msg->newMessage("EstateCovenantRequest");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
+ msg->sendReliable(region->getHost());
+ return rv;
+}
+
+// virtual
bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg)
{
- LL_INFOS() << "LLPanelEstateCovenant::estateUpdate()" << LL_ENDL;
- return true;
+ LL_INFOS() << "LLPanelEstateCovenant::estateUpdate()" << LL_ENDL;
+ return true;
}
-
-// virtual
+
+// virtual
BOOL LLPanelEstateCovenant::postBuild()
{
- mEstateNameText = getChild<LLTextBox>("estate_name_text");
- mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateNameText = getChild<LLTextBox>("estate_name_text");
+ mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
- mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
- mEditor = getChild<LLViewerTextEditor>("covenant_editor");
- LLButton* reset_button = getChild<LLButton>("reset_covenant");
- reset_button->setEnabled(gAgent.canManageEstate());
- reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL);
+ mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
+ mEditor = getChild<LLViewerTextEditor>("covenant_editor");
+ LLButton* reset_button = getChild<LLButton>("reset_covenant");
+ reset_button->setEnabled(gAgent.canManageEstate());
+ reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL);
- return LLPanelRegionInfo::postBuild();
+ return LLPanelRegionInfo::postBuild();
}
-// virtual
+// virtual
void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl)
{
}
// virtual
BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- LLInventoryItem* item = (LLInventoryItem*)cargo_data;
-
- if (!gAgent.canManageEstate())
- {
- *accept = ACCEPT_NO;
- return TRUE;
- }
-
- switch(cargo_type)
- {
- case DAD_NOTECARD:
- *accept = ACCEPT_YES_COPY_SINGLE;
- if (item && drop)
- {
- LLSD payload;
- payload["item_id"] = item->getUUID();
- LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), payload,
- LLPanelEstateCovenant::confirmChangeCovenantCallback);
- }
- break;
- default:
- *accept = ACCEPT_NO;
- break;
- }
-
- return TRUE;
-}
-
-// static
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ LLInventoryItem* item = (LLInventoryItem*)cargo_data;
+
+ if (!gAgent.canManageEstate())
+ {
+ *accept = ACCEPT_NO;
+ return TRUE;
+ }
+
+ switch(cargo_type)
+ {
+ case DAD_NOTECARD:
+ *accept = ACCEPT_YES_COPY_SINGLE;
+ if (item && drop)
+ {
+ LLSD payload;
+ payload["item_id"] = item->getUUID();
+ LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), payload,
+ LLPanelEstateCovenant::confirmChangeCovenantCallback);
+ }
+ break;
+ default:
+ *accept = ACCEPT_NO;
+ break;
+ }
+
+ return TRUE;
+}
+
+// static
bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
- LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+ LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
- if (!item || !self) return false;
+ if (!item || !self) return false;
- switch(option)
- {
- case 0:
- self->loadInvItem(item);
- break;
- default:
- break;
- }
- return false;
+ switch(option)
+ {
+ case 0:
+ self->loadInvItem(item);
+ break;
+ default:
+ break;
+ }
+ return false;
}
// static
void LLPanelEstateCovenant::resetCovenantID(void* userdata)
{
- LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback);
+ LLNotificationsUtil::add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback);
}
// static
bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response)
{
- LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
- if (!self) return false;
+ LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
+ if (!self) return false;
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch(option)
- {
- case 0:
- self->loadInvItem(NULL);
- break;
- default:
- break;
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0:
+ self->loadInvItem(NULL);
+ break;
+ default:
+ break;
+ }
+ return false;
}
void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp)
{
- const BOOL high_priority = TRUE;
- if (itemp)
- {
- gAssetStorage->getInvItemAsset(gAgent.getRegionHost(),
- gAgent.getID(),
- gAgent.getSessionID(),
- itemp->getPermissions().getOwner(),
- LLUUID::null,
- itemp->getUUID(),
- itemp->getAssetUUID(),
- itemp->getType(),
+ const BOOL high_priority = TRUE;
+ if (itemp)
+ {
+ gAssetStorage->getInvItemAsset(gAgent.getRegionHost(),
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ itemp->getPermissions().getOwner(),
+ LLUUID::null,
+ itemp->getUUID(),
+ itemp->getAssetUUID(),
+ itemp->getType(),
onLoadComplete,
- (void*)this,
- high_priority);
- mAssetStatus = ASSET_LOADING;
- }
- else
- {
- mAssetStatus = ASSET_LOADED;
- setCovenantTextEditor(LLTrans::getString("RegionNoCovenant"));
- sendChangeCovenantID(LLUUID::null);
- }
+ (void*)this,
+ high_priority);
+ mAssetStatus = ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = ASSET_LOADED;
+ setCovenantTextEditor(LLTrans::getString("RegionNoCovenant"));
+ sendChangeCovenantID(LLUUID::null);
+ }
}
// static
void LLPanelEstateCovenant::onLoadComplete(const LLUUID& asset_uuid,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status)
-{
- LL_INFOS() << "LLPanelEstateCovenant::onLoadComplete()" << LL_ENDL;
- LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data;
- if( panelp )
- {
- if(0 == status)
- {
- LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
-
- S32 file_length = file.getSize();
-
- std::vector<char> buffer(file_length+1);
- file.read((U8*)&buffer[0], file_length);
- // put a EOS at the end
- buffer[file_length] = 0;
-
- if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
- {
- if( !panelp->mEditor->importBuffer( &buffer[0], file_length+1 ) )
- {
- LL_WARNS() << "Problem importing estate covenant." << LL_ENDL;
- LLNotificationsUtil::add("ProblemImportingEstateCovenant");
- }
- else
- {
- panelp->sendChangeCovenantID(asset_uuid);
- }
- }
- else
- {
- // Version 0 (just text, doesn't include version number)
- panelp->sendChangeCovenantID(asset_uuid);
- }
- }
- else
- {
- if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
- LL_ERR_FILE_EMPTY == status)
- {
- LLNotificationsUtil::add("MissingNotecardAssetID");
- }
- else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
- {
- LLNotificationsUtil::add("NotAllowedToViewNotecard");
- }
- else
- {
- LLNotificationsUtil::add("UnableToLoadNotecardAsset");
- }
-
- LL_WARNS() << "Problem loading notecard: " << status << LL_ENDL;
- }
- panelp->mAssetStatus = ASSET_LOADED;
- panelp->setCovenantID(asset_uuid);
- }
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status)
+{
+ LL_INFOS() << "LLPanelEstateCovenant::onLoadComplete()" << LL_ENDL;
+ LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data;
+ if( panelp )
+ {
+ if(0 == status)
+ {
+ LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
+
+ S32 file_length = file.getSize();
+
+ std::vector<char> buffer(file_length+1);
+ file.read((U8*)&buffer[0], file_length);
+ // put a EOS at the end
+ buffer[file_length] = 0;
+
+ if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
+ {
+ if( !panelp->mEditor->importBuffer( &buffer[0], file_length+1 ) )
+ {
+ LL_WARNS() << "Problem importing estate covenant." << LL_ENDL;
+ LLNotificationsUtil::add("ProblemImportingEstateCovenant");
+ }
+ else
+ {
+ panelp->sendChangeCovenantID(asset_uuid);
+ }
+ }
+ else
+ {
+ // Version 0 (just text, doesn't include version number)
+ panelp->sendChangeCovenantID(asset_uuid);
+ }
+ }
+ else
+ {
+ if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ LLNotificationsUtil::add("MissingNotecardAssetID");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ LLNotificationsUtil::add("NotAllowedToViewNotecard");
+ }
+ else
+ {
+ LLNotificationsUtil::add("UnableToLoadNotecardAsset");
+ }
+
+ LL_WARNS() << "Problem loading notecard: " << status << LL_ENDL;
+ }
+ panelp->mAssetStatus = ASSET_LOADED;
+ panelp->setCovenantID(asset_uuid);
+ }
}
// key = "estatechangecovenantid"
@@ -2315,97 +2616,97 @@ void LLPanelEstateCovenant::onLoadComplete(const LLUUID& asset_uuid,
// strings[1] = str(covenant_id)
void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id)
{
- if (asset_id != getCovenantID())
- {
+ if (asset_id != getCovenantID())
+ {
setCovenantID(asset_id);
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("EstateOwnerMessage");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("EstateOwnerMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
- msg->nextBlock("MethodData");
- msg->addString("Method", "estatechangecovenantid");
- msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
+ msg->nextBlock("MethodData");
+ msg->addString("Method", "estatechangecovenantid");
+ msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
- msg->nextBlock("ParamList");
- msg->addString("Parameter", getCovenantID().asString());
- gAgent.sendReliableMessage();
- }
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", getCovenantID().asString());
+ gAgent.sendReliableMessage();
+ }
}
-// virtual
+// virtual
BOOL LLPanelEstateCovenant::sendUpdate()
{
- return TRUE;
+ return TRUE;
}
std::string LLPanelEstateCovenant::getEstateName() const
{
- return mEstateNameText->getText();
+ return mEstateNameText->getText();
}
void LLPanelEstateCovenant::setEstateName(const std::string& name)
{
- mEstateNameText->setText(name);
+ mEstateNameText->setText(name);
}
// static
void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id)
{
- LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
- if( panelp )
- {
- panelp->mEditor->setText(string);
- panelp->setCovenantID(asset_id);
- }
+ LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
+ if( panelp )
+ {
+ panelp->mEditor->setText(string);
+ panelp->setCovenantID(asset_id);
+ }
}
// static
void LLPanelEstateCovenant::updateEstateName(const std::string& name)
{
- LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
- if( panelp )
- {
- panelp->mEstateNameText->setText(name);
- }
+ LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
+ if( panelp )
+ {
+ panelp->mEstateNameText->setText(name);
+ }
}
// static
void LLPanelEstateCovenant::updateLastModified(const std::string& text)
{
- LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
- if( panelp )
- {
- panelp->mLastModifiedText->setText(text);
- }
+ LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
+ if( panelp )
+ {
+ panelp->mLastModifiedText->setText(text);
+ }
}
// static
void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name)
{
- LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
- if( panelp )
- {
- panelp->mEstateOwnerText->setText(name);
- }
+ LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant();
+ if( panelp )
+ {
+ panelp->mEstateOwnerText->setText(name);
+ }
}
std::string LLPanelEstateCovenant::getOwnerName() const
{
- return mEstateOwnerText->getText();
+ return mEstateOwnerText->getText();
}
void LLPanelEstateCovenant::setOwnerName(const std::string& name)
{
- mEstateOwnerText->setText(name);
+ mEstateOwnerText->setText(name);
}
void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text)
{
- mEditor->setText(text);
+ mEditor->setText(text);
}
// key = "estateupdateinfo"
@@ -2420,47 +2721,47 @@ void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text)
// strings[8] = str(send_to_agent_only)
// strings[9] = str(abuse_email_addr)
bool LLDispatchEstateUpdateInfo::operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings)
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
{
- LL_DEBUGS() << "Received estate update" << LL_ENDL;
+ LL_DEBUGS() << "Received estate update" << LL_ENDL;
- // Update estate info model.
- // This will call LLPanelEstateInfo::refreshFromEstate().
- // *TODO: Move estate message handling stuff to llestateinfomodel.cpp.
- LLEstateInfoModel::instance().update(strings);
+ // Update estate info model.
+ // This will call LLPanelEstateInfo::refreshFromEstate().
+ // *TODO: Move estate message handling stuff to llestateinfomodel.cpp.
+ LLEstateInfoModel::instance().update(strings);
- return true;
+ return true;
}
bool LLDispatchSetEstateAccess::operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings)
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (panel && panel->getPendingUpdate())
- {
- panel->setPendingUpdate(false);
- panel->updateLists();
- }
- return true;
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (panel && panel->getPendingUpdate())
+ {
+ panel->setPendingUpdate(false);
+ panel->updateLists();
+ }
+ return true;
}
// static
LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count )
{
- LLSD idList = LLSD::emptyArray();
- LLUUID id;
- while (count-- > 0 && it < end)
- {
- memcpy(id.mData, (*(it++)).data(), UUID_BYTES);
- idList.append(id);
- }
- return idList;
+ LLSD idList = LLSD::emptyArray();
+ LLUUID id;
+ while (count-- > 0 && it < end)
+ {
+ memcpy(id.mData, (*(it++)).data(), UUID_BYTES);
+ idList.append(id);
+ }
+ return idList;
}
// key = "setexperience"
@@ -2472,92 +2773,92 @@ LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_
// strings[5] = bin(uuid) ...
// ...
bool LLDispatchSetEstateExperience::operator()(
- const LLDispatcher* dispatcher,
- const std::string& key,
- const LLUUID& invoice,
- const sparam_t& strings)
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
{
- LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
- if (!panel)
- return true;
+ LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
+ if (!panel)
+ return true;
- const sparam_t::size_type MIN_SIZE = 5;
- if (strings.size() < MIN_SIZE)
- return true;
+ const sparam_t::size_type MIN_SIZE = 5;
+ if (strings.size() < MIN_SIZE)
+ return true;
- // Skip 2 parameters
- sparam_t::const_iterator it = strings.begin();
- ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10);
- ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10);
+ // Skip 2 parameters
+ sparam_t::const_iterator it = strings.begin();
+ ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10);
+ ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10);
- // Read 3 parameters
- LLUUID id;
- S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10);
- S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10);
- S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10);
+ // Read 3 parameters
+ LLUUID id;
+ S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10);
+ S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10);
+ S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10);
- LLSD ids = LLSD::emptyMap()
- .with("blocked", getIDs(it, strings.end(), num_blocked))
- .with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted))
- .with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed));
+ LLSD ids = LLSD::emptyMap()
+ .with("blocked", getIDs(it, strings.end(), num_blocked))
+ .with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted))
+ .with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed));
- panel->processResponse(ids);
+ panel->processResponse(ids);
- return true;
+ return true;
}
BOOL LLPanelRegionExperiences::postBuild()
{
- mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE);
- mTrusted = setupList("panel_trusted", ESTATE_EXPERIENCE_TRUSTED_ADD, ESTATE_EXPERIENCE_TRUSTED_REMOVE);
- mBlocked = setupList("panel_blocked", ESTATE_EXPERIENCE_BLOCKED_ADD, ESTATE_EXPERIENCE_BLOCKED_REMOVE);
+ mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE);
+ mTrusted = setupList("panel_trusted", ESTATE_EXPERIENCE_TRUSTED_ADD, ESTATE_EXPERIENCE_TRUSTED_REMOVE);
+ mBlocked = setupList("panel_blocked", ESTATE_EXPERIENCE_BLOCKED_ADD, ESTATE_EXPERIENCE_BLOCKED_REMOVE);
- getChild<LLLayoutPanel>("trusted_layout_panel")->setVisible(TRUE);
- getChild<LLTextBox>("experiences_help_text")->setText(getString("estate_caption"));
- getChild<LLTextBox>("trusted_text_help")->setText(getString("trusted_estate_text"));
- getChild<LLTextBox>("allowed_text_help")->setText(getString("allowed_estate_text"));
- getChild<LLTextBox>("blocked_text_help")->setText(getString("blocked_estate_text"));
+ getChild<LLLayoutPanel>("trusted_layout_panel")->setVisible(TRUE);
+ getChild<LLTextBox>("experiences_help_text")->setText(getString("estate_caption"));
+ getChild<LLTextBox>("trusted_text_help")->setText(getString("trusted_estate_text"));
+ getChild<LLTextBox>("allowed_text_help")->setText(getString("allowed_estate_text"));
+ getChild<LLTextBox>("blocked_text_help")->setText(getString("blocked_estate_text"));
- return LLPanelRegionInfo::postBuild();
+ return LLPanelRegionInfo::postBuild();
}
LLPanelExperienceListEditor* LLPanelRegionExperiences::setupList( const char* control_name, U32 add_id, U32 remove_id )
{
- LLPanelExperienceListEditor* child = findChild<LLPanelExperienceListEditor>(control_name);
- if(child)
- {
- child->getChild<LLTextBox>("text_name")->setText(child->getString(control_name));
- child->setMaxExperienceIDs(ESTATE_MAX_EXPERIENCE_IDS);
- child->setAddedCallback( boost::bind(&LLPanelRegionExperiences::itemChanged, this, add_id, _1));
- child->setRemovedCallback(boost::bind(&LLPanelRegionExperiences::itemChanged, this, remove_id, _1));
- }
+ LLPanelExperienceListEditor* child = findChild<LLPanelExperienceListEditor>(control_name);
+ if(child)
+ {
+ child->getChild<LLTextBox>("text_name")->setText(child->getString(control_name));
+ child->setMaxExperienceIDs(ESTATE_MAX_EXPERIENCE_IDS);
+ child->setAddedCallback( boost::bind(&LLPanelRegionExperiences::itemChanged, this, add_id, _1));
+ child->setRemovedCallback(boost::bind(&LLPanelRegionExperiences::itemChanged, this, remove_id, _1));
+ }
- return child;
+ return child;
}
void LLPanelRegionExperiences::processResponse( const LLSD& content )
{
- if(content.has("default"))
- {
- mDefaultExperience = content["default"].asUUID();
- }
-
- mAllowed->setExperienceIds(content["allowed"]);
- mBlocked->setExperienceIds(content["blocked"]);
+ if(content.has("default"))
+ {
+ mDefaultExperience = content["default"].asUUID();
+ }
- LLSD trusted = content["trusted"];
- if(mDefaultExperience.notNull())
- {
- mTrusted->setStickyFunction(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
- trusted.append(mDefaultExperience);
- }
+ mAllowed->setExperienceIds(content["allowed"]);
+ mBlocked->setExperienceIds(content["blocked"]);
- mTrusted->setExperienceIds(trusted);
+ LLSD trusted = content["trusted"];
+ if(mDefaultExperience.notNull())
+ {
+ mTrusted->setStickyFunction(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
+ trusted.append(mDefaultExperience);
+ }
- mAllowed->refreshExperienceCounter();
- mBlocked->refreshExperienceCounter();
- mTrusted->refreshExperienceCounter();
+ mTrusted->setExperienceIds(trusted);
+
+ mAllowed->refreshExperienceCounter();
+ mBlocked->refreshExperienceCounter();
+ mTrusted->refreshExperienceCounter();
}
@@ -2566,81 +2867,81 @@ void LLPanelRegionExperiences::processResponse( const LLSD& content )
// static
bool LLPanelRegionExperiences::experienceCoreConfirm(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
-
- LLViewerRegion* region = gAgent.getRegion();
-
- LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray();
-
- for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray();
- iter != end_it;
- iter++)
- {
- U32 flags = originalFlags;
- if (iter + 1 != end_it)
- flags |= ESTATE_ACCESS_NO_REPLY;
-
- const LLUUID id = iter->asUUID();
- switch(option)
- {
- case 0:
- // This estate
- sendEstateExperienceDelta(flags, id);
- break;
- case 1:
- {
- // All estates, either than I own or manage for this owner.
- // This will be verified on simulator. JC
- if (!region) break;
- if (region->getOwner() == gAgent.getID()
- || gAgent.isGodlike())
- {
- flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES;
- sendEstateExperienceDelta(flags, id);
- }
- else if (region->isEstateManager())
- {
- flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES;
- sendEstateExperienceDelta(flags, id);
- }
- break;
- }
- case 2:
- default:
- break;
- }
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
+
+ LLViewerRegion* region = gAgent.getRegion();
+
+ LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray();
+
+ for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray();
+ iter != end_it;
+ iter++)
+ {
+ U32 flags = originalFlags;
+ if (iter + 1 != end_it)
+ flags |= ESTATE_ACCESS_NO_REPLY;
+
+ const LLUUID id = iter->asUUID();
+ switch(option)
+ {
+ case 0:
+ // This estate
+ sendEstateExperienceDelta(flags, id);
+ break;
+ case 1:
+ {
+ // All estates, either than I own or manage for this owner.
+ // This will be verified on simulator. JC
+ if (!region) break;
+ if (region->getOwner() == gAgent.getID()
+ || gAgent.isGodlike())
+ {
+ flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES;
+ sendEstateExperienceDelta(flags, id);
+ }
+ else if (region->isEstateManager())
+ {
+ flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES;
+ sendEstateExperienceDelta(flags, id);
+ }
+ break;
+ }
+ case 2:
+ default:
+ break;
+ }
+ }
+ return false;
}
// Send the actual "estateexperiencedelta" message
void LLPanelRegionExperiences::sendEstateExperienceDelta(U32 flags, const LLUUID& experience_id)
{
- strings_t str(3, std::string());
- gAgent.getID().toString(str[0]);
- str[1] = llformat("%u", flags);
- experience_id.toString(str[2]);
+ strings_t str(3, std::string());
+ gAgent.getID().toString(str[0]);
+ str[1] = llformat("%u", flags);
+ experience_id.toString(str[2]);
- LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
- if (panel)
- {
- panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str);
- }
+ LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
+ if (panel)
+ {
+ panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str);
+ }
}
void LLPanelRegionExperiences::infoCallback(LLHandle<LLPanelRegionExperiences> handle, const LLSD& content)
-{
- if(handle.isDead())
- return;
+{
+ if(handle.isDead())
+ return;
- LLPanelRegionExperiences* floater = handle.get();
- if (floater)
- {
- floater->processResponse(content);
- }
+ LLPanelRegionExperiences* floater = handle.get();
+ if (floater)
+ {
+ floater->processResponse(content);
+ }
}
/*static*/
@@ -2653,26 +2954,26 @@ std::string LLPanelRegionExperiences::regionCapabilityQuery(LLViewerRegion* regi
bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region)
{
- BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
+ BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
- mAllowed->loading();
- mAllowed->setReadonly(!allow_modify);
- // remove grid-wide experiences
- mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID));
- // remove default experience
- mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
+ mAllowed->loading();
+ mAllowed->setReadonly(!allow_modify);
+ // remove grid-wide experiences
+ mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID));
+ // remove default experience
+ mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
- mBlocked->loading();
- mBlocked->setReadonly(!allow_modify);
- // only grid-wide experiences
- mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithoutProperty, _1, LLExperienceCache::PROPERTY_GRID));
- // but not privileged ones
- mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED));
- // remove default experience
- mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
+ mBlocked->loading();
+ mBlocked->setReadonly(!allow_modify);
+ // only grid-wide experiences
+ mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithoutProperty, _1, LLExperienceCache::PROPERTY_GRID));
+ // but not privileged ones
+ mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED));
+ // remove default experience
+ mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience));
- mTrusted->loading();
- mTrusted->setReadonly(!allow_modify);
+ mTrusted->loading();
+ mTrusted->setReadonly(!allow_modify);
LLExperienceCache::instance().getRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1),
boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle<LLPanelRegionExperiences>(), _1));
@@ -2682,87 +2983,87 @@ bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region)
LLSD LLPanelRegionExperiences::addIds(LLPanelExperienceListEditor* panel)
{
- LLSD ids;
- const uuid_list_t& id_list = panel->getExperienceIds();
- for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
- {
- ids.append(*it);
- }
- return ids;
+ LLSD ids;
+ const uuid_list_t& id_list = panel->getExperienceIds();
+ for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
+ {
+ ids.append(*it);
+ }
+ return ids;
}
BOOL LLPanelRegionExperiences::sendUpdate()
{
- LLViewerRegion* region = gAgent.getRegion();
+ LLViewerRegion* region = gAgent.getRegion();
LLSD content;
- content["allowed"]=addIds(mAllowed);
- content["blocked"]=addIds(mBlocked);
- content["trusted"]=addIds(mTrusted);
+ content["allowed"]=addIds(mAllowed);
+ content["blocked"]=addIds(mBlocked);
+ content["trusted"]=addIds(mTrusted);
LLExperienceCache::instance().setRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1),
content, boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle<LLPanelRegionExperiences>(), _1));
- return TRUE;
+ return TRUE;
}
void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id )
{
- std::string dialog_name;
- switch (event_type)
- {
- case ESTATE_EXPERIENCE_ALLOWED_ADD:
- dialog_name = "EstateAllowedExperienceAdd";
- break;
+ std::string dialog_name;
+ switch (event_type)
+ {
+ case ESTATE_EXPERIENCE_ALLOWED_ADD:
+ dialog_name = "EstateAllowedExperienceAdd";
+ break;
- case ESTATE_EXPERIENCE_ALLOWED_REMOVE:
- dialog_name = "EstateAllowedExperienceRemove";
- break;
+ case ESTATE_EXPERIENCE_ALLOWED_REMOVE:
+ dialog_name = "EstateAllowedExperienceRemove";
+ break;
- case ESTATE_EXPERIENCE_TRUSTED_ADD:
- dialog_name = "EstateTrustedExperienceAdd";
- break;
+ case ESTATE_EXPERIENCE_TRUSTED_ADD:
+ dialog_name = "EstateTrustedExperienceAdd";
+ break;
- case ESTATE_EXPERIENCE_TRUSTED_REMOVE:
- dialog_name = "EstateTrustedExperienceRemove";
- break;
+ case ESTATE_EXPERIENCE_TRUSTED_REMOVE:
+ dialog_name = "EstateTrustedExperienceRemove";
+ break;
- case ESTATE_EXPERIENCE_BLOCKED_ADD:
- dialog_name = "EstateBlockedExperienceAdd";
- break;
+ case ESTATE_EXPERIENCE_BLOCKED_ADD:
+ dialog_name = "EstateBlockedExperienceAdd";
+ break;
- case ESTATE_EXPERIENCE_BLOCKED_REMOVE:
- dialog_name = "EstateBlockedExperienceRemove";
- break;
+ case ESTATE_EXPERIENCE_BLOCKED_REMOVE:
+ dialog_name = "EstateBlockedExperienceRemove";
+ break;
- default:
- return;
- }
+ default:
+ return;
+ }
- LLSD payload;
- payload["operation"] = (S32)event_type;
- payload["dialog_name"] = dialog_name;
- payload["allowed_ids"].append(id);
+ LLSD payload;
+ payload["operation"] = (S32)event_type;
+ payload["dialog_name"] = dialog_name;
+ payload["allowed_ids"].append(id);
- LLSD args;
- args["ALL_ESTATES"] = all_estates_text();
+ LLSD args;
+ args["ALL_ESTATES"] = all_estates_text();
- LLNotification::Params params(dialog_name);
- params.payload(payload)
- .substitutions(args)
- .functor.function(LLPanelRegionExperiences::experienceCoreConfirm);
- if (LLPanelEstateInfo::isLindenEstate())
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
- else
- {
- LLNotifications::instance().add(params);
- }
+ LLNotification::Params params(dialog_name);
+ params.payload(payload)
+ .substitutions(args)
+ .functor.function(LLPanelRegionExperiences::experienceCoreConfirm);
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ else
+ {
+ LLNotifications::instance().add(params);
+ }
- onChangeAnything();
+ onChangeAnything();
}
@@ -2772,99 +3073,99 @@ LLPanelEstateAccess::LLPanelEstateAccess()
BOOL LLPanelEstateAccess::postBuild()
{
- getChild<LLUICtrl>("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
- LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
- if (avatar_name_list)
- {
- avatar_name_list->setCommitOnSelectionChange(TRUE);
- avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
- }
-
- getChild<LLUICtrl>("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2));
- childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this));
- childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this));
- childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this));
-
- getChild<LLUICtrl>("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
- LLNameListCtrl* group_name_list = getChild<LLNameListCtrl>("allowed_group_name_list");
- if (group_name_list)
- {
- group_name_list->setCommitOnSelectionChange(TRUE);
- group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
- }
-
- getChild<LLUICtrl>("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2));
- getChild<LLUICtrl>("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this));
- childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this));
- childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this));
-
- getChild<LLUICtrl>("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
- LLNameListCtrl* banned_name_list = getChild<LLNameListCtrl>("banned_avatar_name_list");
- if (banned_name_list)
- {
- banned_name_list->setCommitOnSelectionChange(TRUE);
- banned_name_list->setMaxItemCount(ESTATE_MAX_BANNED_IDS);
- }
-
- getChild<LLUICtrl>("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2));
- childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this));
- childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this));
- childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this));
-
- getChild<LLUICtrl>("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
- LLNameListCtrl* manager_name_list = getChild<LLNameListCtrl>("estate_manager_name_list");
- if (manager_name_list)
- {
- manager_name_list->setCommitOnSelectionChange(TRUE);
- manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue
- }
-
- childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this));
- childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this));
-
- return TRUE;
+ getChild<LLUICtrl>("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
+ LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
+ if (avatar_name_list)
+ {
+ avatar_name_list->setCommitOnSelectionChange(TRUE);
+ avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
+ }
+
+ getChild<LLUICtrl>("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2));
+ childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this));
+ childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this));
+ childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this));
+
+ getChild<LLUICtrl>("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
+ LLNameListCtrl* group_name_list = getChild<LLNameListCtrl>("allowed_group_name_list");
+ if (group_name_list)
+ {
+ group_name_list->setCommitOnSelectionChange(TRUE);
+ group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
+ }
+
+ getChild<LLUICtrl>("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2));
+ getChild<LLUICtrl>("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this));
+ childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this));
+ childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this));
+
+ getChild<LLUICtrl>("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
+ LLNameListCtrl* banned_name_list = getChild<LLNameListCtrl>("banned_avatar_name_list");
+ if (banned_name_list)
+ {
+ banned_name_list->setCommitOnSelectionChange(TRUE);
+ banned_name_list->setMaxItemCount(ESTATE_MAX_BANNED_IDS);
+ }
+
+ getChild<LLUICtrl>("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2));
+ childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this));
+ childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this));
+ childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this));
+
+ getChild<LLUICtrl>("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));
+ LLNameListCtrl* manager_name_list = getChild<LLNameListCtrl>("estate_manager_name_list");
+ if (manager_name_list)
+ {
+ manager_name_list->setCommitOnSelectionChange(TRUE);
+ manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue
+ }
+
+ childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this));
+ childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this));
+
+ return TRUE;
}
void LLPanelEstateAccess::updateControls(LLViewerRegion* region)
{
- BOOL god = gAgent.isGodlike();
- BOOL owner = (region && (region->getOwner() == gAgent.getID()));
- BOOL manager = (region && region->isEstateManager());
- BOOL enable_cotrols = god || owner || manager;
- setCtrlsEnabled(enable_cotrols);
-
- BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
- BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE;
- BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
- BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE;
-
- getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols);
- getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols);
- getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols);
-
- getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols);
- getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols);
- getChildView("allowed_group_name_list")->setEnabled(enable_cotrols);
-
- // Can't ban people from mainland, orientation islands, etc. because this
- // creates much network traffic and server load.
- // Disable their accounts in CSR tool instead.
- bool linden_estate = LLPanelEstateInfo::isLindenEstate();
- bool enable_ban = enable_cotrols && !linden_estate;
- getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
- getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban);
- getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols);
-
- // estate managers can't add estate managers
- getChildView("add_estate_manager_btn")->setEnabled(god || owner);
- getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner));
- getChildView("estate_manager_name_list")->setEnabled(god || owner);
-
- if (enable_cotrols != mCtrlsEnabled)
- {
- mCtrlsEnabled = enable_cotrols;
- updateLists(); // update the lists on the agent's access level change
- }
+ BOOL god = gAgent.isGodlike();
+ BOOL owner = (region && (region->getOwner() == gAgent.getID()));
+ BOOL manager = (region && region->isEstateManager());
+ BOOL enable_cotrols = god || owner || manager;
+ setCtrlsEnabled(enable_cotrols);
+
+ BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE;
+
+ getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols);
+ getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols);
+ getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols);
+
+ getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols);
+ getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols);
+ getChildView("allowed_group_name_list")->setEnabled(enable_cotrols);
+
+ // Can't ban people from mainland, orientation islands, etc. because this
+ // creates much network traffic and server load.
+ // Disable their accounts in CSR tool instead.
+ bool linden_estate = LLPanelEstateInfo::isLindenEstate();
+ bool enable_ban = enable_cotrols && !linden_estate;
+ getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
+ getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban);
+ getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols);
+
+ // estate managers can't add estate managers
+ getChildView("add_estate_manager_btn")->setEnabled(god || owner);
+ getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner));
+ getChildView("estate_manager_name_list")->setEnabled(god || owner);
+
+ if (enable_cotrols != mCtrlsEnabled)
+ {
+ mCtrlsEnabled = enable_cotrols;
+ updateLists(); // update the lists on the agent's access level change
+ }
}
//---------------------------------------------------------------------------
@@ -2872,483 +3173,483 @@ void LLPanelEstateAccess::updateControls(LLViewerRegion* region)
//---------------------------------------------------------------------------
void LLPanelEstateAccess::onClickAddAllowedAgent()
{
- LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list");
- if (!list) return;
- if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
- {
- //args
+ LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list");
+ if (!list) return;
+ if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
+ {
+ //args
- LLSD args;
- args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
- LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args);
- return;
- }
- accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd");
+ LLSD args;
+ args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
+ LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args);
+ return;
+ }
+ accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd");
}
void LLPanelEstateAccess::onClickRemoveAllowedAgent()
{
- accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list");
+ accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list");
}
void LLPanelEstateAccess::onClickAddAllowedGroup()
{
- LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list");
- if (!list) return;
- if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
- {
- LLSD args;
- args["MAX_GROUPS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
- LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args);
- return;
- }
-
- LLNotification::Params params("ChangeLindenAccess");
- params.functor.function(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2));
- if (LLPanelEstateInfo::isLindenEstate())
- {
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
+ LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list");
+ if (!list) return;
+ if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
+ {
+ LLSD args;
+ args["MAX_GROUPS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
+ LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args);
+ return;
+ }
+
+ LLNotification::Params params("ChangeLindenAccess");
+ params.functor.function(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2));
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
bool LLPanelEstateAccess::addAllowedGroup(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return false;
- LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
- if (widget)
- {
- widget->removeNoneOption();
- widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1));
- if (parent_floater)
- {
- LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
- widget->setOrigin(new_rect.mLeft, new_rect.mBottom);
- parent_floater->addDependentFloater(widget);
- }
- }
+ LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
+ if (widget)
+ {
+ widget->removeNoneOption();
+ widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1));
+ if (parent_floater)
+ {
+ LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
+ widget->setOrigin(new_rect.mLeft, new_rect.mBottom);
+ parent_floater->addDependentFloater(widget);
+ }
+ }
- return false;
+ return false;
}
void LLPanelEstateAccess::onClickRemoveAllowedGroup()
{
- accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list");
+ accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list");
}
void LLPanelEstateAccess::onClickAddBannedAgent()
{
- LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list");
- if (!list) return;
- if (list->getItemCount() >= ESTATE_MAX_BANNED_IDS)
- {
- LLSD args;
- args["MAX_BANNED"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
- LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args);
- return;
- }
- accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd");
+ LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list");
+ if (!list) return;
+ if (list->getItemCount() >= ESTATE_MAX_BANNED_IDS)
+ {
+ LLSD args;
+ args["MAX_BANNED"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
+ LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args);
+ return;
+ }
+ accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd");
}
void LLPanelEstateAccess::onClickRemoveBannedAgent()
{
- accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list");
+ accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list");
}
void LLPanelEstateAccess::onClickCopyAllowedList()
{
- copyListToClipboard("allowed_avatar_name_list");
+ copyListToClipboard("allowed_avatar_name_list");
}
void LLPanelEstateAccess::onClickCopyAllowedGroupList()
{
- copyListToClipboard("allowed_group_name_list");
+ copyListToClipboard("allowed_group_name_list");
}
void LLPanelEstateAccess::onClickCopyBannedList()
{
- copyListToClipboard("banned_avatar_name_list");
+ copyListToClipboard("banned_avatar_name_list");
}
// static
void LLPanelEstateAccess::onClickAddEstateManager()
{
- LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list");
- if (!list) return;
- if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
- { // Tell user they can't add more managers
- LLSD args;
- args["MAX_MANAGER"] = llformat("%d", ESTATE_MAX_MANAGERS);
- LLNotificationsUtil::add("MaxManagersOnRegion", args);
- }
- else
- { // Go pick managers to add
- accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd");
- }
+ LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list");
+ if (!list) return;
+ if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
+ { // Tell user they can't add more managers
+ LLSD args;
+ args["MAX_MANAGER"] = llformat("%d", ESTATE_MAX_MANAGERS);
+ LLNotificationsUtil::add("MaxManagersOnRegion", args);
+ }
+ else
+ { // Go pick managers to add
+ accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd");
+ }
}
// static
void LLPanelEstateAccess::onClickRemoveEstateManager()
{
- accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list");
+ accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list");
}
// Special case callback for groups, since it has different callback format than names
void LLPanelEstateAccess::addAllowedGroup2(LLUUID id)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (panel)
- {
- LLNameListCtrl* group_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
- LLScrollListItem* item = group_list->getNameItemByAgentId(id);
- if (item)
- {
- LLSD args;
- args["GROUP"] = item->getColumn(0)->getValue().asString();
- LLNotificationsUtil::add("GroupIsAlreadyInList", args);
- return;
- }
- }
-
- LLSD payload;
- payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD;
- payload["dialog_name"] = "EstateAllowedGroupAdd";
- payload["allowed_ids"].append(id);
-
- LLSD args;
- args["ALL_ESTATES"] = all_estates_text();
-
- LLNotification::Params params("EstateAllowedGroupAdd");
- params.payload(payload)
- .substitutions(args)
- .functor.function(accessCoreConfirm);
- if (LLPanelEstateInfo::isLindenEstate())
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
- else
- {
- LLNotifications::instance().add(params);
- }
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (panel)
+ {
+ LLNameListCtrl* group_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
+ LLScrollListItem* item = group_list->getNameItemByAgentId(id);
+ if (item)
+ {
+ LLSD args;
+ args["GROUP"] = item->getColumn(0)->getValue().asString();
+ LLNotificationsUtil::add("GroupIsAlreadyInList", args);
+ return;
+ }
+ }
+
+ LLSD payload;
+ payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD;
+ payload["dialog_name"] = "EstateAllowedGroupAdd";
+ payload["allowed_ids"].append(id);
+
+ LLSD args;
+ args["ALL_ESTATES"] = all_estates_text();
+
+ LLNotification::Params params("EstateAllowedGroupAdd");
+ params.payload(payload)
+ .substitutions(args)
+ .functor.function(accessCoreConfirm);
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ else
+ {
+ LLNotifications::instance().add(params);
+ }
}
// static
void LLPanelEstateAccess::accessAddCore(U32 operation_flag, const std::string& dialog_name)
{
- LLSD payload;
- payload["operation"] = (S32)operation_flag;
- payload["dialog_name"] = dialog_name;
- // agent id filled in after avatar picker
+ LLSD payload;
+ payload["operation"] = (S32)operation_flag;
+ payload["dialog_name"] = dialog_name;
+ // agent id filled in after avatar picker
- LLNotification::Params params("ChangeLindenAccess");
- params.payload(payload)
- .functor.function(accessAddCore2);
+ LLNotification::Params params("ChangeLindenAccess");
+ params.payload(payload)
+ .functor.function(accessAddCore2);
- if (LLPanelEstateInfo::isLindenEstate())
- {
- LLNotifications::instance().add(params);
- }
- else
- {
- // same as clicking "OK"
- LLNotifications::instance().forceResponse(params, 0);
- }
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ // same as clicking "OK"
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
// static
bool LLPanelEstateAccess::accessAddCore2(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0)
- {
- // abort change
- return false;
- }
-
- LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
- //Get parent floater name
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
- const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
-
- //Determine the button that triggered opening of the avatar picker
- //(so that a shadow frustum from the button to the avatar picker can be created)
- LLView * button = NULL;
- switch (change_info->mOperationFlag)
- {
- case ESTATE_ACCESS_ALLOWED_AGENT_ADD:
- button = panel->findChild<LLButton>("add_allowed_avatar_btn");
- break;
-
- case ESTATE_ACCESS_BANNED_AGENT_ADD:
- button = panel->findChild<LLButton>("add_banned_avatar_btn");
- break;
-
- case ESTATE_ACCESS_MANAGER_ADD:
- button = panel->findChild<LLButton>("add_estate_manager_btn");
- break;
- }
-
- // avatar picker yes multi-select, yes close-on-select
- LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, (void*)change_info),
- TRUE, TRUE, FALSE, parent_floater_name, button);
-
- //Allows the closed parent floater to close the child floater (avatar picker)
- if (child_floater)
- {
- parent_floater->addDependentFloater(child_floater);
- }
-
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0)
+ {
+ // abort change
+ return false;
+ }
+
+ LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
+ //Get parent floater name
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
+ const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
+
+ //Determine the button that triggered opening of the avatar picker
+ //(so that a shadow frustum from the button to the avatar picker can be created)
+ LLView * button = NULL;
+ switch (change_info->mOperationFlag)
+ {
+ case ESTATE_ACCESS_ALLOWED_AGENT_ADD:
+ button = panel->findChild<LLButton>("add_allowed_avatar_btn");
+ break;
+
+ case ESTATE_ACCESS_BANNED_AGENT_ADD:
+ button = panel->findChild<LLButton>("add_banned_avatar_btn");
+ break;
+
+ case ESTATE_ACCESS_MANAGER_ADD:
+ button = panel->findChild<LLButton>("add_estate_manager_btn");
+ break;
+ }
+
+ // avatar picker yes multi-select, yes close-on-select
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, (void*)change_info),
+ TRUE, TRUE, FALSE, parent_floater_name, button);
+
+ //Allows the closed parent floater to close the child floater (avatar picker)
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
+
+ return false;
}
// static
void LLPanelEstateAccess::accessAddCore3(const uuid_vec_t& ids, std::vector<LLAvatarName> names, void* data)
{
- LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
- if (!change_info) return;
- if (ids.empty())
- {
- // User didn't select a name.
- delete change_info;
- change_info = NULL;
- return;
- }
- // User did select a name.
- change_info->mAgentOrGroupIDs = ids;
- // Can't put estate owner on ban list
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
-
- if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD)
- {
- LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
- int currentCount = (name_list ? name_list->getItemCount() : 0);
- if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
- {
- LLSD args;
- args["NUM_ADDED"] = llformat("%d", ids.size());
- args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
- args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS);
- LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
- delete change_info;
- return;
- }
-
- uuid_vec_t ids_allowed;
- std::vector<LLAvatarName> names_allowed;
- std::string already_allowed;
- bool single = true;
- for (U32 i = 0; i < ids.size(); ++i)
- {
- LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]);
- if (item)
- {
- if (!already_allowed.empty())
- {
- already_allowed += ", ";
- single = false;
- }
- already_allowed += item->getColumn(0)->getValue().asString();
- }
- else
- {
- ids_allowed.push_back(ids[i]);
- names_allowed.push_back(names[i]);
- }
- }
- if (!already_allowed.empty())
- {
- LLSD args;
- args["AGENT"] = already_allowed;
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
- LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args);
- if (ids_allowed.empty())
- {
- delete change_info;
- return;
- }
- }
- change_info->mAgentOrGroupIDs = ids_allowed;
- change_info->mAgentNames = names_allowed;
- }
- if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD)
- {
- LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
- LLNameListCtrl* em_list = panel->getChild<LLNameListCtrl>("estate_manager_name_list");
- int currentCount = (name_list ? name_list->getItemCount() : 0);
- if (ids.size() + currentCount > ESTATE_MAX_BANNED_IDS)
- {
- LLSD args;
- args["NUM_ADDED"] = llformat("%d", ids.size());
- args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
- args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_BANNED_IDS);
- LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
- delete change_info;
- return;
- }
-
- uuid_vec_t ids_allowed;
- std::vector<LLAvatarName> names_allowed;
- std::string already_banned;
- std::string em_ban;
- bool single = true;
- for (U32 i = 0; i < ids.size(); ++i)
- {
- bool is_allowed = true;
- LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]);
- if (em_item)
- {
- if (!em_ban.empty())
- {
- em_ban += ", ";
- }
- em_ban += em_item->getColumn(0)->getValue().asString();
- is_allowed = false;
- }
-
- LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]);
- if (item)
- {
- if (!already_banned.empty())
- {
- already_banned += ", ";
- single = false;
- }
- already_banned += item->getColumn(0)->getValue().asString();
- is_allowed = false;
- }
-
- if (is_allowed)
- {
- ids_allowed.push_back(ids[i]);
- names_allowed.push_back(names[i]);
- }
- }
- if (!em_ban.empty())
- {
- LLSD args;
- args["AGENT"] = em_ban;
- LLNotificationsUtil::add("ProblemBanningEstateManager", args);
- if (ids_allowed.empty())
- {
- delete change_info;
- return;
- }
- }
- if (!already_banned.empty())
- {
- LLSD args;
- args["AGENT"] = already_banned;
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
- LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args);
- if (ids_allowed.empty())
- {
- delete change_info;
- return;
- }
- }
- change_info->mAgentOrGroupIDs = ids_allowed;
- change_info->mAgentNames = names_allowed;
- }
-
- LLSD args;
- args["ALL_ESTATES"] = all_estates_text();
- LLNotification::Params params(change_info->mDialogName);
- params.substitutions(args)
- .payload(change_info->asLLSD())
- .functor.function(accessCoreConfirm);
-
- if (LLPanelEstateInfo::isLindenEstate())
- {
- // just apply to this estate
- LLNotifications::instance().forceResponse(params, 0);
- }
- else
- {
- // ask if this estate or all estates with this owner
- LLNotifications::instance().add(params);
- }
+ LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
+ if (!change_info) return;
+ if (ids.empty())
+ {
+ // User didn't select a name.
+ delete change_info;
+ change_info = NULL;
+ return;
+ }
+ // User did select a name.
+ change_info->mAgentOrGroupIDs = ids;
+ // Can't put estate owner on ban list
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return;
+
+ if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD)
+ {
+ LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
+ int currentCount = (name_list ? name_list->getItemCount() : 0);
+ if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
+ {
+ LLSD args;
+ args["NUM_ADDED"] = llformat("%d", ids.size());
+ args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
+ args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_ACCESS_IDS);
+ LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
+ delete change_info;
+ return;
+ }
+
+ uuid_vec_t ids_allowed;
+ std::vector<LLAvatarName> names_allowed;
+ std::string already_allowed;
+ bool single = true;
+ for (U32 i = 0; i < ids.size(); ++i)
+ {
+ LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]);
+ if (item)
+ {
+ if (!already_allowed.empty())
+ {
+ already_allowed += ", ";
+ single = false;
+ }
+ already_allowed += item->getColumn(0)->getValue().asString();
+ }
+ else
+ {
+ ids_allowed.push_back(ids[i]);
+ names_allowed.push_back(names[i]);
+ }
+ }
+ if (!already_allowed.empty())
+ {
+ LLSD args;
+ args["AGENT"] = already_allowed;
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
+ LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args);
+ if (ids_allowed.empty())
+ {
+ delete change_info;
+ return;
+ }
+ }
+ change_info->mAgentOrGroupIDs = ids_allowed;
+ change_info->mAgentNames = names_allowed;
+ }
+ if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD)
+ {
+ LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
+ LLNameListCtrl* em_list = panel->getChild<LLNameListCtrl>("estate_manager_name_list");
+ int currentCount = (name_list ? name_list->getItemCount() : 0);
+ if (ids.size() + currentCount > ESTATE_MAX_BANNED_IDS)
+ {
+ LLSD args;
+ args["NUM_ADDED"] = llformat("%d", ids.size());
+ args["MAX_AGENTS"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
+ args["NUM_EXCESS"] = llformat("%d", (ids.size() + currentCount) - ESTATE_MAX_BANNED_IDS);
+ LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
+ delete change_info;
+ return;
+ }
+
+ uuid_vec_t ids_allowed;
+ std::vector<LLAvatarName> names_allowed;
+ std::string already_banned;
+ std::string em_ban;
+ bool single = true;
+ for (U32 i = 0; i < ids.size(); ++i)
+ {
+ bool is_allowed = true;
+ LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]);
+ if (em_item)
+ {
+ if (!em_ban.empty())
+ {
+ em_ban += ", ";
+ }
+ em_ban += em_item->getColumn(0)->getValue().asString();
+ is_allowed = false;
+ }
+
+ LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]);
+ if (item)
+ {
+ if (!already_banned.empty())
+ {
+ already_banned += ", ";
+ single = false;
+ }
+ already_banned += item->getColumn(0)->getValue().asString();
+ is_allowed = false;
+ }
+
+ if (is_allowed)
+ {
+ ids_allowed.push_back(ids[i]);
+ names_allowed.push_back(names[i]);
+ }
+ }
+ if (!em_ban.empty())
+ {
+ LLSD args;
+ args["AGENT"] = em_ban;
+ LLNotificationsUtil::add("ProblemBanningEstateManager", args);
+ if (ids_allowed.empty())
+ {
+ delete change_info;
+ return;
+ }
+ }
+ if (!already_banned.empty())
+ {
+ LLSD args;
+ args["AGENT"] = already_banned;
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
+ LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args);
+ if (ids_allowed.empty())
+ {
+ delete change_info;
+ return;
+ }
+ }
+ change_info->mAgentOrGroupIDs = ids_allowed;
+ change_info->mAgentNames = names_allowed;
+ }
+
+ LLSD args;
+ args["ALL_ESTATES"] = all_estates_text();
+ LLNotification::Params params(change_info->mDialogName);
+ params.substitutions(args)
+ .payload(change_info->asLLSD())
+ .functor.function(accessCoreConfirm);
+
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ // just apply to this estate
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ else
+ {
+ // ask if this estate or all estates with this owner
+ LLNotifications::instance().add(params);
+ }
}
// static
void LLPanelEstateAccess::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_ctrl_name);
- if (!name_list) return;
-
- std::vector<LLScrollListItem*> list_vector = name_list->getAllSelected();
- if (list_vector.size() == 0)
- return;
-
- LLSD payload;
- payload["operation"] = (S32)operation_flag;
- payload["dialog_name"] = dialog_name;
-
- for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
- iter != list_vector.end();
- iter++)
- {
- LLScrollListItem *item = (*iter);
- payload["allowed_ids"].append(item->getUUID());
- }
-
- LLNotification::Params params("ChangeLindenAccess");
- params.payload(payload)
- .functor.function(accessRemoveCore2);
-
- if (LLPanelEstateInfo::isLindenEstate())
- {
- // warn on change linden estate
- LLNotifications::instance().add(params);
- }
- else
- {
- // just proceed, as if clicking OK
- LLNotifications::instance().forceResponse(params, 0);
- }
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_ctrl_name);
+ if (!name_list) return;
+
+ std::vector<LLScrollListItem*> list_vector = name_list->getAllSelected();
+ if (list_vector.size() == 0)
+ return;
+
+ LLSD payload;
+ payload["operation"] = (S32)operation_flag;
+ payload["dialog_name"] = dialog_name;
+
+ for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
+ iter != list_vector.end();
+ iter++)
+ {
+ LLScrollListItem *item = (*iter);
+ payload["allowed_ids"].append(item->getUUID());
+ }
+
+ LLNotification::Params params("ChangeLindenAccess");
+ params.payload(payload)
+ .functor.function(accessRemoveCore2);
+
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ // warn on change linden estate
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ // just proceed, as if clicking OK
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
// static
bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0)
- {
- // abort
- return false;
- }
-
- // If Linden estate, can only apply to "this" estate, not all estates
- // owned by NULL.
- if (LLPanelEstateInfo::isLindenEstate())
- {
- accessCoreConfirm(notification, response);
- }
- else
- {
- LLSD args;
- args["ALL_ESTATES"] = all_estates_text();
- LLNotificationsUtil::add(notification["payload"]["dialog_name"],
- args,
- notification["payload"],
- accessCoreConfirm);
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0)
+ {
+ // abort
+ return false;
+ }
+
+ // If Linden estate, can only apply to "this" estate, not all estates
+ // owned by NULL.
+ if (LLPanelEstateInfo::isLindenEstate())
+ {
+ accessCoreConfirm(notification, response);
+ }
+ else
+ {
+ LLSD args;
+ args["ALL_ESTATES"] = all_estates_text();
+ LLNotificationsUtil::add(notification["payload"]["dialog_name"],
+ args,
+ notification["payload"],
+ accessCoreConfirm);
+ }
+ return false;
}
// Used for both access add and remove operations, depending on the mOperationFlag
@@ -3356,133 +3657,133 @@ bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD
// static
bool LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
- U32 flags = originalFlags;
-
- LLViewerRegion* region = gAgent.getRegion();
-
- if (option == 2) // cancel
- {
- return false;
- }
- else if (option == 1)
- {
- // All estates, either than I own or manage for this owner.
- // This will be verified on simulator. JC
- if (!region) return false;
- if (region->getOwner() == gAgent.getID()
- || gAgent.isGodlike())
- {
- flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES;
- }
- else if (region->isEstateManager())
- {
- flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES;
- }
- }
-
- std::string names;
- U32 listed_names = 0;
- for (U32 i = 0; i < notification["payload"]["allowed_ids"].size(); ++i)
- {
- if (i + 1 != notification["payload"]["allowed_ids"].size())
- {
- flags |= ESTATE_ACCESS_NO_REPLY;
- }
- else
- {
- flags &= ~ESTATE_ACCESS_NO_REPLY;
- }
-
- const LLUUID id = notification["payload"]["allowed_ids"][i].asUUID();
- if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD)
- && region && (region->getOwner() == id))
- {
- LLNotificationsUtil::add("OwnerCanNotBeDenied");
- break;
- }
-
- sendEstateAccessDelta(flags, id);
-
- if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0)
- {
- // fill the name list for confirmation
- if (listed_names < MAX_LISTED_NAMES)
- {
- if (!names.empty())
- {
- names += ", ";
- }
- if (!notification["payload"]["allowed_names"][i]["display_name"].asString().empty())
- {
- names += notification["payload"]["allowed_names"][i]["display_name"].asString();
- }
- else
- { //try to get an agent name from cache
- LLAvatarName av_name;
- if (LLAvatarNameCache::get(id, &av_name))
- {
- names += av_name.getCompleteName();
- }
- }
-
- }
- listed_names++;
- }
- }
- if (listed_names > MAX_LISTED_NAMES)
- {
- LLSD args;
- args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES);
- names += " " + LLTrans::getString("AndNMore", args);
- }
-
- if (!names.empty()) // show the conirmation
- {
- LLSD args;
- args["AGENT"] = names;
-
- if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE))
- {
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
- }
- else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE))
- {
- args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
- }
-
- if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES)
- {
- args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates");
- }
- else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES)
- {
- args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates");
- }
- else
- {
- args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate");
- }
-
- bool single = (listed_names == 1);
- if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD))
- {
- LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args);
- }
- else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE))
- {
- LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args);
- }
- }
-
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (panel)
- {
- panel->setPendingUpdate(true);
- }
-
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
+ U32 flags = originalFlags;
+
+ LLViewerRegion* region = gAgent.getRegion();
+
+ if (option == 2) // cancel
+ {
+ return false;
+ }
+ else if (option == 1)
+ {
+ // All estates, either than I own or manage for this owner.
+ // This will be verified on simulator. JC
+ if (!region) return false;
+ if (region->getOwner() == gAgent.getID()
+ || gAgent.isGodlike())
+ {
+ flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES;
+ }
+ else if (region->isEstateManager())
+ {
+ flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES;
+ }
+ }
+
+ std::string names;
+ U32 listed_names = 0;
+ for (U32 i = 0; i < notification["payload"]["allowed_ids"].size(); ++i)
+ {
+ if (i + 1 != notification["payload"]["allowed_ids"].size())
+ {
+ flags |= ESTATE_ACCESS_NO_REPLY;
+ }
+ else
+ {
+ flags &= ~ESTATE_ACCESS_NO_REPLY;
+ }
+
+ const LLUUID id = notification["payload"]["allowed_ids"][i].asUUID();
+ if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD)
+ && region && (region->getOwner() == id))
+ {
+ LLNotificationsUtil::add("OwnerCanNotBeDenied");
+ break;
+ }
+
+ sendEstateAccessDelta(flags, id);
+
+ if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0)
+ {
+ // fill the name list for confirmation
+ if (listed_names < MAX_LISTED_NAMES)
+ {
+ if (!names.empty())
+ {
+ names += ", ";
+ }
+ if (!notification["payload"]["allowed_names"][i]["display_name"].asString().empty())
+ {
+ names += notification["payload"]["allowed_names"][i]["display_name"].asString();
+ }
+ else
+ { //try to get an agent name from cache
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(id, &av_name))
+ {
+ names += av_name.getCompleteName();
+ }
+ }
+
+ }
+ listed_names++;
+ }
+ }
+ if (listed_names > MAX_LISTED_NAMES)
+ {
+ LLSD args;
+ args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES);
+ names += " " + LLTrans::getString("AndNMore", args);
+ }
+
+ if (!names.empty()) // show the conirmation
+ {
+ LLSD args;
+ args["AGENT"] = names;
+
+ if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE))
+ {
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
+ }
+ else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE))
+ {
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
+ }
+
+ if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES)
+ {
+ args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates");
+ }
+ else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES)
+ {
+ args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates");
+ }
+ else
+ {
+ args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate");
+ }
+
+ bool single = (listed_names == 1);
+ if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD))
+ {
+ LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args);
+ }
+ else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE))
+ {
+ LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args);
+ }
+ }
+
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (panel)
+ {
+ panel->setPendingUpdate(true);
+ }
+
+ return false;
}
// key = "estateaccessdelta"
@@ -3493,164 +3794,164 @@ bool LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD
// static
void LLPanelEstateAccess::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id)
{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("EstateOwnerMessage");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("EstateOwnerMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
- msg->nextBlock("MethodData");
- msg->addString("Method", "estateaccessdelta");
- msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
+ msg->nextBlock("MethodData");
+ msg->addString("Method", "estateaccessdelta");
+ msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
- std::string buf;
- gAgent.getID().toString(buf);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buf);
+ std::string buf;
+ gAgent.getID().toString(buf);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
- buf = llformat("%u", flags);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buf);
+ buf = llformat("%u", flags);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
- agent_or_group_id.toString(buf);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buf);
+ agent_or_group_id.toString(buf);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
- gAgent.sendReliableMessage();
+ gAgent.sendReliableMessage();
}
void LLPanelEstateAccess::updateChild(LLUICtrl* child_ctrl)
{
- // Ensure appropriate state of the management ui.
- updateControls(gAgent.getRegion());
+ // Ensure appropriate state of the management ui.
+ updateControls(gAgent.getRegion());
}
void LLPanelEstateAccess::updateLists()
{
- std::string cap_url = gAgent.getRegionCapability("EstateAccess");
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url));
- }
+ std::string cap_url = gAgent.getRegionCapability("EstateAccess");
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url));
+ }
}
void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url)
{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
-
- LLNameListCtrl* allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
- if (allowed_agent_name_list && result.has("AllowedAgents"))
- {
- LLStringUtil::format_map_t args;
- args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size());
- args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
- std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args);
- panel->getChild<LLUICtrl>("allow_resident_label")->setValue(LLSD(msg));
-
- allowed_agent_name_list->clearSortOrder();
- allowed_agent_name_list->deleteAllItems();
- for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it)
- {
- LLUUID id = (*it)["id"].asUUID();
- allowed_agent_name_list->addNameItem(id);
- }
- allowed_agent_name_list->sortByName(TRUE);
- }
-
- LLNameListCtrl* banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
- if (banned_agent_name_list && result.has("BannedAgents"))
- {
- LLStringUtil::format_map_t args;
- args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size());
- args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
- std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
- panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
-
- banned_agent_name_list->clearSortOrder();
- banned_agent_name_list->deleteAllItems();
- for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it)
- {
- LLSD item;
- item["id"] = (*it)["id"].asUUID();
- LLSD& columns = item["columns"];
-
- columns[0]["column"] = "name"; // to be populated later
-
- columns[1]["column"] = "last_login_date";
- columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds
-
- std::string ban_date = (*it)["ban_date"].asString();
- columns[2]["column"] = "ban_date";
- columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : LLTrans::getString("na"); // server returns the "0000-00-00 00:00:00" date in case it doesn't know it
-
- columns[3]["column"] = "bannedby";
- LLUUID banning_id = (*it)["banning_id"].asUUID();
- LLAvatarName av_name;
- if (banning_id.isNull())
- {
- columns[3]["value"] = LLTrans::getString("na");
- }
- else if (LLAvatarNameCache::get(banning_id, &av_name))
- {
- columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached
- }
-
- banned_agent_name_list->addElement(item);
- }
- banned_agent_name_list->sortByName(TRUE);
- }
-
- LLNameListCtrl* allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
- if (allowed_group_name_list && result.has("AllowedGroups"))
- {
- LLStringUtil::format_map_t args;
- args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size());
- args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS);
- std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args);
- panel->getChild<LLUICtrl>("allow_group_label")->setValue(LLSD(msg));
-
- allowed_group_name_list->clearSortOrder();
- allowed_group_name_list->deleteAllItems();
- for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it)
- {
- LLUUID id = (*it)["id"].asUUID();
- allowed_group_name_list->addGroupNameItem(id);
- }
- allowed_group_name_list->sortByName(TRUE);
- }
-
- LLNameListCtrl* estate_manager_name_list = panel->getChild<LLNameListCtrl>("estate_manager_name_list");
- if (estate_manager_name_list && result.has("Managers"))
- {
- LLStringUtil::format_map_t args;
- args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size());
- args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
- std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
- panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
-
- estate_manager_name_list->clearSortOrder();
- estate_manager_name_list->deleteAllItems();
- for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it)
- {
- LLUUID id = (*it)["agent_id"].asUUID();
- estate_manager_name_list->addNameItem(id);
- }
- estate_manager_name_list->sortByName(TRUE);
- }
-
-
- panel->updateControls(gAgent.getRegion());
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+
+ LLNameListCtrl* allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
+ if (allowed_agent_name_list && result.has("AllowedAgents"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size());
+ args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
+ std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args);
+ panel->getChild<LLUICtrl>("allow_resident_label")->setValue(LLSD(msg));
+
+ allowed_agent_name_list->clearSortOrder();
+ allowed_agent_name_list->deleteAllItems();
+ for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it)
+ {
+ LLUUID id = (*it)["id"].asUUID();
+ allowed_agent_name_list->addNameItem(id);
+ }
+ allowed_agent_name_list->sortByName(TRUE);
+ }
+
+ LLNameListCtrl* banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
+ if (banned_agent_name_list && result.has("BannedAgents"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size());
+ args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_BANNED_IDS);
+ std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
+ panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
+
+ banned_agent_name_list->clearSortOrder();
+ banned_agent_name_list->deleteAllItems();
+ for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it)
+ {
+ LLSD item;
+ item["id"] = (*it)["id"].asUUID();
+ LLSD& columns = item["columns"];
+
+ columns[0]["column"] = "name"; // to be populated later
+
+ columns[1]["column"] = "last_login_date";
+ columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds
+
+ std::string ban_date = (*it)["ban_date"].asString();
+ columns[2]["column"] = "ban_date";
+ columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : LLTrans::getString("na"); // server returns the "0000-00-00 00:00:00" date in case it doesn't know it
+
+ columns[3]["column"] = "bannedby";
+ LLUUID banning_id = (*it)["banning_id"].asUUID();
+ LLAvatarName av_name;
+ if (banning_id.isNull())
+ {
+ columns[3]["value"] = LLTrans::getString("na");
+ }
+ else if (LLAvatarNameCache::get(banning_id, &av_name))
+ {
+ columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached
+ }
+
+ banned_agent_name_list->addElement(item);
+ }
+ banned_agent_name_list->sortByName(TRUE);
+ }
+
+ LLNameListCtrl* allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
+ if (allowed_group_name_list && result.has("AllowedGroups"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size());
+ args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS);
+ std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args);
+ panel->getChild<LLUICtrl>("allow_group_label")->setValue(LLSD(msg));
+
+ allowed_group_name_list->clearSortOrder();
+ allowed_group_name_list->deleteAllItems();
+ for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it)
+ {
+ LLUUID id = (*it)["id"].asUUID();
+ allowed_group_name_list->addGroupNameItem(id);
+ }
+ allowed_group_name_list->sortByName(TRUE);
+ }
+
+ LLNameListCtrl* estate_manager_name_list = panel->getChild<LLNameListCtrl>("estate_manager_name_list");
+ if (estate_manager_name_list && result.has("Managers"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size());
+ args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
+ std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
+ panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
+
+ estate_manager_name_list->clearSortOrder();
+ estate_manager_name_list->deleteAllItems();
+ for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it)
+ {
+ LLUUID id = (*it)["agent_id"].asUUID();
+ estate_manager_name_list->addNameItem(id);
+ }
+ estate_manager_name_list->sortByName(TRUE);
+ }
+
+
+ panel->updateControls(gAgent.getRegion());
}
//---------------------------------------------------------------------------
@@ -3658,76 +3959,76 @@ void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url)
//---------------------------------------------------------------------------
void LLPanelEstateAccess::onAllowedSearchEdit(const std::string& search_string)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLNameListCtrl* allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
- searchAgent(allowed_agent_name_list, search_string);
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLNameListCtrl* allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list");
+ searchAgent(allowed_agent_name_list, search_string);
}
void LLPanelEstateAccess::onAllowedGroupsSearchEdit(const std::string& search_string)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLNameListCtrl* allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
- searchAgent(allowed_group_name_list, search_string);
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLNameListCtrl* allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
+ searchAgent(allowed_group_name_list, search_string);
}
void LLPanelEstateAccess::onBannedSearchEdit(const std::string& search_string)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLNameListCtrl* banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
- searchAgent(banned_agent_name_list, search_string);
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLNameListCtrl* banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list");
+ searchAgent(banned_agent_name_list, search_string);
}
void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string)
{
- if (!listCtrl) return;
+ if (!listCtrl) return;
- if (!search_string.empty())
- {
- listCtrl->setSearchColumn(0); // name column
- listCtrl->searchItems(search_string, false, true);
- }
- else
- {
- listCtrl->deselectAllItems(TRUE);
- }
+ if (!search_string.empty())
+ {
+ listCtrl->setSearchColumn(0); // name column
+ listCtrl->searchItems(search_string, false, true);
+ }
+ else
+ {
+ listCtrl->deselectAllItems(TRUE);
+ }
}
void LLPanelEstateAccess::copyListToClipboard(std::string list_name)
{
- LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
- if (!panel) return;
- LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_name);
- if (!name_list) return;
-
- std::vector<LLScrollListItem*> list_vector = name_list->getAllData();
- if (list_vector.size() == 0) return;
-
- LLSD::String list_to_copy;
- for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
- iter != list_vector.end();
- iter++)
- {
- LLScrollListItem *item = (*iter);
- if (item)
- {
- list_to_copy += item->getColumn(0)->getValue().asString();
- }
- if (std::next(iter) != list_vector.end())
- {
- list_to_copy += "\n";
- }
- }
-
- LLClipboard::instance().copyToClipboard(utf8str_to_wstring(list_to_copy), 0, list_to_copy.length());
+ LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess();
+ if (!panel) return;
+ LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_name);
+ if (!name_list) return;
+
+ std::vector<LLScrollListItem*> list_vector = name_list->getAllData();
+ if (list_vector.size() == 0) return;
+
+ LLSD::String list_to_copy;
+ for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
+ iter != list_vector.end();
+ iter++)
+ {
+ LLScrollListItem *item = (*iter);
+ if (item)
+ {
+ list_to_copy += item->getColumn(0)->getValue().asString();
+ }
+ if (std::next(iter) != list_vector.end())
+ {
+ list_to_copy += "\n";
+ }
+ }
+
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(list_to_copy), 0, list_to_copy.length());
}
bool LLPanelEstateAccess::refreshFromRegion(LLViewerRegion* region)
{
- updateLists();
- return LLPanelRegionInfo::refreshFromRegion(region);
+ updateLists();
+ return LLPanelRegionInfo::refreshFromRegion(region);
}
//=========================================================================
@@ -3863,10 +4164,10 @@ void LLPanelRegionEnvironment::onChkAllowOverride(bool value)
if (LLPanelEstateInfo::isLindenEstate())
notification = "ChangeLindenEstate";
- LLSD args;
- args["ESTATENAME"] = LLEstateInfoModel::instance().getName();
- LLNotification::Params params(notification);
- params.substitutions(args);
+ LLSD args;
+ args["ESTATENAME"] = LLEstateInfoModel::instance().getName();
+ LLNotification::Params params(notification);
+ params.substitutions(args);
params.functor.function([this](const LLSD& notification, const LLSD& response) { confirmUpdateEstateEnvironment(notification, response); });
if (!value || LLPanelEstateInfo::isLindenEstate())
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index d235877988..da17212016 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfloaterregioninfo.h
* @author Aaron Brashears
* @brief Declaration of the region info and controls floater and panels.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,6 +36,7 @@
#include "llpanel.h"
#include "llextendedstatus.h"
#include "llpanelenvironment.h"
+#include "llvlcomposition.h"
#include "lleventcoro.h"
@@ -55,6 +56,7 @@ class LLRadioGroup;
class LLSliderCtrl;
class LLSpinCtrl;
class LLTextBox;
+class LLTextureCtrl;
class LLPanelRegionGeneralInfo;
class LLPanelRegionDebugInfo;
@@ -71,58 +73,58 @@ class LLEventTimer;
class LLFloaterRegionInfo : public LLFloater
{
- friend class LLFloaterReg;
+ friend class LLFloaterReg;
public:
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ BOOL postBuild();
-
- static void processEstateOwnerRequest(LLMessageSystem* msg, void**);
+ void onOpen(const LLSD& key) override;
+ void onClose(bool app_quitting) override;
+ BOOL postBuild() override;
- // get and process region info if necessary.
- static void processRegionInfo(LLMessageSystem* msg);
+ static void processEstateOwnerRequest(LLMessageSystem* msg, void**);
- static const LLUUID& getLastInvoice() { return sRequestInvoice; }
- static void nextInvoice() { sRequestInvoice.generate(); }
- //static S32 getSerial() { return sRequestSerial; }
- //static void incrementSerial() { sRequestSerial++; }
+ // get and process region info if necessary.
+ static void processRegionInfo(LLMessageSystem* msg);
- static LLPanelEstateInfo* getPanelEstate();
- static LLPanelEstateAccess* getPanelAccess();
- static LLPanelEstateCovenant* getPanelCovenant();
- static LLPanelRegionTerrainInfo* getPanelRegionTerrain();
- static LLPanelRegionExperiences* getPanelExperiences();
- static LLPanelRegionGeneralInfo* getPanelGeneral();
- static LLPanelRegionEnvironment* getPanelEnvironment();
+ static const LLUUID& getLastInvoice() { return sRequestInvoice; }
+ static void nextInvoice() { sRequestInvoice.generate(); }
+ //static S32 getSerial() { return sRequestSerial; }
+ //static void incrementSerial() { sRequestSerial++; }
- // from LLPanel
- virtual void refresh();
+ static LLPanelEstateInfo* getPanelEstate();
+ static LLPanelEstateAccess* getPanelAccess();
+ static LLPanelEstateCovenant* getPanelCovenant();
+ static LLPanelRegionTerrainInfo* getPanelRegionTerrain();
+ static LLPanelRegionExperiences* getPanelExperiences();
+ static LLPanelRegionGeneralInfo* getPanelGeneral();
+ static LLPanelRegionEnvironment* getPanelEnvironment();
- void onRegionChanged();
- void requestRegionInfo();
- void enableTopButtons();
- void disableTopButtons();
+ // from LLPanel
+ void refresh() override;
+
+ void onRegionChanged();
+ void requestRegionInfo();
+ void enableTopButtons();
+ void disableTopButtons();
private:
-
- LLFloaterRegionInfo(const LLSD& seed);
- ~LLFloaterRegionInfo();
+
+ LLFloaterRegionInfo(const LLSD& seed);
+ ~LLFloaterRegionInfo();
protected:
- void onTabSelected(const LLSD& param);
- void disableTabCtrls();
- void refreshFromRegion(LLViewerRegion* region);
- void onGodLevelChange(U8 god_level);
-
- // member data
- LLTabContainer* mTab;
- typedef std::vector<LLPanelRegionInfo*> info_panels_t;
- info_panels_t mInfoPanels;
+ void onTabSelected(const LLSD& param);
+ void disableTabCtrls();
+ void refreshFromRegion(LLViewerRegion* region);
+ void onGodLevelChange(U8 god_level);
+
+ // member data
+ 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;
+ //static S32 sRequestSerial; // serial # of last EstateOwnerRequest
+ static LLUUID sRequestInvoice;
private:
LLAgent::god_level_change_slot_t mGodLevelChangeSlot;
@@ -134,42 +136,42 @@ private:
class LLPanelRegionInfo : public LLPanel
{
public:
- LLPanelRegionInfo();
-
- void onBtnSet();
- void onChangeChildCtrl(LLUICtrl* ctrl);
- void onChangeAnything();
- static void onChangeText(LLLineEditor* caller, void* user_data);
-
- virtual bool refreshFromRegion(LLViewerRegion* region);
- virtual bool estateUpdate(LLMessageSystem* msg) { return true; }
-
- virtual BOOL postBuild();
- virtual void updateChild(LLUICtrl* child_ctrl);
-
- void enableButton(const std::string& btn_name, BOOL enable = TRUE);
- void disableButton(const std::string& btn_name);
-
- void onClickManageTelehub();
-
+ LLPanelRegionInfo();
+
+ void onBtnSet();
+ void onChangeChildCtrl(LLUICtrl* ctrl);
+ void onChangeAnything();
+ static void onChangeText(LLLineEditor* caller, void* user_data);
+
+ virtual bool refreshFromRegion(LLViewerRegion* region);
+ virtual bool estateUpdate(LLMessageSystem* msg) { return true; }
+
+ BOOL postBuild() override;
+ virtual void updateChild(LLUICtrl* child_ctrl);
+
+ void enableButton(const std::string& btn_name, BOOL enable = TRUE);
+ void disableButton(const std::string& btn_name);
+
+ void onClickManageTelehub();
+
protected:
- void initCtrl(const std::string& name);
-
- // Returns TRUE if update sent and apply button should be
- // disabled.
- virtual BOOL sendUpdate() { return TRUE; }
-
- typedef std::vector<std::string> strings_t;
- //typedef std::vector<U32> integers_t;
- void sendEstateOwnerMessage(
- LLMessageSystem* msg,
- const std::string& request,
- const LLUUID& invoice,
- const strings_t& strings);
-
-
- // member data
- LLHost mHost;
+ void initCtrl(const std::string& name);
+
+ // Returns TRUE if update sent and apply button should be
+ // disabled.
+ virtual BOOL sendUpdate() { return TRUE; }
+
+ typedef std::vector<std::string> strings_t;
+ //typedef std::vector<U32> integers_t;
+ void sendEstateOwnerMessage(
+ LLMessageSystem* msg,
+ const std::string& request,
+ const LLUUID& invoice,
+ const strings_t& strings);
+
+
+ // member data
+ LLHost mHost;
};
/////////////////////////////////////////////////////////////////////////////
@@ -178,31 +180,30 @@ protected:
class LLPanelRegionGeneralInfo : public LLPanelRegionInfo
{
-
+
public:
- LLPanelRegionGeneralInfo()
- : LLPanelRegionInfo() {}
- ~LLPanelRegionGeneralInfo() {}
-
- virtual bool refreshFromRegion(LLViewerRegion* region);
-
- // LLPanel
- virtual BOOL postBuild();
-
- void onBtnSet();
- void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;}
+ LLPanelRegionGeneralInfo()
+ : LLPanelRegionInfo() {}
+ ~LLPanelRegionGeneralInfo() {}
+
+ bool refreshFromRegion(LLViewerRegion* region) override;
+
+ BOOL postBuild() override;
+
+ void onBtnSet();
+ void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;}
protected:
- virtual BOOL sendUpdate();
- void onClickKick();
- void onKickCommit(const uuid_vec_t& ids);
- static void onClickKickAll(void* userdata);
- bool onKickAllCommit(const LLSD& notification, const LLSD& response);
- static void onClickMessage(void* userdata);
- bool onMessageCommit(const LLSD& notification, const LLSD& response);
- bool onChangeObjectBonus(const LLSD& notification, const LLSD& response);
+ BOOL sendUpdate() override;
+ void onClickKick();
+ void onKickCommit(const uuid_vec_t& ids);
+ static void onClickKickAll(void* userdata);
+ bool onKickAllCommit(const LLSD& notification, const LLSD& response);
+ static void onClickMessage(void* userdata);
+ bool onMessageCommit(const LLSD& notification, const LLSD& response);
+ bool onChangeObjectBonus(const LLSD& notification, const LLSD& response);
- F32 mObjBonusFactor;
+ F32 mObjBonusFactor;
};
@@ -211,63 +212,73 @@ protected:
class LLPanelRegionDebugInfo : public LLPanelRegionInfo
{
public:
- LLPanelRegionDebugInfo()
- : LLPanelRegionInfo(), mTargetAvatar() {}
- ~LLPanelRegionDebugInfo() {}
- // LLPanel
- virtual BOOL postBuild();
-
- virtual bool refreshFromRegion(LLViewerRegion* region);
-
+ LLPanelRegionDebugInfo()
+ : LLPanelRegionInfo(), mTargetAvatar() {}
+ ~LLPanelRegionDebugInfo() {}
+
+ BOOL postBuild() override;
+
+ bool refreshFromRegion(LLViewerRegion* region) override;
+
protected:
- virtual BOOL sendUpdate();
-
- void onClickChooseAvatar();
- void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
- static void onClickReturn(void *);
- bool callbackReturn(const LLSD& notification, const LLSD& response);
- static void onClickTopColliders(void*);
- static void onClickTopScripts(void*);
- static void onClickRestart(void* data);
- bool callbackRestart(const LLSD& notification, const LLSD& response);
- static void onClickCancelRestart(void* data);
- static void onClickDebugConsole(void* data);
-
+ BOOL sendUpdate() override;
+
+ void onClickChooseAvatar();
+ void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
+ static void onClickReturn(void *);
+ bool callbackReturn(const LLSD& notification, const LLSD& response);
+ static void onClickTopColliders(void*);
+ static void onClickTopScripts(void*);
+ static void onClickRestart(void* data);
+ bool callbackRestart(const LLSD& notification, const LLSD& response);
+ static void onClickCancelRestart(void* data);
+ static void onClickDebugConsole(void* data);
+
private:
- LLUUID mTargetAvatar;
+ LLUUID mTargetAvatar;
};
/////////////////////////////////////////////////////////////////////////////
class LLPanelRegionTerrainInfo : public LLPanelRegionInfo
{
- LOG_CLASS(LLPanelRegionTerrainInfo);
+ LOG_CLASS(LLPanelRegionTerrainInfo);
public:
- LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {}
- ~LLPanelRegionTerrainInfo() {}
-
- virtual BOOL postBuild(); // LLPanel
+ LLPanelRegionTerrainInfo();
+ ~LLPanelRegionTerrainInfo() {}
+
+ BOOL postBuild() override;
+
+ bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator
+ void setEnvControls(bool available); // Whether environment settings are available for this region
+
+ bool validateTextureSizes();
+ bool validateMaterials();
+ BOOL validateTextureHeights();
+
+ //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button
+
+ void onSelectMaterialType();
+ void updateForMaterialType();
+
+ static void onClickDownloadRaw(void*);
+ static void onClickUploadRaw(void*);
+ static void onClickBakeTerrain(void*);
+ bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
+ bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
- virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator
- void setEnvControls(bool available); // Whether environment settings are available for this region
-
- BOOL validateTextureSizes();
- BOOL validateTextureHeights();
-
- //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button
-
- virtual BOOL sendUpdate();
-
- static void onClickDownloadRaw(void*);
- static void onClickUploadRaw(void*);
- static void onClickBakeTerrain(void*);
- bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
- bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
+protected:
+ BOOL sendUpdate() override;
private:
- bool mConfirmedTextureHeights;
- bool mAskedTextureHeights;
+ bool mConfirmedTextureHeights;
+ bool mAskedTextureHeights;
+ LLCheckBoxCtrl* mMaterialTypeCtrl = nullptr;
+ LLTextureCtrl* mTextureDetailCtrl[LLTerrainMaterials::ASSET_COUNT];
+ LLTextureCtrl* mMaterialDetailCtrl[LLTerrainMaterials::ASSET_COUNT];
+ LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT];
+ LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT];
};
/////////////////////////////////////////////////////////////////////////////
@@ -275,60 +286,59 @@ private:
class LLPanelEstateInfo : public LLPanelRegionInfo
{
public:
- static void initDispatch(LLDispatcher& dispatch);
-
- void onChangeFixedSun();
- void onChangeUseGlobalTime();
- void onChangeAccessOverride();
-
- void onClickEditSky();
- void onClickEditSkyHelp();
- void onClickEditDayCycle();
- void onClickEditDayCycleHelp();
-
- void onClickKickUser();
-
-
- bool kickUserConfirm(const LLSD& notification, const LLSD& response);
-
- void onKickUserCommit(const uuid_vec_t& ids);
- static void onClickMessageEstate(void* data);
- bool onMessageCommit(const LLSD& notification, const LLSD& response);
-
- LLPanelEstateInfo();
- ~LLPanelEstateInfo() {}
-
- void updateControls(LLViewerRegion* region);
-
- static void updateEstateName(const std::string& name);
- static void updateEstateOwnerName(const std::string& name);
-
- virtual bool refreshFromRegion(LLViewerRegion* region);
- virtual bool estateUpdate(LLMessageSystem* msg);
-
- // LLPanel
- virtual BOOL postBuild();
- virtual void updateChild(LLUICtrl* child_ctrl);
- virtual void refresh();
-
- void refreshFromEstate();
-
- static bool isLindenEstate();
-
- const std::string getOwnerName() const;
- void setOwnerName(const std::string& name);
+ static void initDispatch(LLDispatcher& dispatch);
+
+ void onChangeFixedSun();
+ void onChangeUseGlobalTime();
+ void onChangeAccessOverride();
+
+ void onClickEditSky();
+ void onClickEditSkyHelp();
+ void onClickEditDayCycle();
+ void onClickEditDayCycleHelp();
+
+ void onClickKickUser();
+
+
+ bool kickUserConfirm(const LLSD& notification, const LLSD& response);
+
+ void onKickUserCommit(const uuid_vec_t& ids);
+ static void onClickMessageEstate(void* data);
+ bool onMessageCommit(const LLSD& notification, const LLSD& response);
+
+ LLPanelEstateInfo();
+ ~LLPanelEstateInfo() {}
+
+ void updateControls(LLViewerRegion* region);
+
+ static void updateEstateName(const std::string& name);
+ static void updateEstateOwnerName(const std::string& name);
+
+ bool refreshFromRegion(LLViewerRegion* region) override;
+ bool estateUpdate(LLMessageSystem* msg) override;
+
+ BOOL postBuild() override;
+ void updateChild(LLUICtrl* child_ctrl) override;
+ void refresh() override;
+
+ void refreshFromEstate();
+
+ static bool isLindenEstate();
+
+ const std::string getOwnerName() const;
+ void setOwnerName(const std::string& name);
protected:
- virtual BOOL sendUpdate();
- // confirmation dialog callback
- bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
-
- void commitEstateAccess();
- void commitEstateManagers();
+ BOOL sendUpdate() override;
+ // confirmation dialog callback
+ bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
- BOOL checkSunHourSlider(LLUICtrl* child_ctrl);
+ void commitEstateAccess();
+ void commitEstateManagers();
+
+ BOOL checkSunHourSlider(LLUICtrl* child_ctrl);
- U32 mEstateID;
+ U32 mEstateID;
};
/////////////////////////////////////////////////////////////////////////////
@@ -336,60 +346,59 @@ protected:
class LLPanelEstateCovenant : public LLPanelRegionInfo
{
public:
- LLPanelEstateCovenant();
- ~LLPanelEstateCovenant() {}
-
- // LLPanel
- virtual BOOL postBuild();
- virtual void updateChild(LLUICtrl* child_ctrl);
- virtual bool refreshFromRegion(LLViewerRegion* region);
- virtual bool estateUpdate(LLMessageSystem* msg);
-
- // LLView overrides
- BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type,
- void *cargo_data, EAcceptance *accept,
- std::string& tooltip_msg);
- static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response);
- static void resetCovenantID(void* userdata);
- static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
- void sendChangeCovenantID(const LLUUID &asset_id);
- void loadInvItem(LLInventoryItem *itemp);
- static void onLoadComplete(const LLUUID& asset_uuid,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status);
-
- // Accessor functions
- static void updateCovenantText(const std::string& string, const LLUUID& asset_id);
- static void updateEstateName(const std::string& name);
- static void updateLastModified(const std::string& text);
- static void updateEstateOwnerName(const std::string& name);
-
- const LLUUID& getCovenantID() const { return mCovenantID; }
- void setCovenantID(const LLUUID& id) { mCovenantID = id; }
- std::string getEstateName() const;
- void setEstateName(const std::string& name);
- std::string getOwnerName() const;
- void setOwnerName(const std::string& name);
- void setCovenantTextEditor(const std::string& text);
-
- typedef enum e_asset_status
- {
- ASSET_ERROR,
- ASSET_UNLOADED,
- ASSET_LOADING,
- ASSET_LOADED
- } EAssetStatus;
+ LLPanelEstateCovenant();
+ ~LLPanelEstateCovenant() {}
+
+ BOOL postBuild() override;
+ void updateChild(LLUICtrl* child_ctrl) override;
+ bool refreshFromRegion(LLViewerRegion* region) override;
+ bool estateUpdate(LLMessageSystem* msg) override;
+
+ // LLView overrides
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type,
+ void *cargo_data, EAcceptance *accept,
+ std::string& tooltip_msg) override;
+ static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response);
+ static void resetCovenantID(void* userdata);
+ static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
+ void sendChangeCovenantID(const LLUUID &asset_id);
+ void loadInvItem(LLInventoryItem *itemp);
+ static void onLoadComplete(const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status);
+
+ // Accessor functions
+ static void updateCovenantText(const std::string& string, const LLUUID& asset_id);
+ static void updateEstateName(const std::string& name);
+ static void updateLastModified(const std::string& text);
+ static void updateEstateOwnerName(const std::string& name);
+
+ const LLUUID& getCovenantID() const { return mCovenantID; }
+ void setCovenantID(const LLUUID& id) { mCovenantID = id; }
+ std::string getEstateName() const;
+ void setEstateName(const std::string& name);
+ std::string getOwnerName() const;
+ void setOwnerName(const std::string& name);
+ void setCovenantTextEditor(const std::string& text);
+
+ typedef enum e_asset_status
+ {
+ ASSET_ERROR,
+ ASSET_UNLOADED,
+ ASSET_LOADING,
+ ASSET_LOADED
+ } EAssetStatus;
protected:
- virtual BOOL sendUpdate();
- LLTextBox* mEstateNameText;
- LLTextBox* mEstateOwnerText;
- LLTextBox* mLastModifiedText;
- // CovenantID from sim
- LLUUID mCovenantID;
- LLViewerTextEditor* mEditor;
- EAssetStatus mAssetStatus;
+ BOOL sendUpdate() override;
+ LLTextBox* mEstateNameText;
+ LLTextBox* mEstateOwnerText;
+ LLTextBox* mLastModifiedText;
+ // CovenantID from sim
+ LLUUID mCovenantID;
+ LLViewerTextEditor* mEditor;
+ EAssetStatus mAssetStatus;
};
/////////////////////////////////////////////////////////////////////////////
@@ -400,93 +409,96 @@ class LLPanelRegionExperiences : public LLPanelRegionInfo
LOG_CLASS(LLPanelRegionExperiences);
public:
- LLPanelRegionExperiences(){}
- /*virtual*/ BOOL postBuild();
- virtual BOOL sendUpdate();
+ LLPanelRegionExperiences(){}
+ BOOL postBuild() override;
+
+ static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response);
+ static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id);
- static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response);
- static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id);
+ static void infoCallback(LLHandle<LLPanelRegionExperiences> handle, const LLSD& content);
+ bool refreshFromRegion(LLViewerRegion* region) override;
+ void sendPurchaseRequest()const;
+ void processResponse( const LLSD& content );
+
+protected:
+ BOOL sendUpdate() override;
- static void infoCallback(LLHandle<LLPanelRegionExperiences> handle, const LLSD& content);
- bool refreshFromRegion(LLViewerRegion* region);
- void sendPurchaseRequest()const;
- void processResponse( const LLSD& content );
private:
- void refreshRegionExperiences();
+ void refreshRegionExperiences();
static std::string regionCapabilityQuery(LLViewerRegion* region, const std::string &cap);
- LLPanelExperienceListEditor* setupList(const char* control_name, U32 add_id, U32 remove_id);
- static LLSD addIds( LLPanelExperienceListEditor* panel );
+ LLPanelExperienceListEditor* setupList(const char* control_name, U32 add_id, U32 remove_id);
+ static LLSD addIds( LLPanelExperienceListEditor* panel );
- void itemChanged(U32 event_type, const LLUUID& id);
+ void itemChanged(U32 event_type, const LLUUID& id);
- LLPanelExperienceListEditor* mTrusted;
- LLPanelExperienceListEditor* mAllowed;
- LLPanelExperienceListEditor* mBlocked;
- LLUUID mDefaultExperience;
+ LLPanelExperienceListEditor* mTrusted;
+ LLPanelExperienceListEditor* mAllowed;
+ LLPanelExperienceListEditor* mBlocked;
+ LLUUID mDefaultExperience;
};
class LLPanelEstateAccess : public LLPanelRegionInfo
{
- LOG_CLASS(LLPanelEstateAccess);
+ LOG_CLASS(LLPanelEstateAccess);
public:
- LLPanelEstateAccess();
+ LLPanelEstateAccess();
- virtual BOOL postBuild();
- virtual void updateChild(LLUICtrl* child_ctrl);
+ BOOL postBuild() override;
+ void updateChild(LLUICtrl* child_ctrl) override;
- void updateControls(LLViewerRegion* region);
- void updateLists();
+ void updateControls(LLViewerRegion* region);
+ void updateLists();
- void setPendingUpdate(bool pending) { mPendingUpdate = pending; }
- bool getPendingUpdate() { return mPendingUpdate; }
+ void setPendingUpdate(bool pending) { mPendingUpdate = pending; }
+ bool getPendingUpdate() { return mPendingUpdate; }
- virtual bool refreshFromRegion(LLViewerRegion* region);
+ bool refreshFromRegion(LLViewerRegion* region) override;
private:
- void onClickAddAllowedAgent();
- void onClickRemoveAllowedAgent();
- void onClickCopyAllowedList();
- void onClickAddAllowedGroup();
- void onClickRemoveAllowedGroup();
- void onClickCopyAllowedGroupList();
- void onClickAddBannedAgent();
- void onClickRemoveBannedAgent();
+ void onClickAddAllowedAgent();
+ void onClickRemoveAllowedAgent();
+ void onClickCopyAllowedList();
+ void onClickAddAllowedGroup();
+ void onClickRemoveAllowedGroup();
+ void onClickCopyAllowedGroupList();
+ void onClickAddBannedAgent();
+ void onClickRemoveBannedAgent();
void onClickCopyBannedList();
- void onClickAddEstateManager();
- void onClickRemoveEstateManager();
- void onAllowedSearchEdit(const std::string& search_string);
- void onAllowedGroupsSearchEdit(const std::string& search_string);
- void onBannedSearchEdit(const std::string& search_string);
-
- // Group picker callback is different, can't use core methods below
- bool addAllowedGroup(const LLSD& notification, const LLSD& response);
- void addAllowedGroup2(LLUUID id);
+ void onClickAddEstateManager();
+ void onClickRemoveEstateManager();
+ void onAllowedSearchEdit(const std::string& search_string);
+ void onAllowedGroupsSearchEdit(const std::string& search_string);
+ void onBannedSearchEdit(const std::string& search_string);
+
+ // Group picker callback is different, can't use core methods below
+ bool addAllowedGroup(const LLSD& notification, const LLSD& response);
+ void addAllowedGroup2(LLUUID id);
- // Core methods for all above add/remove button clicks
- static void accessAddCore(U32 operation_flag, const std::string& dialog_name);
- static bool accessAddCore2(const LLSD& notification, const LLSD& response);
- static void accessAddCore3(const uuid_vec_t& ids, std::vector<LLAvatarName> names, void* data);
+ // Core methods for all above add/remove button clicks
+ static void accessAddCore(U32 operation_flag, const std::string& dialog_name);
+ static bool accessAddCore2(const LLSD& notification, const LLSD& response);
+ static void accessAddCore3(const uuid_vec_t& ids, std::vector<LLAvatarName> names, void* data);
- static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name);
- static bool accessRemoveCore2(const LLSD& notification, const LLSD& response);
+ static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name);
+ static bool accessRemoveCore2(const LLSD& notification, const LLSD& response);
- // used for both add and remove operations
- static bool accessCoreConfirm(const LLSD& notification, const LLSD& response);
+ // used for both add and remove operations
+ static bool accessCoreConfirm(const LLSD& notification, const LLSD& response);
- // Send the actual EstateOwnerRequest "estateaccessdelta" message
- static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id);
+ // Send the actual EstateOwnerRequest "estateaccessdelta" message
+ static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id);
- static void requestEstateGetAccessCoro(std::string url);
+ static void requestEstateGetAccessCoro(std::string url);
- void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string);
- void copyListToClipboard(std::string list_name);
+ void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string);
+ void copyListToClipboard(std::string list_name);
- bool mPendingUpdate;
- BOOL mCtrlsEnabled;
+ bool mPendingUpdate;
+ BOOL mCtrlsEnabled;
};
#endif
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index b36c302a67..4c9dc8f7cd 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -58,8 +58,6 @@ LLGLTFMaterialList::modify_queue_t LLGLTFMaterialList::sModifyQueue;
LLGLTFMaterialList::apply_queue_t LLGLTFMaterialList::sApplyQueue;
LLSD LLGLTFMaterialList::sUpdates;
-const LLUUID LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID("968cbad0-4dad-d64e-71b5-72bf13ad051a");
-
#ifdef SHOW_ASSERT
// return true if given data is (probably) valid update message for ModifyMaterialParams capability
static bool is_valid_update(const LLSD& data)
@@ -78,7 +76,7 @@ static bool is_valid_update(const LLSD& data)
++count;
}
else
- {
+ {
LL_WARNS() << "Missing required parameter: object_id" << LL_ENDL;
return false;
}
@@ -98,7 +96,7 @@ static bool is_valid_update(const LLSD& data)
++count;
}
else
- {
+ {
LL_WARNS() << "Missing required parameter: side" << LL_ENDL;
return false;
}
@@ -124,7 +122,7 @@ static bool is_valid_update(const LLSD& data)
}
if (count < 3)
- {
+ {
LL_WARNS() << "Only specified object_id and side, update won't actually change anything and is just noise" << LL_ENDL;
return false;
}
@@ -178,7 +176,7 @@ void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::s
LLSDSerialize::fromNotation(data, str, data_in.length());
const LLHost& host = msg->getSender();
-
+
LLViewerRegion* region = LLWorld::instance().getRegion(host);
llassert(region);
@@ -204,7 +202,7 @@ void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::s
bool has_te[MAX_TES] = { false };
if (tes.isArray()) // NOTE: if no "te" array exists, this is a malformed message (null out all overrides will come in as an empty te array)
- {
+ {
LLGLTFOverrideCacheEntry cache;
cache.mLocalId = local_id;
cache.mObjectId = id;
@@ -247,6 +245,7 @@ void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::s
}
region->cacheFullUpdateGLTFOverride(cache);
+ LL_DEBUGS("GLTF") << "GLTF Material Override: " << cache.mObjectId << " " << cache.mLocalId << " " << cache.mRegionHandle << " (sides:" << (cache.mSides.size()) << ")" << LL_ENDL;
}
}
@@ -256,7 +255,7 @@ void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFM
{
#if 0
override_list_t& overrides = mQueuedOverrides[id];
-
+
if (overrides.size() < side + 1)
{
overrides.resize(side + 1);
@@ -376,7 +375,7 @@ void LLGLTFMaterialList::queueUpdate(const LLSD& data)
{
sUpdates = LLSD::emptyArray();
}
-
+
sUpdates[sUpdates.size()] = data;
}
@@ -396,7 +395,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;
-
+
if (e.has_override)
{
data[i]["gltf_json"] = e.override_data.asJSON();
@@ -471,7 +470,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
if (status != LL_ERR_NOERR)
{
LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
- asset_data->mMaterial->materialComplete();
+ asset_data->mMaterial->materialComplete(false);
delete asset_data;
}
else
@@ -556,7 +555,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL;
}
- asset_data->mMaterial->materialComplete();
+ asset_data->mMaterial->materialComplete(true);
delete asset_data;
});
@@ -582,7 +581,7 @@ LLFetchedGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, onAssetLoadComplete, (void*)user_data);
}
-
+
return mat;
}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index c1e0dd0a64..6eab86ff0a 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -40,8 +40,6 @@ class LLGLTFOverrideCacheEntry;
class LLGLTFMaterialList
{
public:
- static const LLUUID BLANK_MATERIAL_ASSET_ID;
-
LLGLTFMaterialList() {}
@@ -81,14 +79,14 @@ public:
static void flushUpdates(void(*done_callback)(bool) = nullptr);
static void addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side));
-
+
// Queue an explicit LLSD ModifyMaterialParams update apply given override data
// overrides -- LLSD map (or array of maps) in the format:
// object_id UUID(required) id of object
// side integer(required) TE index of face to set, or -1 for all faces
// gltf_json string(optional) override data to set, empty string nulls out override data, omissions of this parameter keeps existing data
// asset_id UUID(optional) id of material asset to set, omission of this parameter keeps existing material asset id
- //
+ //
// NOTE: Unless you already have a gltf_json string you want to send, strongly prefer using queueModify
// If the queue/flush API is insufficient, extend it.
static void queueUpdate(const LLSD& data);
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
new file mode 100644
index 0000000000..1c39f1ae7d
--- /dev/null
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -0,0 +1,590 @@
+/**
+ * @file llgltfmaterialpreviewmgr.cpp
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 "llgltfmaterialpreviewmgr.h"
+
+#include <memory>
+#include <vector>
+
+#include "llavatarappearancedefines.h"
+#include "llenvironment.h"
+#include "llselectmgr.h"
+#include "llviewercamera.h"
+#include "llviewercontrol.h"
+#include "llviewerobject.h"
+#include "llviewershadermgr.h"
+#include "llviewertexturelist.h"
+#include "llviewerwindow.h"
+#include "llvolumemgr.h"
+#include "pipeline.h"
+
+LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
+
+namespace
+{
+ constexpr S32 FULLY_LOADED = 0;
+ constexpr S32 NOT_LOADED = 99;
+};
+
+LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels()
+{
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ levels[i] = NOT_LOADED;
+ }
+}
+
+bool LLGLTFPreviewTexture::MaterialLoadLevels::isFullyLoaded()
+{
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (levels[i] != FULLY_LOADED) { return false; }
+ }
+ return true;
+}
+
+S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i)
+{
+ llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
+ return levels[i];
+}
+
+const S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) const
+{
+ llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
+ return levels[i];
+}
+
+bool LLGLTFPreviewTexture::MaterialLoadLevels::operator<(const MaterialLoadLevels& other) const
+{
+ bool less = false;
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (((*this)[i] > other[i])) { return false; }
+ less = less || ((*this)[i] < other[i]);
+ }
+ return less;
+}
+
+bool LLGLTFPreviewTexture::MaterialLoadLevels::operator>(const MaterialLoadLevels& other) const
+{
+ bool great = false;
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (((*this)[i] < other[i])) { return false; }
+ great = great || ((*this)[i] > other[i]);
+ }
+ return great;
+}
+
+namespace
+{
+ void fetch_texture_for_ui(LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
+ {
+ if (!img && id.notNull())
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ if (obj)
+ {
+ LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
+ img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+ }
+ }
+ else
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
+ }
+ if (img)
+ {
+ img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ img->forceToSaveRawImage(0);
+ }
+ };
+
+ // *NOTE: Does not use the same conventions as texture discard level. Lower is better.
+ S32 get_texture_load_level(const LLPointer<LLViewerFetchedTexture>& texture)
+ {
+ if (!texture) { return FULLY_LOADED; }
+ const S32 raw_level = texture->getDiscardLevel();
+ if (raw_level < 0) { return NOT_LOADED; }
+ return raw_level;
+ }
+
+ LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material)
+ {
+ llassert(!material.isFetching());
+
+ using MaterialTextures = LLPointer<LLViewerFetchedTexture>*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
+
+ MaterialTextures textures;
+
+ textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = &material.mBaseColorTexture;
+ textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = &material.mNormalTexture;
+ textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = &material.mMetallicRoughnessTexture;
+ textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = &material.mEmissiveTexture;
+
+ LLGLTFPreviewTexture::MaterialLoadLevels levels;
+
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ fetch_texture_for_ui(*textures[i], material.mTextureId[i]);
+ levels[i] = get_texture_load_level(*textures[i]);
+ }
+
+ return levels;
+ }
+
+ // Is the material loaded enough to start rendering a preview?
+ bool is_material_loaded_enough_for_ui(LLFetchedGLTFMaterial& material)
+ {
+ if (material.isFetching())
+ {
+ return false;
+ }
+
+ LLGLTFPreviewTexture::MaterialLoadLevels levels = get_material_load_levels(material);
+
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (levels[i] == NOT_LOADED)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}; // namespace
+
+LLGLTFPreviewTexture::LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width)
+ : LLViewerDynamicTexture(width, width, 4, EOrder::ORDER_MIDDLE, FALSE)
+ , mGLTFMaterial(material)
+{
+}
+
+// static
+LLPointer<LLGLTFPreviewTexture> LLGLTFPreviewTexture::create(LLPointer<LLFetchedGLTFMaterial> material)
+{
+ return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH);
+}
+
+BOOL LLGLTFPreviewTexture::needsRender()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ if (!mShouldRender && mBestLoad.isFullyLoaded()) { return false; }
+ MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get());
+ if (current_load < mBestLoad)
+ {
+ mShouldRender = true;
+ mBestLoad = current_load;
+ return true;
+ }
+ return false;
+}
+
+void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ llassert(mShouldRender);
+ if (!mShouldRender) { return; }
+
+ LLViewerDynamicTexture::preRender(clear_depth);
+}
+
+
+namespace {
+
+struct GLTFPreviewModel
+{
+ GLTFPreviewModel(LLPointer<LLDrawInfo>& info, const LLMatrix4& mat)
+ : mDrawInfo(info)
+ , mModelMatrix(mat)
+ {
+ mDrawInfo->mModelMatrix = &mModelMatrix;
+ }
+ GLTFPreviewModel(GLTFPreviewModel&) = delete;
+ ~GLTFPreviewModel()
+ {
+ // No model matrix necromancy
+ llassert(gGLLastMatrix != &mModelMatrix);
+ gGLLastMatrix = nullptr;
+ }
+ LLPointer<LLDrawInfo> mDrawInfo;
+ LLMatrix4 mModelMatrix; // Referenced by mDrawInfo
+};
+
+using PreviewSpherePart = std::unique_ptr<GLTFPreviewModel>;
+using PreviewSphere = std::vector<PreviewSpherePart>;
+
+// Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking.
+PreviewSphere create_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ const LLColor4U vertex_color(material->mBaseColor);
+
+ LLPrimitive prim;
+ prim.init_primitive(LL_PCODE_VOLUME);
+ LLVolumeParams params;
+ params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
+ params.setBeginAndEndS(0.f, 1.f);
+ params.setBeginAndEndT(0.f, 1.f);
+ params.setRatio(1, 1);
+ params.setShear(0, 0);
+ constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1;
+ prim.setVolume(params, MAX_LOD);
+
+ LLVolume* volume = prim.getVolume();
+ llassert(volume);
+ for (LLVolumeFace& face : volume->getVolumeFaces())
+ {
+ face.createTangents();
+ }
+
+ PreviewSphere preview_sphere;
+ preview_sphere.reserve(volume->getNumFaces());
+
+ LLPointer<LLVertexBuffer> buf = new LLVertexBuffer(
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TANGENT
+ );
+ U32 nv = 0;
+ U32 ni = 0;
+ for (LLVolumeFace& face : volume->getVolumeFaces())
+ {
+ nv += face.mNumVertices;
+ ni += face.mNumIndices;
+ }
+ buf->allocateBuffer(nv, ni);
+
+ // UV hacks
+ // Higher factor helps to see more details on the preview sphere
+ const LLVector2 uv_factor(2.0f, 2.0f);
+ // Offset places center of material in center of view
+ const LLVector2 uv_offset(-0.5f, -0.5f);
+
+ LLStrider<U16> indices;
+ LLStrider<LLVector4a> positions;
+ LLStrider<LLVector4a> normals;
+ LLStrider<LLVector2> texcoords;
+ LLStrider<LLColor4U> colors;
+ LLStrider<LLVector4a> tangents;
+ buf->getIndexStrider(indices);
+ buf->getVertexStrider(positions);
+ buf->getNormalStrider(normals);
+ buf->getTexCoord0Strider(texcoords);
+ buf->getColorStrider(colors);
+ buf->getTangentStrider(tangents);
+ U32 index_offset = 0;
+ U32 vertex_offset = 0;
+ for (const LLVolumeFace& face : volume->getVolumeFaces())
+ {
+ for (S32 i = 0; i < face.mNumIndices; ++i)
+ {
+ *indices++ = face.mIndices[i] + vertex_offset;
+ }
+ for (S32 v = 0; v < face.mNumVertices; ++v)
+ {
+ *positions++ = face.mPositions[v];
+ *normals++ = face.mNormals[v];
+ LLVector2 uv(face.mTexCoords[v]);
+ uv.scaleVec(uv_factor);
+ uv += uv_offset;
+ *texcoords++ = uv;
+ *colors++ = vertex_color;
+ *tangents++ = face.mTangents[v];
+ }
+
+ constexpr LLViewerTexture* no_media = nullptr;
+ LLPointer<LLDrawInfo> info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get());
+ info->mGLTFMaterial = material;
+ preview_sphere.emplace_back(std::make_unique<GLTFPreviewModel>(info, model_matrix));
+ index_offset += face.mNumIndices;
+ vertex_offset += face.mNumVertices;
+ }
+
+ buf->unmapBuffer();
+
+ return preview_sphere;
+}
+
+void set_preview_sphere_material(PreviewSphere& preview_sphere, LLPointer<LLFetchedGLTFMaterial>& material)
+{
+ llassert(!preview_sphere.empty());
+ if (preview_sphere.empty()) { return; }
+
+ const LLColor4U vertex_color(material->mBaseColor);
+
+ // See comments about unmapBuffer in llvertexbuffer.h
+ for (PreviewSpherePart& part : preview_sphere)
+ {
+ LLDrawInfo* info = part->mDrawInfo.get();
+ info->mGLTFMaterial = material;
+ LLVertexBuffer* buf = info->mVertexBuffer.get();
+ LLStrider<LLColor4U> colors;
+ const S32 count = info->mEnd - info->mStart + 1;
+ buf->getColorStrider(colors, info->mStart, count);
+ for (S32 i = 0; i < count; ++i)
+ {
+ *colors++ = vertex_color;
+ }
+ buf->unmapBuffer();
+ }
+}
+
+PreviewSphere& get_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
+{
+ static PreviewSphere preview_sphere;
+ if (preview_sphere.empty())
+ {
+ preview_sphere = create_preview_sphere(material, model_matrix);
+ }
+ else
+ {
+ set_preview_sphere_material(preview_sphere, material);
+ }
+ return preview_sphere;
+}
+
+// Final, direct modifications to shader constants, just before render
+void fixup_shader_constants(LLGLSLShader& shader)
+{
+ // Sunlight intensity of 0 no matter what
+ shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
+ shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, LLColor3::white.mV);
+ shader.uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, 0.0f);
+
+ // Ignore sun shadow (if enabled)
+ for (U32 i = 0; i < 6; i++)
+ {
+ const S32 channel = shader.getTextureChannel(LLShaderMgr::DEFERRED_SHADOW0+i);
+ if (channel != -1)
+ {
+ gGL.getTexUnit(channel)->bind(LLViewerFetchedTexture::sWhiteImagep, TRUE);
+ }
+ }
+}
+
+// Set a variable to a value temporarily, and restor the variable's old value
+// when this object leaves scope.
+template<typename T>
+struct SetTemporarily
+{
+ T* mRef;
+ T mOldVal;
+ SetTemporarily(T* var, T temp_val)
+ {
+ mRef = var;
+ mOldVal = *mRef;
+ *mRef = temp_val;
+ }
+ ~SetTemporarily()
+ {
+ *mRef = mOldVal;
+ }
+};
+
+}; // namespace
+
+BOOL LLGLTFPreviewTexture::render()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ if (!mShouldRender) { return FALSE; }
+
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ LLGLDepthTest(GL_FALSE);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ LLGLDisable scissor(GL_SCISSOR_TEST);
+ SetTemporarily<bool> no_dof(&LLPipeline::RenderDepthOfField, false);
+ SetTemporarily<bool> no_glow(&LLPipeline::sRenderGlow, false);
+ SetTemporarily<bool> no_ssr(&LLPipeline::RenderScreenSpaceReflections, false);
+ SetTemporarily<U32> no_fxaa(&LLPipeline::RenderFSAASamples, U32(0));
+ SetTemporarily<LLPipeline::RenderTargetPack*> use_auxiliary_render_target(&gPipeline.mRT, &gPipeline.mAuxillaryRT);
+
+ LLVector3 light_dir3(1.0f, 1.0f, 1.0f);
+ light_dir3.normalize();
+ const LLVector4 light_dir = LLVector4(light_dir3, 0);
+ const S32 old_local_light_count = gSavedSettings.get<S32>("RenderLocalLightCount");
+ gSavedSettings.set<S32>("RenderLocalLightCount", 0);
+
+ gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms();
+
+ LLViewerCamera camera;
+
+ // Calculate the object distance at which the object of a given radius will
+ // span the partial width of the screen given by fill_ratio.
+ // Assume the primitive has a scale of 1 (this is the default).
+ constexpr F32 fill_ratio = 0.8f;
+ constexpr F32 object_radius = 0.5f;
+ const F32 object_distance = (object_radius / fill_ratio) * tan(camera.getDefaultFOV());
+ // Negative coordinate shows the textures on the sphere right-side up, when
+ // combined with the UV hacks in create_preview_sphere
+ const LLVector3 object_position(0.0, -object_distance, 0.0);
+ LLMatrix4 object_transform;
+ object_transform.translate(object_position);
+
+ // Set up camera and viewport
+ const LLVector3 origin(0.0, 0.0, 0.0);
+ camera.lookAt(origin, object_position);
+ camera.setAspect(mFullHeight / mFullWidth);
+ const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);
+ camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), FALSE, camera.getNear(), MAX_FAR_CLIP*2.f);
+
+ // Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is
+ // discarded, but the sphere should be cached in LLVolumeMgr.)
+ PreviewSphere& preview_sphere = get_preview_sphere(mGLTFMaterial, object_transform);
+
+ gPipeline.setupHWLights();
+ glh::matrix4f mat = copy_matrix(gGLModelView);
+ glh::vec4f transformed_light_dir(light_dir.mV);
+ mat.mult_matrix_vec(transformed_light_dir);
+ SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir.v));
+ // Override lights to ensure the sun is always shining from a certain direction (low graphics)
+ // See also force_sun_direction_high_graphics and fixup_shader_constants
+ {
+ LLLightState* light = gGL.getLight(0);
+ light->setPosition(light_dir);
+ constexpr bool sun_up = true;
+ light->setSunPrimary(sun_up);
+ }
+
+ LLRenderTarget& screen = gPipeline.mAuxillaryRT.screen;
+
+ // *HACK: Force reset of the model matrix
+ gGLLastMatrix = nullptr;
+
+#if 0
+ if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE || mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ // *TODO: Opaque/alpha mask rendering
+ }
+ else
+#endif
+ {
+ // Alpha blend rendering
+
+ screen.bindTarget();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ LLGLSLShader& shader = gDeferredPBRAlphaProgram;
+
+ gPipeline.bindDeferredShader(shader);
+ fixup_shader_constants(shader);
+
+ for (PreviewSpherePart& part : preview_sphere)
+ {
+ LLRenderPass::pushGLTFBatch(*part->mDrawInfo);
+ }
+
+ gPipeline.unbindDeferredShader(shader);
+
+ screen.flush();
+ }
+
+ // *HACK: Hide mExposureMap from generateExposure
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
+ gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
+ gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
+ gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false);
+ gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap);
+ LLVertexBuffer::unbind();
+ gPipeline.generateGlow(&gPipeline.mPostMap);
+ gPipeline.combineGlow(&gPipeline.mPostMap, &screen);
+ gPipeline.renderDoF(&screen, &gPipeline.mPostMap);
+ gPipeline.applyFXAA(&gPipeline.mPostMap, &screen);
+
+ // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame)
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
+ // Final render
+
+ gDeferredPostNoDoFProgram.bind();
+
+ // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems."
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true);
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredPostNoDoFProgram.unbind();
+
+ // Clean up
+ gPipeline.setupHWLights();
+ gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false);
+ gSavedSettings.set<S32>("RenderLocalLightCount", old_local_light_count);
+
+ return TRUE;
+}
+
+void LLGLTFPreviewTexture::postRender(BOOL success)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ if (!mShouldRender) { return; }
+ mShouldRender = false;
+
+ LLViewerDynamicTexture::postRender(success);
+}
+
+LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetchedGLTFMaterial> &material)
+{
+ if (!material)
+ {
+ return nullptr;
+ }
+
+ static LLCachedControl<bool> sUIPreviewMaterial(gSavedSettings, "UIPreviewMaterial", false);
+ if (!sUIPreviewMaterial)
+ {
+ fetch_texture_for_ui(material->mBaseColorTexture, material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ return material->mBaseColorTexture;
+ }
+
+ if (!is_material_loaded_enough_for_ui(*material))
+ {
+ return nullptr;
+ }
+
+ return LLGLTFPreviewTexture::create(material);
+}
diff --git a/indra/newview/llgltfmaterialpreviewmgr.h b/indra/newview/llgltfmaterialpreviewmgr.h
new file mode 100644
index 0000000000..981c8b0592
--- /dev/null
+++ b/indra/newview/llgltfmaterialpreviewmgr.h
@@ -0,0 +1,78 @@
+/**
+ * @file llgltfmaterialpreviewmgr.h
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "lldrawpool.h"
+#include "lldynamictexture.h"
+#include "llfetchedgltfmaterial.h"
+#include "llsingleton.h"
+#include "lltexture.h"
+
+class LLGLTFPreviewTexture : public LLViewerDynamicTexture
+{
+protected:
+ LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width);
+
+public:
+ // Width scales with size of material's textures
+ static LLPointer<LLGLTFPreviewTexture> create(LLPointer<LLFetchedGLTFMaterial> material);
+
+ BOOL needsRender() override;
+ void preRender(BOOL clear_depth = TRUE) override;
+ BOOL render() override;
+ void postRender(BOOL success) override;
+
+ struct MaterialLoadLevels
+ {
+ S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
+
+ MaterialLoadLevels();
+ bool isFullyLoaded();
+ S32& operator[](size_t i);
+ const S32& operator[](size_t i) const;
+ // Less is better
+ // Returns false if lhs is not strictly less or equal for all levels
+ bool operator<(const MaterialLoadLevels& other) const;
+ // Less is better
+ // Returns false if lhs is not strictly greater or equal for all levels
+ bool operator>(const MaterialLoadLevels& other) const;
+ };
+
+private:
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+ bool mShouldRender = true;
+ MaterialLoadLevels mBestLoad;
+};
+
+class LLGLTFMaterialPreviewMgr
+{
+ public:
+ // Returns null if the material is not loaded yet.
+ // *NOTE: User should cache the texture if the same material is being previewed
+ LLPointer<LLViewerTexture> getPreview(LLPointer<LLFetchedGLTFMaterial> &material);
+};
+
+extern LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
new file mode 100644
index 0000000000..55539a49d8
--- /dev/null
+++ b/indra/newview/llheroprobemanager.cpp
@@ -0,0 +1,632 @@
+/**
+ * @file LLHeroProbeManager.cpp
+ * @brief LLHeroProbeManager class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llheroprobemanager.h"
+#include "llreflectionmapmanager.h"
+#include "llviewercamera.h"
+#include "llspatialpartition.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llviewercontrol.h"
+#include "llenvironment.h"
+#include "llstartup.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llviewerwindow.h"
+#include "llviewerjoystick.h"
+#include "llviewermediafocus.h"
+
+extern BOOL gCubeSnapshot;
+extern BOOL gTeleportDisplay;
+
+// get the next highest power of two of v (or v if v is already a power of two)
+//defined in llvertexbuffer.cpp
+extern U32 nhpo2(U32 v);
+
+static void touch_default_probe(LLReflectionMap* probe)
+{
+ if (LLViewerCamera::getInstance())
+ {
+ LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
+ origin.mV[2] += 64.f;
+
+ probe->mOrigin.load3(origin.mV);
+ }
+}
+
+LLHeroProbeManager::LLHeroProbeManager()
+{
+}
+
+LLHeroProbeManager::~LLHeroProbeManager()
+{
+ cleanup();
+
+ mHeroVOList.clear();
+ mNearestHero = nullptr;
+}
+
+// helper class to seed octree with probes
+void LLHeroProbeManager::update()
+{
+ if (!LLPipeline::RenderMirrors || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot); // assert a snapshot is not in progress
+ if (LLAppViewer::instance()->logoutRequestSent())
+ {
+ return;
+ }
+
+ initReflectionMaps();
+
+ if (!mRenderTarget.isComplete())
+ {
+ U32 color_fmt = GL_RGBA16F;
+ mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true);
+ }
+
+ if (mMipChain.empty())
+ {
+ U32 res = mProbeResolution;
+ U32 count = log2((F32)res) + 0.5f;
+
+ mMipChain.resize(count);
+ for (int i = 0; i < count; ++i)
+ {
+ mMipChain[i].allocate(res, res, GL_RGBA16F);
+ res /= 2;
+ }
+ }
+
+ llassert(mProbes[0] == mDefaultProbe);
+
+ LLVector4a probe_pos;
+ LLVector3 camera_pos = LLViewerCamera::instance().mOrigin;
+ F32 near_clip = 0.1f;
+ bool probe_present = false;
+ LLQuaternion cameraOrientation = LLViewerCamera::instance().getQuaternion();
+ LLVector3 cameraDirection = LLVector3::z_axis * cameraOrientation;
+
+ if (mHeroVOList.size() > 0)
+ {
+ // Find our nearest hero candidate.
+ float last_distance = 99999.f;
+ float camera_center_distance = 99999.f;
+ for (auto vo : mHeroVOList)
+ {
+ if (vo && !vo->isDead() && vo->mDrawable.notNull())
+ {
+ float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec();
+ float center_distance = cameraDirection * (vo->getPositionAgent() - camera_pos);
+
+ if (distance > LLViewerCamera::instance().getFar())
+ continue;
+
+ LLVector4a center;
+ center.load3(vo->getPositionAgent().mV);
+ LLVector4a size;
+
+ size.load3(vo->getScale().mV);
+
+ bool visible = LLViewerCamera::instance().AABBInFrustum(center, size);
+
+ if (distance < last_distance && center_distance < camera_center_distance && visible)
+ {
+ probe_present = true;
+ mNearestHero = vo;
+ last_distance = distance;
+ camera_center_distance = center_distance;
+ }
+ }
+ else
+ {
+ unregisterViewerObject(vo);
+ }
+ }
+
+ // Don't even try to do anything if we didn't find a single mirror present.
+ if (!probe_present)
+ return;
+
+ if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull())
+ {
+ LLVector3 hero_pos = mNearestHero->getPositionAgent();
+ LLVector3 face_normal = LLVector3(0, 0, 1);
+
+ face_normal *= mNearestHero->mDrawable->getWorldRotation();
+ face_normal.normalize();
+
+ LLVector3 offset = camera_pos - hero_pos;
+ LLVector3 project = face_normal * (offset * face_normal);
+ LLVector3 reject = offset - project;
+ LLVector3 point = (reject - project) + hero_pos;
+
+ mCurrentClipPlane.setVec(hero_pos, face_normal);
+ mMirrorPosition = hero_pos;
+ mMirrorNormal = face_normal;
+
+ probe_pos.load3(point.mV);
+
+ // Detect visible faces of a cube based on camera direction and distance
+
+ // Define the cube faces
+ static LLVector3 cubeFaces[6] = {
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+ };
+
+ // Iterate through each face of the cube
+ for (int i = 0; i < 6; i++)
+ {
+ float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])) * 0.6 + 0.4;
+
+ float updateRate;
+ if (cube_facing < 0.1f)
+ {
+ updateRate = 0;
+ }
+ else
+ {
+ updateRate = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier);
+ }
+
+ mFaceUpdateList[i] = updateRate;
+ }
+ }
+ else
+ {
+ mNearestHero = nullptr;
+ }
+
+ mHeroProbeStrength = 1;
+ }
+ else
+ {
+ probe_pos.load3(camera_pos.mV);
+ }
+
+
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1);
+ static LLCachedControl<S32> sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3);
+
+ if (mNearestHero != nullptr)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime");
+ // Probe 0 is always our mirror probe.
+ mProbes[0]->mOrigin = probe_pos;
+
+ bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass();
+
+ gPipeline.mReflectionMapManager.mRadiancePass = true;
+ mRenderingMirror = true;
+
+ doOcclusion();
+
+ for (U32 j = 0; j < mProbes.size(); j++)
+ {
+ for (U32 i = 0; i < 6; ++i)
+ {
+ if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0)
+ {
+ updateProbeFace(mProbes[j], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip);
+ mCurrentProbeUpdateFrame = 0;
+ }
+ }
+ generateRadiance(mProbes[j]);
+ }
+ mRenderingMirror = false;
+
+ gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass;
+
+ mProbes[0]->mViewerObject = mNearestHero;
+ mProbes[0]->autoAdjustOrigin();
+ }
+
+ mCurrentProbeUpdateFrame++;
+}
+
+// Do the reflection map update render passes.
+// For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated
+// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate
+// a simple mip chain (not convolution filter).
+// At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe
+// The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain.
+// At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe.
+// In effect this simulates single-bounce lighting.
+void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip)
+{
+ // hacky hot-swap of camera specific render targets
+ gPipeline.mRT = &gPipeline.mHeroProbeRT;
+
+ probe->update(mRenderTarget.getWidth(), face, is_dynamic, near_clip);
+
+ gPipeline.mRT = &gPipeline.mMainRT;
+
+ S32 sourceIdx = mReflectionProbeCount;
+
+ // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes.
+ sourceIdx += 1;
+
+ gGL.setColorMask(true, true);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+
+ // downsample to placeholder map
+ {
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.matrixMode(gGL.MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.flush();
+ U32 res = mProbeResolution * 2;
+
+ static LLStaticHashedString resScale("resScale");
+ static LLStaticHashedString direction("direction");
+ static LLStaticHashedString znear("znear");
+ static LLStaticHashedString zfar("zfar");
+
+ LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen;
+ LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.deferredScreen;
+
+ // perform a gaussian blur on the super sampled render before downsampling
+ {
+ gGaussianProgram.bind();
+ gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
+ S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
+
+ // horizontal
+ gGaussianProgram.uniform2f(direction, 1.f, 0.f);
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ mRenderTarget.bindTarget();
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mRenderTarget.flush();
+
+ // vertical
+ gGaussianProgram.uniform2f(direction, 0.f, 1.f);
+ gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget);
+ screen_rt->bindTarget();
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ screen_rt->flush();
+ gGaussianProgram.unbind();
+ }
+
+ S32 mips = log2((F32)mProbeResolution) + 0.5f;
+
+ gReflectionMipProgram.bind();
+ S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
+ S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE);
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip");
+ mMipChain[i].bindTarget();
+ if (i == 0)
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
+ }
+
+ gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
+
+ gReflectionMipProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
+ gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
+ gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
+
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ res /= 2;
+
+ S32 mip = i - (mMipChain.size() - mips);
+
+ if (mip >= 0)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip copy");
+ mTexture->bind(0);
+
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res);
+
+ mTexture->unbind();
+ }
+ mMipChain[i].flush();
+ }
+
+ gGL.popMatrix();
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE);
+ gReflectionMipProgram.unbind();
+ }
+}
+
+// Separate out radiance generation as a separate stage.
+// This is to better enable independent control over how we generate radiance vs. having it coupled with processing the final face of the probe.
+// Useful when we may not always be rendering a full set of faces of the probe.
+void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe)
+{
+ S32 sourceIdx = mReflectionProbeCount;
+
+ // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes.
+ sourceIdx += 1;
+ {
+ mMipChain[0].bindTarget();
+ static LLStaticHashedString sSourceIdx("sourceIdx");
+
+ {
+ // generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map)
+ gHeroRadianceGenProgram.bind();
+ mVertexBuffer->setBuffer();
+
+ S32 channel = gHeroRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+ gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
+ gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
+ gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength);
+
+ U32 res = mMipChain[0].getWidth();
+
+ for (int i = 0; i < mMipChain.size() / 4; ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe radiance gen");
+ static LLStaticHashedString sMipLevel("mipLevel");
+ static LLStaticHashedString sRoughness("roughness");
+ static LLStaticHashedString sWidth("u_width");
+ static LLStaticHashedString sStrength("probe_strength");
+
+ gHeroRadianceGenProgram.uniform1f(sRoughness, (F32) i / (F32) (mMipChain.size() - 1));
+ gHeroRadianceGenProgram.uniform1f(sMipLevel, i);
+ gHeroRadianceGenProgram.uniform1i(sWidth, mProbeResolution);
+ gHeroRadianceGenProgram.uniform1f(sStrength, 1);
+
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ }
+
+ if (i != mMipChain.size() - 1)
+ {
+ res /= 2;
+ glViewport(0, 0, res, res);
+ }
+ }
+
+ gHeroRadianceGenProgram.unbind();
+ }
+
+ mMipChain[0].flush();
+ }
+}
+
+void LLHeroProbeManager::updateUniforms()
+{
+ if (!gPipeline.RenderMirrors)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+ oa.set(0, 0, 0, 0);
+ mHeroData.heroProbeCount = 1;
+
+ if (mNearestHero != nullptr && !mNearestHero->isDead())
+ {
+ if (mNearestHero->getReflectionProbeIsBox())
+ {
+ LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+ mProbes[0]->mRadius = s.magVec();
+ }
+ else
+ {
+ mProbes[0]->mRadius = mNearestHero->getScale().mV[0] * 0.5f;
+ }
+
+ modelview.affineTransform(mProbes[0]->mOrigin, oa);
+ mHeroData.heroShape = 0;
+ if (!mProbes[0]->getBox(mHeroData.heroBox))
+ {
+ mHeroData.heroShape = 1;
+ }
+
+ mHeroData.heroSphere.set(oa.getF32ptr());
+ mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius;
+ }
+
+ mHeroData.heroMipCount = mMipChain.size();
+}
+
+void LLHeroProbeManager::renderDebug()
+{
+ gDebugProgram.bind();
+
+ for (auto& probe : mProbes)
+ {
+ renderReflectionProbe(probe);
+ }
+
+ gDebugProgram.unbind();
+}
+
+
+void LLHeroProbeManager::initReflectionMaps()
+{
+ U32 count = LL_MAX_HERO_PROBE_COUNT;
+
+ if ((mTexture.isNull() || mReflectionProbeCount != count || mReset) && LLPipeline::RenderMirrors)
+ {
+
+ if (mReset)
+ {
+ cleanup();
+ }
+
+ mReset = false;
+ mReflectionProbeCount = count;
+ mProbeResolution = gSavedSettings.getS32("RenderHeroProbeResolution");
+ mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1
+
+ mTexture = new LLCubeMapArray();
+
+ // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+
+ if (mDefaultProbe.isNull())
+ {
+ llassert(mProbes.empty()); // default probe MUST be the first probe created
+ mDefaultProbe = new LLReflectionMap();
+ mProbes.push_back(mDefaultProbe);
+ }
+
+ llassert(mProbes[0] == mDefaultProbe);
+
+ // For hero probes, we treat this as the main mirror probe.
+
+ mDefaultProbe->mCubeIndex = 0;
+ mDefaultProbe->mCubeArray = mTexture;
+ mDefaultProbe->mDistance = gSavedSettings.getF32("RenderHeroProbeDistance");
+ mDefaultProbe->mRadius = 4096.f;
+ mDefaultProbe->mProbeIndex = 0;
+ touch_default_probe(mDefaultProbe);
+
+ mProbes.push_back(mDefaultProbe);
+ }
+
+ if (mVertexBuffer.isNull())
+ {
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask);
+ buff->allocateBuffer(4, 0);
+
+ LLStrider<LLVector3> v;
+
+ buff->getVertexStrider(v);
+
+ v[0] = LLVector3(-1, -1, -1);
+ v[1] = LLVector3(1, -1, -1);
+ v[2] = LLVector3(-1, 1, -1);
+ v[3] = LLVector3(1, 1, -1);
+
+ buff->unmapBuffer();
+
+ mVertexBuffer = buff;
+ }
+}
+
+void LLHeroProbeManager::cleanup()
+{
+ mVertexBuffer = nullptr;
+ mRenderTarget.release();
+ mHeroRenderTarget.release();
+
+ mMipChain.clear();
+
+ mTexture = nullptr;
+
+ mProbes.clear();
+
+ mReflectionMaps.clear();
+
+ mDefaultProbe = nullptr;
+ mUpdatingProbe = nullptr;
+ /*
+ */
+}
+
+void LLHeroProbeManager::doOcclusion()
+{
+ LLVector4a eye;
+ eye.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ for (auto& probe : mProbes)
+ {
+ if (probe != nullptr && probe != mDefaultProbe)
+ {
+ probe->doOcclusion(eye);
+ }
+ }
+}
+
+void LLHeroProbeManager::reset()
+{
+ mReset = true;
+}
+
+bool LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep)
+{
+ llassert(drawablep != nullptr);
+
+ if (std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep) == mHeroVOList.end())
+ {
+ // Probe isn't in our list for consideration. Add it.
+ mHeroVOList.push_back(drawablep);
+ return true;
+ }
+
+ return false;
+}
+
+void LLHeroProbeManager::unregisterViewerObject(LLVOVolume* drawablep)
+{
+ std::vector<LLPointer<LLVOVolume>>::iterator found_itr = std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep);
+ if (found_itr != mHeroVOList.end())
+ {
+ mHeroVOList.erase(found_itr);
+ }
+}
diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h
new file mode 100644
index 0000000000..5df146f2f1
--- /dev/null
+++ b/indra/newview/llheroprobemanager.h
@@ -0,0 +1,156 @@
+/**
+ * @file llheroprobemanager.h
+ * @brief LLHeroProbeManager class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llreflectionmap.h"
+#include "llrendertarget.h"
+#include "llcubemaparray.h"
+#include "llcubemap.h"
+#include "lldrawable.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+// number of reflection probes to keep in vram
+#define LL_MAX_HERO_PROBE_COUNT 2
+
+struct HeroProbeData
+{
+ LLMatrix4 heroBox;
+ LLVector4 heroSphere;
+ GLint heroShape;
+ GLint heroMipCount;
+ GLint heroProbeCount;
+};
+
+class alignas(16) LLHeroProbeManager
+{
+ LL_ALIGN_NEW
+public:
+ enum class DetailLevel
+ {
+ STATIC_ONLY = 0,
+ STATIC_AND_DYNAMIC,
+ REALTIME = 2
+ };
+
+ // allocate an environment map of the given resolution
+ LLHeroProbeManager();
+ ~LLHeroProbeManager();
+
+ // release any GL state
+ void cleanup();
+
+ // maintain reflection probes
+ void update();
+
+ // debug display, called from llspatialpartition if reflection
+ // probe debug display is active
+ void renderDebug();
+
+ // call once at startup to allocate cubemap arrays
+ void initReflectionMaps();
+
+ // perform occlusion culling on all active reflection probes
+ void doOcclusion();
+
+ void reset();
+
+ bool registerViewerObject(LLVOVolume *drawablep);
+ void unregisterViewerObject(LLVOVolume* drawablep);
+
+ bool isMirrorPass() const { return mRenderingMirror; }
+
+ LLVector3 mMirrorPosition;
+ LLVector3 mMirrorNormal;
+ HeroProbeData mHeroData;
+
+private:
+ friend class LLPipeline;
+ friend class LLReflectionMapManager;
+
+ // update UBO used for rendering (call only once per render pipe flush)
+ void updateUniforms();
+
+ // bind UBO used for rendering
+
+ // render target for cube snapshots
+ // used to generate mipmaps without doing a copy-to-texture
+ LLRenderTarget mRenderTarget;
+
+ LLRenderTarget mHeroRenderTarget;
+
+ std::vector<LLRenderTarget> mMipChain;
+
+ // storage for reflection probe radiance maps (plus two scratch space cubemaps)
+ LLPointer<LLCubeMapArray> mTexture;
+
+ // vertex buffer for pushing verts to filter shaders
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+
+ LLPlane mCurrentClipPlane;
+
+
+ // update the specified face of the specified probe
+ void updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip);
+ void generateRadiance(LLReflectionMap *probe);
+
+ // list of active reflection maps
+ std::vector<LLPointer<LLReflectionMap>> mProbes;
+
+ // list of maps being used for rendering
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
+ LLReflectionMap* mUpdatingProbe = nullptr;
+
+ LLPointer<LLReflectionMap> mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0)
+
+ // number of reflection probes to use for rendering
+ U32 mReflectionProbeCount;
+
+ // resolution of reflection probes
+ U32 mProbeResolution = 1024;
+
+ // maximum LoD of reflection probes (mip levels - 1)
+ F32 mMaxProbeLOD = 6.f;
+
+ F32 mHeroProbeStrength = 1.f;
+ bool mIsInTransition = false;
+
+ // if true, reset all probe render state on the next update (for teleports and sky changes)
+ bool mReset = false;
+
+ bool mRenderingMirror = false;
+ std::map<int, int> mFaceUpdateList;
+
+ U32 mCurrentProbeUpdateFrame = 0;
+
+ std::vector<LLPointer<LLVOVolume>> mHeroVOList;
+ LLPointer<LLVOVolume> mNearestHero;
+
+};
+
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 3f03469db9..8a284686ad 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llmanip.cpp
* @brief LLManip 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$
*/
@@ -49,7 +49,7 @@
#include "llviewerobject.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
-#include "llworld.h" // for LLWorld::getInstance()
+#include "llworld.h" // for LLWorld::getInstance()
#include "llresmgr.h"
#include "pipeline.h"
#include "llglheaders.h"
@@ -57,39 +57,39 @@
// Local constants...
const S32 VERTICAL_OFFSET = 50;
-F32 LLManip::sHelpTextVisibleTime = 2.f;
-F32 LLManip::sHelpTextFadeTime = 2.f;
-S32 LLManip::sNumTimesHelpTextShown = 0;
-S32 LLManip::sMaxTimesShowHelpText = 5;
-F32 LLManip::sGridMaxSubdivisionLevel = 32.f;
-F32 LLManip::sGridMinSubdivisionLevel = 1.f / 32.f;
+F32 LLManip::sHelpTextVisibleTime = 2.f;
+F32 LLManip::sHelpTextFadeTime = 2.f;
+S32 LLManip::sNumTimesHelpTextShown = 0;
+S32 LLManip::sMaxTimesShowHelpText = 5;
+F32 LLManip::sGridMaxSubdivisionLevel = 32.f;
+F32 LLManip::sGridMinSubdivisionLevel = 1.f / 32.f;
LLVector2 LLManip::sTickLabelSpacing(60.f, 25.f);
//static
void LLManip::rebuild(LLViewerObject* vobj)
{
- LLDrawable* drawablep = vobj->mDrawable;
- if (drawablep && drawablep->getVOVolume())
- {
- gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME);
- drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
- drawablep->updateMove();
- LLSpatialGroup* group = drawablep->getSpatialGroup();
- if (group)
- {
- group->dirtyGeom();
- gPipeline.markRebuild(group);
- }
-
- LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end();
- iter != endIter; ++iter)
- {
- LLViewerObject* child = *iter;
- rebuild(child);
- }
- }
+ LLDrawable* drawablep = vobj->mDrawable;
+ if (drawablep && drawablep->getVOVolume())
+ {
+ gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME);
+ drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
+ drawablep->updateMove();
+ LLSpatialGroup* group = drawablep->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
+
+ LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end();
+ iter != endIter; ++iter)
+ {
+ LLViewerObject* child = *iter;
+ rebuild(child);
+ }
+ }
}
//////////////////////////////////////////////////////////////////////////////
@@ -97,204 +97,204 @@ void LLManip::rebuild(LLViewerObject* vobj)
LLManip::LLManip( const std::string& name, LLToolComposite* composite )
- :
- LLTool( name, composite ),
- mInSnapRegime(FALSE),
- mHighlightedPart(LL_NO_PART),
- mManipPart(LL_NO_PART)
+ :
+ LLTool( name, composite ),
+ mInSnapRegime(FALSE),
+ mHighlightedPart(LL_NO_PART),
+ mManipPart(LL_NO_PART)
{
}
void LLManip::getManipNormal(LLViewerObject* object, EManipPart manip, LLVector3 &normal)
{
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW)
- {
- LLVector3 arrow_axis;
- getManipAxis(object, manip, arrow_axis);
-
- LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis();
- normal = cross % arrow_axis;
- normal.normVec();
- }
- else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE)
- {
- switch (manip)
- {
- case LL_YZ_PLANE:
- normal = LLVector3::x_axis;
- break;
- case LL_XZ_PLANE:
- normal = LLVector3::y_axis;
- break;
- case LL_XY_PLANE:
- normal = LLVector3::z_axis;
- break;
- default:
- break;
- }
- normal.rotVec(grid_rotation);
- }
- else
- {
- normal.clearVec();
- }
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW)
+ {
+ LLVector3 arrow_axis;
+ getManipAxis(object, manip, arrow_axis);
+
+ LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis();
+ normal = cross % arrow_axis;
+ normal.normVec();
+ }
+ else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE)
+ {
+ switch (manip)
+ {
+ case LL_YZ_PLANE:
+ normal = LLVector3::x_axis;
+ break;
+ case LL_XZ_PLANE:
+ normal = LLVector3::y_axis;
+ break;
+ case LL_XY_PLANE:
+ normal = LLVector3::z_axis;
+ break;
+ default:
+ break;
+ }
+ normal.rotVec(grid_rotation);
+ }
+ else
+ {
+ normal.clearVec();
+ }
}
BOOL LLManip::getManipAxis(LLViewerObject* object, EManipPart manip, LLVector3 &axis)
{
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- if (manip == LL_X_ARROW)
- {
- axis = LLVector3::x_axis;
- }
- else if (manip == LL_Y_ARROW)
- {
- axis = LLVector3::y_axis;
- }
- else if (manip == LL_Z_ARROW)
- {
- axis = LLVector3::z_axis;
- }
- else
- {
- return FALSE;
- }
-
- axis.rotVec( grid_rotation );
- return TRUE;
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ if (manip == LL_X_ARROW)
+ {
+ axis = LLVector3::x_axis;
+ }
+ else if (manip == LL_Y_ARROW)
+ {
+ axis = LLVector3::y_axis;
+ }
+ else if (manip == LL_Z_ARROW)
+ {
+ axis = LLVector3::z_axis;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ axis.rotVec( grid_rotation );
+ return TRUE;
}
F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVector3 &translate_axis, F32 grid_scale, S32 min_pixel_spacing, F32 min_subdivisions, F32 max_subdivisions)
{
- //update current snap subdivision level
- LLVector3 cam_to_reference;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
- }
- else
- {
- cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin();
- }
- F32 current_range = cam_to_reference.normVec();
-
- F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec();
- F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f);
- // figure out nearest power of 2 that subdivides grid_scale with result > min_pixel_spacing
- subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), min_subdivisions, max_subdivisions);
-
- return subdivisions;
+ //update current snap subdivision level
+ LLVector3 cam_to_reference;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
+ }
+ else
+ {
+ cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin();
+ }
+ F32 current_range = cam_to_reference.normVec();
+
+ F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec();
+ F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f);
+ // figure out nearest power of 2 that subdivides grid_scale with result > min_pixel_spacing
+ subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), min_subdivisions, max_subdivisions);
+
+ return subdivisions;
}
void LLManip::handleSelect()
{
- mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+ mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
}
void LLManip::handleDeselect()
{
- mHighlightedPart = LL_NO_PART;
- mManipPart = LL_NO_PART;
- mObjectSelection = NULL;
+ mHighlightedPart = LL_NO_PART;
+ mManipPart = LL_NO_PART;
+ mObjectSelection = NULL;
}
LLObjectSelectionHandle LLManip::getSelection()
{
- return mObjectSelection;
+ return mObjectSelection;
}
BOOL LLManip::handleHover(S32 x, S32 y, MASK mask)
{
- // We only handle the event if mousedown started with us
- if( hasMouseCapture() )
- {
- if( mObjectSelection->isEmpty() )
- {
- // Somehow the object got deselected while we were dragging it.
- // Release the mouse
- setMouseCapture( FALSE );
- }
-
- LL_DEBUGS("UserInput") << "hover handled by LLManip (active)" << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("UserInput") << "hover handled by LLManip (inactive)" << LL_ENDL;
- }
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- return TRUE;
+ // We only handle the event if mousedown started with us
+ if( hasMouseCapture() )
+ {
+ if( mObjectSelection->isEmpty() )
+ {
+ // Somehow the object got deselected while we were dragging it.
+ // Release the mouse
+ setMouseCapture( FALSE );
+ }
+
+ LL_DEBUGS("UserInput") << "hover handled by LLManip (active)" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("UserInput") << "hover handled by LLManip (inactive)" << LL_ENDL;
+ }
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ return TRUE;
}
BOOL LLManip::handleMouseUp(S32 x, S32 y, MASK mask)
{
- BOOL handled = FALSE;
- if( hasMouseCapture() )
- {
- handled = TRUE;
- setMouseCapture( FALSE );
- }
- return handled;
+ BOOL handled = FALSE;
+ if( hasMouseCapture() )
+ {
+ handled = TRUE;
+ setMouseCapture( FALSE );
+ }
+ return handled;
}
void LLManip::updateGridSettings()
{
- sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f;
+ sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f;
}
BOOL LLManip::getMousePointOnPlaneAgent(LLVector3& point, S32 x, S32 y, LLVector3 origin, LLVector3 normal)
{
- LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin);
- LLVector3d global_point;
- BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal);
- point = gAgent.getPosAgentFromGlobal(global_point);
- return result;
+ LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin);
+ LLVector3d global_point;
+ BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal);
+ point = gAgent.getPosAgentFromGlobal(global_point);
+ return result;
}
BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVector3d origin, LLVector3 normal) const
{
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- BOOL result = FALSE;
- F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
- F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom;
-
- LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);
- LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y);
- if (llabs(normal.mV[VX]) < 0.001f)
- {
- // use largish value that should be outside HUD manipulation range
- mouse_pos.mV[VX] = 10.f;
- }
- else
- {
- mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos))
- / (normal.mV[VX]);
- result = TRUE;
- }
-
- point = gAgent.getPosGlobalFromAgent(mouse_pos);
- return result;
- }
- else
- {
- return gViewerWindow->mousePointOnPlaneGlobal(
- point, x, y, origin, normal );
- }
-
- //return FALSE;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ BOOL result = FALSE;
+ F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
+ F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom;
+
+ LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);
+ LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y);
+ if (llabs(normal.mV[VX]) < 0.001f)
+ {
+ // use largish value that should be outside HUD manipulation range
+ mouse_pos.mV[VX] = 10.f;
+ }
+ else
+ {
+ mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos))
+ / (normal.mV[VX]);
+ result = TRUE;
+ }
+
+ point = gAgent.getPosGlobalFromAgent(mouse_pos);
+ return result;
+ }
+ else
+ {
+ return gViewerWindow->mousePointOnPlaneGlobal(
+ point, x, y, origin, normal );
+ }
+
+ //return FALSE;
}
// Given the line defined by mouse cursor (a1 + a_param*(a2-a1)) and the line defined by b1 + b_param*(b2-b1),
@@ -302,153 +302,159 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect
// Returns false if the two lines are parallel.
BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, const LLVector3& b2, F32 &a_param, F32 &b_param )
{
- LLVector3 a1;
- LLVector3 a2;
-
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
- F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom;
- a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y);
- a2 = a1 + LLVector3(1.f, 0.f, 0.f);
- }
- else
- {
- a1 = gAgentCamera.getCameraPositionAgent();
- a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y));
- }
-
- BOOL parallel = TRUE;
- LLVector3 a = a2 - a1;
- LLVector3 b = b2 - b1;
-
- LLVector3 normal;
- F32 dist, denom;
- normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b)
- normal.normVec();
- dist = b1 * normal; // distance from origin to P
-
- denom = normal * a;
- if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
- {
- a_param = (dist - normal * a1) / denom;
- parallel = FALSE;
- }
-
- normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b)
- normal.normVec();
- dist = a1 * normal; // distance from origin to P
- denom = normal * b;
- if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
- {
- b_param = (dist - normal * b1) / denom;
- parallel = FALSE;
- }
-
- return parallel;
+ LLVector3 a1;
+ LLVector3 a2;
+
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
+ F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom;
+ a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y);
+ a2 = a1 + LLVector3(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ a1 = gAgentCamera.getCameraPositionAgent();
+ a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y));
+ }
+
+ BOOL parallel = TRUE;
+ LLVector3 a = a2 - a1;
+ LLVector3 b = b2 - b1;
+
+ LLVector3 normal;
+ F32 dist, denom;
+ normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b)
+ normal.normVec();
+ dist = b1 * normal; // distance from origin to P
+
+ denom = normal * a;
+ if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
+ {
+ a_param = (dist - normal * a1) / denom;
+ parallel = FALSE;
+ }
+
+ normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b)
+ normal.normVec();
+ dist = a1 * normal; // distance from origin to P
+ denom = normal * b;
+ if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
+ {
+ b_param = (dist - normal * b1) / denom;
+ parallel = FALSE;
+ }
+
+ return parallel;
}
LLVector3 LLManip::getSavedPivotPoint() const
{
- return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+ return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
}
LLVector3 LLManip::getPivotPoint()
{
- if (mObjectSelection->getFirstObject() && mObjectSelection->getObjectCount() == 1 && mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
- {
- return mObjectSelection->getFirstObject()->getPivotPositionAgent();
- }
- return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
+ LLViewerObject* object = mObjectSelection->getFirstObject();
+ if (object && mObjectSelection->getObjectCount() == 1 && mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ LLSelectNode* select_node = mObjectSelection->getFirstNode();
+ if (select_node->mSelectedGLTFNode != -1)
+ {
+ return object->getGLTFNodePositionAgent(select_node->mSelectedGLTFNode);
+ }
+ return mObjectSelection->getFirstObject()->getPivotPositionAgent();
+ }
+ return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
}
void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
{
- LLVector3 grid_origin;
- LLQuaternion grid_rot;
- LLVector3 grid_scale;
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale);
-
- const BOOL children_ok = TRUE;
- LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok);
- if (!object)
- {
- return;
- }
-
- //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
- LLVector3 center_agent = getPivotPoint();
-
- gGL.pushMatrix();
- {
- gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]);
-
- F32 angle_radians, x, y, z;
-
- grid_rot.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
- F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters();
-
- const F32 LINE_ALPHA = 0.33f;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLUI::setLineWidth(1.5f);
-
- if (draw_x)
- {
- gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA);
- gGL.begin(LLRender::LINES);
- gGL.vertex3f( -region_size, 0.f, 0.f );
- gGL.vertex3f( region_size, 0.f, 0.f );
- gGL.end();
- }
-
- if (draw_y)
- {
- gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA);
- gGL.begin(LLRender::LINES);
- gGL.vertex3f( 0.f, -region_size, 0.f );
- gGL.vertex3f( 0.f, region_size, 0.f );
- gGL.end();
- }
-
- if (draw_z)
- {
- gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA);
- gGL.begin(LLRender::LINES);
- gGL.vertex3f( 0.f, 0.f, -region_size );
- gGL.vertex3f( 0.f, 0.f, region_size );
- gGL.end();
- }
- LLUI::setLineWidth(1.0f);
- }
- gGL.popMatrix();
+ LLVector3 grid_origin;
+ LLQuaternion grid_rot;
+ LLVector3 grid_scale;
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale);
+
+ const BOOL children_ok = TRUE;
+ LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok);
+ if (!object)
+ {
+ return;
+ }
+
+ //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
+ LLVector3 center_agent = getPivotPoint();
+
+ gGL.pushMatrix();
+ {
+ gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]);
+
+ F32 angle_radians, x, y, z;
+
+ grid_rot.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+ F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters();
+
+ const F32 LINE_ALPHA = 0.33f;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLUI::setLineWidth(1.5f);
+
+ if (draw_x)
+ {
+ gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3f( -region_size, 0.f, 0.f );
+ gGL.vertex3f( region_size, 0.f, 0.f );
+ gGL.end();
+ }
+
+ if (draw_y)
+ {
+ gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3f( 0.f, -region_size, 0.f );
+ gGL.vertex3f( 0.f, region_size, 0.f );
+ gGL.end();
+ }
+
+ if (draw_z)
+ {
+ gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3f( 0.f, 0.f, -region_size );
+ gGL.vertex3f( 0.f, 0.f, region_size );
+ gGL.end();
+ }
+ LLUI::setLineWidth(1.0f);
+ }
+ gGL.popMatrix();
}
-void LLManip::renderXYZ(const LLVector3 &vec)
+void LLManip::renderXYZ(const LLVector3 &vec)
{
- const S32 PAD = 10;
- std::string feedback_string;
- S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
- S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2;
- S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
-
-
- gGL.pushMatrix();
- {
- LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
- gViewerWindow->setup2DRender();
- const LLVector2& display_scale = gViewerWindow->getDisplayScale();
- gGL.color4f(0.f, 0.f, 0.f, 0.7f);
-
- imagep->draw(
- (window_center_x - 115) * display_scale.mV[VX],
- (window_center_y + vertical_offset - PAD) * display_scale.mV[VY],
- 235 * display_scale.mV[VX],
- (PAD * 2 + 10) * display_scale.mV[VY],
- LLColor4(0.f, 0.f, 0.f, 0.7f) );
+ const S32 PAD = 10;
+ std::string feedback_string;
+ S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
+ S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2;
+ S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
+
+
+ gGL.pushMatrix();
+ {
+ LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
+ gViewerWindow->setup2DRender();
+ const LLVector2& display_scale = gViewerWindow->getDisplayScale();
+ gGL.color4f(0.f, 0.f, 0.f, 0.7f);
+
+ imagep->draw(
+ (window_center_x - 115) * display_scale.mV[VX],
+ (window_center_y + vertical_offset - PAD) * display_scale.mV[VY],
+ 235 * display_scale.mV[VX],
+ (PAD * 2 + 10) * display_scale.mV[VY],
+ LLColor4(0.f, 0.f, 0.f, 0.7f) );
LLFontGL* font = LLFontGL::getFontSansSerif();
LLLocale locale(LLLocale::USER_LOCALE);
@@ -494,129 +500,129 @@ void LLManip::renderXYZ(const LLVector3 &vec)
void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color)
{
- const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
-
- BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- LLVector3 render_pos = pos;
- if (hud_selection)
- {
- F32 zoom_amt = gAgentCamera.mHUDCurZoom;
- F32 inv_zoom_amt = 1.f / zoom_amt;
- // scale text back up to counter-act zoom level
- render_pos = pos * zoom_amt;
- gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
- }
-
- // render shadow first
- LLColor4 shadow_color = LLColor4::black;
- shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
- gViewerWindow->setup3DViewport(1, -1);
- hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- gViewerWindow->setup3DViewport();
- hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
-
- gGL.popMatrix();
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+
+ BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ LLVector3 render_pos = pos;
+ if (hud_selection)
+ {
+ F32 zoom_amt = gAgentCamera.mHUDCurZoom;
+ F32 inv_zoom_amt = 1.f / zoom_amt;
+ // scale text back up to counter-act zoom level
+ render_pos = pos * zoom_amt;
+ gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
+ }
+
+ // render shadow first
+ LLColor4 shadow_color = LLColor4::black;
+ shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
+ gViewerWindow->setup3DViewport(1, -1);
+ hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ gViewerWindow->setup3DViewport();
+ hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+
+ gGL.popMatrix();
}
void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string& suffix, const LLColor4 &color)
{
- LLLocale locale(LLLocale::USER_LOCALE);
-
- const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
- const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall();
-
- std::string val_string;
- std::string fraction_string;
- F32 val_to_print = ll_round(value, 0.001f);
- S32 fractional_portion = ll_round(fmodf(llabs(val_to_print), 1.f) * 100.f);
- if (val_to_print < 0.f)
- {
- if (fractional_portion == 0)
- {
- val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
- }
- else
- {
- val_string = llformat("-%d", lltrunc(llabs(val_to_print)));
- }
- }
- else
- {
- if (fractional_portion == 0)
- {
- val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
- }
- else
- {
- val_string = llformat("%d", lltrunc(val_to_print));
- }
- }
-
- BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- {
- LLVector3 render_pos = pos;
- if (hud_selection)
- {
- F32 zoom_amt = gAgentCamera.mHUDCurZoom;
- F32 inv_zoom_amt = 1.f / zoom_amt;
- // scale text back up to counter-act zoom level
- render_pos = pos * zoom_amt;
- gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
- }
-
- LLColor4 shadow_color = LLColor4::black;
- shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
-
- if (fractional_portion != 0)
- {
- fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str());
-
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
- hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection);
- }
- else
- {
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
- }
- }
- gGL.popMatrix();
+ LLLocale locale(LLLocale::USER_LOCALE);
+
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+ const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall();
+
+ std::string val_string;
+ std::string fraction_string;
+ F32 val_to_print = ll_round(value, 0.001f);
+ S32 fractional_portion = ll_round(fmodf(llabs(val_to_print), 1.f) * 100.f);
+ if (val_to_print < 0.f)
+ {
+ if (fractional_portion == 0)
+ {
+ val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
+ }
+ else
+ {
+ val_string = llformat("-%d", lltrunc(llabs(val_to_print)));
+ }
+ }
+ else
+ {
+ if (fractional_portion == 0)
+ {
+ val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
+ }
+ else
+ {
+ val_string = llformat("%d", lltrunc(val_to_print));
+ }
+ }
+
+ BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ {
+ LLVector3 render_pos = pos;
+ if (hud_selection)
+ {
+ F32 zoom_amt = gAgentCamera.mHUDCurZoom;
+ F32 inv_zoom_amt = 1.f / zoom_amt;
+ // scale text back up to counter-act zoom level
+ render_pos = pos * zoom_amt;
+ gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
+ }
+
+ LLColor4 shadow_color = LLColor4::black;
+ shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
+
+ if (fractional_portion != 0)
+ {
+ fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str());
+
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
+ hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection);
+ }
+ else
+ {
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
+ }
+ }
+ gGL.popMatrix();
}
LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass)
{
- static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor");
- static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor");
- static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor");
-
- LLColor4 line_color;
- F32 line_alpha = gSavedSettings.getF32("GridOpacity");
-
- switch(pass)
- {
- case 0:
- // shadow
- gViewerWindow->setup3DViewport(1, -1);
- line_color = grid_color_shadow;
- line_color.mV[VALPHA] *= line_alpha;
- LLUI::setLineWidth(2.f);
- break;
- case 1:
- // hidden lines
- gViewerWindow->setup3DViewport();
- line_color = grid_color_bg;
- line_color.mV[VALPHA] *= line_alpha;
- LLUI::setLineWidth(1.f);
- break;
- case 2:
- // visible lines
- line_color = grid_color_fg;
- line_color.mV[VALPHA] *= line_alpha;
- break;
- }
-
- return line_color;
+ static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor");
+ static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor");
+ static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor");
+
+ LLColor4 line_color;
+ F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+
+ switch(pass)
+ {
+ case 0:
+ // shadow
+ gViewerWindow->setup3DViewport(1, -1);
+ line_color = grid_color_shadow;
+ line_color.mV[VALPHA] *= line_alpha;
+ LLUI::setLineWidth(2.f);
+ break;
+ case 1:
+ // hidden lines
+ gViewerWindow->setup3DViewport();
+ line_color = grid_color_bg;
+ line_color.mV[VALPHA] *= line_alpha;
+ LLUI::setLineWidth(1.f);
+ break;
+ case 2:
+ // visible lines
+ line_color = grid_color_fg;
+ line_color.mV[VALPHA] *= line_alpha;
+ break;
+ }
+
+ return line_color;
}
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index f9a2c79679..1ac1992fe0 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llmaniprotate.cpp
* @brief LLManipRotate class implementation
*
* $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$
*/
@@ -63,7 +63,7 @@
#include "llvoavatarself.h"
#include "llhudrender.h"
-const F32 RADIUS_PIXELS = 100.f; // size in screen space
+const F32 RADIUS_PIXELS = 100.f; // size in screen space
const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS;
const F32 WIDTH_PIXELS = 8;
const S32 CIRCLE_STEPS = 100;
@@ -83,1634 +83,1659 @@ const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f;
extern void handle_reset_rotation(void*); // in LLViewerWindow
LLManipRotate::LLManipRotate( LLToolComposite* composite )
-: LLManip( std::string("Rotate"), composite ),
- mRotationCenter(),
- mCenterScreen(),
- mRotation(),
- mMouseDown(),
- mMouseCur(),
- mRadiusMeters(0.f),
- mCenterToCam(),
- mCenterToCamNorm(),
- mCenterToCamMag(0.f),
- mCenterToProfilePlane(),
- mCenterToProfilePlaneMag(0.f),
- mSendUpdateOnMouseUp( FALSE ),
- mSmoothRotate( FALSE ),
- mCamEdgeOn(FALSE),
- mManipulatorScales(1.f, 1.f, 1.f, 1.f)
+: LLManip( std::string("Rotate"), composite ),
+ mRotationCenter(),
+ mCenterScreen(),
+ mRotation(),
+ mMouseDown(),
+ mMouseCur(),
+ mRadiusMeters(0.f),
+ mCenterToCam(),
+ mCenterToCamNorm(),
+ mCenterToCamMag(0.f),
+ mCenterToProfilePlane(),
+ mCenterToProfilePlaneMag(0.f),
+ mSendUpdateOnMouseUp( FALSE ),
+ mSmoothRotate( FALSE ),
+ mCamEdgeOn(FALSE),
+ mManipulatorScales(1.f, 1.f, 1.f, 1.f)
{ }
void LLManipRotate::handleSelect()
{
- // *FIX: put this in mouseDown?
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ // *FIX: put this in mouseDown?
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
if (gFloaterTools)
{
gFloaterTools->setStatusText("rotate");
}
- LLManip::handleSelect();
+ LLManip::handleSelect();
}
void LLManipRotate::render()
{
- LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
- LLGLDepthTest gls_depth(GL_TRUE);
- LLGLEnable gl_blend(GL_BLEND);
-
- // You can rotate if you can move
- LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);
- if( !first_object )
- {
- return;
- }
-
- if( !updateVisiblity() )
- {
- return;
- }
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 zoom = gAgentCamera.mHUDCurZoom;
- gGL.scalef(zoom, zoom, zoom);
- }
-
-
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
-
- LLColor4 highlight_outside( 1.f, 1.f, 0.f, 1.f );
- LLColor4 highlight_inside( 0.7f, 0.7f, 0.f, 0.5f );
- F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS;
-
- gGL.pushMatrix();
- {
-
- // are we in the middle of a constrained drag?
- if (mManipPart >= LL_ROT_X && mManipPart <= LL_ROT_Z)
- {
- renderSnapGuides();
- }
- else
- {
- gDebugProgram.bind();
-
- LLGLEnable cull_face(GL_CULL_FACE);
- LLGLDepthTest gls_depth(GL_FALSE);
- gGL.pushMatrix();
- {
- // Draw "sphere" (intersection of sphere with tangent cone that has apex at camera)
- gGL.translatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] );
- gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
-
- // Inverse change of basis vectors
- LLVector3 forward = mCenterToCamNorm;
- LLVector3 left = gAgent.getUpAxis() % forward;
- left.normVec();
- LLVector3 up = forward % left;
-
- LLVector4 a(-forward);
- a.mV[3] = 0;
- LLVector4 b(up);
- b.mV[3] = 0;
- LLVector4 c(left);
- c.mV[3] = 0;
- LLMatrix4 mat;
- mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f));
-
- gGL.multMatrix( &mat.mMatrix[0][0] );
-
- gGL.rotatef( -90, 0.f, 1.f, 0.f);
- LLColor4 color;
- if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL)
- {
- color.setVec(0.8f, 0.8f, 0.8f, 0.8f);
- gGL.scalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]);
- }
- else
- {
- color.setVec( 0.7f, 0.7f, 0.7f, 0.6f );
- }
- gGL.diffuseColor4fv(color.mV);
- gl_washer_2d(mRadiusMeters + width_meters, mRadiusMeters, CIRCLE_STEPS, color, color);
-
-
- if (mManipPart == LL_NO_PART)
- {
- gGL.color4f( 0.7f, 0.7f, 0.7f, 0.3f );
- gGL.diffuseColor4f(0.7f, 0.7f, 0.7f, 0.3f);
- gl_circle_2d( 0, 0, mRadiusMeters, CIRCLE_STEPS, TRUE );
- }
-
- gGL.flush();
- }
- gGL.popMatrix();
-
- gUIProgram.bind();
- }
-
- gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
-
- LLQuaternion rot;
- F32 angle_radians, x, y, z;
-
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
-
- gDebugProgram.bind();
-
- if (mManipPart == LL_ROT_Z)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.pushMatrix();
- {
- // selected part
- gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
- renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f) , LLColor4( 0.f, 0.f, 1.f, 0.3f ));
- }
- gGL.popMatrix();
- }
- else if (mManipPart == LL_ROT_Y)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.pushMatrix();
- {
- gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
- gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
- renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f));
- }
- gGL.popMatrix();
- }
- else if (mManipPart == LL_ROT_X)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.pushMatrix();
- {
- gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
- gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
- renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f));
- }
- gGL.popMatrix();
- }
- else if (mManipPart == LL_ROT_ROLL)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- }
- else if (mManipPart == LL_NO_PART)
- {
- if (mHighlightedPart == LL_NO_PART)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- }
-
- LLGLEnable cull_face(GL_CULL_FACE);
- LLGLEnable clip_plane0(GL_CLIP_PLANE0);
- LLGLDepthTest gls_depth(GL_FALSE);
- //LLGLDisable gls_stencil(GL_STENCIL_TEST);
-
- // First pass: centers. Second pass: sides.
- for( S32 i=0; i<2; i++ )
- {
-
- gGL.pushMatrix();
- {
- if (mHighlightedPart == LL_ROT_Z)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
- // hovering over part
- gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i);
- }
- else
- {
- // default
- gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 0.8f, 0.8f ), LLColor4( 0.f, 0.f, 0.8f, 0.4f ), CIRCLE_STEPS, i);
- }
- }
- gGL.popMatrix();
-
- gGL.pushMatrix();
- {
- gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
- if (mHighlightedPart == LL_ROT_Y)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
- // hovering over part
- gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
- }
- else
- {
- // default
- gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.8f, 0.f, 0.8f ), LLColor4( 0.f, 0.8f, 0.f, 0.4f ), CIRCLE_STEPS, i);
- }
- }
- gGL.popMatrix();
-
- gGL.pushMatrix();
- {
- gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
- if (mHighlightedPart == LL_ROT_X)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
-
- // hovering over part
- gl_ring( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f ), LLColor4( 1.f, 0.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
- }
- else
- {
- // default
- gl_ring( mRadiusMeters, width_meters, LLColor4( 0.8f, 0.f, 0.f, 0.8f ), LLColor4( 0.8f, 0.f, 0.f, 0.4f ), CIRCLE_STEPS, i);
- }
- }
- gGL.popMatrix();
-
- if (mHighlightedPart == LL_ROT_ROLL)
- {
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
- }
-
- }
-
- }
-
- gUIProgram.bind();
- }
- gGL.popMatrix();
- gGL.popMatrix();
-
-
- LLVector3 euler_angles;
- LLQuaternion object_rot = first_object->getRotationEdit();
- object_rot.getEulerAngles(&(euler_angles.mV[VX]), &(euler_angles.mV[VY]), &(euler_angles.mV[VZ]));
- euler_angles *= RAD_TO_DEG;
- euler_angles.mV[VX] = ll_round(fmodf(euler_angles.mV[VX] + 360.f, 360.f), 0.05f);
- euler_angles.mV[VY] = ll_round(fmodf(euler_angles.mV[VY] + 360.f, 360.f), 0.05f);
- euler_angles.mV[VZ] = ll_round(fmodf(euler_angles.mV[VZ] + 360.f, 360.f), 0.05f);
-
- renderXYZ(euler_angles);
+ LLGLSUIDefault gls_ui;
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
+ LLGLDepthTest gls_depth(GL_TRUE);
+ LLGLEnable gl_blend(GL_BLEND);
+
+ // You can rotate if you can move
+ LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);
+ if( !first_object )
+ {
+ return;
+ }
+
+ if( !updateVisiblity() )
+ {
+ return;
+ }
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 zoom = gAgentCamera.mHUDCurZoom;
+ gGL.scalef(zoom, zoom, zoom);
+ }
+
+
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+
+ LLColor4 highlight_outside( 1.f, 1.f, 0.f, 1.f );
+ LLColor4 highlight_inside( 0.7f, 0.7f, 0.f, 0.5f );
+ F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS;
+
+ gGL.pushMatrix();
+ {
+
+ // are we in the middle of a constrained drag?
+ if (mManipPart >= LL_ROT_X && mManipPart <= LL_ROT_Z)
+ {
+ renderSnapGuides();
+ }
+ else
+ {
+ gDebugProgram.bind();
+
+ LLGLEnable cull_face(GL_CULL_FACE);
+ LLGLDepthTest gls_depth(GL_FALSE);
+ gGL.pushMatrix();
+ {
+ // Draw "sphere" (intersection of sphere with tangent cone that has apex at camera)
+ gGL.translatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] );
+ gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
+
+ // Inverse change of basis vectors
+ LLVector3 forward = mCenterToCamNorm;
+ LLVector3 left = gAgent.getUpAxis() % forward;
+ left.normVec();
+ LLVector3 up = forward % left;
+
+ LLVector4 a(-forward);
+ a.mV[3] = 0;
+ LLVector4 b(up);
+ b.mV[3] = 0;
+ LLVector4 c(left);
+ c.mV[3] = 0;
+ LLMatrix4 mat;
+ mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f));
+
+ gGL.multMatrix( &mat.mMatrix[0][0] );
+
+ gGL.rotatef( -90, 0.f, 1.f, 0.f);
+ LLColor4 color;
+ if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL)
+ {
+ color.setVec(0.8f, 0.8f, 0.8f, 0.8f);
+ gGL.scalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]);
+ }
+ else
+ {
+ color.setVec( 0.7f, 0.7f, 0.7f, 0.6f );
+ }
+ gGL.diffuseColor4fv(color.mV);
+ gl_washer_2d(mRadiusMeters + width_meters, mRadiusMeters, CIRCLE_STEPS, color, color);
+
+
+ if (mManipPart == LL_NO_PART)
+ {
+ gGL.color4f( 0.7f, 0.7f, 0.7f, 0.3f );
+ gGL.diffuseColor4f(0.7f, 0.7f, 0.7f, 0.3f);
+ gl_circle_2d( 0, 0, mRadiusMeters, CIRCLE_STEPS, TRUE );
+ }
+
+ gGL.flush();
+ }
+ gGL.popMatrix();
+
+ gUIProgram.bind();
+ }
+
+ gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
+
+ LLQuaternion rot;
+ F32 angle_radians, x, y, z;
+
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+
+ gDebugProgram.bind();
+
+ if (mManipPart == LL_ROT_Z)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.pushMatrix();
+ {
+ // selected part
+ gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
+ renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f) , LLColor4( 0.f, 0.f, 1.f, 0.3f ));
+ }
+ gGL.popMatrix();
+ }
+ else if (mManipPart == LL_ROT_Y)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.pushMatrix();
+ {
+ gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
+ gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
+ renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f));
+ }
+ gGL.popMatrix();
+ }
+ else if (mManipPart == LL_ROT_X)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.pushMatrix();
+ {
+ gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
+ gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
+ renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f));
+ }
+ gGL.popMatrix();
+ }
+ else if (mManipPart == LL_ROT_ROLL)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ }
+ else if (mManipPart == LL_NO_PART)
+ {
+ if (mHighlightedPart == LL_NO_PART)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ }
+
+ LLGLEnable cull_face(GL_CULL_FACE);
+ LLGLEnable clip_plane0(GL_CLIP_PLANE0);
+ LLGLDepthTest gls_depth(GL_FALSE);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
+
+ // First pass: centers. Second pass: sides.
+ for( S32 i=0; i<2; i++ )
+ {
+
+ gGL.pushMatrix();
+ {
+ if (mHighlightedPart == LL_ROT_Z)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
+ // hovering over part
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i);
+ }
+ else
+ {
+ // default
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 0.8f, 0.8f ), LLColor4( 0.f, 0.f, 0.8f, 0.4f ), CIRCLE_STEPS, i);
+ }
+ }
+ gGL.popMatrix();
+
+ gGL.pushMatrix();
+ {
+ gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
+ if (mHighlightedPart == LL_ROT_Y)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
+ // hovering over part
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
+ }
+ else
+ {
+ // default
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.8f, 0.f, 0.8f ), LLColor4( 0.f, 0.8f, 0.f, 0.4f ), CIRCLE_STEPS, i);
+ }
+ }
+ gGL.popMatrix();
+
+ gGL.pushMatrix();
+ {
+ gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
+ if (mHighlightedPart == LL_ROT_X)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
+
+ // hovering over part
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f ), LLColor4( 1.f, 0.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
+ }
+ else
+ {
+ // default
+ gl_ring( mRadiusMeters, width_meters, LLColor4( 0.8f, 0.f, 0.f, 0.8f ), LLColor4( 0.8f, 0.f, 0.f, 0.4f ), CIRCLE_STEPS, i);
+ }
+ }
+ gGL.popMatrix();
+
+ if (mHighlightedPart == LL_ROT_ROLL)
+ {
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ }
+
+ }
+
+ }
+
+ gUIProgram.bind();
+ }
+ gGL.popMatrix();
+ gGL.popMatrix();
+
+
+ LLVector3 euler_angles;
+ LLQuaternion object_rot = first_object->getRotationEdit();
+ object_rot.getEulerAngles(&(euler_angles.mV[VX]), &(euler_angles.mV[VY]), &(euler_angles.mV[VZ]));
+ euler_angles *= RAD_TO_DEG;
+ euler_angles.mV[VX] = ll_round(fmodf(euler_angles.mV[VX] + 360.f, 360.f), 0.05f);
+ euler_angles.mV[VY] = ll_round(fmodf(euler_angles.mV[VY] + 360.f, 360.f), 0.05f);
+ euler_angles.mV[VZ] = ll_round(fmodf(euler_angles.mV[VZ] + 360.f, 360.f), 0.05f);
+
+ renderXYZ(euler_angles);
}
BOOL LLManipRotate::handleMouseDown(S32 x, S32 y, MASK mask)
{
- BOOL handled = FALSE;
-
- LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);
- if( first_object )
- {
- if( mHighlightedPart != LL_NO_PART )
- {
- handled = handleMouseDownOnPart( x, y, mask );
- }
- }
-
- return handled;
+ BOOL handled = FALSE;
+
+ LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);
+ if( first_object )
+ {
+ if( mHighlightedPart != LL_NO_PART )
+ {
+ handled = handleMouseDownOnPart( x, y, mask );
+ }
+ }
+
+ return handled;
}
// Assumes that one of the parts of the manipulator was hit.
BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
{
- BOOL can_rotate = canAffectSelection();
- if (!can_rotate)
- {
- return FALSE;
- }
-
- highlightManipulators(x, y);
- S32 hit_part = mHighlightedPart;
- // we just started a drag, so save initial object positions
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE);
-
- // save selection center
- mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstance()->getSelectionCenterGlobal();
-
- mManipPart = (EManipPart)hit_part;
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
-
- if( mManipPart == LL_ROT_GENERAL)
- {
- mMouseDown = intersectMouseWithSphere( x, y, center, mRadiusMeters);
- }
- else
- {
- // Project onto the plane of the ring
- LLVector3 axis = getConstraintAxis();
-
- F32 axis_onto_cam = llabs( axis * mCenterToCamNorm );
- const F32 AXIS_ONTO_CAM_TOL = cos( 85.f * DEG_TO_RAD );
- if( axis_onto_cam < AXIS_ONTO_CAM_TOL )
- {
- LLVector3 up_from_axis = mCenterToCamNorm % axis;
- up_from_axis.normVec();
- LLVector3 cur_intersection;
- getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam);
- cur_intersection -= center;
- mMouseDown = projected_vec(cur_intersection, up_from_axis);
- F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
- F32 mouse_dist_sqrd = mMouseDown.magVecSquared();
- if (mouse_dist_sqrd > 0.0001f)
- {
- mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
- mouse_dist_sqrd);
- }
- LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, axis);
- mMouseDown += mouse_depth * projected_center_to_cam;
-
- }
- else
- {
- mMouseDown = findNearestPointOnRing( x, y, center, axis ) - center;
- mMouseDown.normVec();
- }
- }
-
- mMouseCur = mMouseDown;
- mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value
-
- // Route future Mouse messages here preemptively. (Release on mouse up.)
- setMouseCapture( TRUE );
- LLSelectMgr::getInstance()->enableSilhouette(FALSE);
-
- mHelpTextTimer.reset();
- sNumTimesHelpTextShown++;
- return TRUE;
+ BOOL can_rotate = canAffectSelection();
+ if (!can_rotate)
+ {
+ return FALSE;
+ }
+
+ highlightManipulators(x, y);
+ S32 hit_part = mHighlightedPart;
+ // we just started a drag, so save initial object positions
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE);
+
+ // save selection center
+ mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstance()->getSelectionCenterGlobal();
+
+ mManipPart = (EManipPart)hit_part;
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+
+ if( mManipPart == LL_ROT_GENERAL)
+ {
+ mMouseDown = intersectMouseWithSphere( x, y, center, mRadiusMeters);
+ }
+ else
+ {
+ // Project onto the plane of the ring
+ LLVector3 axis = getConstraintAxis();
+
+ F32 axis_onto_cam = llabs( axis * mCenterToCamNorm );
+ const F32 AXIS_ONTO_CAM_TOL = cos( 85.f * DEG_TO_RAD );
+ if( axis_onto_cam < AXIS_ONTO_CAM_TOL )
+ {
+ LLVector3 up_from_axis = mCenterToCamNorm % axis;
+ up_from_axis.normVec();
+ LLVector3 cur_intersection;
+ getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam);
+ cur_intersection -= center;
+ mMouseDown = projected_vec(cur_intersection, up_from_axis);
+ F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+ F32 mouse_dist_sqrd = mMouseDown.magVecSquared();
+ if (mouse_dist_sqrd > 0.0001f)
+ {
+ mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
+ mouse_dist_sqrd);
+ }
+ LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, axis);
+ mMouseDown += mouse_depth * projected_center_to_cam;
+
+ }
+ else
+ {
+ mMouseDown = findNearestPointOnRing( x, y, center, axis ) - center;
+ mMouseDown.normVec();
+ }
+ }
+
+ mMouseCur = mMouseDown;
+ mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value
+
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ setMouseCapture( TRUE );
+ LLSelectMgr::getInstance()->enableSilhouette(FALSE);
+
+ mHelpTextTimer.reset();
+ sNumTimesHelpTextShown++;
+ return TRUE;
}
LLVector3 LLManipRotate::findNearestPointOnRing( S32 x, S32 y, const LLVector3& center, const LLVector3& axis )
{
- // Project the delta onto the ring and rescale it by the radius so that it's _on_ the ring.
- LLVector3 proj_onto_ring;
- getMousePointOnPlaneAgent(proj_onto_ring, x, y, center, axis);
- proj_onto_ring -= center;
- proj_onto_ring.normVec();
+ // Project the delta onto the ring and rescale it by the radius so that it's _on_ the ring.
+ LLVector3 proj_onto_ring;
+ getMousePointOnPlaneAgent(proj_onto_ring, x, y, center, axis);
+ proj_onto_ring -= center;
+ proj_onto_ring.normVec();
- return center + proj_onto_ring * mRadiusMeters;
+ return center + proj_onto_ring * mRadiusMeters;
}
BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask)
{
- // first, perform normal processing in case this was a quick-click
- handleHover(x, y, mask);
-
- if( hasMouseCapture() )
- {
- for (LLObjectSelection::iterator iter = mObjectSelection->begin();
- iter != mObjectSelection->end(); iter++)
- {
- LLSelectNode* selectNode = *iter;
- LLViewerObject* object = selectNode->getObject();
- LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
-
- // have permission to move and object is root of selection or individually selected
- if (object->permMove() && !object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- (object->isRootEdit() || selectNode->mIndividualSelection))
- {
- object->mUnselectedChildrenPositions.clear() ;
- }
- }
-
- mManipPart = LL_NO_PART;
-
- // Might have missed last update due to timing.
- LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION );
- LLSelectMgr::getInstance()->enableSilhouette(TRUE);
- //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
-
- LLSelectMgr::getInstance()->updateSelectionCenter();
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- }
-
- return LLManip::handleMouseUp(x, y, mask);
+ // first, perform normal processing in case this was a quick-click
+ handleHover(x, y, mask);
+
+ if( hasMouseCapture() )
+ {
+ for (LLObjectSelection::iterator iter = mObjectSelection->begin();
+ iter != mObjectSelection->end(); iter++)
+ {
+ LLSelectNode* selectNode = *iter;
+ LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
+
+ // have permission to move and object is root of selection or individually selected
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (object->isRootEdit() || selectNode->mIndividualSelection))
+ {
+ object->mUnselectedChildrenPositions.clear() ;
+ }
+ }
+
+ mManipPart = LL_NO_PART;
+
+ // Might have missed last update due to timing.
+ LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION );
+ LLSelectMgr::getInstance()->enableSilhouette(TRUE);
+ //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
+
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ }
+
+ return LLManip::handleMouseUp(x, y, mask);
}
BOOL LLManipRotate::handleHover(S32 x, S32 y, MASK mask)
{
- if( hasMouseCapture() )
- {
- if( mObjectSelection->isEmpty() )
- {
- // Somehow the object got deselected while we were dragging it.
- setMouseCapture( FALSE );
- }
- else
- {
- drag(x, y);
- }
-
- LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (active)" << LL_ENDL;
- }
- else
- {
- highlightManipulators(x, y);
- LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (inactive)" << LL_ENDL;
- }
-
- gViewerWindow->setCursor(UI_CURSOR_TOOLROTATE);
- return TRUE;
+ if( hasMouseCapture() )
+ {
+ if( mObjectSelection->isEmpty() )
+ {
+ // Somehow the object got deselected while we were dragging it.
+ setMouseCapture( FALSE );
+ }
+ else
+ {
+ drag(x, y);
+ }
+
+ LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (active)" << LL_ENDL;
+ }
+ else
+ {
+ highlightManipulators(x, y);
+ LL_DEBUGS("UserInput") << "hover handled by LLManipRotate (inactive)" << LL_ENDL;
+ }
+
+ gViewerWindow->setCursor(UI_CURSOR_TOOLROTATE);
+ return TRUE;
}
-LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere )
+LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere )
{
- F32 z = 0.f;
- F32 dist_squared = x*x + y*y;
+ F32 z = 0.f;
+ F32 dist_squared = x*x + y*y;
- *on_sphere = dist_squared <= SQ_RADIUS;
+ *on_sphere = dist_squared <= SQ_RADIUS;
if( *on_sphere )
- {
+ {
z = sqrt(SQ_RADIUS - dist_squared);
}
- return LLVector3( x, y, z );
+ return LLVector3( x, y, z );
}
// Freeform rotation
void LLManipRotate::drag( S32 x, S32 y )
{
- if( !updateVisiblity() )
- {
- return;
- }
-
- if( mManipPart == LL_ROT_GENERAL )
- {
- mRotation = dragUnconstrained(x, y);
- }
- else
- {
- mRotation = dragConstrained(x, y);
- }
-
- BOOL damped = mSmoothRotate;
- mSmoothRotate = FALSE;
-
- for (LLObjectSelection::iterator iter = mObjectSelection->begin();
- iter != mObjectSelection->end(); iter++)
- {
- LLSelectNode* selectNode = *iter;
- LLViewerObject* object = selectNode->getObject();
- LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
-
- // have permission to move and object is root of selection or individually selected
- if (object->permMove() && !object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- (object->isRootEdit() || selectNode->mIndividualSelection))
- {
- if (!object->isRootEdit())
+ if( !updateVisiblity() )
+ {
+ return;
+ }
+
+ if( mManipPart == LL_ROT_GENERAL )
+ {
+ mRotation = dragUnconstrained(x, y);
+ }
+ else
+ {
+ mRotation = dragConstrained(x, y);
+ }
+
+ BOOL damped = mSmoothRotate;
+ mSmoothRotate = FALSE;
+ bool gltf_mode = false;
+
+ for (LLObjectSelection::iterator iter = mObjectSelection->begin();
+ iter != mObjectSelection->end(); iter++)
+ {
+ LLSelectNode* selectNode = *iter;
+ LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
+
+ // have permission to move and object is root of selection or individually selected
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (object->isRootEdit() || selectNode->mIndividualSelection))
+ {
+
+ if (selectNode->mSelectedGLTFNode != -1)
{
- // child objects should not update if parent is selected
- LLViewerObject* editable_root = (LLViewerObject*)object->getParent();
- if (editable_root->isSelected())
- {
- // we will be moved properly by our parent, so skip
- continue;
- }
- }
+ LLQuaternion new_rot = selectNode->mSavedRotation * mRotation;
- LLQuaternion new_rot = selectNode->mSavedRotation * mRotation;
- std::vector<LLVector3>& child_positions = object->mUnselectedChildrenPositions ;
- std::vector<LLQuaternion> child_rotations;
- if (object->isRootEdit() && selectNode->mIndividualSelection)
- {
- object->saveUnselectedChildrenRotation(child_rotations) ;
- object->saveUnselectedChildrenPosition(child_positions) ;
- }
+ object->setGLTFNodeRotationAgent(selectNode->mSelectedGLTFNode, new_rot);
- if (object->getParent() && object->mDrawable.notNull())
- {
- LLQuaternion invParentRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
- invParentRotation.transQuat();
-
- object->setRotation(new_rot * invParentRotation, damped);
- rebuild(object);
+ gltf_mode = true;
}
- else
+ else if (!gltf_mode)
{
- object->setRotation(new_rot, damped);
- LLVOAvatar* avatar = object->asAvatar();
- if (avatar && avatar->isSelf()
- && LLSelectMgr::getInstance()->mAllowSelectAvatar
- && !object->getParent())
+ if (!object->isRootEdit())
{
- // Normal avatars use object's orienttion, but self uses
- // separate LLCoordFrame
- // See LVOAvatar::updateOrientation()
- if (gAgentCamera.getFocusOnAvatar())
+ // child objects should not update if parent is selected
+ LLViewerObject* editable_root = (LLViewerObject*)object->getParent();
+ if (editable_root->isSelected())
{
- //Don't rotate camera with avatar
- gAgentCamera.setFocusOnAvatar(false, false, false);
+ // we will be moved properly by our parent, so skip
+ continue;
}
-
- LLVector3 at_axis = mAgentSelfAtAxis;
- at_axis *= mRotation;
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis);
}
- rebuild(object);
- }
-
- // for individually selected roots, we need to counterrotate all the children
- if (object->isRootEdit() && selectNode->mIndividualSelection)
- {
- //RN: must do non-damped updates on these objects so relative rotation appears constant
- // instead of having two competing slerps making the child objects appear to "wobble"
- object->resetChildrenRotationAndPosition(child_rotations, child_positions) ;
- }
- }
- }
-
- // update positions
- for (LLObjectSelection::iterator iter = mObjectSelection->begin();
- iter != mObjectSelection->end(); iter++)
- {
- LLSelectNode* selectNode = *iter;
- LLViewerObject* object = selectNode->getObject();
- LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
- // to avoid cumulative position changes we calculate the objects new position using its saved position
- if (object && object->permMove() && !object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()))
- {
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
-
- LLVector3 old_position;
- LLVector3 new_position;
-
- if (object->isAttachment() && object->mDrawable.notNull())
- {
- // need to work in drawable space to handle selected items from multiple attachments
- // (which have no shared frame of reference other than their render positions)
- LLXform* parent_xform = object->mDrawable->getXform()->getParent();
- new_position = (selectNode->mSavedPositionLocal * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
- old_position = (object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();//object->getRenderPosition();
- }
- else
- {
- new_position = gAgent.getPosAgentFromGlobal( selectNode->mSavedPositionGlobal );
- old_position = object->getPositionAgent();
- }
-
- new_position = (new_position - center) * mRotation; // new relative rotated position
- new_position += center;
-
- if (object->isRootEdit() && !object->isAttachment())
- {
- LLVector3d new_pos_global = gAgent.getPosGlobalFromAgent(new_position);
- new_pos_global = LLWorld::getInstance()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, new_pos_global);
- new_position = gAgent.getPosAgentFromGlobal(new_pos_global);
- }
-
- // for individually selected child objects
- if (!object->isRootEdit() && selectNode->mIndividualSelection)
- {
- LLViewerObject* parentp = (LLViewerObject*)object->getParent();
- if (!parentp->isSelected())
+ LLQuaternion new_rot = selectNode->mSavedRotation * mRotation;
+ std::vector<LLVector3>& child_positions = object->mUnselectedChildrenPositions;
+ std::vector<LLQuaternion> child_rotations;
+ if (object->isRootEdit() && selectNode->mIndividualSelection)
{
- if (object->isAttachment() && object->mDrawable.notNull())
- {
- // find position relative to render position of parent
- object->setPosition((new_position - parentp->getRenderPosition()) * ~parentp->getRenderRotation());
- rebuild(object);
- }
- else
- {
- object->setPositionParent((new_position - parentp->getPositionAgent()) * ~parentp->getRotationRegion());
- rebuild(object);
- }
+ object->saveUnselectedChildrenRotation(child_rotations);
+ object->saveUnselectedChildrenPosition(child_positions);
}
- }
- else if (object->isRootEdit())
- {
- if (object->isAttachment() && object->mDrawable.notNull())
+
+ if (object->getParent() && object->mDrawable.notNull())
{
- LLXform* parent_xform = object->mDrawable->getXform()->getParent();
- object->setPosition((new_position - parent_xform->getWorldPosition()) * ~parent_xform->getWorldRotation());
+ LLQuaternion invParentRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
+ invParentRotation.transQuat();
+
+ object->setRotation(new_rot * invParentRotation, damped);
rebuild(object);
}
else
{
- object->setPositionAgent(new_position);
+ object->setRotation(new_rot, damped);
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar && avatar->isSelf()
+ && LLSelectMgr::getInstance()->mAllowSelectAvatar
+ && !object->getParent())
+ {
+ // Normal avatars use object's orienttion, but self uses
+ // separate LLCoordFrame
+ // See LVOAvatar::updateOrientation()
+ if (gAgentCamera.getFocusOnAvatar())
+ {
+ //Don't rotate camera with avatar
+ gAgentCamera.setFocusOnAvatar(false, false, false);
+ }
+
+ LLVector3 at_axis = mAgentSelfAtAxis;
+ at_axis *= mRotation;
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis);
+ }
rebuild(object);
}
- }
- // for individually selected roots, we need to counter-translate all unselected children
- if (object->isRootEdit() && selectNode->mIndividualSelection)
- {
- // only offset by parent's translation as we've already countered parent's rotation
- rebuild(object);
- object->resetChildrenPosition(old_position - new_position) ;
+ // for individually selected roots, we need to counterrotate all the children
+ if (object->isRootEdit() && selectNode->mIndividualSelection)
+ {
+ //RN: must do non-damped updates on these objects so relative rotation appears constant
+ // instead of having two competing slerps making the child objects appear to "wobble"
+ object->resetChildrenRotationAndPosition(child_rotations, child_positions);
+ }
}
- }
- }
+ }
+ }
- // store changes to override updates
- for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
- iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
+ // update positions
+ if (!gltf_mode)
{
- LLSelectNode* selectNode = *iter;
- LLViewerObject*cur = selectNode->getObject();
- LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
- if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar))
+ for (LLObjectSelection::iterator iter = mObjectSelection->begin();
+ iter != mObjectSelection->end(); iter++)
{
- selectNode->mLastRotation = cur->getRotation();
- selectNode->mLastPositionLocal = cur->getPosition();
- }
- }
-
- LLSelectMgr::getInstance()->updateSelectionCenter();
-
- // RN: just clear focus so camera doesn't follow spurious object updates
- gAgentCamera.clearFocusObject();
- dialog_refresh_all();
-}
-
-void LLManipRotate::renderActiveRing( F32 radius, F32 width, const LLColor4& front_color, const LLColor4& back_color)
-{
- LLGLEnable cull_face(GL_CULL_FACE);
- {
- gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, FALSE);
- gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, TRUE);
- }
- {
- LLGLDepthTest gls_depth(GL_FALSE);
- gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, FALSE);
- gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, TRUE);
- }
-}
-
-void LLManipRotate::renderSnapGuides()
-{
- static LLCachedControl<bool> snap_enabled(gSavedSettings, "SnapEnabled", true);
- if (!snap_enabled)
- {
- return;
- }
-
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true);
-
- LLVector3 constraint_axis = getConstraintAxis();
-
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
- LLVector3 cam_at_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_at_axis.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_at_axis = center - gAgentCamera.getCameraPositionAgent();
- cam_at_axis.normVec();
- }
-
- LLVector3 world_snap_axis;
- LLVector3 test_axis = constraint_axis;
-
- BOOL constrain_to_ref_object = FALSE;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
- {
- test_axis = test_axis * ~grid_rotation;
- }
- else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
- {
- test_axis = test_axis * ~grid_rotation;
- constrain_to_ref_object = TRUE;
- }
-
- test_axis.abs();
-
- // find closest global/reference axis to local constraint axis;
- if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ])
- {
- world_snap_axis = LLVector3::y_axis;
- }
- else if (test_axis.mV[VY] > test_axis.mV[VZ])
- {
- world_snap_axis = LLVector3::z_axis;
- }
- else
- {
- world_snap_axis = LLVector3::x_axis;
- }
-
- LLVector3 projected_snap_axis = world_snap_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
- {
- projected_snap_axis = projected_snap_axis * grid_rotation;
- }
- else if (constrain_to_ref_object)
- {
- projected_snap_axis = projected_snap_axis * grid_rotation;
- }
-
- // project world snap axis onto constraint plane
- projected_snap_axis -= projected_vec(projected_snap_axis, constraint_axis);
- projected_snap_axis.normVec();
+ LLSelectNode* selectNode = *iter;
+ LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
- S32 num_rings = mCamEdgeOn ? 2 : 1;
- for (S32 ring_num = 0; ring_num < num_rings; ring_num++)
- {
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
- if (mCamEdgeOn)
- {
- // draw two opposing rings
- if (ring_num == 0)
- {
- center += constraint_axis * mRadiusMeters * 0.5f;
- }
- else
+ // to avoid cumulative position changes we calculate the objects new position using its saved position
+ if (object && object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()))
{
- center -= constraint_axis * mRadiusMeters * 0.5f;
- }
- }
-
- LLGLDepthTest gls_depth(GL_FALSE);
- for (S32 pass = 0; pass < 3; pass++)
- {
- // render snap guide ring
- gGL.pushMatrix();
-
- LLQuaternion snap_guide_rot;
- F32 angle_radians, x, y, z;
- snap_guide_rot.shortestArc(LLVector3::z_axis, getConstraintAxis());
- snap_guide_rot.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+ LLVector3 center = gAgent.getPosAgentFromGlobal(mRotationCenter);
- LLColor4 line_color = setupSnapGuideRenderPass(pass);
+ LLVector3 old_position;
+ LLVector3 new_position;
- gGL.color4fv(line_color.mV);
-
- if (mCamEdgeOn)
- {
- // render an arc
- LLVector3 edge_normal = cam_at_axis % constraint_axis;
- edge_normal.normVec();
- LLVector3 x_axis_snap = LLVector3::x_axis * snap_guide_rot;
- LLVector3 y_axis_snap = LLVector3::y_axis * snap_guide_rot;
-
- F32 end_angle = atan2(y_axis_snap * edge_normal, x_axis_snap * edge_normal);
- //F32 start_angle = angle_between((-1.f * LLVector3::x_axis) * snap_guide_rot, edge_normal);
- F32 start_angle = end_angle - F_PI;
- gl_arc_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE, start_angle, end_angle);
- }
- else
- {
- gl_circle_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE);
- }
- gGL.popMatrix();
+ if (selectNode->mSelectedGLTFNode != -1)
+ {
- for (S32 i = 0; i < 64; i++)
- {
- BOOL render_text = TRUE;
- F32 deg = 5.625f * (F32)i;
- LLVector3 inner_point;
- LLVector3 outer_point;
- LLVector3 text_point;
- LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis);
- gGL.begin(LLRender::LINES);
+ }
+ else
{
- inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center;
- F32 tick_length = 0.f;
- if (i % 16 == 0)
- {
- tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_1 - SNAP_GUIDE_INNER_RADIUS);
- }
- else if (i % 8 == 0)
- {
- tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_2 - SNAP_GUIDE_INNER_RADIUS);
- }
- else if (i % 4 == 0)
- {
- tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_3 - SNAP_GUIDE_INNER_RADIUS);
- }
- else if (i % 2 == 0)
+ if (object->isAttachment() && object->mDrawable.notNull())
{
- tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_4 - SNAP_GUIDE_INNER_RADIUS);
+ // need to work in drawable space to handle selected items from multiple attachments
+ // (which have no shared frame of reference other than their render positions)
+ LLXform* parent_xform = object->mDrawable->getXform()->getParent();
+ new_position = (selectNode->mSavedPositionLocal * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
+ old_position = (object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();//object->getRenderPosition();
}
else
{
- tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_5 - SNAP_GUIDE_INNER_RADIUS);
+ new_position = gAgent.getPosAgentFromGlobal(selectNode->mSavedPositionGlobal);
+ old_position = object->getPositionAgent();
}
- if (mCamEdgeOn)
- {
- // don't draw ticks that are on back side of circle
- F32 dot = cam_at_axis * (projected_snap_axis * rot);
- if (dot > 0.f)
- {
- outer_point = inner_point;
- render_text = FALSE;
- }
- else
- {
- if (ring_num == 0)
- {
- outer_point = inner_point + (constraint_axis * tick_length) * rot;
- }
- else
- {
- outer_point = inner_point - (constraint_axis * tick_length) * rot;
- }
- }
- }
- else
+ new_position = (new_position - center) * mRotation; // new relative rotated position
+ new_position += center;
+
+ if (object->isRootEdit() && !object->isAttachment())
{
- outer_point = inner_point + (projected_snap_axis * tick_length) * rot;
+ LLVector3d new_pos_global = gAgent.getPosGlobalFromAgent(new_position);
+ new_pos_global = LLWorld::getInstance()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, new_pos_global);
+ new_position = gAgent.getPosAgentFromGlobal(new_pos_global);
}
- text_point = outer_point + (projected_snap_axis * mRadiusMeters * 0.1f) * rot;
-
- gGL.vertex3fv(inner_point.mV);
- gGL.vertex3fv(outer_point.mV);
- }
- gGL.end();
-
- //RN: text rendering does own shadow pass, so only render once
- if (pass == 1 && render_text && i % 16 == 0)
- {
- if (world_snap_axis.mV[VX])
+ // for individually selected child objects
+ if (!object->isRootEdit() && selectNode->mIndividualSelection)
{
- if (i == 0)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
- }
- else if (i == 16)
- {
- if (constraint_axis.mV[VZ] > 0.f)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
- }
- else
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
- }
- }
- else if (i == 32)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
- }
- else
+ LLViewerObject* parentp = (LLViewerObject*)object->getParent();
+ if (!parentp->isSelected())
{
- if (constraint_axis.mV[VZ] > 0.f)
+ if (object->isAttachment() && object->mDrawable.notNull())
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
+ // find position relative to render position of parent
+ object->setPosition((new_position - parentp->getRenderPosition()) * ~parentp->getRenderRotation());
+ rebuild(object);
}
else
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
+ object->setPositionParent((new_position - parentp->getPositionAgent()) * ~parentp->getRotationRegion());
+ rebuild(object);
}
}
}
- else if (world_snap_axis.mV[VY])
+ else if (object->isRootEdit())
{
- if (i == 0)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
- }
- else if (i == 16)
+ if (object->isAttachment() && object->mDrawable.notNull())
{
- if (constraint_axis.mV[VX] > 0.f)
- {
- renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
- }
- else
- {
- renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
- }
- }
- else if (i == 32)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
+ LLXform* parent_xform = object->mDrawable->getXform()->getParent();
+ object->setPosition((new_position - parent_xform->getWorldPosition()) * ~parent_xform->getWorldRotation());
+ rebuild(object);
}
else
{
- if (constraint_axis.mV[VX] > 0.f)
- {
- renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
- }
- else
- {
- renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
- }
+ object->setPositionAgent(new_position);
+ rebuild(object);
}
}
- else if (world_snap_axis.mV[VZ])
- {
- if (i == 0)
- {
- renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
- }
- else if (i == 16)
- {
- if (constraint_axis.mV[VY] > 0.f)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
- }
- else
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
- }
- }
- else if (i == 32)
- {
- renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
- }
- else
- {
- if (constraint_axis.mV[VY] > 0.f)
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
- }
- else
- {
- renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
- }
- }
- }
- }
- gGL.color4fv(line_color.mV);
- }
- // now render projected object axis
- if (mInSnapRegime)
- {
- LLVector3 object_axis;
- getObjectAxisClosestToMouse(object_axis);
-
- // project onto constraint plane
- LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE);
- object_axis = object_axis * first_node->getObject()->getRenderRotation();
- object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
- object_axis.normVec();
- object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center;
- LLVector3 line_start = center;
-
- gGL.begin(LLRender::LINES);
- {
- gGL.vertex3fv(line_start.mV);
- gGL.vertex3fv(object_axis.mV);
- }
- gGL.end();
-
- // draw snap guide arrow
- gGL.begin(LLRender::TRIANGLES);
- {
- LLVector3 arrow_dir;
- LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
- arrow_span.normVec();
-
- arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start;
- arrow_dir.normVec();
- if (ring_num == 1)
+ // for individually selected roots, we need to counter-translate all unselected children
+ if (object->isRootEdit() && selectNode->mIndividualSelection)
{
- arrow_dir *= -1.f;
- }
- gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV);
- gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV);
- gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV);
- }
- gGL.end();
-
- {
- LLGLDepthTest gls_depth(GL_TRUE);
- gGL.begin(LLRender::LINES);
- {
- gGL.vertex3fv(line_start.mV);
- gGL.vertex3fv(object_axis.mV);
- }
- gGL.end();
-
- // draw snap guide arrow
- gGL.begin(LLRender::TRIANGLES);
- {
- LLVector3 arrow_dir;
- LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
- arrow_span.normVec();
-
- arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start;
- arrow_dir.normVec();
- if (ring_num == 1)
- {
- arrow_dir *= -1.f;
- }
-
- gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV);
- gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV);
- gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV);
+ // only offset by parent's translation as we've already countered parent's rotation
+ rebuild(object);
+ object->resetChildrenPosition(old_position - new_position);
}
- gGL.end();
}
}
}
}
+ // store changes to override updates
+ for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
+ {
+ LLSelectNode* selectNode = *iter;
+ LLViewerObject*cur = selectNode->getObject();
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
- // render help text
- if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
- {
- if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
- {
- LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
-
- LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis();
-
- F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar))
+ {
+ selectNode->mLastRotation = cur->getRotation();
+ selectNode->mLastPositionLocal = cur->getPosition();
+ }
+ }
+
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+
+ // RN: just clear focus so camera doesn't follow spurious object updates
+ gAgentCamera.clearFocusObject();
+ dialog_refresh_all();
+}
- LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir);
- const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+void LLManipRotate::renderActiveRing( F32 radius, F32 width, const LLColor4& front_color, const LLColor4& back_color)
+{
+ LLGLEnable cull_face(GL_CULL_FACE);
+ {
+ gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, FALSE);
+ gl_ring(radius, width, back_color, back_color * 0.5f, CIRCLE_STEPS, TRUE);
+ }
+ {
+ LLGLDepthTest gls_depth(GL_FALSE);
+ gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, FALSE);
+ gl_ring(radius, width, front_color, front_color * 0.5f, CIRCLE_STEPS, TRUE);
+ }
+}
- std::string help_text = LLTrans::getString("manip_hint1");
- LLColor4 help_text_color = LLColor4::white;
- help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
- help_text = LLTrans::getString("manip_hint2");
- help_text_pos -= offset_dir * mRadiusMeters * 0.4f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
- }
- }
+void LLManipRotate::renderSnapGuides()
+{
+ static LLCachedControl<bool> snap_enabled(gSavedSettings, "SnapEnabled", true);
+ if (!snap_enabled)
+ {
+ return;
+ }
+
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true);
+
+ LLVector3 constraint_axis = getConstraintAxis();
+
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+ LLVector3 cam_at_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_at_axis.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_at_axis = center - gAgentCamera.getCameraPositionAgent();
+ cam_at_axis.normVec();
+ }
+
+ LLVector3 world_snap_axis;
+ LLVector3 test_axis = constraint_axis;
+
+ BOOL constrain_to_ref_object = FALSE;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+ {
+ test_axis = test_axis * ~grid_rotation;
+ }
+ else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
+ {
+ test_axis = test_axis * ~grid_rotation;
+ constrain_to_ref_object = TRUE;
+ }
+
+ test_axis.abs();
+
+ // find closest global/reference axis to local constraint axis;
+ if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ])
+ {
+ world_snap_axis = LLVector3::y_axis;
+ }
+ else if (test_axis.mV[VY] > test_axis.mV[VZ])
+ {
+ world_snap_axis = LLVector3::z_axis;
+ }
+ else
+ {
+ world_snap_axis = LLVector3::x_axis;
+ }
+
+ LLVector3 projected_snap_axis = world_snap_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+ {
+ projected_snap_axis = projected_snap_axis * grid_rotation;
+ }
+ else if (constrain_to_ref_object)
+ {
+ projected_snap_axis = projected_snap_axis * grid_rotation;
+ }
+
+ // project world snap axis onto constraint plane
+ projected_snap_axis -= projected_vec(projected_snap_axis, constraint_axis);
+ projected_snap_axis.normVec();
+
+ S32 num_rings = mCamEdgeOn ? 2 : 1;
+ for (S32 ring_num = 0; ring_num < num_rings; ring_num++)
+ {
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+
+ if (mCamEdgeOn)
+ {
+ // draw two opposing rings
+ if (ring_num == 0)
+ {
+ center += constraint_axis * mRadiusMeters * 0.5f;
+ }
+ else
+ {
+ center -= constraint_axis * mRadiusMeters * 0.5f;
+ }
+ }
+
+ LLGLDepthTest gls_depth(GL_FALSE);
+ for (S32 pass = 0; pass < 3; pass++)
+ {
+ // render snap guide ring
+ gGL.pushMatrix();
+
+ LLQuaternion snap_guide_rot;
+ F32 angle_radians, x, y, z;
+ snap_guide_rot.shortestArc(LLVector3::z_axis, getConstraintAxis());
+ snap_guide_rot.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+ LLColor4 line_color = setupSnapGuideRenderPass(pass);
+
+ gGL.color4fv(line_color.mV);
+
+ if (mCamEdgeOn)
+ {
+ // render an arc
+ LLVector3 edge_normal = cam_at_axis % constraint_axis;
+ edge_normal.normVec();
+ LLVector3 x_axis_snap = LLVector3::x_axis * snap_guide_rot;
+ LLVector3 y_axis_snap = LLVector3::y_axis * snap_guide_rot;
+
+ F32 end_angle = atan2(y_axis_snap * edge_normal, x_axis_snap * edge_normal);
+ //F32 start_angle = angle_between((-1.f * LLVector3::x_axis) * snap_guide_rot, edge_normal);
+ F32 start_angle = end_angle - F_PI;
+ gl_arc_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE, start_angle, end_angle);
+ }
+ else
+ {
+ gl_circle_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE);
+ }
+ gGL.popMatrix();
+
+ for (S32 i = 0; i < 64; i++)
+ {
+ BOOL render_text = TRUE;
+ F32 deg = 5.625f * (F32)i;
+ LLVector3 inner_point;
+ LLVector3 outer_point;
+ LLVector3 text_point;
+ LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis);
+ gGL.begin(LLRender::LINES);
+ {
+ inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center;
+ F32 tick_length = 0.f;
+ if (i % 16 == 0)
+ {
+ tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_1 - SNAP_GUIDE_INNER_RADIUS);
+ }
+ else if (i % 8 == 0)
+ {
+ tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_2 - SNAP_GUIDE_INNER_RADIUS);
+ }
+ else if (i % 4 == 0)
+ {
+ tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_3 - SNAP_GUIDE_INNER_RADIUS);
+ }
+ else if (i % 2 == 0)
+ {
+ tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_4 - SNAP_GUIDE_INNER_RADIUS);
+ }
+ else
+ {
+ tick_length = mRadiusMeters * (SNAP_GUIDE_RADIUS_5 - SNAP_GUIDE_INNER_RADIUS);
+ }
+
+ if (mCamEdgeOn)
+ {
+ // don't draw ticks that are on back side of circle
+ F32 dot = cam_at_axis * (projected_snap_axis * rot);
+ if (dot > 0.f)
+ {
+ outer_point = inner_point;
+ render_text = FALSE;
+ }
+ else
+ {
+ if (ring_num == 0)
+ {
+ outer_point = inner_point + (constraint_axis * tick_length) * rot;
+ }
+ else
+ {
+ outer_point = inner_point - (constraint_axis * tick_length) * rot;
+ }
+ }
+ }
+ else
+ {
+ outer_point = inner_point + (projected_snap_axis * tick_length) * rot;
+ }
+
+ text_point = outer_point + (projected_snap_axis * mRadiusMeters * 0.1f) * rot;
+
+ gGL.vertex3fv(inner_point.mV);
+ gGL.vertex3fv(outer_point.mV);
+ }
+ gGL.end();
+
+ //RN: text rendering does own shadow pass, so only render once
+ if (pass == 1 && render_text && i % 16 == 0)
+ {
+ if (world_snap_axis.mV[VX])
+ {
+ if (i == 0)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
+ }
+ else if (i == 16)
+ {
+ if (constraint_axis.mV[VZ] > 0.f)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
+ }
+ }
+ else if (i == 32)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
+ }
+ else
+ {
+ if (constraint_axis.mV[VZ] > 0.f)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
+ }
+ }
+ }
+ else if (world_snap_axis.mV[VY])
+ {
+ if (i == 0)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Left") : LLTrans::getString("Direction_North"), LLColor4::white);
+ }
+ else if (i == 16)
+ {
+ if (constraint_axis.mV[VX] > 0.f)
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
+ }
+ }
+ else if (i == 32)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Right") : LLTrans::getString("Direction_South"), LLColor4::white);
+ }
+ else
+ {
+ if (constraint_axis.mV[VX] > 0.f)
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
+ }
+ }
+ }
+ else if (world_snap_axis.mV[VZ])
+ {
+ if (i == 0)
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Up"), LLColor4::white);
+ }
+ else if (i == 16)
+ {
+ if (constraint_axis.mV[VY] > 0.f)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
+ }
+ }
+ else if (i == 32)
+ {
+ renderTickText(text_point, LLTrans::getString("Direction_Down"), LLColor4::white);
+ }
+ else
+ {
+ if (constraint_axis.mV[VY] > 0.f)
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Back") : LLTrans::getString("Direction_West"), LLColor4::white);
+ }
+ else
+ {
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Direction_Forward") : LLTrans::getString("Direction_East"), LLColor4::white);
+ }
+ }
+ }
+ }
+ gGL.color4fv(line_color.mV);
+ }
+
+ // now render projected object axis
+ if (mInSnapRegime)
+ {
+ LLVector3 object_axis;
+ getObjectAxisClosestToMouse(object_axis);
+
+ // project onto constraint plane
+ LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE);
+ object_axis = object_axis * first_node->getObject()->getRenderRotation();
+ object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+ object_axis.normVec();
+ object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center;
+ LLVector3 line_start = center;
+
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.vertex3fv(line_start.mV);
+ gGL.vertex3fv(object_axis.mV);
+ }
+ gGL.end();
+
+ // draw snap guide arrow
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ LLVector3 arrow_dir;
+ LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
+ arrow_span.normVec();
+
+ arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start;
+ arrow_dir.normVec();
+ if (ring_num == 1)
+ {
+ arrow_dir *= -1.f;
+ }
+ gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV);
+ gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV);
+ gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV);
+ }
+ gGL.end();
+
+ {
+ LLGLDepthTest gls_depth(GL_TRUE);
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.vertex3fv(line_start.mV);
+ gGL.vertex3fv(object_axis.mV);
+ }
+ gGL.end();
+
+ // draw snap guide arrow
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ LLVector3 arrow_dir;
+ LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
+ arrow_span.normVec();
+
+ arrow_dir = mCamEdgeOn ? getConstraintAxis() : object_axis - line_start;
+ arrow_dir.normVec();
+ if (ring_num == 1)
+ {
+ arrow_dir *= -1.f;
+ }
+
+ gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV);
+ gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV);
+ gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV);
+ }
+ gGL.end();
+ }
+ }
+ }
+ }
+
+
+ // render help text
+ if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
+ {
+ LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+
+ LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis();
+
+ F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+
+ LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir);
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+
+ std::string help_text = LLTrans::getString("manip_hint1");
+ LLColor4 help_text_color = LLColor4::white;
+ help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
+ help_text_pos -= offset_dir * mRadiusMeters * 0.4f;
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ }
+ }
}
// Returns TRUE if center of sphere is visible. Also sets a bunch of member variables that are used later (e.g. mCenterToCam)
BOOL LLManipRotate::updateVisiblity()
{
- // Don't want to recalculate the center of the selection during a drag.
- // Due to packet delays, sometimes half the objects in the selection have their
- // new position and half have their old one. This creates subtle errors in the
- // computed center position for that frame. Unfortunately, these errors
- // accumulate. The result is objects seem to "fly apart" during rotations.
- // JC - 03.26.2002
- if (!hasMouseCapture())
- {
- mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstance()->getSelectionCenterGlobal();
- }
-
- BOOL visible = FALSE;
-
- //Assume that UI scale factor is equivalent for X and Y axis
- F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX];
-
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- mCenterToCam = LLVector3(-1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
- mCenterToCamNorm = mCenterToCam;
- mCenterToCamMag = mCenterToCamNorm.normVec();
-
- mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
- mRadiusMeters /= gAgentCamera.mHUDCurZoom;
- mRadiusMeters *= ui_scale_factor;
-
- mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
- mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
-
- // x axis range is (-aspect * 0.5f, +aspect * 0.5)
- // y axis range is (-0.5, 0.5)
- // so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates
- mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()),
- (S32)((center.mV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()));
- visible = TRUE;
- }
- else
- {
- visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen );
- if( visible )
- {
- mCenterToCam = gAgentCamera.getCameraPositionAgent() - center;
- mCenterToCamNorm = mCenterToCam;
- mCenterToCamMag = mCenterToCamNorm.normVec();
- LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
- cameraAtAxis.normVec();
-
- F32 z_dist = -1.f * (mCenterToCam * cameraAtAxis);
-
- // Don't drag manip if object too far away
- if (gSavedSettings.getBOOL("LimitSelectDistance"))
- {
- F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance");
- if (dist_vec_squared(gAgent.getPositionAgent(), center) > (max_select_distance * max_select_distance))
- {
- visible = FALSE;
- }
- }
-
- if (mCenterToCamMag > 0.001f)
- {
- F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
- F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
- mRadiusMeters = z_dist * tan(apparent_angle);
- mRadiusMeters *= ui_scale_factor;
-
- mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
- mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
- }
- else
- {
- visible = FALSE;
- }
- }
- }
-
- mCamEdgeOn = FALSE;
- F32 axis_onto_cam = mManipPart >= LL_ROT_X ? llabs( getConstraintAxis() * mCenterToCamNorm ) : 0.f;
- if( axis_onto_cam < AXIS_ONTO_CAM_TOLERANCE )
- {
- mCamEdgeOn = TRUE;
- }
-
- return visible;
+ // Don't want to recalculate the center of the selection during a drag.
+ // Due to packet delays, sometimes half the objects in the selection have their
+ // new position and half have their old one. This creates subtle errors in the
+ // computed center position for that frame. Unfortunately, these errors
+ // accumulate. The result is objects seem to "fly apart" during rotations.
+ // JC - 03.26.2002
+ if (!hasMouseCapture())
+ {
+ mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstance()->getSelectionCenterGlobal();
+ }
+
+ BOOL visible = FALSE;
+
+ //Assume that UI scale factor is equivalent for X and Y axis
+ F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX];
+
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ mCenterToCam = LLVector3(-1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
+ mCenterToCamNorm = mCenterToCam;
+ mCenterToCamMag = mCenterToCamNorm.normVec();
+
+ mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
+ mRadiusMeters /= gAgentCamera.mHUDCurZoom;
+ mRadiusMeters *= ui_scale_factor;
+
+ mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
+ mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
+
+ // x axis range is (-aspect * 0.5f, +aspect * 0.5)
+ // y axis range is (-0.5, 0.5)
+ // so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates
+ mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()),
+ (S32)((center.mV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()));
+ visible = TRUE;
+ }
+ else
+ {
+ visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen );
+ if( visible )
+ {
+ mCenterToCam = gAgentCamera.getCameraPositionAgent() - center;
+ mCenterToCamNorm = mCenterToCam;
+ mCenterToCamMag = mCenterToCamNorm.normVec();
+ LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
+ cameraAtAxis.normVec();
+
+ F32 z_dist = -1.f * (mCenterToCam * cameraAtAxis);
+
+ // Don't drag manip if object too far away
+ if (gSavedSettings.getBOOL("LimitSelectDistance"))
+ {
+ F32 max_select_distance = gSavedSettings.getF32("MaxSelectDistance");
+ if (dist_vec_squared(gAgent.getPositionAgent(), center) > (max_select_distance * max_select_distance))
+ {
+ visible = FALSE;
+ }
+ }
+
+ if (mCenterToCamMag > 0.001f)
+ {
+ F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
+ F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
+ mRadiusMeters = z_dist * tan(apparent_angle);
+ mRadiusMeters *= ui_scale_factor;
+
+ mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
+ mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
+ }
+ else
+ {
+ visible = FALSE;
+ }
+ }
+ }
+
+ mCamEdgeOn = FALSE;
+ F32 axis_onto_cam = mManipPart >= LL_ROT_X ? llabs( getConstraintAxis() * mCenterToCamNorm ) : 0.f;
+ if( axis_onto_cam < AXIS_ONTO_CAM_TOLERANCE )
+ {
+ mCamEdgeOn = TRUE;
+ }
+
+ return visible;
}
LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y )
{
- LLVector3 cam = gAgentCamera.getCameraPositionAgent();
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
-
- mMouseCur = intersectMouseWithSphere( x, y, center, mRadiusMeters);
-
- F32 delta_x = (F32)(mCenterScreen.mX - x);
- F32 delta_y = (F32)(mCenterScreen.mY - y);
-
- F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y);
-
- LLVector3 axis = mMouseDown % mMouseCur;
- F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur);
- axis.normVec();
- LLQuaternion sphere_rot( angle, axis );
-
- if (is_approx_zero(1.f - mMouseDown * mMouseCur))
- {
- return LLQuaternion::DEFAULT;
- }
- else if (dist_from_sphere_center < RADIUS_PIXELS)
- {
- return sphere_rot;
- }
- else
- {
- LLVector3 intersection;
- getMousePointOnPlaneAgent( intersection, x, y, center + mCenterToProfilePlane, mCenterToCamNorm );
-
- // amount dragging in sphere from center to periphery would rotate object
- F32 in_sphere_angle = F_PI_BY_TWO;
- F32 dist_to_tangent_point = mRadiusMeters;
- if( !is_approx_zero( mCenterToProfilePlaneMag ) )
- {
- dist_to_tangent_point = sqrt( mRadiusMeters * mRadiusMeters - mCenterToProfilePlaneMag * mCenterToProfilePlaneMag );
- in_sphere_angle = atan2( dist_to_tangent_point, mCenterToProfilePlaneMag );
- }
-
- LLVector3 profile_center_to_intersection = intersection - (center + mCenterToProfilePlane);
- F32 dist_to_intersection = profile_center_to_intersection.normVec();
- F32 angle = (-1.f + dist_to_intersection / dist_to_tangent_point) * in_sphere_angle;
-
- LLVector3 axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- axis = LLVector3(-1.f, 0.f, 0.f) % profile_center_to_intersection;
- }
- else
- {
- axis = (cam - center) % profile_center_to_intersection;
- axis.normVec();
- }
- return sphere_rot * LLQuaternion( angle, axis );
- }
+ LLVector3 cam = gAgentCamera.getCameraPositionAgent();
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+
+ mMouseCur = intersectMouseWithSphere( x, y, center, mRadiusMeters);
+
+ F32 delta_x = (F32)(mCenterScreen.mX - x);
+ F32 delta_y = (F32)(mCenterScreen.mY - y);
+
+ F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y);
+
+ LLVector3 axis = mMouseDown % mMouseCur;
+ F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur);
+ axis.normVec();
+ LLQuaternion sphere_rot( angle, axis );
+
+ if (is_approx_zero(1.f - mMouseDown * mMouseCur))
+ {
+ return LLQuaternion::DEFAULT;
+ }
+ else if (dist_from_sphere_center < RADIUS_PIXELS)
+ {
+ return sphere_rot;
+ }
+ else
+ {
+ LLVector3 intersection;
+ getMousePointOnPlaneAgent( intersection, x, y, center + mCenterToProfilePlane, mCenterToCamNorm );
+
+ // amount dragging in sphere from center to periphery would rotate object
+ F32 in_sphere_angle = F_PI_BY_TWO;
+ F32 dist_to_tangent_point = mRadiusMeters;
+ if( !is_approx_zero( mCenterToProfilePlaneMag ) )
+ {
+ dist_to_tangent_point = sqrt( mRadiusMeters * mRadiusMeters - mCenterToProfilePlaneMag * mCenterToProfilePlaneMag );
+ in_sphere_angle = atan2( dist_to_tangent_point, mCenterToProfilePlaneMag );
+ }
+
+ LLVector3 profile_center_to_intersection = intersection - (center + mCenterToProfilePlane);
+ F32 dist_to_intersection = profile_center_to_intersection.normVec();
+ F32 angle = (-1.f + dist_to_intersection / dist_to_tangent_point) * in_sphere_angle;
+
+ LLVector3 axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ axis = LLVector3(-1.f, 0.f, 0.f) % profile_center_to_intersection;
+ }
+ else
+ {
+ axis = (cam - center) % profile_center_to_intersection;
+ axis.normVec();
+ }
+ return sphere_rot * LLQuaternion( angle, axis );
+ }
}
LLVector3 LLManipRotate::getConstraintAxis()
{
- LLVector3 axis;
- if( LL_ROT_ROLL == mManipPart )
- {
- axis = mCenterToCamNorm;
- }
- else
- {
- S32 axis_dir = mManipPart - LL_ROT_X;
- if ((axis_dir >= LL_NO_PART) && (axis_dir < LL_Z_ARROW))
- {
- axis.mV[axis_dir] = 1.f;
- }
- else
- {
+ LLVector3 axis;
+ if( LL_ROT_ROLL == mManipPart )
+ {
+ axis = mCenterToCamNorm;
+ }
+ else
+ {
+ S32 axis_dir = mManipPart - LL_ROT_X;
+ if ((axis_dir >= LL_NO_PART) && (axis_dir < LL_Z_ARROW))
+ {
+ axis.mV[axis_dir] = 1.f;
+ }
+ else
+ {
#ifndef LL_RELEASE_FOR_DOWNLOAD
- LL_ERRS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL;
+ LL_ERRS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL;
#else
- LL_WARNS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL;
+ LL_WARNS() << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << LL_ENDL;
#endif
- axis.mV[0] = 1.f;
- }
+ axis.mV[0] = 1.f;
+ }
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
- LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE);
- if (first_node)
- {
- // *FIX: get agent local attachment grid working
- // Put rotation into frame of first selected root object
- axis = axis * grid_rotation;
- }
- }
+ LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE);
+ if (first_node)
+ {
+ // *FIX: get agent local attachment grid working
+ // Put rotation into frame of first selected root object
+ axis = axis * grid_rotation;
+ }
+ }
- return axis;
+ return axis;
}
LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
{
- LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE);
- LLVector3 constraint_axis = getConstraintAxis();
- LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
-
- F32 angle = 0.f;
-
- // build snap axes
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- LLVector3 axis1;
- LLVector3 axis2;
-
- LLVector3 test_axis = constraint_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
- {
- test_axis = test_axis * ~grid_rotation;
- }
- else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
- {
- test_axis = test_axis * ~grid_rotation;
- }
- test_axis.abs();
-
- // find closest global axis to constraint axis;
- if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ])
- {
- axis1 = LLVector3::y_axis;
- }
- else if (test_axis.mV[VY] > test_axis.mV[VZ])
- {
- axis1 = LLVector3::z_axis;
- }
- else
- {
- axis1 = LLVector3::x_axis;
- }
-
- if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
- {
- axis1 = axis1 * grid_rotation;
- }
- else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
- {
- axis1 = axis1 * grid_rotation;
- }
-
- //project axis onto constraint plane
- axis1 -= (axis1 * constraint_axis) * constraint_axis;
- axis1.normVec();
-
- // calculate third and final axis
- axis2 = constraint_axis % axis1;
-
- //F32 axis_onto_cam = llabs( constraint_axis * mCenterToCamNorm );
- if( mCamEdgeOn )
- {
- // We're looking at the ring edge-on.
- LLVector3 snap_plane_center = (center + (constraint_axis * mRadiusMeters * 0.5f));
- LLVector3 cam_to_snap_plane;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
- cam_to_snap_plane.normVec();
- }
-
- LLVector3 projected_mouse;
- BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
- projected_mouse -= snap_plane_center;
-
- if (gSavedSettings.getBOOL("SnapEnabled")) {
- S32 snap_plane = 0;
-
- F32 dot = cam_to_snap_plane * constraint_axis;
- if (llabs(dot) < 0.01f)
- {
- // looking at ring edge on, project onto view plane and check if mouse is past ring
- getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
- projected_mouse -= snap_plane_center;
- dot = projected_mouse * constraint_axis;
- if (projected_mouse * constraint_axis > 0)
- {
- snap_plane = 1;
- }
- projected_mouse -= dot * constraint_axis;
- }
- else if (dot > 0.f)
- {
- // look for mouse position outside and in front of snap circle
- if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
- {
- snap_plane = 1;
- }
- }
- else
- {
- // look for mouse position inside or in back of snap circle
- if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
- {
- snap_plane = 1;
- }
- }
-
- if (snap_plane == 0)
- {
- // try other plane
- snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
- cam_to_snap_plane.normVec();
- }
-
- hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
- projected_mouse -= snap_plane_center;
-
- dot = cam_to_snap_plane * constraint_axis;
- if (llabs(dot) < 0.01f)
- {
- // looking at ring edge on, project onto view plane and check if mouse is past ring
- getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
- projected_mouse -= snap_plane_center;
- dot = projected_mouse * constraint_axis;
- if (projected_mouse * constraint_axis < 0)
- {
- snap_plane = 2;
- }
- projected_mouse -= dot * constraint_axis;
- }
- else if (dot < 0.f)
- {
- // look for mouse position outside and in front of snap circle
- if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
- {
- snap_plane = 2;
- }
- }
- else
- {
- // look for mouse position inside or in back of snap circle
- if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
- {
- snap_plane = 2;
- }
- }
- }
-
- if (snap_plane > 0)
- {
- LLVector3 cam_at_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_at_axis.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
- cam_at_axis.normVec();
- }
-
- // first, project mouse onto screen plane at point tangent to rotation radius.
- getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
- // project that point onto rotation plane
- projected_mouse -= snap_plane_center;
- projected_mouse -= projected_vec(projected_mouse, constraint_axis);
-
- F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
- F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
- if (llabs(mouse_lateral_dist) > 0.01f)
- {
- mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
- (mouse_lateral_dist * mouse_lateral_dist));
- }
- LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
- projected_mouse -= mouse_depth * projected_camera_at;
-
- if (!mInSnapRegime)
- {
- mSmoothRotate = TRUE;
- }
- mInSnapRegime = TRUE;
- // 0 to 360 deg
- F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
-
- F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
-
- LLVector3 object_axis;
- getObjectAxisClosestToMouse(object_axis);
+ LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE);
+ LLVector3 constraint_axis = getConstraintAxis();
+ LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
+
+ F32 angle = 0.f;
+
+ // build snap axes
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ LLVector3 axis1;
+ LLVector3 axis2;
+
+ LLVector3 test_axis = constraint_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+ {
+ test_axis = test_axis * ~grid_rotation;
+ }
+ else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
+ {
+ test_axis = test_axis * ~grid_rotation;
+ }
+ test_axis.abs();
+
+ // find closest global axis to constraint axis;
+ if (test_axis.mV[VX] > test_axis.mV[VY] && test_axis.mV[VX] > test_axis.mV[VZ])
+ {
+ axis1 = LLVector3::y_axis;
+ }
+ else if (test_axis.mV[VY] > test_axis.mV[VZ])
+ {
+ axis1 = LLVector3::z_axis;
+ }
+ else
+ {
+ axis1 = LLVector3::x_axis;
+ }
+
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+ {
+ axis1 = axis1 * grid_rotation;
+ }
+ else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT)
+ {
+ axis1 = axis1 * grid_rotation;
+ }
+
+ //project axis onto constraint plane
+ axis1 -= (axis1 * constraint_axis) * constraint_axis;
+ axis1.normVec();
+
+ // calculate third and final axis
+ axis2 = constraint_axis % axis1;
+
+ //F32 axis_onto_cam = llabs( constraint_axis * mCenterToCamNorm );
+ if( mCamEdgeOn )
+ {
+ // We're looking at the ring edge-on.
+ LLVector3 snap_plane_center = (center + (constraint_axis * mRadiusMeters * 0.5f));
+ LLVector3 cam_to_snap_plane;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+ cam_to_snap_plane.normVec();
+ }
+
+ LLVector3 projected_mouse;
+ BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
+ projected_mouse -= snap_plane_center;
+
+ if (gSavedSettings.getBOOL("SnapEnabled")) {
+ S32 snap_plane = 0;
+
+ F32 dot = cam_to_snap_plane * constraint_axis;
+ if (llabs(dot) < 0.01f)
+ {
+ // looking at ring edge on, project onto view plane and check if mouse is past ring
+ getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
+ projected_mouse -= snap_plane_center;
+ dot = projected_mouse * constraint_axis;
+ if (projected_mouse * constraint_axis > 0)
+ {
+ snap_plane = 1;
+ }
+ projected_mouse -= dot * constraint_axis;
+ }
+ else if (dot > 0.f)
+ {
+ // look for mouse position outside and in front of snap circle
+ if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
+ {
+ snap_plane = 1;
+ }
+ }
+ else
+ {
+ // look for mouse position inside or in back of snap circle
+ if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
+ {
+ snap_plane = 1;
+ }
+ }
+
+ if (snap_plane == 0)
+ {
+ // try other plane
+ snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+ cam_to_snap_plane.normVec();
+ }
+
+ hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
+ projected_mouse -= snap_plane_center;
+
+ dot = cam_to_snap_plane * constraint_axis;
+ if (llabs(dot) < 0.01f)
+ {
+ // looking at ring edge on, project onto view plane and check if mouse is past ring
+ getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
+ projected_mouse -= snap_plane_center;
+ dot = projected_mouse * constraint_axis;
+ if (projected_mouse * constraint_axis < 0)
+ {
+ snap_plane = 2;
+ }
+ projected_mouse -= dot * constraint_axis;
+ }
+ else if (dot < 0.f)
+ {
+ // look for mouse position outside and in front of snap circle
+ if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
+ {
+ snap_plane = 2;
+ }
+ }
+ else
+ {
+ // look for mouse position inside or in back of snap circle
+ if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
+ {
+ snap_plane = 2;
+ }
+ }
+ }
+
+ if (snap_plane > 0)
+ {
+ LLVector3 cam_at_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_at_axis.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+ cam_at_axis.normVec();
+ }
+
+ // first, project mouse onto screen plane at point tangent to rotation radius.
+ getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
+ // project that point onto rotation plane
+ projected_mouse -= snap_plane_center;
+ projected_mouse -= projected_vec(projected_mouse, constraint_axis);
+
+ F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
+ F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+ if (llabs(mouse_lateral_dist) > 0.01f)
+ {
+ mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
+ (mouse_lateral_dist * mouse_lateral_dist));
+ }
+ LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
+ projected_mouse -= mouse_depth * projected_camera_at;
+
+ if (!mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = TRUE;
+ // 0 to 360 deg
+ F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
+
+ F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
+
+ LLVector3 object_axis;
+ getObjectAxisClosestToMouse(object_axis);
if (first_object_node)
{
object_axis = object_axis * first_object_node->mSavedRotation;
}
-
- // project onto constraint plane
- object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
- object_axis.normVec();
-
- if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
- {
- F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
- angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
- }
- else
- {
- angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
- }
- return LLQuaternion( -angle, constraint_axis );
- }
- else
- {
- if (mInSnapRegime)
- {
- mSmoothRotate = TRUE;
- }
- mInSnapRegime = FALSE;
- }
- }
- else {
- if (mInSnapRegime)
- {
- mSmoothRotate = TRUE;
- }
- mInSnapRegime = FALSE;
- }
-
- if (!mInSnapRegime)
- {
- LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
- up_from_axis.normVec();
- LLVector3 cur_intersection;
- getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam);
- cur_intersection -= center;
- mMouseCur = projected_vec(cur_intersection, up_from_axis);
- F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
- F32 mouse_dist_sqrd = mMouseCur.magVecSquared();
- if (mouse_dist_sqrd > 0.0001f)
- {
- mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
- mouse_dist_sqrd);
- }
- LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, constraint_axis);
- mMouseCur += mouse_depth * projected_center_to_cam;
-
- F32 dist = (cur_intersection * up_from_axis) - (mMouseDown * up_from_axis);
- angle = dist / (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * -F_PI_BY_TWO;
- }
- }
- else
- {
- LLVector3 projected_mouse;
- getMousePointOnPlaneAgent(projected_mouse, x, y, center, constraint_axis);
- projected_mouse -= center;
- mMouseCur = projected_mouse;
- mMouseCur.normVec();
-
- if (!first_object_node)
- {
- return LLQuaternion::DEFAULT;
- }
-
- if (gSavedSettings.getBOOL("SnapEnabled") && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters)
- {
- if (!mInSnapRegime)
- {
- mSmoothRotate = TRUE;
- }
- mInSnapRegime = TRUE;
- // 0 to 360 deg
- F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
-
- F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
-
- LLVector3 object_axis;
- getObjectAxisClosestToMouse(object_axis);
- object_axis = object_axis * first_object_node->mSavedRotation;
-
- // project onto constraint plane
- object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
- object_axis.normVec();
-
- if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
- {
- F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
- angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
- }
- else
- {
- angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
- }
- return LLQuaternion( -angle, constraint_axis );
- }
- else
- {
- if (mInSnapRegime)
- {
- mSmoothRotate = TRUE;
- }
- mInSnapRegime = FALSE;
- }
-
- LLVector3 cross_product = mMouseDown % mMouseCur;
- angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown);
- F32 dir = cross_product * constraint_axis; // cross product
- if( dir < 0.f )
- {
- angle *= -1.f;
- }
- }
-
- F32 rot_step = gSavedSettings.getF32("RotationStep");
- F32 step_size = DEG_TO_RAD * rot_step;
- angle -= fmod(angle, step_size);
-
- return LLQuaternion( angle, constraint_axis );
+
+ // project onto constraint plane
+ object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+ object_axis.normVec();
+
+ if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+ {
+ F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
+ angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ else
+ {
+ angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ return LLQuaternion( -angle, constraint_axis );
+ }
+ else
+ {
+ if (mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = FALSE;
+ }
+ }
+ else {
+ if (mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = FALSE;
+ }
+
+ if (!mInSnapRegime)
+ {
+ LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
+ up_from_axis.normVec();
+ LLVector3 cur_intersection;
+ getMousePointOnPlaneAgent(cur_intersection, x, y, center, mCenterToCam);
+ cur_intersection -= center;
+ mMouseCur = projected_vec(cur_intersection, up_from_axis);
+ F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+ F32 mouse_dist_sqrd = mMouseCur.magVecSquared();
+ if (mouse_dist_sqrd > 0.0001f)
+ {
+ mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
+ mouse_dist_sqrd);
+ }
+ LLVector3 projected_center_to_cam = mCenterToCamNorm - projected_vec(mCenterToCamNorm, constraint_axis);
+ mMouseCur += mouse_depth * projected_center_to_cam;
+
+ F32 dist = (cur_intersection * up_from_axis) - (mMouseDown * up_from_axis);
+ angle = dist / (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * -F_PI_BY_TWO;
+ }
+ }
+ else
+ {
+ LLVector3 projected_mouse;
+ getMousePointOnPlaneAgent(projected_mouse, x, y, center, constraint_axis);
+ projected_mouse -= center;
+ mMouseCur = projected_mouse;
+ mMouseCur.normVec();
+
+ if (!first_object_node)
+ {
+ return LLQuaternion::DEFAULT;
+ }
+
+ if (gSavedSettings.getBOOL("SnapEnabled") && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters)
+ {
+ if (!mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = TRUE;
+ // 0 to 360 deg
+ F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
+
+ F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
+
+ LLVector3 object_axis;
+ getObjectAxisClosestToMouse(object_axis);
+ object_axis = object_axis * first_object_node->mSavedRotation;
+
+ // project onto constraint plane
+ object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+ object_axis.normVec();
+
+ if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+ {
+ F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
+ angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ else
+ {
+ angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ return LLQuaternion( -angle, constraint_axis );
+ }
+ else
+ {
+ if (mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = FALSE;
+ }
+
+ LLVector3 cross_product = mMouseDown % mMouseCur;
+ angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown);
+ F32 dir = cross_product * constraint_axis; // cross product
+ if( dir < 0.f )
+ {
+ angle *= -1.f;
+ }
+ }
+
+ F32 rot_step = gSavedSettings.getF32("RotationStep");
+ F32 step_size = DEG_TO_RAD * rot_step;
+ angle -= fmod(angle, step_size);
+
+ return LLQuaternion( angle, constraint_axis );
}
LLVector3 LLManipRotate::intersectMouseWithSphere( S32 x, S32 y, const LLVector3& sphere_center, F32 sphere_radius)
{
- LLVector3 ray_pt;
- LLVector3 ray_dir;
- mouseToRay( x, y, &ray_pt, &ray_dir);
- return intersectRayWithSphere( ray_pt, ray_dir, sphere_center, sphere_radius );
+ LLVector3 ray_pt;
+ LLVector3 ray_dir;
+ mouseToRay( x, y, &ray_pt, &ray_dir);
+ return intersectRayWithSphere( ray_pt, ray_dir, sphere_center, sphere_radius );
}
LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius)
{
- LLVector3 ray_pt_to_center = sphere_center - ray_pt;
- F32 center_distance = ray_pt_to_center.normVec();
-
- F32 dot = ray_dir * ray_pt_to_center;
-
- if (dot == 0.f)
- {
- return LLVector3::zero;
- }
-
- // point which ray hits plane centered on sphere origin, facing ray origin
- LLVector3 intersection_sphere_plane = ray_pt + (ray_dir * center_distance / dot);
- // vector from sphere origin to the point, normalized to sphere radius
- LLVector3 sphere_center_to_intersection = (intersection_sphere_plane - sphere_center) / sphere_radius;
-
- F32 dist_squared = sphere_center_to_intersection.magVecSquared();
- LLVector3 result;
-
- if (dist_squared > 1.f)
- {
- result = sphere_center_to_intersection;
- result.normVec();
- }
- else
- {
- result = sphere_center_to_intersection - ray_dir * sqrt(1.f - dist_squared);
- }
-
- return result;
+ LLVector3 ray_pt_to_center = sphere_center - ray_pt;
+ F32 center_distance = ray_pt_to_center.normVec();
+
+ F32 dot = ray_dir * ray_pt_to_center;
+
+ if (dot == 0.f)
+ {
+ return LLVector3::zero;
+ }
+
+ // point which ray hits plane centered on sphere origin, facing ray origin
+ LLVector3 intersection_sphere_plane = ray_pt + (ray_dir * center_distance / dot);
+ // vector from sphere origin to the point, normalized to sphere radius
+ LLVector3 sphere_center_to_intersection = (intersection_sphere_plane - sphere_center) / sphere_radius;
+
+ F32 dist_squared = sphere_center_to_intersection.magVecSquared();
+ LLVector3 result;
+
+ if (dist_squared > 1.f)
+ {
+ result = sphere_center_to_intersection;
+ result.normVec();
+ }
+ else
+ {
+ result = sphere_center_to_intersection - ray_dir * sqrt(1.f - dist_squared);
+ }
+
+ return result;
}
// Utility function. Should probably be moved to another class.
@@ -1718,233 +1743,233 @@ LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const
//static
void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_dir )
{
- if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom;
- F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom;
-
- *ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);
- *ray_dir = LLVector3(1.f, 0.f, 0.f);
- }
- else
- {
- *ray_pt = gAgentCamera.getCameraPositionAgent();
+ if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom;
+ F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom;
+
+ *ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);
+ *ray_dir = LLVector3(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ *ray_pt = gAgentCamera.getCameraPositionAgent();
*ray_dir = gViewerWindow->mouseDirectionGlobal(x, y);
- }
+ }
}
void LLManipRotate::highlightManipulators( S32 x, S32 y )
{
- mHighlightedPart = LL_NO_PART;
-
- //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
- LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE);
-
- if (!first_object)
- {
- return;
- }
-
- LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter);
- LLVector3 mouse_dir_x;
- LLVector3 mouse_dir_y;
- LLVector3 mouse_dir_z;
- LLVector3 intersection_roll;
-
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- LLVector3 rot_x_axis = LLVector3::x_axis * grid_rotation;
- LLVector3 rot_y_axis = LLVector3::y_axis * grid_rotation;
- LLVector3 rot_z_axis = LLVector3::z_axis * grid_rotation;
-
- F32 proj_rot_x_axis = llabs(rot_x_axis * mCenterToCamNorm);
- F32 proj_rot_y_axis = llabs(rot_y_axis * mCenterToCamNorm);
- F32 proj_rot_z_axis = llabs(rot_z_axis * mCenterToCamNorm);
-
- F32 min_select_distance = 0.f;
- F32 cur_select_distance = 0.f;
-
- // test x
- getMousePointOnPlaneAgent(mouse_dir_x, x, y, rotation_center, rot_x_axis);
- mouse_dir_x -= rotation_center;
- // push intersection point out when working at obtuse angle to make ring easier to hit
- mouse_dir_x *= 1.f + (1.f - llabs(rot_x_axis * mCenterToCamNorm)) * 0.1f;
-
- // test y
- getMousePointOnPlaneAgent(mouse_dir_y, x, y, rotation_center, rot_y_axis);
- mouse_dir_y -= rotation_center;
- mouse_dir_y *= 1.f + (1.f - llabs(rot_y_axis * mCenterToCamNorm)) * 0.1f;
-
- // test z
- getMousePointOnPlaneAgent(mouse_dir_z, x, y, rotation_center, rot_z_axis);
- mouse_dir_z -= rotation_center;
- mouse_dir_z *= 1.f + (1.f - llabs(rot_z_axis * mCenterToCamNorm)) * 0.1f;
-
- // test roll
- getMousePointOnPlaneAgent(intersection_roll, x, y, rotation_center, mCenterToCamNorm);
- intersection_roll -= rotation_center;
-
- F32 dist_x = mouse_dir_x.normVec();
- F32 dist_y = mouse_dir_y.normVec();
- F32 dist_z = mouse_dir_z.normVec();
-
- F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightScaled();
-
- if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold)
- {
- // selected x
- cur_select_distance = dist_x * mouse_dir_x * mCenterToCamNorm;
- if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
- {
- min_select_distance = cur_select_distance;
- mHighlightedPart = LL_ROT_X;
- }
- }
- if (llabs(dist_y - mRadiusMeters) * llmax(0.05f, proj_rot_y_axis) < distance_threshold)
- {
- // selected y
- cur_select_distance = dist_y * mouse_dir_y * mCenterToCamNorm;
- if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
- {
- min_select_distance = cur_select_distance;
- mHighlightedPart = LL_ROT_Y;
- }
- }
- if (llabs(dist_z - mRadiusMeters) * llmax(0.05f, proj_rot_z_axis) < distance_threshold)
- {
- // selected z
- cur_select_distance = dist_z * mouse_dir_z * mCenterToCamNorm;
- if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
- {
- min_select_distance = cur_select_distance;
- mHighlightedPart = LL_ROT_Z;
- }
- }
-
- // test for edge-on intersections
- if (proj_rot_x_axis < 0.05f)
- {
- if ((proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_x_axis) < distance_threshold) && dist_y < mRadiusMeters) ||
- (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_x_axis) < distance_threshold) && dist_z < mRadiusMeters))
- {
- mHighlightedPart = LL_ROT_X;
- }
- }
-
- if (proj_rot_y_axis < 0.05f)
- {
- if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_y_axis) < distance_threshold) && dist_x < mRadiusMeters) ||
- (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_y_axis) < distance_threshold) && dist_z < mRadiusMeters))
- {
- mHighlightedPart = LL_ROT_Y;
- }
- }
-
- if (proj_rot_z_axis < 0.05f)
- {
- if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_z_axis) < distance_threshold) && dist_x < mRadiusMeters) ||
- (proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_z_axis) < distance_threshold) && dist_y < mRadiusMeters))
- {
- mHighlightedPart = LL_ROT_Z;
- }
- }
-
- // test for roll
- if (mHighlightedPart == LL_NO_PART)
- {
- F32 roll_distance = intersection_roll.magVec();
- F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS;
-
- // use larger distance threshold for roll as it is checked only if something else wasn't highlighted
- if (llabs(roll_distance - (mRadiusMeters + (width_meters * 2.f))) < distance_threshold * 2.f)
- {
- mHighlightedPart = LL_ROT_ROLL;
- }
- else if (roll_distance < mRadiusMeters)
- {
- mHighlightedPart = LL_ROT_GENERAL;
- }
- }
+ mHighlightedPart = LL_NO_PART;
+
+ //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE);
+
+ if (!first_object)
+ {
+ return;
+ }
+
+ LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter);
+ LLVector3 mouse_dir_x;
+ LLVector3 mouse_dir_y;
+ LLVector3 mouse_dir_z;
+ LLVector3 intersection_roll;
+
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ LLVector3 rot_x_axis = LLVector3::x_axis * grid_rotation;
+ LLVector3 rot_y_axis = LLVector3::y_axis * grid_rotation;
+ LLVector3 rot_z_axis = LLVector3::z_axis * grid_rotation;
+
+ F32 proj_rot_x_axis = llabs(rot_x_axis * mCenterToCamNorm);
+ F32 proj_rot_y_axis = llabs(rot_y_axis * mCenterToCamNorm);
+ F32 proj_rot_z_axis = llabs(rot_z_axis * mCenterToCamNorm);
+
+ F32 min_select_distance = 0.f;
+ F32 cur_select_distance = 0.f;
+
+ // test x
+ getMousePointOnPlaneAgent(mouse_dir_x, x, y, rotation_center, rot_x_axis);
+ mouse_dir_x -= rotation_center;
+ // push intersection point out when working at obtuse angle to make ring easier to hit
+ mouse_dir_x *= 1.f + (1.f - llabs(rot_x_axis * mCenterToCamNorm)) * 0.1f;
+
+ // test y
+ getMousePointOnPlaneAgent(mouse_dir_y, x, y, rotation_center, rot_y_axis);
+ mouse_dir_y -= rotation_center;
+ mouse_dir_y *= 1.f + (1.f - llabs(rot_y_axis * mCenterToCamNorm)) * 0.1f;
+
+ // test z
+ getMousePointOnPlaneAgent(mouse_dir_z, x, y, rotation_center, rot_z_axis);
+ mouse_dir_z -= rotation_center;
+ mouse_dir_z *= 1.f + (1.f - llabs(rot_z_axis * mCenterToCamNorm)) * 0.1f;
+
+ // test roll
+ getMousePointOnPlaneAgent(intersection_roll, x, y, rotation_center, mCenterToCamNorm);
+ intersection_roll -= rotation_center;
+
+ F32 dist_x = mouse_dir_x.normVec();
+ F32 dist_y = mouse_dir_y.normVec();
+ F32 dist_z = mouse_dir_z.normVec();
+
+ F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightScaled();
+
+ if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold)
+ {
+ // selected x
+ cur_select_distance = dist_x * mouse_dir_x * mCenterToCamNorm;
+ if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
+ {
+ min_select_distance = cur_select_distance;
+ mHighlightedPart = LL_ROT_X;
+ }
+ }
+ if (llabs(dist_y - mRadiusMeters) * llmax(0.05f, proj_rot_y_axis) < distance_threshold)
+ {
+ // selected y
+ cur_select_distance = dist_y * mouse_dir_y * mCenterToCamNorm;
+ if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
+ {
+ min_select_distance = cur_select_distance;
+ mHighlightedPart = LL_ROT_Y;
+ }
+ }
+ if (llabs(dist_z - mRadiusMeters) * llmax(0.05f, proj_rot_z_axis) < distance_threshold)
+ {
+ // selected z
+ cur_select_distance = dist_z * mouse_dir_z * mCenterToCamNorm;
+ if (cur_select_distance >= -0.05f && (min_select_distance == 0.f || cur_select_distance > min_select_distance))
+ {
+ min_select_distance = cur_select_distance;
+ mHighlightedPart = LL_ROT_Z;
+ }
+ }
+
+ // test for edge-on intersections
+ if (proj_rot_x_axis < 0.05f)
+ {
+ if ((proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_x_axis) < distance_threshold) && dist_y < mRadiusMeters) ||
+ (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_x_axis) < distance_threshold) && dist_z < mRadiusMeters))
+ {
+ mHighlightedPart = LL_ROT_X;
+ }
+ }
+
+ if (proj_rot_y_axis < 0.05f)
+ {
+ if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_y_axis) < distance_threshold) && dist_x < mRadiusMeters) ||
+ (proj_rot_z_axis > 0.05f && (dist_z * llabs(mouse_dir_z * rot_y_axis) < distance_threshold) && dist_z < mRadiusMeters))
+ {
+ mHighlightedPart = LL_ROT_Y;
+ }
+ }
+
+ if (proj_rot_z_axis < 0.05f)
+ {
+ if ((proj_rot_x_axis > 0.05f && (dist_x * llabs(mouse_dir_x * rot_z_axis) < distance_threshold) && dist_x < mRadiusMeters) ||
+ (proj_rot_y_axis > 0.05f && (dist_y * llabs(mouse_dir_y * rot_z_axis) < distance_threshold) && dist_y < mRadiusMeters))
+ {
+ mHighlightedPart = LL_ROT_Z;
+ }
+ }
+
+ // test for roll
+ if (mHighlightedPart == LL_NO_PART)
+ {
+ F32 roll_distance = intersection_roll.magVec();
+ F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS;
+
+ // use larger distance threshold for roll as it is checked only if something else wasn't highlighted
+ if (llabs(roll_distance - (mRadiusMeters + (width_meters * 2.f))) < distance_threshold * 2.f)
+ {
+ mHighlightedPart = LL_ROT_ROLL;
+ }
+ else if (roll_distance < mRadiusMeters)
+ {
+ mHighlightedPart = LL_ROT_GENERAL;
+ }
+ }
}
S32 LLManipRotate::getObjectAxisClosestToMouse(LLVector3& object_axis)
{
- LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE);
-
- if (!first_object_node)
- {
- object_axis.clearVec();
- return -1;
- }
-
- LLQuaternion obj_rotation = first_object_node->mSavedRotation;
- LLVector3 mouse_down_object = mMouseDown * ~obj_rotation;
- LLVector3 mouse_down_abs = mouse_down_object;
- mouse_down_abs.abs();
-
- S32 axis_index = 0;
- if (mouse_down_abs.mV[VX] > mouse_down_abs.mV[VY] && mouse_down_abs.mV[VX] > mouse_down_abs.mV[VZ])
- {
- if (mouse_down_object.mV[VX] > 0.f)
- {
- object_axis = LLVector3::x_axis;
- }
- else
- {
- object_axis = LLVector3::x_axis_neg;
- }
- axis_index = VX;
- }
- else if (mouse_down_abs.mV[VY] > mouse_down_abs.mV[VZ])
- {
- if (mouse_down_object.mV[VY] > 0.f)
- {
- object_axis = LLVector3::y_axis;
- }
- else
- {
- object_axis = LLVector3::y_axis_neg;
- }
- axis_index = VY;
- }
- else
- {
- if (mouse_down_object.mV[VZ] > 0.f)
- {
- object_axis = LLVector3::z_axis;
- }
- else
- {
- object_axis = LLVector3::z_axis_neg;
- }
- axis_index = VZ;
- }
-
- return axis_index;
+ LLSelectNode* first_object_node = mObjectSelection->getFirstMoveableNode(TRUE);
+
+ if (!first_object_node)
+ {
+ object_axis.clearVec();
+ return -1;
+ }
+
+ LLQuaternion obj_rotation = first_object_node->mSavedRotation;
+ LLVector3 mouse_down_object = mMouseDown * ~obj_rotation;
+ LLVector3 mouse_down_abs = mouse_down_object;
+ mouse_down_abs.abs();
+
+ S32 axis_index = 0;
+ if (mouse_down_abs.mV[VX] > mouse_down_abs.mV[VY] && mouse_down_abs.mV[VX] > mouse_down_abs.mV[VZ])
+ {
+ if (mouse_down_object.mV[VX] > 0.f)
+ {
+ object_axis = LLVector3::x_axis;
+ }
+ else
+ {
+ object_axis = LLVector3::x_axis_neg;
+ }
+ axis_index = VX;
+ }
+ else if (mouse_down_abs.mV[VY] > mouse_down_abs.mV[VZ])
+ {
+ if (mouse_down_object.mV[VY] > 0.f)
+ {
+ object_axis = LLVector3::y_axis;
+ }
+ else
+ {
+ object_axis = LLVector3::y_axis_neg;
+ }
+ axis_index = VY;
+ }
+ else
+ {
+ if (mouse_down_object.mV[VZ] > 0.f)
+ {
+ object_axis = LLVector3::z_axis;
+ }
+ else
+ {
+ object_axis = LLVector3::z_axis_neg;
+ }
+ axis_index = VZ;
+ }
+
+ return axis_index;
}
//virtual
BOOL LLManipRotate::canAffectSelection()
{
- BOOL can_rotate = mObjectSelection->getObjectCount() != 0;
- if (can_rotate)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* objectp)
- {
- LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
- return objectp->permMove() && !objectp->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
- }
- } func;
- can_rotate = mObjectSelection->applyToObjects(&func);
- }
- return can_rotate;
+ BOOL can_rotate = mObjectSelection->getObjectCount() != 0;
+ if (can_rotate)
+ {
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
+ return objectp->permMove() && !objectp->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ }
+ } func;
+ can_rotate = mObjectSelection->applyToObjects(&func);
+ }
+ return can_rotate;
}
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 8cd7f44f70..9fc5ad502c 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llmaniptranslate.cpp
* @brief LLManipTranslate class implementation
*
* $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$
*/
@@ -76,202 +76,202 @@ const F32 SNAP_ARROW_SCALE = 0.7f;
static LLPointer<LLViewerTexture> sGridTex = NULL ;
-const LLManip::EManipPart MANIPULATOR_IDS[9] =
+const LLManip::EManipPart MANIPULATOR_IDS[9] =
{
- LLManip::LL_X_ARROW,
- LLManip::LL_Y_ARROW,
- LLManip::LL_Z_ARROW,
- LLManip::LL_X_ARROW,
- LLManip::LL_Y_ARROW,
- LLManip::LL_Z_ARROW,
- LLManip::LL_YZ_PLANE,
- LLManip::LL_XZ_PLANE,
- LLManip::LL_XY_PLANE
+ LLManip::LL_X_ARROW,
+ LLManip::LL_Y_ARROW,
+ LLManip::LL_Z_ARROW,
+ LLManip::LL_X_ARROW,
+ LLManip::LL_Y_ARROW,
+ LLManip::LL_Z_ARROW,
+ LLManip::LL_YZ_PLANE,
+ LLManip::LL_XZ_PLANE,
+ LLManip::LL_XY_PLANE
};
-const U32 ARROW_TO_AXIS[4] =
+const U32 ARROW_TO_AXIS[4] =
{
- VX,
- VX,
- VY,
- VZ
+ VX,
+ VX,
+ VY,
+ VZ
};
// Sort manipulator handles by their screen-space projection
struct ClosestToCamera
{
- bool operator()(const LLManipTranslate::ManipulatorHandle& a,
- const LLManipTranslate::ManipulatorHandle& b) const
- {
- return a.mEndPosition.mV[VZ] < b.mEndPosition.mV[VZ];
- }
+ bool operator()(const LLManipTranslate::ManipulatorHandle& a,
+ const LLManipTranslate::ManipulatorHandle& b) const
+ {
+ return a.mEndPosition.mV[VZ] < b.mEndPosition.mV[VZ];
+ }
};
LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
-: LLManip( std::string("Move"), composite ),
- mLastHoverMouseX(-1),
- mLastHoverMouseY(-1),
- mMouseOutsideSlop(FALSE),
- mCopyMadeThisDrag(FALSE),
- mMouseDownX(-1),
- mMouseDownY(-1),
- mAxisArrowLength(50),
- mConeSize(0),
- mArrowLengthMeters(0.f),
- mGridSizeMeters(1.f),
- mPlaneManipOffsetMeters(0.f),
- mUpdateTimer(),
- mSnapOffsetMeters(0.f),
- mSubdivisions(10.f),
- mInSnapRegime(FALSE),
- mArrowScales(1.f, 1.f, 1.f),
- mPlaneScales(1.f, 1.f, 1.f),
- mPlaneManipPositions(1.f, 1.f, 1.f, 1.f)
-{
- if (sGridTex.isNull())
- {
- restoreGL();
- }
+: LLManip( std::string("Move"), composite ),
+ mLastHoverMouseX(-1),
+ mLastHoverMouseY(-1),
+ mMouseOutsideSlop(FALSE),
+ mCopyMadeThisDrag(FALSE),
+ mMouseDownX(-1),
+ mMouseDownY(-1),
+ mAxisArrowLength(50),
+ mConeSize(0),
+ mArrowLengthMeters(0.f),
+ mGridSizeMeters(1.f),
+ mPlaneManipOffsetMeters(0.f),
+ mUpdateTimer(),
+ mSnapOffsetMeters(0.f),
+ mSubdivisions(10.f),
+ mInSnapRegime(FALSE),
+ mArrowScales(1.f, 1.f, 1.f),
+ mPlaneScales(1.f, 1.f, 1.f),
+ mPlaneManipPositions(1.f, 1.f, 1.f, 1.f)
+{
+ if (sGridTex.isNull())
+ {
+ restoreGL();
+ }
}
//static
U32 LLManipTranslate::getGridTexName()
{
- if(sGridTex.isNull())
- {
- restoreGL() ;
- }
+ if(sGridTex.isNull())
+ {
+ restoreGL() ;
+ }
- return sGridTex.isNull() ? 0 : sGridTex->getTexName() ;
+ return sGridTex.isNull() ? 0 : sGridTex->getTexName() ;
}
//static
void LLManipTranslate::destroyGL()
{
- if (sGridTex)
- {
- sGridTex = NULL ;
- }
+ if (sGridTex)
+ {
+ sGridTex = NULL ;
+ }
}
//static
void LLManipTranslate::restoreGL()
{
- //generate grid texture
- U32 rez = 512;
- U32 mip = 0;
-
- destroyGL() ;
- sGridTex = LLViewerTextureManager::getLocalTexture() ;
- if(!sGridTex->createGLTexture())
- {
- sGridTex = NULL ;
- return ;
- }
-
- GLuint* d = new GLuint[rez*rez];
-
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex->getTexName(), true);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
-
- while (rez >= 1)
- {
- for (U32 i = 0; i < rez*rez; i++)
- {
- d[i] = 0x00FFFFFF;
- }
-
- U32 subcol = 0xFFFFFFFF;
- if (rez >= 4)
- { //large grain grid
- for (U32 i = 0; i < rez; i++)
- {
- if (rez <= 16)
- {
- if (rez == 16)
- {
- subcol = 0xA0FFFFFF;
- }
- else if (rez == 8)
- {
- subcol = 0x80FFFFFF;
- }
- else
- {
- subcol = 0x40FFFFFF;
- }
- }
- else
- {
- subcol = 0xFFFFFFFF;
- }
- d[i *rez+ 0 ] = subcol;
- d[0 *rez+ i ] = subcol;
- if (rez >= 32)
- {
- d[i *rez+ (rez-1)] = subcol;
- d[(rez-1) *rez+ i ] = subcol;
- }
-
- if (rez >= 64)
- {
- subcol = 0xFFFFFFFF;
-
- if (i > 0 && i < (rez-1))
- {
- d[i *rez+ 1 ] = subcol;
- d[i *rez+ (rez-2)] = subcol;
- d[1 *rez+ i ] = subcol;
- d[(rez-2) *rez+ i ] = subcol;
- }
- }
- }
- }
-
- subcol = 0x50A0A0A0;
- if (rez >= 128)
- { //small grain grid
- for (U32 i = 8; i < rez; i+=8)
- {
- for (U32 j = 2; j < rez-2; j++)
- {
- d[i *rez+ j] = subcol;
- d[j *rez+ i] = subcol;
- }
- }
- }
- if (rez >= 64)
- { //medium grain grid
- if (rez == 64)
- {
- subcol = 0x50A0A0A0;
- }
- else
- {
- subcol = 0xA0D0D0D0;
- }
-
- for (U32 i = 32; i < rez; i+=32)
- {
- U32 pi = i-1;
- for (U32 j = 2; j < rez-2; j++)
- {
- d[i *rez+ j] = subcol;
- d[j *rez+ i] = subcol;
-
- if (rez > 128)
- {
- d[pi *rez+ j] = subcol;
- d[j *rez+ pi] = subcol;
- }
- }
- }
- }
- LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_BYTE, d);
- rez = rez >> 1;
- mip++;
- }
- delete [] d;
+ //generate grid texture
+ U32 rez = 512;
+ U32 mip = 0;
+
+ destroyGL() ;
+ sGridTex = LLViewerTextureManager::getLocalTexture() ;
+ if(!sGridTex->createGLTexture())
+ {
+ sGridTex = NULL ;
+ return ;
+ }
+
+ GLuint* d = new GLuint[rez*rez];
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex->getTexName(), true);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+
+ while (rez >= 1)
+ {
+ for (U32 i = 0; i < rez*rez; i++)
+ {
+ d[i] = 0x00FFFFFF;
+ }
+
+ U32 subcol = 0xFFFFFFFF;
+ if (rez >= 4)
+ { //large grain grid
+ for (U32 i = 0; i < rez; i++)
+ {
+ if (rez <= 16)
+ {
+ if (rez == 16)
+ {
+ subcol = 0xA0FFFFFF;
+ }
+ else if (rez == 8)
+ {
+ subcol = 0x80FFFFFF;
+ }
+ else
+ {
+ subcol = 0x40FFFFFF;
+ }
+ }
+ else
+ {
+ subcol = 0xFFFFFFFF;
+ }
+ d[i *rez+ 0 ] = subcol;
+ d[0 *rez+ i ] = subcol;
+ if (rez >= 32)
+ {
+ d[i *rez+ (rez-1)] = subcol;
+ d[(rez-1) *rez+ i ] = subcol;
+ }
+
+ if (rez >= 64)
+ {
+ subcol = 0xFFFFFFFF;
+
+ if (i > 0 && i < (rez-1))
+ {
+ d[i *rez+ 1 ] = subcol;
+ d[i *rez+ (rez-2)] = subcol;
+ d[1 *rez+ i ] = subcol;
+ d[(rez-2) *rez+ i ] = subcol;
+ }
+ }
+ }
+ }
+
+ subcol = 0x50A0A0A0;
+ if (rez >= 128)
+ { //small grain grid
+ for (U32 i = 8; i < rez; i+=8)
+ {
+ for (U32 j = 2; j < rez-2; j++)
+ {
+ d[i *rez+ j] = subcol;
+ d[j *rez+ i] = subcol;
+ }
+ }
+ }
+ if (rez >= 64)
+ { //medium grain grid
+ if (rez == 64)
+ {
+ subcol = 0x50A0A0A0;
+ }
+ else
+ {
+ subcol = 0xA0D0D0D0;
+ }
+
+ for (U32 i = 32; i < rez; i+=32)
+ {
+ U32 pi = i-1;
+ for (U32 j = 2; j < rez-2; j++)
+ {
+ d[i *rez+ j] = subcol;
+ d[j *rez+ i] = subcol;
+
+ if (rez > 128)
+ {
+ d[pi *rez+ j] = subcol;
+ d[j *rez+ pi] = subcol;
+ }
+ }
+ }
+ }
+ LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_BYTE, d);
+ rez = rez >> 1;
+ mip++;
+ }
+ delete [] d;
}
@@ -282,2018 +282,2029 @@ LLManipTranslate::~LLManipTranslate()
void LLManipTranslate::handleSelect()
{
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
if (gFloaterTools)
{
gFloaterTools->setStatusText("move");
}
- LLManip::handleSelect();
+ LLManip::handleSelect();
}
BOOL LLManipTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
{
- BOOL handled = FALSE;
-
- // didn't click in any UI object, so must have clicked in the world
- if( (mHighlightedPart == LL_X_ARROW ||
- mHighlightedPart == LL_Y_ARROW ||
- mHighlightedPart == LL_Z_ARROW ||
- mHighlightedPart == LL_YZ_PLANE ||
- mHighlightedPart == LL_XZ_PLANE ||
- mHighlightedPart == LL_XY_PLANE ) )
- {
- handled = handleMouseDownOnPart( x, y, mask );
- }
-
- return handled;
+ BOOL handled = FALSE;
+
+ // didn't click in any UI object, so must have clicked in the world
+ if( (mHighlightedPart == LL_X_ARROW ||
+ mHighlightedPart == LL_Y_ARROW ||
+ mHighlightedPart == LL_Z_ARROW ||
+ mHighlightedPart == LL_YZ_PLANE ||
+ mHighlightedPart == LL_XZ_PLANE ||
+ mHighlightedPart == LL_XY_PLANE ) )
+ {
+ handled = handleMouseDownOnPart( x, y, mask );
+ }
+
+ return handled;
}
// Assumes that one of the arrows on an object was hit.
BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
{
- BOOL can_move = canAffectSelection();
- if (!can_move)
- {
- return FALSE;
- }
-
- highlightManipulators(x, y);
- S32 hit_part = mHighlightedPart;
-
- if( (hit_part != LL_X_ARROW) &&
- (hit_part != LL_Y_ARROW) &&
- (hit_part != LL_Z_ARROW) &&
- (hit_part != LL_YZ_PLANE) &&
- (hit_part != LL_XZ_PLANE) &&
- (hit_part != LL_XY_PLANE) )
- {
- return TRUE;
- }
-
- mHelpTextTimer.reset();
- sNumTimesHelpTextShown++;
-
- LLSelectMgr::getInstance()->getGrid(mGridOrigin, mGridRotation, mGridScale);
-
- LLSelectMgr::getInstance()->enableSilhouette(FALSE);
-
- // we just started a drag, so save initial object positions
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE);
-
- mManipPart = (EManipPart)hit_part;
- mMouseDownX = x;
- mMouseDownY = y;
- mMouseOutsideSlop = FALSE;
-
- LLVector3 axis;
-
- LLSelectNode *selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
-
- if (!selectNode)
- {
- // didn't find the object in our selection...oh well
- LL_WARNS() << "Trying to translate an unselected object" << LL_ENDL;
- return TRUE;
- }
-
- LLViewerObject *selected_object = selectNode->getObject();
- if (!selected_object)
- {
- // somehow we lost the object!
- LL_WARNS() << "Translate manip lost the object, no selected object" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
- }
-
- // Compute unit vectors for arrow hit and a plane through that vector
- BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis);
- getManipNormal(selected_object, mManipPart, mManipNormal);
-
- //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal());
- // TomY: The above should (?) be identical to the below
- LLVector3 select_center_agent = getPivotPoint();
- mSubdivisions = getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale());
-
- // if we clicked on a planar manipulator, recenter mouse cursor
- if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
- {
- LLCoordGL mouse_pos;
- if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(select_center_agent, mouse_pos))
- {
- // mouse_pos may be nonsense
- LL_WARNS() << "Failed to project object center to screen" << LL_ENDL;
- }
- else if (gSavedSettings.getBOOL("SnapToMouseCursor"))
- {
- LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
- x = mouse_pos.mX;
- y = mouse_pos.mY;
- }
- }
-
- LLSelectMgr::getInstance()->updateSelectionCenter();
- LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
- getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal);
- mDragSelectionStartGlobal = object_start_global;
- mCopyMadeThisDrag = FALSE;
-
- // Route future Mouse messages here preemptively. (Release on mouse up.)
- setMouseCapture( TRUE );
-
- return TRUE;
+ BOOL can_move = canAffectSelection();
+ if (!can_move)
+ {
+ return FALSE;
+ }
+
+ highlightManipulators(x, y);
+ S32 hit_part = mHighlightedPart;
+
+ if( (hit_part != LL_X_ARROW) &&
+ (hit_part != LL_Y_ARROW) &&
+ (hit_part != LL_Z_ARROW) &&
+ (hit_part != LL_YZ_PLANE) &&
+ (hit_part != LL_XZ_PLANE) &&
+ (hit_part != LL_XY_PLANE) )
+ {
+ return TRUE;
+ }
+
+ mHelpTextTimer.reset();
+ sNumTimesHelpTextShown++;
+
+ LLSelectMgr::getInstance()->getGrid(mGridOrigin, mGridRotation, mGridScale);
+
+ LLSelectMgr::getInstance()->enableSilhouette(FALSE);
+
+ // we just started a drag, so save initial object positions
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE);
+
+ mManipPart = (EManipPart)hit_part;
+ mMouseDownX = x;
+ mMouseDownY = y;
+ mMouseOutsideSlop = FALSE;
+
+ LLVector3 axis;
+
+ LLSelectNode *selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
+
+ if (!selectNode)
+ {
+ // didn't find the object in our selection...oh well
+ LL_WARNS() << "Trying to translate an unselected object" << LL_ENDL;
+ return TRUE;
+ }
+
+ LLViewerObject *selected_object = selectNode->getObject();
+ if (!selected_object)
+ {
+ // somehow we lost the object!
+ LL_WARNS() << "Translate manip lost the object, no selected object" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+ }
+
+ // Compute unit vectors for arrow hit and a plane through that vector
+ BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis);
+ getManipNormal(selected_object, mManipPart, mManipNormal);
+
+ //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal());
+ // TomY: The above should (?) be identical to the below
+ LLVector3 select_center_agent = getPivotPoint();
+ mSubdivisions = getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale());
+
+ // if we clicked on a planar manipulator, recenter mouse cursor
+ if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
+ {
+ LLCoordGL mouse_pos;
+ if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(select_center_agent, mouse_pos))
+ {
+ // mouse_pos may be nonsense
+ LL_WARNS() << "Failed to project object center to screen" << LL_ENDL;
+ }
+ else if (gSavedSettings.getBOOL("SnapToMouseCursor"))
+ {
+ LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
+ x = mouse_pos.mX;
+ y = mouse_pos.mY;
+ }
+ }
+
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
+ getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal);
+ mDragSelectionStartGlobal = object_start_global;
+ mCopyMadeThisDrag = FALSE;
+
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ setMouseCapture( TRUE );
+
+ return TRUE;
}
BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
{
- // Translation tool only works if mouse button is down.
- // Bail out if mouse not down.
- if( !hasMouseCapture() )
- {
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (inactive)" << LL_ENDL;
- // Always show cursor
- // gViewerWindow->setCursor(UI_CURSOR_ARROW);
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
-
- highlightManipulators(x, y);
- return TRUE;
- }
-
- // Handle auto-rotation if necessary.
- LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
- const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
- const S32 ROTATE_H_MARGIN = world_rect.getWidth() / 20;
- const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
- BOOL rotated = FALSE;
-
- // ...build mode moves camera about focus point
- if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
- {
- if (x < ROTATE_H_MARGIN)
- {
- gAgentCamera.cameraOrbitAround(rotate_angle);
- rotated = TRUE;
- }
- else if (x > world_rect.getWidth() - ROTATE_H_MARGIN)
- {
- gAgentCamera.cameraOrbitAround(-rotate_angle);
- rotated = TRUE;
- }
- }
-
- // Suppress processing if mouse hasn't actually moved.
- // This may cause problems if the camera moves outside of the
- // rotation above.
- if( x == mLastHoverMouseX && y == mLastHoverMouseY && !rotated)
- {
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse unmoved)" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
- }
- mLastHoverMouseX = x;
- mLastHoverMouseY = y;
-
- // Suppress if mouse hasn't moved past the initial slop region
- // Reset once we start moving
- if( !mMouseOutsideSlop )
- {
- if (abs(mMouseDownX - x) < MOUSE_DRAG_SLOP && abs(mMouseDownY - y) < MOUSE_DRAG_SLOP )
- {
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse inside slop)" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
- }
- else
- {
- // ...just went outside the slop region
- mMouseOutsideSlop = TRUE;
- // If holding down shift, leave behind a copy.
- if (mask == MASK_COPY)
- {
- // ...we're trying to make a copy
- LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE);
- mCopyMadeThisDrag = TRUE;
-
- // When we make the copy, we don't want to do any other processing.
- // If so, the object will also be moved, and the copy will be offset.
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (made copy)" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- }
- }
- }
-
- // Throttle updates to 10 per second.
-
- LLVector3 axis_f;
- LLVector3d axis_d;
-
- // pick the first object to constrain to grid w/ common origin
- // this is so we don't screw up groups
- LLSelectNode* selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
- if (!selectNode)
- {
- // somehow we lost the object!
- LL_WARNS() << "Translate manip lost the object, no selectNode" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
- }
-
- LLViewerObject* object = selectNode->getObject();
- if (!object)
- {
- // somehow we lost the object!
- LL_WARNS() << "Translate manip lost the object, no object in selectNode" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
- }
-
- // Compute unit vectors for arrow hit and a plane through that vector
- BOOL axis_exists = getManipAxis(object, mManipPart, axis_f); // TODO: move this
-
- axis_d.setVec(axis_f);
-
- LLSelectMgr::getInstance()->updateSelectionCenter();
- LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
-
- mSubdivisions = getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale());
-
- // Project the cursor onto that plane
- LLVector3d relative_move;
- getMousePointOnPlaneGlobal(relative_move, x, y, current_pos_global, mManipNormal);\
- relative_move -= mDragCursorStartGlobal;
-
- // You can't move more than some distance from your original mousedown point.
- if (gSavedSettings.getBOOL("LimitDragDistance"))
- {
- F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance");
-
- if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance)
- {
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (too far)" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
- return TRUE;
- }
- }
-
- F64 axis_magnitude = relative_move * axis_d; // dot product
- LLVector3d cursor_point_snap_line;
-
- F64 off_axis_magnitude;
-
- getMousePointOnPlaneGlobal(cursor_point_snap_line, x, y, current_pos_global, mSnapOffsetAxis % axis_f);
- off_axis_magnitude = axis_exists ? llabs((cursor_point_snap_line - current_pos_global) * LLVector3d(mSnapOffsetAxis)) : 0.f;
-
- if (gSavedSettings.getBOOL("SnapEnabled"))
- {
- if (off_axis_magnitude > mSnapOffsetMeters)
- {
- mInSnapRegime = TRUE;
- LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line);
-
- F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f;
-
- F32 snap_dist = getMinGridScale() / (2.f * mSubdivisions);
- F32 relative_snap_dist = fmodf(llabs(cursor_grid_dist) + snap_dist, getMinGridScale() / mSubdivisions);
- if (relative_snap_dist < snap_dist * 2.f)
- {
- if (cursor_grid_dist > 0.f)
- {
- cursor_grid_dist -= relative_snap_dist - snap_dist;
- }
- else
- {
- cursor_grid_dist += relative_snap_dist - snap_dist;
- }
- }
-
- F32 object_start_on_axis = (gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal) - mGridOrigin) * axis_f;
- axis_magnitude = cursor_grid_dist - object_start_on_axis;
- }
- else if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
- {
- // subtract offset from object center
- LLVector3d cursor_point_global;
- getMousePointOnPlaneGlobal( cursor_point_global, x, y, current_pos_global, mManipNormal );
- cursor_point_global -= (mDragCursorStartGlobal - mDragSelectionStartGlobal);
-
- // snap to planar grid
- LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global);
- LLVector3 camera_plane_projection = LLViewerCamera::getInstance()->getAtAxis();
- camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal);
- camera_plane_projection.normVec();
- LLVector3 camera_projected_dir = camera_plane_projection;
- camera_plane_projection.rotVec(~mGridRotation);
- camera_plane_projection.scaleVec(mGridScale);
- camera_plane_projection.abs();
- F32 max_grid_scale;
- if (camera_plane_projection.mV[VX] > camera_plane_projection.mV[VY] &&
- camera_plane_projection.mV[VX] > camera_plane_projection.mV[VZ])
- {
- max_grid_scale = mGridScale.mV[VX];
- }
- else if (camera_plane_projection.mV[VY] > camera_plane_projection.mV[VZ])
- {
- max_grid_scale = mGridScale.mV[VY];
- }
- else
- {
- max_grid_scale = mGridScale.mV[VZ];
- }
-
- F32 num_subdivisions = getSubdivisionLevel(getPivotPoint(), camera_projected_dir, max_grid_scale);
-
- F32 grid_scale_a;
- F32 grid_scale_b;
- LLVector3 cursor_point_grid = (cursor_point_agent - mGridOrigin) * ~mGridRotation;
-
- switch (mManipPart)
- {
- case LL_YZ_PLANE:
- grid_scale_a = mGridScale.mV[VY] / num_subdivisions;
- grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
- cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
- cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
- break;
- case LL_XZ_PLANE:
- grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
- grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
- cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
- cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
- break;
- case LL_XY_PLANE:
- grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
- grid_scale_b = mGridScale.mV[VY] / num_subdivisions;
- cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
- cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
- break;
- default:
- break;
- }
- cursor_point_agent = (cursor_point_grid * mGridRotation) + mGridOrigin;
- relative_move.setVec(cursor_point_agent - gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal));
- mInSnapRegime = TRUE;
- }
- else
- {
- mInSnapRegime = FALSE;
- }
- }
- else
- {
- mInSnapRegime = FALSE;
- }
-
- // Clamp to arrow direction
- // *FIX: does this apply anymore?
- if (!axis_exists)
- {
- axis_magnitude = relative_move.normVec();
- axis_d.setVec(relative_move);
- axis_d.normVec();
- axis_f.setVec(axis_d);
- }
-
- LLVector3d clamped_relative_move = axis_magnitude * axis_d; // scalar multiply
- LLVector3 clamped_relative_move_f = (F32)axis_magnitude * axis_f; // scalar multiply
-
+ // Translation tool only works if mouse button is down.
+ // Bail out if mouse not down.
+ if( !hasMouseCapture() )
+ {
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (inactive)" << LL_ENDL;
+ // Always show cursor
+ // gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+
+ highlightManipulators(x, y);
+ return TRUE;
+ }
+
+ // Handle auto-rotation if necessary.
+ LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
+ const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
+ const S32 ROTATE_H_MARGIN = world_rect.getWidth() / 20;
+ const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
+ BOOL rotated = FALSE;
+
+ // ...build mode moves camera about focus point
+ if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ if (x < ROTATE_H_MARGIN)
+ {
+ gAgentCamera.cameraOrbitAround(rotate_angle);
+ rotated = TRUE;
+ }
+ else if (x > world_rect.getWidth() - ROTATE_H_MARGIN)
+ {
+ gAgentCamera.cameraOrbitAround(-rotate_angle);
+ rotated = TRUE;
+ }
+ }
+
+ // Suppress processing if mouse hasn't actually moved.
+ // This may cause problems if the camera moves outside of the
+ // rotation above.
+ if( x == mLastHoverMouseX && y == mLastHoverMouseY && !rotated)
+ {
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse unmoved)" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+ }
+ mLastHoverMouseX = x;
+ mLastHoverMouseY = y;
+
+ // Suppress if mouse hasn't moved past the initial slop region
+ // Reset once we start moving
+ if( !mMouseOutsideSlop )
+ {
+ if (abs(mMouseDownX - x) < MOUSE_DRAG_SLOP && abs(mMouseDownY - y) < MOUSE_DRAG_SLOP )
+ {
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (mouse inside slop)" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+ }
+ else
+ {
+ // ...just went outside the slop region
+ mMouseOutsideSlop = TRUE;
+ // If holding down shift, leave behind a copy.
+ if (mask == MASK_COPY)
+ {
+ // ...we're trying to make a copy
+ LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE);
+ mCopyMadeThisDrag = TRUE;
+
+ // When we make the copy, we don't want to do any other processing.
+ // If so, the object will also be moved, and the copy will be offset.
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (made copy)" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ }
+ }
+ }
+
+ // Throttle updates to 10 per second.
+
+ LLVector3 axis_f;
+ LLVector3d axis_d;
+
+ // pick the first object to constrain to grid w/ common origin
+ // this is so we don't screw up groups
+ LLSelectNode* selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
+ if (!selectNode)
+ {
+ // somehow we lost the object!
+ LL_WARNS() << "Translate manip lost the object, no selectNode" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+ }
+
+ LLViewerObject* object = selectNode->getObject();
+ if (!object)
+ {
+ // somehow we lost the object!
+ LL_WARNS() << "Translate manip lost the object, no object in selectNode" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+ }
+
+ // Compute unit vectors for arrow hit and a plane through that vector
+ BOOL axis_exists = getManipAxis(object, mManipPart, axis_f); // TODO: move this
+
+ axis_d.setVec(axis_f);
+
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
+
+ mSubdivisions = getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale());
+
+ // Project the cursor onto that plane
+ LLVector3d relative_move;
+ getMousePointOnPlaneGlobal(relative_move, x, y, current_pos_global, mManipNormal);\
+ relative_move -= mDragCursorStartGlobal;
+
+ // You can't move more than some distance from your original mousedown point.
+ if (gSavedSettings.getBOOL("LimitDragDistance"))
+ {
+ F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance");
+
+ if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance)
+ {
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (too far)" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
+ return TRUE;
+ }
+ }
+
+ F64 axis_magnitude = relative_move * axis_d; // dot product
+ LLVector3d cursor_point_snap_line;
+
+ F64 off_axis_magnitude;
+
+ getMousePointOnPlaneGlobal(cursor_point_snap_line, x, y, current_pos_global, mSnapOffsetAxis % axis_f);
+ off_axis_magnitude = axis_exists ? llabs((cursor_point_snap_line - current_pos_global) * LLVector3d(mSnapOffsetAxis)) : 0.f;
+
+ if (gSavedSettings.getBOOL("SnapEnabled"))
+ {
+ if (off_axis_magnitude > mSnapOffsetMeters)
+ {
+ mInSnapRegime = TRUE;
+ LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line);
+
+ F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f;
+
+ F32 snap_dist = getMinGridScale() / (2.f * mSubdivisions);
+ F32 relative_snap_dist = fmodf(llabs(cursor_grid_dist) + snap_dist, getMinGridScale() / mSubdivisions);
+ if (relative_snap_dist < snap_dist * 2.f)
+ {
+ if (cursor_grid_dist > 0.f)
+ {
+ cursor_grid_dist -= relative_snap_dist - snap_dist;
+ }
+ else
+ {
+ cursor_grid_dist += relative_snap_dist - snap_dist;
+ }
+ }
+
+ F32 object_start_on_axis = (gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal) - mGridOrigin) * axis_f;
+ axis_magnitude = cursor_grid_dist - object_start_on_axis;
+ }
+ else if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
+ {
+ // subtract offset from object center
+ LLVector3d cursor_point_global;
+ getMousePointOnPlaneGlobal( cursor_point_global, x, y, current_pos_global, mManipNormal );
+ cursor_point_global -= (mDragCursorStartGlobal - mDragSelectionStartGlobal);
+
+ // snap to planar grid
+ LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global);
+ LLVector3 camera_plane_projection = LLViewerCamera::getInstance()->getAtAxis();
+ camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal);
+ camera_plane_projection.normVec();
+ LLVector3 camera_projected_dir = camera_plane_projection;
+ camera_plane_projection.rotVec(~mGridRotation);
+ camera_plane_projection.scaleVec(mGridScale);
+ camera_plane_projection.abs();
+ F32 max_grid_scale;
+ if (camera_plane_projection.mV[VX] > camera_plane_projection.mV[VY] &&
+ camera_plane_projection.mV[VX] > camera_plane_projection.mV[VZ])
+ {
+ max_grid_scale = mGridScale.mV[VX];
+ }
+ else if (camera_plane_projection.mV[VY] > camera_plane_projection.mV[VZ])
+ {
+ max_grid_scale = mGridScale.mV[VY];
+ }
+ else
+ {
+ max_grid_scale = mGridScale.mV[VZ];
+ }
+
+ F32 num_subdivisions = getSubdivisionLevel(getPivotPoint(), camera_projected_dir, max_grid_scale);
+
+ F32 grid_scale_a;
+ F32 grid_scale_b;
+ LLVector3 cursor_point_grid = (cursor_point_agent - mGridOrigin) * ~mGridRotation;
+
+ switch (mManipPart)
+ {
+ case LL_YZ_PLANE:
+ grid_scale_a = mGridScale.mV[VY] / num_subdivisions;
+ grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
+ cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
+ cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
+ break;
+ case LL_XZ_PLANE:
+ grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
+ grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
+ cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
+ cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
+ break;
+ case LL_XY_PLANE:
+ grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
+ grid_scale_b = mGridScale.mV[VY] / num_subdivisions;
+ cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
+ cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
+ break;
+ default:
+ break;
+ }
+ cursor_point_agent = (cursor_point_grid * mGridRotation) + mGridOrigin;
+ relative_move.setVec(cursor_point_agent - gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal));
+ mInSnapRegime = TRUE;
+ }
+ else
+ {
+ mInSnapRegime = FALSE;
+ }
+ }
+ else
+ {
+ mInSnapRegime = FALSE;
+ }
+
+ // Clamp to arrow direction
+ // *FIX: does this apply anymore?
+ if (!axis_exists)
+ {
+ axis_magnitude = relative_move.normVec();
+ axis_d.setVec(relative_move);
+ axis_d.normVec();
+ axis_f.setVec(axis_d);
+ }
+
+ LLVector3d clamped_relative_move = axis_magnitude * axis_d; // scalar multiply
+ LLVector3 clamped_relative_move_f = (F32)axis_magnitude * axis_f; // scalar multiply
+
for (LLObjectSelection::iterator iter = mObjectSelection->begin();
- iter != mObjectSelection->end(); iter++)
+ iter != mObjectSelection->end(); iter++)
{
LLSelectNode* selectNode = *iter;
LLViewerObject* object = selectNode->getObject();
- // Only apply motion to root objects and objects selected
- // as "individual".
- if (!object->isRootEdit() && !selectNode->mIndividualSelection)
+ if (selectNode->mSelectedGLTFNode != -1)
{
- continue;
+ // manipulating a GLTF node
+ clamped_relative_move_f -= selectNode->mLastMoveLocal;
+ object->moveGLTFNode(selectNode->mSelectedGLTFNode, clamped_relative_move_f);
+ selectNode->mLastMoveLocal += clamped_relative_move_f;
}
-
- if (!object->isRootEdit())
+ else
{
- // child objects should not update if parent is selected
- LLViewerObject* editable_root = (LLViewerObject*)object->getParent();
- if (editable_root->isSelected())
+ // Only apply motion to root objects and objects selected
+ // as "individual".
+ if (!object->isRootEdit() && !selectNode->mIndividualSelection)
{
- // we will be moved properly by our parent, so skip
continue;
}
- }
- LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
- if (object->permMove() && !object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()))
- {
- // handle attachments in local space
- if (object->isAttachment() && object->mDrawable.notNull())
+ if (!object->isRootEdit())
{
- // calculate local version of relative move
- LLQuaternion objWorldRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
- objWorldRotation.transQuat();
-
- LLVector3 old_position_local = object->getPosition();
- LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
-
- //RN: I forget, but we need to do this because of snapping which doesn't often result
- // in position changes even when the mouse moves
- object->setPosition(new_position_local);
- rebuild(object);
- gAgentAvatarp->clampAttachmentPositions();
- new_position_local = object->getPosition();
-
- if (selectNode->mIndividualSelection)
+ // child objects should not update if parent is selected
+ LLViewerObject* editable_root = (LLViewerObject*)object->getParent();
+ if (editable_root->isSelected())
{
- // counter-translate child objects if we are moving the root as an individual
- object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ;
+ // we will be moved properly by our parent, so skip
+ continue;
}
}
- else
- {
- // compute new position to send to simulators, but don't set it yet.
- // We need the old position to know which simulator to send the move message to.
- LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move;
-
- // Don't let object centers go too far underground
- F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object, object->getPositionGlobal());
- if (new_position_global.mdV[VZ] < min_height)
- {
- new_position_global.mdV[VZ] = min_height;
- }
-
- // For safety, cap heights where objects can be dragged
- if (new_position_global.mdV[VZ] > MAX_OBJECT_Z)
- {
- new_position_global.mdV[VZ] = MAX_OBJECT_Z;
- }
- // Grass is always drawn on the ground, so clamp its position to the ground
- if (object->getPCode() == LL_PCODE_LEGACY_GRASS)
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()))
+ {
+ // handle attachments in local space
+ if (object->isAttachment() && object->mDrawable.notNull())
{
- new_position_global.mdV[VZ] = LLWorld::getInstance()->resolveLandHeightGlobal(new_position_global) + 1.f;
- }
+ // calculate local version of relative move
+ LLQuaternion objWorldRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
+ objWorldRotation.transQuat();
- if (object->isRootEdit())
- {
- new_position_global = LLWorld::getInstance()->clipToVisibleRegions(object->getPositionGlobal(), new_position_global);
- }
+ LLVector3 old_position_local = object->getPosition();
+ LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
- // PR: Only update if changed
- LLVector3 old_position_agent = object->getPositionAgent();
- LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
- if (object->isRootEdit())
- {
- // finally, move parent object after children have calculated new offsets
- object->setPositionAgent(new_position_agent);
+ //RN: I forget, but we need to do this because of snapping which doesn't often result
+ // in position changes even when the mouse moves
+ object->setPosition(new_position_local);
rebuild(object);
+ gAgentAvatarp->clampAttachmentPositions();
+ new_position_local = object->getPosition();
+
+ if (selectNode->mIndividualSelection)
+ {
+ // counter-translate child objects if we are moving the root as an individual
+ object->resetChildrenPosition(old_position_local - new_position_local, TRUE);
+ }
}
else
{
- LLViewerObject* root_object = object->getRootEdit();
- new_position_agent -= root_object->getPositionAgent();
- new_position_agent = new_position_agent * ~root_object->getRotation();
- object->setPositionParent(new_position_agent, FALSE);
- rebuild(object);
- }
-
- if (selectNode->mIndividualSelection)
- {
- // counter-translate child objects if we are moving the root as an individual
- object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ;
- }
- }
- selectNode->mLastPositionLocal = object->getPosition();
- }
- }
-
- LLSelectMgr::getInstance()->updateSelectionCenter();
- gAgentCamera.clearFocusObject();
- dialog_refresh_all(); // ??? is this necessary?
-
- LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (active)" << LL_ENDL;
- gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
- return TRUE;
-}
-
-void LLManipTranslate::highlightManipulators(S32 x, S32 y)
-{
- mHighlightedPart = LL_NO_PART;
+ // compute new position to send to simulators, but don't set it yet.
+ // We need the old position to know which simulator to send the move message to.
+ LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move;
- if (!mObjectSelection->getObjectCount())
- {
- return;
- }
-
- //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
- LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection();
- LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview();
-
- LLVector3 object_position = getPivotPoint();
-
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- LLVector3 relative_camera_dir;
-
- LLMatrix4 transform;
-
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation;
- LLVector4 translation(object_position);
- transform.initRotTrans(grid_rotation, translation);
- LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
- transform *= cfr;
- LLMatrix4 window_scale;
- F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom;
- window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),
- LLQuaternion::DEFAULT,
- LLVector3::zero);
- transform *= window_scale;
- }
- else
- {
- relative_camera_dir = (object_position - LLViewerCamera::getInstance()->getOrigin()) * ~grid_rotation;
- relative_camera_dir.normVec();
-
- transform.initRotTrans(grid_rotation, LLVector4(object_position));
- transform *= modelView;
- transform *= projMatrix;
- }
-
- S32 numManips = 0;
-
- // edges
- mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
-
- mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
-
- mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 1.f);
-
- mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
-
- mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
-
- mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 1.f);
- mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 1.f);
-
- S32 num_arrow_manips = numManips;
-
- // planar manipulators
- BOOL planar_manip_yz_visible = FALSE;
- BOOL planar_manip_xz_visible = FALSE;
- BOOL planar_manip_xy_visible = FALSE;
-
- mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- if (llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- planar_manip_yz_visible = TRUE;
- }
-
- mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- if (llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- planar_manip_xz_visible = TRUE;
- }
-
- mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
- mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
- if (llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- planar_manip_xy_visible = TRUE;
- }
+ // Don't let object centers go too far underground
+ F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object, object->getPositionGlobal());
+ if (new_position_global.mdV[VZ] < min_height)
+ {
+ new_position_global.mdV[VZ] = min_height;
+ }
- // Project up to 9 manipulators to screen space 2*X, 2*Y, 2*Z, 3*planes
- std::vector<ManipulatorHandle> projected_manipulators;
- projected_manipulators.reserve(9);
+ // For safety, cap heights where objects can be dragged
+ if (new_position_global.mdV[VZ] > MAX_OBJECT_Z)
+ {
+ new_position_global.mdV[VZ] = MAX_OBJECT_Z;
+ }
- for (S32 i = 0; i < num_arrow_manips; i+= 2)
- {
- LLVector4 projected_start = mManipulatorVertices[i] * transform;
- projected_start = projected_start * (1.f / projected_start.mV[VW]);
-
- LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
- projected_end = projected_end * (1.f / projected_end.mV[VW]);
-
- ManipulatorHandle projected_manip(
- LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
- LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
- MANIPULATOR_IDS[i / 2],
- 10.f); // 10 pixel hotspot for arrows
- projected_manipulators.push_back(projected_manip);
- }
+ // Grass is always drawn on the ground, so clamp its position to the ground
+ if (object->getPCode() == LL_PCODE_LEGACY_GRASS)
+ {
+ new_position_global.mdV[VZ] = LLWorld::getInstance()->resolveLandHeightGlobal(new_position_global) + 1.f;
+ }
- if (planar_manip_yz_visible)
- {
- S32 i = num_arrow_manips;
- LLVector4 projected_start = mManipulatorVertices[i] * transform;
- projected_start = projected_start * (1.f / projected_start.mV[VW]);
-
- LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
- projected_end = projected_end * (1.f / projected_end.mV[VW]);
-
- ManipulatorHandle projected_manip(
- LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
- LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
- MANIPULATOR_IDS[i / 2],
- 20.f); // 20 pixels for planar manipulators
- projected_manipulators.push_back(projected_manip);
- }
+ if (object->isRootEdit())
+ {
+ new_position_global = LLWorld::getInstance()->clipToVisibleRegions(object->getPositionGlobal(), new_position_global);
+ }
- if (planar_manip_xz_visible)
- {
- S32 i = num_arrow_manips + 2;
- LLVector4 projected_start = mManipulatorVertices[i] * transform;
- projected_start = projected_start * (1.f / projected_start.mV[VW]);
-
- LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
- projected_end = projected_end * (1.f / projected_end.mV[VW]);
-
- ManipulatorHandle projected_manip(
- LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
- LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
- MANIPULATOR_IDS[i / 2],
- 20.f); // 20 pixels for planar manipulators
- projected_manipulators.push_back(projected_manip);
- }
+ // PR: Only update if changed
+ LLVector3 old_position_agent = object->getPositionAgent();
+ LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
+ if (object->isRootEdit())
+ {
+ // finally, move parent object after children have calculated new offsets
+ object->setPositionAgent(new_position_agent);
+ rebuild(object);
+ }
+ else
+ {
+ LLViewerObject* root_object = object->getRootEdit();
+ new_position_agent -= root_object->getPositionAgent();
+ new_position_agent = new_position_agent * ~root_object->getRotation();
+ object->setPositionParent(new_position_agent, FALSE);
+ rebuild(object);
+ }
- if (planar_manip_xy_visible)
- {
- S32 i = num_arrow_manips + 4;
- LLVector4 projected_start = mManipulatorVertices[i] * transform;
- projected_start = projected_start * (1.f / projected_start.mV[VW]);
-
- LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
- projected_end = projected_end * (1.f / projected_end.mV[VW]);
-
- ManipulatorHandle projected_manip(
- LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
- LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
- MANIPULATOR_IDS[i / 2],
- 20.f); // 20 pixels for planar manipulators
- projected_manipulators.push_back(projected_manip);
+ if (selectNode->mIndividualSelection)
+ {
+ // counter-translate child objects if we are moving the root as an individual
+ object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE);
+ }
+ }
+ selectNode->mLastPositionLocal = object->getPosition();
+ }
+ }
}
- LLVector2 manip_start_2d;
- LLVector2 manip_end_2d;
- LLVector2 manip_dir;
- LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled();
- F32 half_width = (F32)world_view_rect.getWidth() / 2.f;
- F32 half_height = (F32)world_view_rect.getHeight() / 2.f;
- LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
- LLVector2 mouse_delta;
-
- // Keep order consistent with insertion via stable_sort
- std::stable_sort( projected_manipulators.begin(),
- projected_manipulators.end(),
- ClosestToCamera() );
-
- std::vector<ManipulatorHandle>::iterator it = projected_manipulators.begin();
- for ( ; it != projected_manipulators.end(); ++it)
- {
- ManipulatorHandle& manipulator = *it;
- {
- manip_start_2d.setVec(manipulator.mStartPosition.mV[VX] * half_width, manipulator.mStartPosition.mV[VY] * half_height);
- manip_end_2d.setVec(manipulator.mEndPosition.mV[VX] * half_width, manipulator.mEndPosition.mV[VY] * half_height);
- manip_dir = manip_end_2d - manip_start_2d;
-
- mouse_delta = mousePos - manip_start_2d;
- F32 manip_length = manip_dir.normVec();
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ gAgentCamera.clearFocusObject();
+ dialog_refresh_all(); // ??? is this necessary?
- F32 mouse_pos_manip = mouse_delta * manip_dir;
- F32 mouse_dist_manip_squared = mouse_delta.magVecSquared() - (mouse_pos_manip * mouse_pos_manip);
+ LL_DEBUGS("UserInput") << "hover handled by LLManipTranslate (active)" << LL_ENDL;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
+ return TRUE;
+}
- if (mouse_pos_manip > 0.f &&
- mouse_pos_manip < manip_length &&
- mouse_dist_manip_squared < manipulator.mHotSpotRadius * manipulator.mHotSpotRadius)
- {
- mHighlightedPart = manipulator.mManipID;
- break;
- }
- }
- }
+void LLManipTranslate::highlightManipulators(S32 x, S32 y)
+{
+ mHighlightedPart = LL_NO_PART;
+
+ if (!mObjectSelection->getObjectCount())
+ {
+ return;
+ }
+
+ //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection();
+ LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview();
+
+ LLVector3 object_position = getPivotPoint();
+
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+
+ LLVector3 relative_camera_dir;
+
+ LLMatrix4 transform;
+
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation;
+ LLVector4 translation(object_position);
+ transform.initRotTrans(grid_rotation, translation);
+ LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
+ transform *= cfr;
+ LLMatrix4 window_scale;
+ F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom;
+ window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),
+ LLQuaternion::DEFAULT,
+ LLVector3::zero);
+ transform *= window_scale;
+ }
+ else
+ {
+ relative_camera_dir = (object_position - LLViewerCamera::getInstance()->getOrigin()) * ~grid_rotation;
+ relative_camera_dir.normVec();
+
+ transform.initRotTrans(grid_rotation, LLVector4(object_position));
+ transform *= modelView;
+ transform *= projMatrix;
+ }
+
+ S32 numManips = 0;
+
+ // edges
+ mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
+
+ mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
+
+ mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 1.f);
+
+ mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
+
+ mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
+
+ mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 1.f);
+ mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 1.f);
+
+ S32 num_arrow_manips = numManips;
+
+ // planar manipulators
+ BOOL planar_manip_yz_visible = FALSE;
+ BOOL planar_manip_xz_visible = FALSE;
+ BOOL planar_manip_xy_visible = FALSE;
+
+ mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ if (llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ planar_manip_yz_visible = TRUE;
+ }
+
+ mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ if (llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ planar_manip_xz_visible = TRUE;
+ }
+
+ mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
+ mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
+ if (llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ planar_manip_xy_visible = TRUE;
+ }
+
+ // Project up to 9 manipulators to screen space 2*X, 2*Y, 2*Z, 3*planes
+ std::vector<ManipulatorHandle> projected_manipulators;
+ projected_manipulators.reserve(9);
+
+ for (S32 i = 0; i < num_arrow_manips; i+= 2)
+ {
+ LLVector4 projected_start = mManipulatorVertices[i] * transform;
+ projected_start = projected_start * (1.f / projected_start.mV[VW]);
+
+ LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
+ projected_end = projected_end * (1.f / projected_end.mV[VW]);
+
+ ManipulatorHandle projected_manip(
+ LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
+ LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
+ MANIPULATOR_IDS[i / 2],
+ 10.f); // 10 pixel hotspot for arrows
+ projected_manipulators.push_back(projected_manip);
+ }
+
+ if (planar_manip_yz_visible)
+ {
+ S32 i = num_arrow_manips;
+ LLVector4 projected_start = mManipulatorVertices[i] * transform;
+ projected_start = projected_start * (1.f / projected_start.mV[VW]);
+
+ LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
+ projected_end = projected_end * (1.f / projected_end.mV[VW]);
+
+ ManipulatorHandle projected_manip(
+ LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
+ LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
+ MANIPULATOR_IDS[i / 2],
+ 20.f); // 20 pixels for planar manipulators
+ projected_manipulators.push_back(projected_manip);
+ }
+
+ if (planar_manip_xz_visible)
+ {
+ S32 i = num_arrow_manips + 2;
+ LLVector4 projected_start = mManipulatorVertices[i] * transform;
+ projected_start = projected_start * (1.f / projected_start.mV[VW]);
+
+ LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
+ projected_end = projected_end * (1.f / projected_end.mV[VW]);
+
+ ManipulatorHandle projected_manip(
+ LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
+ LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
+ MANIPULATOR_IDS[i / 2],
+ 20.f); // 20 pixels for planar manipulators
+ projected_manipulators.push_back(projected_manip);
+ }
+
+ if (planar_manip_xy_visible)
+ {
+ S32 i = num_arrow_manips + 4;
+ LLVector4 projected_start = mManipulatorVertices[i] * transform;
+ projected_start = projected_start * (1.f / projected_start.mV[VW]);
+
+ LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
+ projected_end = projected_end * (1.f / projected_end.mV[VW]);
+
+ ManipulatorHandle projected_manip(
+ LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
+ LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
+ MANIPULATOR_IDS[i / 2],
+ 20.f); // 20 pixels for planar manipulators
+ projected_manipulators.push_back(projected_manip);
+ }
+
+ LLVector2 manip_start_2d;
+ LLVector2 manip_end_2d;
+ LLVector2 manip_dir;
+ LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled();
+ F32 half_width = (F32)world_view_rect.getWidth() / 2.f;
+ F32 half_height = (F32)world_view_rect.getHeight() / 2.f;
+ LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
+ LLVector2 mouse_delta;
+
+ // Keep order consistent with insertion via stable_sort
+ std::stable_sort( projected_manipulators.begin(),
+ projected_manipulators.end(),
+ ClosestToCamera() );
+
+ std::vector<ManipulatorHandle>::iterator it = projected_manipulators.begin();
+ for ( ; it != projected_manipulators.end(); ++it)
+ {
+ ManipulatorHandle& manipulator = *it;
+ {
+ manip_start_2d.setVec(manipulator.mStartPosition.mV[VX] * half_width, manipulator.mStartPosition.mV[VY] * half_height);
+ manip_end_2d.setVec(manipulator.mEndPosition.mV[VX] * half_width, manipulator.mEndPosition.mV[VY] * half_height);
+ manip_dir = manip_end_2d - manip_start_2d;
+
+ mouse_delta = mousePos - manip_start_2d;
+
+ F32 manip_length = manip_dir.normVec();
+
+ F32 mouse_pos_manip = mouse_delta * manip_dir;
+ F32 mouse_dist_manip_squared = mouse_delta.magVecSquared() - (mouse_pos_manip * mouse_pos_manip);
+
+ if (mouse_pos_manip > 0.f &&
+ mouse_pos_manip < manip_length &&
+ mouse_dist_manip_squared < manipulator.mHotSpotRadius * manipulator.mHotSpotRadius)
+ {
+ mHighlightedPart = manipulator.mManipID;
+ break;
+ }
+ }
+ }
}
F32 LLManipTranslate::getMinGridScale()
{
- F32 scale;
- switch (mManipPart)
- {
- case LL_NO_PART:
- default:
- scale = 1.f;
- break;
- case LL_X_ARROW:
- scale = mGridScale.mV[VX];
- break;
- case LL_Y_ARROW:
- scale = mGridScale.mV[VY];
- break;
- case LL_Z_ARROW:
- scale = mGridScale.mV[VZ];
- break;
- case LL_YZ_PLANE:
- scale = llmin(mGridScale.mV[VY], mGridScale.mV[VZ]);
- break;
- case LL_XZ_PLANE:
- scale = llmin(mGridScale.mV[VX], mGridScale.mV[VZ]);
- break;
- case LL_XY_PLANE:
- scale = llmin(mGridScale.mV[VX], mGridScale.mV[VY]);
- break;
- }
-
- return scale;
+ F32 scale;
+ switch (mManipPart)
+ {
+ case LL_NO_PART:
+ default:
+ scale = 1.f;
+ break;
+ case LL_X_ARROW:
+ scale = mGridScale.mV[VX];
+ break;
+ case LL_Y_ARROW:
+ scale = mGridScale.mV[VY];
+ break;
+ case LL_Z_ARROW:
+ scale = mGridScale.mV[VZ];
+ break;
+ case LL_YZ_PLANE:
+ scale = llmin(mGridScale.mV[VY], mGridScale.mV[VZ]);
+ break;
+ case LL_XZ_PLANE:
+ scale = llmin(mGridScale.mV[VX], mGridScale.mV[VZ]);
+ break;
+ case LL_XY_PLANE:
+ scale = llmin(mGridScale.mV[VX], mGridScale.mV[VY]);
+ break;
+ }
+
+ return scale;
}
BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask)
{
- // first, perform normal processing in case this was a quick-click
- handleHover(x, y, mask);
-
- if(hasMouseCapture())
- {
- // make sure arrow colors go back to normal
- mManipPart = LL_NO_PART;
- LLSelectMgr::getInstance()->enableSilhouette(TRUE);
-
- // Might have missed last update due to UPDATE_DELAY timing.
- LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_POSITION );
-
- mInSnapRegime = FALSE;
- LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
- }
-
- return LLManip::handleMouseUp(x, y, mask);
+ // first, perform normal processing in case this was a quick-click
+ handleHover(x, y, mask);
+
+ if(hasMouseCapture())
+ {
+ // make sure arrow colors go back to normal
+ mManipPart = LL_NO_PART;
+ LLSelectMgr::getInstance()->enableSilhouette(TRUE);
+
+ // Might have missed last update due to UPDATE_DELAY timing.
+ LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_POSITION );
+
+ mInSnapRegime = FALSE;
+ LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
+ }
+
+ return LLManip::handleMouseUp(x, y, mask);
}
void LLManipTranslate::render()
{
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 zoom = gAgentCamera.mHUDCurZoom;
- gGL.scalef(zoom, zoom, zoom);
- }
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- renderGuidelines();
- }
- {
- //LLGLDisable gls_stencil(GL_STENCIL_TEST);
- renderTranslationHandles();
- renderSnapGuides();
- }
- gGL.popMatrix();
-
- renderText();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 zoom = gAgentCamera.mHUDCurZoom;
+ gGL.scalef(zoom, zoom, zoom);
+ }
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+ renderGuidelines();
+ }
+ {
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ renderTranslationHandles();
+ renderSnapGuides();
+ }
+ gGL.popMatrix();
+
+ renderText();
}
void LLManipTranslate::renderSnapGuides()
{
- if (!gSavedSettings.getBOOL("SnapEnabled"))
- {
- return;
- }
-
- F32 max_subdivisions = sGridMaxSubdivisionLevel;//(F32)gSavedSettings.getS32("GridSubdivision");
- F32 line_alpha = gSavedSettings.getF32("GridOpacity");
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest gls_depth(GL_TRUE);
- LLGLDisable gls_cull(GL_CULL_FACE);
- LLVector3 translate_axis;
-
- if (mManipPart == LL_NO_PART)
- {
- return;
- }
-
- LLSelectNode *first_node = mObjectSelection->getFirstMoveableNode(TRUE);
- if (!first_node)
- {
- return;
- }
-
- updateGridSettings();
-
- F32 smallest_grid_unit_scale = getMinGridScale() / max_subdivisions;
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
- LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
- LLVector3 selection_center = getPivotPoint();
-
- LLViewerObject *first_object = first_node->getObject();
-
- //pick appropriate projection plane for snap rulers according to relative camera position
- if (mManipPart >= LL_X_ARROW && mManipPart <= LL_Z_ARROW)
- {
- LLVector3 normal;
+ if (!gSavedSettings.getBOOL("SnapEnabled"))
+ {
+ return;
+ }
+
+ F32 max_subdivisions = sGridMaxSubdivisionLevel;//(F32)gSavedSettings.getS32("GridSubdivision");
+ F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLDepthTest gls_depth(GL_TRUE);
+ LLGLDisable gls_cull(GL_CULL_FACE);
+ LLVector3 translate_axis;
+
+ if (mManipPart == LL_NO_PART)
+ {
+ return;
+ }
+
+ LLSelectNode *first_node = mObjectSelection->getFirstMoveableNode(TRUE);
+ if (!first_node)
+ {
+ return;
+ }
+
+ updateGridSettings();
+
+ F32 smallest_grid_unit_scale = getMinGridScale() / max_subdivisions;
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+ LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+ LLVector3 selection_center = getPivotPoint();
+
+ LLViewerObject *first_object = first_node->getObject();
+
+ //pick appropriate projection plane for snap rulers according to relative camera position
+ if (mManipPart >= LL_X_ARROW && mManipPart <= LL_Z_ARROW)
+ {
+ LLVector3 normal;
+ LLColor4 inner_color;
+ LLManip::EManipPart temp_manip = mManipPart;
+ switch (mManipPart)
+ {
+ case LL_X_ARROW:
+ normal.setVec(1,0,0);
+ inner_color.setVec(0,1,1,line_alpha);
+ mManipPart = LL_YZ_PLANE;
+ break;
+ case LL_Y_ARROW:
+ normal.setVec(0,1,0);
+ inner_color.setVec(1,0,1,line_alpha);
+ mManipPart = LL_XZ_PLANE;
+ break;
+ case LL_Z_ARROW:
+ normal.setVec(0,0,1);
+ inner_color.setVec(1,1,0,line_alpha);
+ mManipPart = LL_XY_PLANE;
+ break;
+ default:
+ break;
+ }
+
+ highlightIntersection(normal, selection_center, grid_rotation, inner_color);
+ mManipPart = temp_manip;
+ getManipAxis(first_object, mManipPart, translate_axis);
+
+ LLVector3 at_axis_abs;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ at_axis_abs = LLVector3::x_axis * ~grid_rotation;
+ }
+ else
+ {
+ at_axis_abs = saved_selection_center - LLViewerCamera::getInstance()->getOrigin();
+ at_axis_abs.normVec();
+
+ at_axis_abs = at_axis_abs * ~grid_rotation;
+ }
+ at_axis_abs.abs();
+
+ if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY] && at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
+ {
+ if (mManipPart == LL_Y_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::z_axis;
+ }
+ else if (mManipPart == LL_Z_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::y_axis;
+ }
+ else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
+ {
+ mSnapOffsetAxis = LLVector3::z_axis;
+ }
+ else
+ {
+ mSnapOffsetAxis = LLVector3::y_axis;
+ }
+ }
+ else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
+ {
+ if (mManipPart == LL_X_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::z_axis;
+ }
+ else if (mManipPart == LL_Z_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::x_axis;
+ }
+ else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
+ {
+ mSnapOffsetAxis = LLVector3::z_axis;
+ }
+ else
+ {
+ mSnapOffsetAxis = LLVector3::x_axis;
+ }
+ }
+ else
+ {
+ if (mManipPart == LL_X_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::y_axis;
+ }
+ else if (mManipPart == LL_Y_ARROW)
+ {
+ mSnapOffsetAxis = LLVector3::x_axis;
+ }
+ else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY])
+ {
+ mSnapOffsetAxis = LLVector3::y_axis;
+ }
+ else
+ {
+ mSnapOffsetAxis = LLVector3::x_axis;
+ }
+ }
+
+ mSnapOffsetAxis = mSnapOffsetAxis * grid_rotation;
+
+ F32 guide_size_meters;
+
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ guide_size_meters = 1.f / gAgentCamera.mHUDCurZoom;
+ mSnapOffsetMeters = mArrowLengthMeters * 1.5f;
+ }
+ else
+ {
+ LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin();
+ F32 current_range = cam_to_selection.normVec();
+ guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio();
+
+ F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
+ F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
+ F32 offset_at_camera = tan(apparent_angle) * 1.5f;
+ F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstance()->getOrigin());
+ mSnapOffsetMeters = range * offset_at_camera;
+ }
+
+ LLVector3 tick_start;
+ LLVector3 tick_end;
+
+ // how far away from grid origin is the selection along the axis of translation?
+ F32 dist_grid_axis = (selection_center - mGridOrigin) * translate_axis;
+ // find distance to nearest smallest grid unit
+ F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale);
+ // how many smallest grid units are we away from largest grid scale?
+ S32 sub_div_offset = ll_round(fmodf(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale);
+ S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale));
+
+ LLGLDepthTest gls_depth(GL_FALSE);
+
+ for (S32 pass = 0; pass < 3; pass++)
+ {
+ LLColor4 line_color = setupSnapGuideRenderPass(pass);
+ LLGLDepthTest gls_depth(pass != 1);
+
+ gGL.begin(LLRender::LINES);
+ {
+ LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
+ LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
+ LLVector3 line_mid = (line_start + line_end) * 0.5f;
+
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
+ gGL.vertex3fv(line_start.mV);
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
+ gGL.vertex3fv(line_mid.mV);
+ gGL.vertex3fv(line_mid.mV);
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
+ gGL.vertex3fv(line_end.mV);
+
+ line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f));
+ line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f));
+ line_mid = (line_start + line_end) * 0.5f;
+
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
+ gGL.vertex3fv(line_start.mV);
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
+ gGL.vertex3fv(line_mid.mV);
+ gGL.vertex3fv(line_mid.mV);
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
+ gGL.vertex3fv(line_end.mV);
+
+ for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
+ {
+ tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit));
+
+ //No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208)
+ //F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale());
+ /*if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f)
+ {
+ continue;
+ }*/
+
+ // add in off-axis offset
+ tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
+
+ F32 tick_scale = 1.f;
+ for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ {
+ if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
+ {
+ break;
+ }
+ tick_scale *= 0.7f;
+ }
+
+// S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side;
+// F32 alpha = line_alpha * (1.f - (0.8f * ((F32)llabs(i) / (F32)num_ticks_to_fade)));
+
+ tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
+
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
+ gGL.vertex3fv(tick_start.mV);
+ gGL.vertex3fv(tick_end.mV);
+
+ tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) +
+ (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit));
+ tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
+
+ gGL.vertex3fv(tick_start.mV);
+ gGL.vertex3fv(tick_end.mV);
+ }
+ }
+ gGL.end();
+
+ if (mInSnapRegime)
+ {
+ LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters;
+ LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters;
+
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
+
+ gGL.vertex3fv(line_start.mV);
+ gGL.vertex3fv(line_end.mV);
+ }
+ gGL.end();
+
+ // draw snap guide arrow
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
+
+ LLVector3 arrow_dir;
+ LLVector3 arrow_span = translate_axis;
+
+ arrow_dir = -mSnapOffsetAxis;
+ gGL.vertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
+ gGL.vertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
+ gGL.vertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
+
+ arrow_dir = mSnapOffsetAxis;
+ gGL.vertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
+ gGL.vertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
+ gGL.vertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
+ }
+ gGL.end();
+ }
+ }
+
+ sub_div_offset = ll_round(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale);
+
+ LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstance()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstance()->getUpAxis()));
+ screen_translate_axis.normVec();
+
+ S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing);
+
+ // render tickmark values
+ for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
+ {
+ LLVector3 tick_pos = selection_center + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit));
+ F32 alpha = line_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side)));
+
+ F32 tick_scale = 1.f;
+ for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ {
+ if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
+ {
+ break;
+ }
+ tick_scale *= 0.7f;
+ }
+
+ if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / getSubdivisionLevel(tick_pos, translate_axis, getMinGridScale(), tick_label_spacing))) == 0.f)
+ {
+ F32 snap_offset_meters;
+
+ if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f)
+ {
+ snap_offset_meters = mSnapOffsetMeters;
+ }
+ else
+ {
+ snap_offset_meters = -mSnapOffsetMeters;
+ }
+ LLVector3 text_origin = selection_center +
+ (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)) +
+ (mSnapOffsetAxis * snap_offset_meters * (1.f + tick_scale));
+
+ LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation;
+ F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale();
+ EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
+ F32 text_highlight = 0.8f;
+ if(i - ll_round(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime)
+ {
+ text_highlight = 1.f;
+ }
+
+ if (grid_mode == GRID_MODE_WORLD)
+ {
+ // rescale units to meters from multiple of grid scale
+ offset_val *= 2.f * grid_scale[ARROW_TO_AXIS[mManipPart]];
+ renderTickValue(text_origin, offset_val, std::string("m"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ }
+ else
+ {
+ renderTickValue(text_origin, offset_val, std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ }
+ }
+ }
+ if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ // render helpful text
+ if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
+ {
+ F32 snap_offset_meters_up;
+ if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f)
+ {
+ snap_offset_meters_up = mSnapOffsetMeters;
+ }
+ else
+ {
+ snap_offset_meters_up = -mSnapOffsetMeters;
+ }
+
+ LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+
+ LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis);
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+
+ std::string help_text = LLTrans::getString("manip_hint1");
+ LLColor4 help_text_color = LLColor4::white;
+ help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
+ help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f;
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ }
+ }
+ }
+ else
+ {
+ // render gridlines for planar snapping
+
+ F32 u = 0, v = 0;
LLColor4 inner_color;
- LLManip::EManipPart temp_manip = mManipPart;
- switch (mManipPart)
- {
- case LL_X_ARROW:
- normal.setVec(1,0,0);
- inner_color.setVec(0,1,1,line_alpha);
- mManipPart = LL_YZ_PLANE;
- break;
- case LL_Y_ARROW:
- normal.setVec(0,1,0);
- inner_color.setVec(1,0,1,line_alpha);
- mManipPart = LL_XZ_PLANE;
- break;
- case LL_Z_ARROW:
- normal.setVec(0,0,1);
- inner_color.setVec(1,1,0,line_alpha);
- mManipPart = LL_XY_PLANE;
- break;
- default:
- break;
- }
-
- highlightIntersection(normal, selection_center, grid_rotation, inner_color);
- mManipPart = temp_manip;
- getManipAxis(first_object, mManipPart, translate_axis);
-
- LLVector3 at_axis_abs;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- at_axis_abs = LLVector3::x_axis * ~grid_rotation;
- }
- else
- {
- at_axis_abs = saved_selection_center - LLViewerCamera::getInstance()->getOrigin();
- at_axis_abs.normVec();
-
- at_axis_abs = at_axis_abs * ~grid_rotation;
- }
- at_axis_abs.abs();
-
- if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY] && at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
- {
- if (mManipPart == LL_Y_ARROW)
- {
- mSnapOffsetAxis = LLVector3::z_axis;
- }
- else if (mManipPart == LL_Z_ARROW)
- {
- mSnapOffsetAxis = LLVector3::y_axis;
- }
- else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
- {
- mSnapOffsetAxis = LLVector3::z_axis;
- }
- else
- {
- mSnapOffsetAxis = LLVector3::y_axis;
- }
- }
- else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
- {
- if (mManipPart == LL_X_ARROW)
- {
- mSnapOffsetAxis = LLVector3::z_axis;
- }
- else if (mManipPart == LL_Z_ARROW)
- {
- mSnapOffsetAxis = LLVector3::x_axis;
- }
- else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
- {
- mSnapOffsetAxis = LLVector3::z_axis;
- }
- else
- {
- mSnapOffsetAxis = LLVector3::x_axis;
- }
- }
- else
- {
- if (mManipPart == LL_X_ARROW)
- {
- mSnapOffsetAxis = LLVector3::y_axis;
- }
- else if (mManipPart == LL_Y_ARROW)
- {
- mSnapOffsetAxis = LLVector3::x_axis;
- }
- else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY])
- {
- mSnapOffsetAxis = LLVector3::y_axis;
- }
- else
- {
- mSnapOffsetAxis = LLVector3::x_axis;
- }
- }
-
- mSnapOffsetAxis = mSnapOffsetAxis * grid_rotation;
-
- F32 guide_size_meters;
-
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- guide_size_meters = 1.f / gAgentCamera.mHUDCurZoom;
- mSnapOffsetMeters = mArrowLengthMeters * 1.5f;
- }
- else
- {
- LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin();
- F32 current_range = cam_to_selection.normVec();
- guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio();
-
- F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
- F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
- F32 offset_at_camera = tan(apparent_angle) * 1.5f;
- F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstance()->getOrigin());
- mSnapOffsetMeters = range * offset_at_camera;
- }
-
- LLVector3 tick_start;
- LLVector3 tick_end;
-
- // how far away from grid origin is the selection along the axis of translation?
- F32 dist_grid_axis = (selection_center - mGridOrigin) * translate_axis;
- // find distance to nearest smallest grid unit
- F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale);
- // how many smallest grid units are we away from largest grid scale?
- S32 sub_div_offset = ll_round(fmodf(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale);
- S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale));
-
- LLGLDepthTest gls_depth(GL_FALSE);
-
- for (S32 pass = 0; pass < 3; pass++)
- {
- LLColor4 line_color = setupSnapGuideRenderPass(pass);
- LLGLDepthTest gls_depth(pass != 1);
-
- gGL.begin(LLRender::LINES);
- {
- LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
- LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
- LLVector3 line_mid = (line_start + line_end) * 0.5f;
-
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
- gGL.vertex3fv(line_start.mV);
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
- gGL.vertex3fv(line_mid.mV);
- gGL.vertex3fv(line_mid.mV);
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
- gGL.vertex3fv(line_end.mV);
-
- line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f));
- line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f));
- line_mid = (line_start + line_end) * 0.5f;
-
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
- gGL.vertex3fv(line_start.mV);
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
- gGL.vertex3fv(line_mid.mV);
- gGL.vertex3fv(line_mid.mV);
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
- gGL.vertex3fv(line_end.mV);
-
- for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
- {
- tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit));
-
- //No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208)
- //F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale());
- /*if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f)
- {
- continue;
- }*/
-
- // add in off-axis offset
- tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
-
- F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
- {
- if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
- {
- break;
- }
- tick_scale *= 0.7f;
- }
-
-// S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side;
-// F32 alpha = line_alpha * (1.f - (0.8f * ((F32)llabs(i) / (F32)num_ticks_to_fade)));
-
- tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
-
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
- gGL.vertex3fv(tick_start.mV);
- gGL.vertex3fv(tick_end.mV);
-
- tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) +
- (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit));
- tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
-
- gGL.vertex3fv(tick_start.mV);
- gGL.vertex3fv(tick_end.mV);
- }
- }
- gGL.end();
-
- if (mInSnapRegime)
- {
- LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters;
- LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters;
-
- gGL.begin(LLRender::LINES);
- {
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
-
- gGL.vertex3fv(line_start.mV);
- gGL.vertex3fv(line_end.mV);
- }
- gGL.end();
-
- // draw snap guide arrow
- gGL.begin(LLRender::TRIANGLES);
- {
- gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
-
- LLVector3 arrow_dir;
- LLVector3 arrow_span = translate_axis;
-
- arrow_dir = -mSnapOffsetAxis;
- gGL.vertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
- gGL.vertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
- gGL.vertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
-
- arrow_dir = mSnapOffsetAxis;
- gGL.vertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
- gGL.vertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
- gGL.vertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
- }
- gGL.end();
- }
- }
-
- sub_div_offset = ll_round(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale);
-
- LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstance()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstance()->getUpAxis()));
- screen_translate_axis.normVec();
-
- S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing);
-
- // render tickmark values
- for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
- {
- LLVector3 tick_pos = selection_center + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit));
- F32 alpha = line_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side)));
-
- F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
- {
- if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
- {
- break;
- }
- tick_scale *= 0.7f;
- }
-
- if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / getSubdivisionLevel(tick_pos, translate_axis, getMinGridScale(), tick_label_spacing))) == 0.f)
- {
- F32 snap_offset_meters;
-
- if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f)
- {
- snap_offset_meters = mSnapOffsetMeters;
- }
- else
- {
- snap_offset_meters = -mSnapOffsetMeters;
- }
- LLVector3 text_origin = selection_center +
- (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)) +
- (mSnapOffsetAxis * snap_offset_meters * (1.f + tick_scale));
-
- LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation;
- F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale();
- EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
- F32 text_highlight = 0.8f;
- if(i - ll_round(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime)
- {
- text_highlight = 1.f;
- }
-
- if (grid_mode == GRID_MODE_WORLD)
- {
- // rescale units to meters from multiple of grid scale
- offset_val *= 2.f * grid_scale[ARROW_TO_AXIS[mManipPart]];
- renderTickValue(text_origin, offset_val, std::string("m"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
- }
- else
- {
- renderTickValue(text_origin, offset_val, std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
- }
- }
- }
- if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
- {
- // render helpful text
- if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
- {
- F32 snap_offset_meters_up;
- if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f)
- {
- snap_offset_meters_up = mSnapOffsetMeters;
- }
- else
- {
- snap_offset_meters_up = -mSnapOffsetMeters;
- }
-
- LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
-
- LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis);
- const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
-
- std::string help_text = LLTrans::getString("manip_hint1");
- LLColor4 help_text_color = LLColor4::white;
- help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
- help_text = LLTrans::getString("manip_hint2");
- help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
- }
- }
- }
- else
- {
- // render gridlines for planar snapping
-
- F32 u = 0, v = 0;
- LLColor4 inner_color;
- LLVector3 normal;
- LLVector3 grid_center = selection_center - grid_origin;
- F32 usc = 1;
- F32 vsc = 1;
-
- grid_center *= ~grid_rotation;
-
- switch (mManipPart)
- {
- case LL_YZ_PLANE:
- u = grid_center.mV[VY];
- v = grid_center.mV[VZ];
- usc = grid_scale.mV[VY];
- vsc = grid_scale.mV[VZ];
- inner_color.setVec(0,1,1,line_alpha);
- normal.setVec(1,0,0);
- break;
- case LL_XZ_PLANE:
- u = grid_center.mV[VX];
- v = grid_center.mV[VZ];
- usc = grid_scale.mV[VX];
- vsc = grid_scale.mV[VZ];
- inner_color.setVec(1,0,1,line_alpha);
- normal.setVec(0,1,0);
- break;
- case LL_XY_PLANE:
- u = grid_center.mV[VX];
- v = grid_center.mV[VY];
- usc = grid_scale.mV[VX];
- vsc = grid_scale.mV[VY];
- inner_color.setVec(1,1,0,line_alpha);
- normal.setVec(0,0,1);
- break;
- default:
- break;
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- highlightIntersection(normal, selection_center, grid_rotation, inner_color);
-
- gGL.pushMatrix();
-
- F32 x,y,z,angle_radians;
- grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
- F32 sz = mGridSizeMeters;
- F32 tiles = sz;
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.pushMatrix();
- usc = 1.0f/usc;
- vsc = 1.0f/vsc;
-
- while (usc > vsc*4.0f)
- {
- usc *= 0.5f;
- }
- while (vsc > usc * 4.0f)
- {
- vsc *= 0.5f;
- }
-
- gGL.scalef(usc, vsc, 1.0f);
- gGL.translatef(u, v, 0);
-
- float a = line_alpha;
-
- {
- //draw grid behind objects
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- {
- //LLGLDisable stencil(GL_STENCIL_TEST);
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
- gGL.flush();
- gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
- renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f);
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
-
- {
- //draw black overlay
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f);
-
- //draw grid top
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
- renderGrid(u,v,tiles,1,1,1,a);
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
-
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- renderGuidelines();
- }
-
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
- gGL.flush();
-
- switch (mManipPart)
- {
- case LL_YZ_PLANE:
- renderGuidelines(FALSE, TRUE, TRUE);
- break;
- case LL_XZ_PLANE:
- renderGuidelines(TRUE, FALSE, TRUE);
- break;
- case LL_XY_PLANE:
- renderGuidelines(TRUE, TRUE, FALSE);
- break;
- default:
- break;
- }
- gGL.flush();
- }
- }
- }
- }
+ LLVector3 normal;
+ LLVector3 grid_center = selection_center - grid_origin;
+ F32 usc = 1;
+ F32 vsc = 1;
+
+ grid_center *= ~grid_rotation;
+
+ switch (mManipPart)
+ {
+ case LL_YZ_PLANE:
+ u = grid_center.mV[VY];
+ v = grid_center.mV[VZ];
+ usc = grid_scale.mV[VY];
+ vsc = grid_scale.mV[VZ];
+ inner_color.setVec(0,1,1,line_alpha);
+ normal.setVec(1,0,0);
+ break;
+ case LL_XZ_PLANE:
+ u = grid_center.mV[VX];
+ v = grid_center.mV[VZ];
+ usc = grid_scale.mV[VX];
+ vsc = grid_scale.mV[VZ];
+ inner_color.setVec(1,0,1,line_alpha);
+ normal.setVec(0,1,0);
+ break;
+ case LL_XY_PLANE:
+ u = grid_center.mV[VX];
+ v = grid_center.mV[VY];
+ usc = grid_scale.mV[VX];
+ vsc = grid_scale.mV[VY];
+ inner_color.setVec(1,1,0,line_alpha);
+ normal.setVec(0,0,1);
+ break;
+ default:
+ break;
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ highlightIntersection(normal, selection_center, grid_rotation, inner_color);
+
+ gGL.pushMatrix();
+
+ F32 x,y,z,angle_radians;
+ grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+ F32 sz = mGridSizeMeters;
+ F32 tiles = sz;
+
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.pushMatrix();
+ usc = 1.0f/usc;
+ vsc = 1.0f/vsc;
+
+ while (usc > vsc*4.0f)
+ {
+ usc *= 0.5f;
+ }
+ while (vsc > usc * 4.0f)
+ {
+ vsc *= 0.5f;
+ }
+
+ gGL.scalef(usc, vsc, 1.0f);
+ gGL.translatef(u, v, 0);
+
+ float a = line_alpha;
+
+ {
+ //draw grid behind objects
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+
+ {
+ //LLGLDisable stencil(GL_STENCIL_TEST);
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
+ gGL.flush();
+ gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+ renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f);
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
+
+ {
+ //draw black overlay
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f);
+
+ //draw grid top
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
+ renderGrid(u,v,tiles,1,1,1,a);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+ renderGuidelines();
+ }
+
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.flush();
+
+ switch (mManipPart)
+ {
+ case LL_YZ_PLANE:
+ renderGuidelines(FALSE, TRUE, TRUE);
+ break;
+ case LL_XZ_PLANE:
+ renderGuidelines(TRUE, FALSE, TRUE);
+ break;
+ case LL_XY_PLANE:
+ renderGuidelines(TRUE, TRUE, FALSE);
+ break;
+ default:
+ break;
+ }
+ gGL.flush();
+ }
+ }
+ }
+ }
}
void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F32 a)
{
- F32 d = size*0.5f;
-
- for (F32 xx = -size-d; xx < size+d; xx += d)
- {
- gGL.begin(LLRender::TRIANGLE_STRIP);
- for (F32 yy = -size-d; yy < size+d; yy += d)
- {
- float dx, dy, da;
-
- dx = xx; dy = yy;
- da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
- gGL.texCoord2f(dx, dy);
- renderGridVert(dx,dy,r,g,b,da);
-
- dx = xx+d; dy = yy;
- da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
- gGL.texCoord2f(dx, dy);
- renderGridVert(dx,dy,r,g,b,da);
-
- dx = xx; dy = yy+d;
- da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
- gGL.texCoord2f(dx, dy);
- renderGridVert(dx,dy,r,g,b,da);
-
- dx = xx+d; dy = yy+d;
- da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
- gGL.texCoord2f(dx, dy);
- renderGridVert(dx,dy,r,g,b,da);
- }
- gGL.end();
- }
-
-
+ F32 d = size*0.5f;
+
+ for (F32 xx = -size-d; xx < size+d; xx += d)
+ {
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ for (F32 yy = -size-d; yy < size+d; yy += d)
+ {
+ float dx, dy, da;
+
+ dx = xx; dy = yy;
+ da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
+ gGL.texCoord2f(dx, dy);
+ renderGridVert(dx,dy,r,g,b,da);
+
+ dx = xx+d; dy = yy;
+ da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
+ gGL.texCoord2f(dx, dy);
+ renderGridVert(dx,dy,r,g,b,da);
+
+ dx = xx; dy = yy+d;
+ da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
+ gGL.texCoord2f(dx, dy);
+ renderGridVert(dx,dy,r,g,b,da);
+
+ dx = xx+d; dy = yy+d;
+ da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
+ gGL.texCoord2f(dx, dy);
+ renderGridVert(dx,dy,r,g,b,da);
+ }
+ gGL.end();
+ }
+
+
}
-void LLManipTranslate::highlightIntersection(LLVector3 normal,
- LLVector3 selection_center,
- LLQuaternion grid_rotation,
- LLColor4 inner_color)
+void LLManipTranslate::highlightIntersection(LLVector3 normal,
+ LLVector3 selection_center,
+ LLQuaternion grid_rotation,
+ LLColor4 inner_color)
{
#if 0 // DEPRECATED
- if (!gSavedSettings.getBOOL("GridCrossSections"))
- {
- return;
- }
-
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
-
- static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
- static const U32 num_types = LL_ARRAY_SIZE(types);
-
- GLuint stencil_mask = 0xFFFFFFFF;
- //stencil in volumes
-
- gGL.flush();
-
- if (shader)
- {
- gClipProgram.bind();
- }
-
- {
- //glStencilMask(stencil_mask); //deprecated
- //glClearStencil(1);
- //glClear(GL_STENCIL_BUFFER_BIT);
- LLGLEnable cull_face(GL_CULL_FACE);
- //LLGLEnable stencil(GL_STENCIL_TEST);
- LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
- //glStencilFunc(GL_ALWAYS, 0, stencil_mask);
- gGL.setColorMask(false, false);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.diffuseColor4f(1,1,1,1);
-
- //setup clip plane
- normal = normal * grid_rotation;
- if (normal * (LLViewerCamera::getInstance()->getOrigin()-selection_center) < 0)
- {
- normal = -normal;
- }
- F32 d = -(selection_center * normal);
- glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d );
-
- gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
-
- static LLStaticHashedString sClipPlane("clip_plane");
- gClipProgram.uniform4fv(sClipPlane, 1, plane.v);
-
- BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
- BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
-
- if (particles)
- {
- LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
- }
- if (clouds)
- {
- LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
- }
-
- //stencil in volumes
- //glStencilOp(GL_INCR, GL_INCR, GL_INCR);
- glCullFace(GL_FRONT);
- for (U32 i = 0; i < num_types; i++)
- {
- gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
- }
-
- //glStencilOp(GL_DECR, GL_DECR, GL_DECR);
- glCullFace(GL_BACK);
- for (U32 i = 0; i < num_types; i++)
- {
- gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
- }
-
- if (particles)
- {
- LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
- }
- if (clouds)
- {
- LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
- }
-
- gGL.setColorMask(true, false);
- }
- gGL.color4f(1,1,1,1);
-
- gGL.pushMatrix();
-
- F32 x,y,z,angle_radians;
- grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
- F32 sz = mGridSizeMeters;
- F32 tiles = sz;
-
- if (shader)
- {
- shader->bind();
- }
-
- if (shader)
- {
- shader->bind();
- }
-
- //draw volume/plane intersections
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest depth(GL_FALSE);
- //LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_EQUAL, 0, stencil_mask);
- renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
- }
-
- glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
- glStencilMask(0xFFFFFFFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
- gGL.popMatrix();
+ if (!gSavedSettings.getBOOL("GridCrossSections"))
+ {
+ return;
+ }
+
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+
+ static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
+ static const U32 num_types = LL_ARRAY_SIZE(types);
+
+ GLuint stencil_mask = 0xFFFFFFFF;
+ //stencil in volumes
+
+ gGL.flush();
+
+ if (shader)
+ {
+ gClipProgram.bind();
+ }
+
+ {
+ //glStencilMask(stencil_mask); //deprecated
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
+ LLGLEnable cull_face(GL_CULL_FACE);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
+ //glStencilFunc(GL_ALWAYS, 0, stencil_mask);
+ gGL.setColorMask(false, false);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.diffuseColor4f(1,1,1,1);
+
+ //setup clip plane
+ normal = normal * grid_rotation;
+ if (normal * (LLViewerCamera::getInstance()->getOrigin()-selection_center) < 0)
+ {
+ normal = -normal;
+ }
+ F32 d = -(selection_center * normal);
+ glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d );
+
+ gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
+
+ static LLStaticHashedString sClipPlane("clip_plane");
+ gClipProgram.uniform4fv(sClipPlane, 1, plane.v);
+
+ BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
+ BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
+
+ if (particles)
+ {
+ LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
+ }
+ if (clouds)
+ {
+ LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
+ }
+
+ //stencil in volumes
+ //glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+ glCullFace(GL_FRONT);
+ for (U32 i = 0; i < num_types; i++)
+ {
+ gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+ }
+
+ //glStencilOp(GL_DECR, GL_DECR, GL_DECR);
+ glCullFace(GL_BACK);
+ for (U32 i = 0; i < num_types; i++)
+ {
+ gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+ }
+
+ if (particles)
+ {
+ LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
+ }
+ if (clouds)
+ {
+ LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
+ }
+
+ gGL.setColorMask(true, false);
+ }
+ gGL.color4f(1,1,1,1);
+
+ gGL.pushMatrix();
+
+ F32 x,y,z,angle_radians;
+ grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+ F32 sz = mGridSizeMeters;
+ F32 tiles = sz;
+
+ if (shader)
+ {
+ shader->bind();
+ }
+
+ if (shader)
+ {
+ shader->bind();
+ }
+
+ //draw volume/plane intersections
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLDepthTest depth(GL_FALSE);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilFunc(GL_EQUAL, 0, stencil_mask);
+ renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
+ }
+
+ glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+ glStencilMask(0xFFFFFFFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+ gGL.popMatrix();
#endif
}
void LLManipTranslate::renderText()
{
- if (mObjectSelection->getRootObjectCount() && !mObjectSelection->isAttachment())
- {
- LLVector3 pos = getPivotPoint();
- renderXYZ(pos);
- }
- else
- {
- const BOOL children_ok = TRUE;
- LLViewerObject* objectp = mObjectSelection->getFirstRootObject(children_ok);
- if (objectp)
- {
- renderXYZ(objectp->getPositionEdit());
- }
- }
+ if (mObjectSelection->getRootObjectCount() && !mObjectSelection->isAttachment())
+ {
+ LLVector3 pos = getPivotPoint();
+ renderXYZ(pos);
+ }
+ else
+ {
+ const BOOL children_ok = TRUE;
+ LLViewerObject* objectp = mObjectSelection->getFirstRootObject(children_ok);
+ if (objectp)
+ {
+ renderXYZ(objectp->getPositionEdit());
+ }
+ }
}
void LLManipTranslate::renderTranslationHandles()
{
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
- LLGLDepthTest gls_depth(GL_FALSE);
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
- LLVector3 at_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- at_axis = LLVector3::x_axis * ~grid_rotation;
- }
- else
- {
- at_axis = LLViewerCamera::getInstance()->getAtAxis() * ~grid_rotation;
- }
-
- if (at_axis.mV[VX] > 0.f)
- {
- mPlaneManipPositions.mV[VX] = 1.f;
- }
- else
- {
- mPlaneManipPositions.mV[VX] = -1.f;
- }
-
- if (at_axis.mV[VY] > 0.f)
- {
- mPlaneManipPositions.mV[VY] = 1.f;
- }
- else
- {
- mPlaneManipPositions.mV[VY] = -1.f;
- }
-
- if (at_axis.mV[VZ] > 0.f)
- {
- mPlaneManipPositions.mV[VZ] = 1.f;
- }
- else
- {
- mPlaneManipPositions.mV[VZ] = -1.f;
- }
-
- LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE);
- if (!first_object) return;
-
- LLVector3 selection_center = getPivotPoint();
-
- // Drag handles
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeightRaw();
- mArrowLengthMeters /= gAgentCamera.mHUDCurZoom;
- }
- else
- {
- LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent();
- F32 range = dist_vec(camera_pos_agent, selection_center);
- F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center);
-
- // Don't draw handles if you're too far away
- if (gSavedSettings.getBOOL("LimitSelectDistance"))
- {
- if (range_from_agent > gSavedSettings.getF32("MaxSelectDistance"))
- {
- return;
- }
- }
-
- if (range > 0.001f)
- {
- // range != zero
- F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
- F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
- mArrowLengthMeters = range * tan(apparent_angle);
- }
- else
- {
- // range == zero
- mArrowLengthMeters = 1.0f;
- }
- }
- //Assume that UI scale factor is equivalent for X and Y axis
- F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX];
- mArrowLengthMeters *= ui_scale_factor;
-
- mPlaneManipOffsetMeters = mArrowLengthMeters * 1.8f;
- mGridSizeMeters = gSavedSettings.getF32("GridDrawSize");
- mConeSize = mArrowLengthMeters / 4.f;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- {
- gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
-
- F32 angle_radians, x, y, z;
- grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
-
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
- LLQuaternion invRotation = grid_rotation;
- invRotation.conjQuat();
-
- LLVector3 relative_camera_dir;
-
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- relative_camera_dir = LLVector3::x_axis * invRotation;
- }
- else
- {
- relative_camera_dir = (selection_center - LLViewerCamera::getInstance()->getOrigin()) * invRotation;
- }
- relative_camera_dir.normVec();
-
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDisable cull_face(GL_CULL_FACE);
-
- LLColor4 color1;
- LLColor4 color2;
-
- // update manipulator sizes
- for (S32 index = 0; index < 3; index++)
- {
- if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)
- {
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- }
- else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)
- {
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- }
- else
- {
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- }
- }
-
- if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- // render YZ plane manipulator
- gGL.pushMatrix();
- gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
- gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters);
- gGL.scalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]);
- if (mHighlightedPart == LL_YZ_PLANE)
- {
- color1.setVec(0.f, 1.f, 0.f, 1.f);
- color2.setVec(0.f, 0.f, 1.f, 1.f);
- }
- else
- {
- color1.setVec(0.f, 1.f, 0.f, 0.6f);
- color2.setVec(0.f, 0.f, 1.f, 0.6f);
- }
- gGL.begin(LLRender::TRIANGLES);
- {
- gGL.color4fv(color1.mV);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
-
- gGL.color4fv(color2.mV);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
- }
- gGL.end();
-
- LLUI::setLineWidth(3.0f);
- gGL.begin(LLRender::LINES);
- {
- gGL.color4f(0.f, 0.f, 0.f, 0.3f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
-
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
- }
- gGL.end();
- LLUI::setLineWidth(1.0f);
- gGL.popMatrix();
- }
-
- if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- // render XZ plane manipulator
- gGL.pushMatrix();
- gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
- gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters);
- gGL.scalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]);
- if (mHighlightedPart == LL_XZ_PLANE)
- {
- color1.setVec(0.f, 0.f, 1.f, 1.f);
- color2.setVec(1.f, 0.f, 0.f, 1.f);
- }
- else
- {
- color1.setVec(0.f, 0.f, 1.f, 0.6f);
- color2.setVec(1.f, 0.f, 0.f, 0.6f);
- }
-
- gGL.begin(LLRender::TRIANGLES);
- {
- gGL.color4fv(color1.mV);
- gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
-
- gGL.color4fv(color2.mV);
- gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
- gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
- gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
- }
- gGL.end();
-
- LLUI::setLineWidth(3.0f);
- gGL.begin(LLRender::LINES);
- {
- gGL.color4f(0.f, 0.f, 0.f, 0.3f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
- gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
-
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
- gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
- }
- gGL.end();
- LLUI::setLineWidth(1.0f);
-
- gGL.popMatrix();
- }
-
- if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
- {
- // render XY plane manipulator
- gGL.pushMatrix();
- gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
-
-/* Y
- ^
- v1
- | \
- |<- v0
- | /| \
- v2__v__v3 > X
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+ LLGLDepthTest gls_depth(GL_FALSE);
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+ LLVector3 at_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ at_axis = LLVector3::x_axis * ~grid_rotation;
+ }
+ else
+ {
+ at_axis = LLViewerCamera::getInstance()->getAtAxis() * ~grid_rotation;
+ }
+
+ if (at_axis.mV[VX] > 0.f)
+ {
+ mPlaneManipPositions.mV[VX] = 1.f;
+ }
+ else
+ {
+ mPlaneManipPositions.mV[VX] = -1.f;
+ }
+
+ if (at_axis.mV[VY] > 0.f)
+ {
+ mPlaneManipPositions.mV[VY] = 1.f;
+ }
+ else
+ {
+ mPlaneManipPositions.mV[VY] = -1.f;
+ }
+
+ if (at_axis.mV[VZ] > 0.f)
+ {
+ mPlaneManipPositions.mV[VZ] = 1.f;
+ }
+ else
+ {
+ mPlaneManipPositions.mV[VZ] = -1.f;
+ }
+
+ LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE);
+ if (!first_object) return;
+
+ LLVector3 selection_center = getPivotPoint();
+
+ // Drag handles
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeightRaw();
+ mArrowLengthMeters /= gAgentCamera.mHUDCurZoom;
+ }
+ else
+ {
+ LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent();
+ F32 range = dist_vec(camera_pos_agent, selection_center);
+ F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center);
+
+ // Don't draw handles if you're too far away
+ if (gSavedSettings.getBOOL("LimitSelectDistance"))
+ {
+ if (range_from_agent > gSavedSettings.getF32("MaxSelectDistance"))
+ {
+ return;
+ }
+ }
+
+ if (range > 0.001f)
+ {
+ // range != zero
+ F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
+ F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
+ mArrowLengthMeters = range * tan(apparent_angle);
+ }
+ else
+ {
+ // range == zero
+ mArrowLengthMeters = 1.0f;
+ }
+ }
+ //Assume that UI scale factor is equivalent for X and Y axis
+ F32 ui_scale_factor = LLUI::getScaleFactor().mV[VX];
+ mArrowLengthMeters *= ui_scale_factor;
+
+ mPlaneManipOffsetMeters = mArrowLengthMeters * 1.8f;
+ mGridSizeMeters = gSavedSettings.getF32("GridDrawSize");
+ mConeSize = mArrowLengthMeters / 4.f;
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ {
+ gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
+
+ F32 angle_radians, x, y, z;
+ grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
+
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+
+ LLQuaternion invRotation = grid_rotation;
+ invRotation.conjQuat();
+
+ LLVector3 relative_camera_dir;
+
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ relative_camera_dir = LLVector3::x_axis * invRotation;
+ }
+ else
+ {
+ relative_camera_dir = (selection_center - LLViewerCamera::getInstance()->getOrigin()) * invRotation;
+ }
+ relative_camera_dir.normVec();
+
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLDisable cull_face(GL_CULL_FACE);
+
+ LLColor4 color1;
+ LLColor4 color2;
+
+ // update manipulator sizes
+ for (S32 index = 0; index < 3; index++)
+ {
+ if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)
+ {
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ }
+ else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)
+ {
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ }
+ else
+ {
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ }
+ }
+
+ if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ // render YZ plane manipulator
+ gGL.pushMatrix();
+ gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+ gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters);
+ gGL.scalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]);
+ if (mHighlightedPart == LL_YZ_PLANE)
+ {
+ color1.setVec(0.f, 1.f, 0.f, 1.f);
+ color2.setVec(0.f, 0.f, 1.f, 1.f);
+ }
+ else
+ {
+ color1.setVec(0.f, 1.f, 0.f, 0.6f);
+ color2.setVec(0.f, 0.f, 1.f, 0.6f);
+ }
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ gGL.color4fv(color1.mV);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+
+ gGL.color4fv(color2.mV);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
+ }
+ gGL.end();
+
+ LLUI::setLineWidth(3.0f);
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.color4f(0.f, 0.f, 0.f, 0.3f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
+
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
+ }
+ gGL.end();
+ LLUI::setLineWidth(1.0f);
+ gGL.popMatrix();
+ }
+
+ if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ // render XZ plane manipulator
+ gGL.pushMatrix();
+ gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+ gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters);
+ gGL.scalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]);
+ if (mHighlightedPart == LL_XZ_PLANE)
+ {
+ color1.setVec(0.f, 0.f, 1.f, 1.f);
+ color2.setVec(1.f, 0.f, 0.f, 1.f);
+ }
+ else
+ {
+ color1.setVec(0.f, 0.f, 1.f, 0.6f);
+ color2.setVec(1.f, 0.f, 0.f, 0.6f);
+ }
+
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ gGL.color4fv(color1.mV);
+ gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
+
+ gGL.color4fv(color2.mV);
+ gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
+ gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
+ gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
+ }
+ gGL.end();
+
+ LLUI::setLineWidth(3.0f);
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.color4f(0.f, 0.f, 0.f, 0.3f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
+
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
+ gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
+ }
+ gGL.end();
+ LLUI::setLineWidth(1.0f);
+
+ gGL.popMatrix();
+ }
+
+ if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
+ {
+ // render XY plane manipulator
+ gGL.pushMatrix();
+ gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+
+/* Y
+ ^
+ v1
+ | \
+ |<- v0
+ | /| \
+ v2__v__v3 > X
*/
- LLVector3 v0,v1,v2,v3;
+ LLVector3 v0,v1,v2,v3;
#if 0
- // This should theoretically work but looks off; could be tuned later -SJB
- gGL.translatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f);
- v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
- v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f);
- v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
- v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
+ // This should theoretically work but looks off; could be tuned later -SJB
+ gGL.translatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f);
+ v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
+ v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f);
+ v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
+ v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
#else
- gGL.translatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f);
- v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
- v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f);
- v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
- v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
+ gGL.translatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f);
+ v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
+ v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f);
+ v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
+ v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
#endif
- gGL.scalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]);
- if (mHighlightedPart == LL_XY_PLANE)
- {
- color1.setVec(1.f, 0.f, 0.f, 1.f);
- color2.setVec(0.f, 1.f, 0.f, 1.f);
- }
- else
- {
- color1.setVec(0.8f, 0.f, 0.f, 0.6f);
- color2.setVec(0.f, 0.8f, 0.f, 0.6f);
- }
-
- gGL.begin(LLRender::TRIANGLES);
- {
- gGL.color4fv(color1.mV);
- gGL.vertex3fv(v0.mV);
- gGL.vertex3fv(v1.mV);
- gGL.vertex3fv(v2.mV);
-
- gGL.color4fv(color2.mV);
- gGL.vertex3fv(v2.mV);
- gGL.vertex3fv(v3.mV);
- gGL.vertex3fv(v0.mV);
- }
- gGL.end();
-
- LLUI::setLineWidth(3.0f);
- gGL.begin(LLRender::LINES);
- {
- gGL.color4f(0.f, 0.f, 0.f, 0.3f);
- LLVector3 v12 = (v1 + v2) * .5f;
- gGL.vertex3fv(v0.mV);
- gGL.vertex3fv(v12.mV);
- gGL.vertex3fv(v12.mV);
- gGL.vertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV);
- gGL.vertex3fv(v12.mV);
- gGL.vertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV);
-
- LLVector3 v23 = (v2 + v3) * .5f;
- gGL.vertex3fv(v0.mV);
- gGL.vertex3fv(v23.mV);
- gGL.vertex3fv(v23.mV);
- gGL.vertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV);
- gGL.vertex3fv(v23.mV);
- gGL.vertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV);
- }
- gGL.end();
- LLUI::setLineWidth(1.0f);
-
- gGL.popMatrix();
- }
- }
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Since we draw handles with depth testing off, we need to draw them in the
- // proper depth order.
-
- // Copied from LLDrawable::updateGeometry
- LLVector3 pos_agent = first_object->getPositionAgent();
- LLVector3 camera_agent = gAgentCamera.getCameraPositionAgent();
- LLVector3 headPos = pos_agent - camera_agent;
-
- LLVector3 orientWRTHead = headPos * invRotation;
-
- // Find nearest vertex
- U32 nearest = (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
- (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
- (orientWRTHead.mV[2] < 0.0f ? 4 : 0);
-
- // opposite faces on Linden cubes:
- // 0 & 5
- // 1 & 3
- // 2 & 4
-
- // Table of order to draw faces, based on nearest vertex
- static U32 face_list[8][NUM_AXES*2] = {
- { 2,0,1, 4,5,3 }, // v6 F201 F453
- { 2,0,3, 4,5,1 }, // v7 F203 F451
- { 4,0,1, 2,5,3 }, // v5 F401 F253
- { 4,0,3, 2,5,1 }, // v4 F403 F251
- { 2,5,1, 4,0,3 }, // v2 F251 F403
- { 2,5,3, 4,0,1 }, // v3 F253 F401
- { 4,5,1, 2,0,3 }, // v1 F451 F203
- { 4,5,3, 2,0,1 }, // v0 F453 F201
- };
- static const EManipPart which_arrow[6] = {
- LL_Z_ARROW,
- LL_X_ARROW,
- LL_Y_ARROW,
- LL_X_ARROW,
- LL_Y_ARROW,
- LL_Z_ARROW};
-
- // draw arrows for deeper faces first, closer faces last
- LLVector3 camera_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- camera_axis = LLVector3::x_axis;
- }
- else
- {
- camera_axis.setVec(gAgentCamera.getCameraPositionAgent() - first_object->getPositionAgent());
- }
-
- for (U32 i = 0; i < NUM_AXES*2; i++)
- {
- U32 face = face_list[nearest][i];
-
- LLVector3 arrow_axis;
- getManipAxis(first_object, which_arrow[face], arrow_axis);
-
- renderArrow(which_arrow[face],
- mManipPart,
- (face >= 3) ? -mConeSize : mConeSize,
- (face >= 3) ? -mArrowLengthMeters : mArrowLengthMeters,
- mConeSize,
- FALSE);
- }
- }
- }
- gGL.popMatrix();
+ gGL.scalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]);
+ if (mHighlightedPart == LL_XY_PLANE)
+ {
+ color1.setVec(1.f, 0.f, 0.f, 1.f);
+ color2.setVec(0.f, 1.f, 0.f, 1.f);
+ }
+ else
+ {
+ color1.setVec(0.8f, 0.f, 0.f, 0.6f);
+ color2.setVec(0.f, 0.8f, 0.f, 0.6f);
+ }
+
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ gGL.color4fv(color1.mV);
+ gGL.vertex3fv(v0.mV);
+ gGL.vertex3fv(v1.mV);
+ gGL.vertex3fv(v2.mV);
+
+ gGL.color4fv(color2.mV);
+ gGL.vertex3fv(v2.mV);
+ gGL.vertex3fv(v3.mV);
+ gGL.vertex3fv(v0.mV);
+ }
+ gGL.end();
+
+ LLUI::setLineWidth(3.0f);
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.color4f(0.f, 0.f, 0.f, 0.3f);
+ LLVector3 v12 = (v1 + v2) * .5f;
+ gGL.vertex3fv(v0.mV);
+ gGL.vertex3fv(v12.mV);
+ gGL.vertex3fv(v12.mV);
+ gGL.vertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV);
+ gGL.vertex3fv(v12.mV);
+ gGL.vertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV);
+
+ LLVector3 v23 = (v2 + v3) * .5f;
+ gGL.vertex3fv(v0.mV);
+ gGL.vertex3fv(v23.mV);
+ gGL.vertex3fv(v23.mV);
+ gGL.vertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV);
+ gGL.vertex3fv(v23.mV);
+ gGL.vertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV);
+ }
+ gGL.end();
+ LLUI::setLineWidth(1.0f);
+
+ gGL.popMatrix();
+ }
+ }
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Since we draw handles with depth testing off, we need to draw them in the
+ // proper depth order.
+
+ // Copied from LLDrawable::updateGeometry
+ LLVector3 pos_agent = first_object->getPositionAgent();
+ LLVector3 camera_agent = gAgentCamera.getCameraPositionAgent();
+ LLVector3 headPos = pos_agent - camera_agent;
+
+ LLVector3 orientWRTHead = headPos * invRotation;
+
+ // Find nearest vertex
+ U32 nearest = (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
+ (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
+ (orientWRTHead.mV[2] < 0.0f ? 4 : 0);
+
+ // opposite faces on Linden cubes:
+ // 0 & 5
+ // 1 & 3
+ // 2 & 4
+
+ // Table of order to draw faces, based on nearest vertex
+ static U32 face_list[8][NUM_AXES*2] = {
+ { 2,0,1, 4,5,3 }, // v6 F201 F453
+ { 2,0,3, 4,5,1 }, // v7 F203 F451
+ { 4,0,1, 2,5,3 }, // v5 F401 F253
+ { 4,0,3, 2,5,1 }, // v4 F403 F251
+ { 2,5,1, 4,0,3 }, // v2 F251 F403
+ { 2,5,3, 4,0,1 }, // v3 F253 F401
+ { 4,5,1, 2,0,3 }, // v1 F451 F203
+ { 4,5,3, 2,0,1 }, // v0 F453 F201
+ };
+ static const EManipPart which_arrow[6] = {
+ LL_Z_ARROW,
+ LL_X_ARROW,
+ LL_Y_ARROW,
+ LL_X_ARROW,
+ LL_Y_ARROW,
+ LL_Z_ARROW};
+
+ // draw arrows for deeper faces first, closer faces last
+ LLVector3 camera_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ camera_axis = LLVector3::x_axis;
+ }
+ else
+ {
+ camera_axis.setVec(gAgentCamera.getCameraPositionAgent() - first_object->getPositionAgent());
+ }
+
+ for (U32 i = 0; i < NUM_AXES*2; i++)
+ {
+ U32 face = face_list[nearest][i];
+
+ LLVector3 arrow_axis;
+ getManipAxis(first_object, which_arrow[face], arrow_axis);
+
+ renderArrow(which_arrow[face],
+ mManipPart,
+ (face >= 3) ? -mConeSize : mConeSize,
+ (face >= 3) ? -mArrowLengthMeters : mArrowLengthMeters,
+ mConeSize,
+ FALSE);
+ }
+ }
+ }
+ gGL.popMatrix();
}
void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_size, F32 arrow_size, F32 handle_size, BOOL reverse_direction)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable gls_blend(GL_BLEND);
-
- for (S32 pass = 1; pass <= 2; pass++)
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER);
- gGL.pushMatrix();
-
- S32 index = 0;
-
- index = ARROW_TO_AXIS[which_arrow];
-
- // assign a color for this arrow
- LLColor4 color; // black
- if (which_arrow == selected_arrow || which_arrow == mHighlightedPart)
- {
- color.mV[index] = (pass == 1) ? 1.f : 0.5f;
- }
- else if (selected_arrow != LL_NO_PART)
- {
- color.mV[VALPHA] = 0.f;
- }
- else
- {
- color.mV[index] = pass == 1 ? .8f : .35f ; // red, green, or blue
- color.mV[VALPHA] = 0.6f;
- }
- gGL.color4fv( color.mV );
-
- LLVector3 vec;
-
- {
- LLUI::setLineWidth(2.0f);
- gGL.begin(LLRender::LINES);
- vec.mV[index] = box_size;
- gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
-
- vec.mV[index] = arrow_size;
- gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
- gGL.end();
- LLUI::setLineWidth(1.0f);
- }
-
- gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]);
- gGL.scalef(handle_size, handle_size, handle_size);
-
- F32 rot = 0.0f;
- LLVector3 axis;
-
- switch(which_arrow)
- {
- case LL_X_ARROW:
- rot = reverse_direction ? -90.0f : 90.0f;
- axis.mV[1] = 1.0f;
- break;
- case LL_Y_ARROW:
- rot = reverse_direction ? 90.0f : -90.0f;
- axis.mV[0] = 1.0f;
- break;
- case LL_Z_ARROW:
- rot = reverse_direction ? 180.0f : 0.0f;
- axis.mV[0] = 1.0f;
- break;
- default:
- LL_ERRS() << "renderArrow called with bad arrow " << which_arrow << LL_ENDL;
- break;
- }
-
- gGL.diffuseColor4fv(color.mV);
- gGL.rotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]);
- gGL.scalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f);
-
- gCone.render();
-
- gGL.popMatrix();
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLEnable gls_blend(GL_BLEND);
+
+ for (S32 pass = 1; pass <= 2; pass++)
+ {
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER);
+ gGL.pushMatrix();
+
+ S32 index = 0;
+
+ index = ARROW_TO_AXIS[which_arrow];
+
+ // assign a color for this arrow
+ LLColor4 color; // black
+ if (which_arrow == selected_arrow || which_arrow == mHighlightedPart)
+ {
+ color.mV[index] = (pass == 1) ? 1.f : 0.5f;
+ }
+ else if (selected_arrow != LL_NO_PART)
+ {
+ color.mV[VALPHA] = 0.f;
+ }
+ else
+ {
+ color.mV[index] = pass == 1 ? .8f : .35f ; // red, green, or blue
+ color.mV[VALPHA] = 0.6f;
+ }
+ gGL.color4fv( color.mV );
+
+ LLVector3 vec;
+
+ {
+ LLUI::setLineWidth(2.0f);
+ gGL.begin(LLRender::LINES);
+ vec.mV[index] = box_size;
+ gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
+
+ vec.mV[index] = arrow_size;
+ gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
+ gGL.end();
+ LLUI::setLineWidth(1.0f);
+ }
+
+ gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]);
+ gGL.scalef(handle_size, handle_size, handle_size);
+
+ F32 rot = 0.0f;
+ LLVector3 axis;
+
+ switch(which_arrow)
+ {
+ case LL_X_ARROW:
+ rot = reverse_direction ? -90.0f : 90.0f;
+ axis.mV[1] = 1.0f;
+ break;
+ case LL_Y_ARROW:
+ rot = reverse_direction ? 90.0f : -90.0f;
+ axis.mV[0] = 1.0f;
+ break;
+ case LL_Z_ARROW:
+ rot = reverse_direction ? 180.0f : 0.0f;
+ axis.mV[0] = 1.0f;
+ break;
+ default:
+ LL_ERRS() << "renderArrow called with bad arrow " << which_arrow << LL_ENDL;
+ break;
+ }
+
+ gGL.diffuseColor4fv(color.mV);
+ gGL.rotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]);
+ gGL.scalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f);
+
+ gCone.render();
+
+ gGL.popMatrix();
+ }
}
void LLManipTranslate::renderGridVert(F32 x_trans, F32 y_trans, F32 r, F32 g, F32 b, F32 alpha)
{
- gGL.color4f(r, g, b, alpha);
- switch (mManipPart)
- {
- case LL_YZ_PLANE:
- gGL.vertex3f(0, x_trans, y_trans);
- break;
- case LL_XZ_PLANE:
- gGL.vertex3f(x_trans, 0, y_trans);
- break;
- case LL_XY_PLANE:
- gGL.vertex3f(x_trans, y_trans, 0);
- break;
- default:
- gGL.vertex3f(0,0,0);
- break;
- }
+ gGL.color4f(r, g, b, alpha);
+ switch (mManipPart)
+ {
+ case LL_YZ_PLANE:
+ gGL.vertex3f(0, x_trans, y_trans);
+ break;
+ case LL_XZ_PLANE:
+ gGL.vertex3f(x_trans, 0, y_trans);
+ break;
+ case LL_XY_PLANE:
+ gGL.vertex3f(x_trans, y_trans, 0);
+ break;
+ default:
+ gGL.vertex3f(0,0,0);
+ break;
+ }
}
// virtual
BOOL LLManipTranslate::canAffectSelection()
{
- BOOL can_move = mObjectSelection->getObjectCount() != 0;
- if (can_move)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* objectp)
- {
- LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
- return objectp->permMove() && !objectp->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
- }
- } func;
- can_move = mObjectSelection->applyToObjects(&func);
- }
- return can_move;
+ BOOL can_move = mObjectSelection->getObjectCount() != 0;
+ if (can_move)
+ {
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
+ return objectp->permMove() && !objectp->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ }
+ } func;
+ can_move = mObjectSelection->applyToObjects(&func);
+ }
+ return can_move;
}
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index b7811dfb43..84446b626a 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llmaterialeditor.cpp
* @brief Implementation of the gltf material editor
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -48,7 +48,7 @@
#include "llviewertexture.h"
#include "llsdutil.h"
#include "llselectmgr.h"
-#include "llstatusbar.h" // can_afford_transaction()
+#include "llstatusbar.h" // can_afford_transaction()
#include "lltoolpie.h"
#include "llviewerinventory.h"
#include "llinventory.h"
@@ -489,11 +489,10 @@ BOOL LLMaterialEditor::postBuild()
}
else
{
- S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
- getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
- getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mBaseColorFetched)));
+ getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mMetallicRoughnessFetched)));
+ getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mEmissiveFetched)));
+ getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost(mNormalFetched)));
}
boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
@@ -503,7 +502,7 @@ BOOL LLMaterialEditor::postBuild()
// Apply changes to object live
applyToSelection();
};
-
+
childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY);
// BaseColor
@@ -551,7 +550,7 @@ BOOL LLMaterialEditor::postBuild()
// Disable/enable setCanApplyImmediately() based on
// working from inventory, upload or editing inworld
- return LLPreview::postBuild();
+ return LLPreview::postBuild();
}
void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
@@ -842,25 +841,24 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
setCanSave(false);
}
- S32 upload_texture_count = 0;
- if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId())
+ mExpectedUploadCost = 0;
+ if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId() && mBaseColorFetched)
{
- upload_texture_count++;
+ mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mBaseColorFetched);
}
- if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId())
+ if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicRoughnessFetched)
{
- upload_texture_count++;
+ mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mMetallicRoughnessFetched);
}
- if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId())
+ if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId() && mEmissiveFetched)
{
- upload_texture_count++;
+ mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mEmissiveFetched);
}
- if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId())
+ if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId() && mNormalFetched)
{
- upload_texture_count++;
+ mExpectedUploadCost += LLAgentBenefitsMgr::current().getTextureUploadCost(mNormalFetched);
}
- mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost();
getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
}
@@ -1228,7 +1226,7 @@ std::string LLMaterialEditor::getEncodedAsset()
bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
{
LLSD asset;
-
+
std::istrstream str(&buffer[0], buffer.size());
if (LLSDSerialize::deserialize(asset, str, buffer.size()))
{
@@ -1292,7 +1290,7 @@ const std::string LLMaterialEditor::buildMaterialDescription()
desc << LLTrans::getString("Material Texture Name Header");
// add the texture names for each just so long as the material
- // we loaded has an entry for it (i think testing the texture
+ // we loaded has an entry for it (i think testing the texture
// control UUI for NULL is a valid metric for if it was loaded
// or not but I suspect this code will change a lot so may need
// to revisit
@@ -1374,7 +1372,7 @@ bool LLMaterialEditor::saveIfNeeded()
}
}
else
- {
+ {
// Make a new inventory item and set upload permissions
LLPermissions local_permissions;
local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
@@ -1403,7 +1401,7 @@ bool LLMaterialEditor::saveIfNeeded()
// We do not update floater with uploaded asset yet, so just close it.
closeFloater();
}
-
+
return true;
}
@@ -1818,7 +1816,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD&
}
else
{
- LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response)
+ LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response)
{
LLNotificationsUtil::add("SaveMaterialAs", LLSD().with("DESC", mMaterialName), LLSD(),
boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
@@ -1870,7 +1868,7 @@ static void pack_textures(
if (normal_img)
{
// create a losslessly compressed version of the normal map
- normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true);
+ normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 2048, false, true);
LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL;
}
@@ -1978,7 +1976,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
std::list<std::string> material_list;
std::vector<tinygltf::Material>::const_iterator mat_iter = model_in.materials.begin();
std::vector<tinygltf::Material>::const_iterator mat_end = model_in.materials.end();
-
+
for (; mat_iter != mat_end; mat_iter++)
{
std::string mat_name = mat_iter->name;
@@ -2124,7 +2122,7 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
// Look for the item to base permissions off of
item_out = nullptr;
- const bool blank_material = func.mMaterialId == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ const bool blank_material = func.mMaterialId == BLANK_MATERIAL_ASSET_ID;
if (!blank_material)
{
LLAssetIDMatchesWithPerms item_has_perms(func.mMaterialId, ops);
@@ -2617,28 +2615,28 @@ bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index,
}
/**
- * Build a texture name from the contents of the (in tinyGLFT parlance)
+ * Build a texture name from the contents of the (in tinyGLFT parlance)
* Image URI. This often is filepath to the original image on the users'
* local file system.
*/
const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type)
{
- // getBaseFileName() works differently on each platform and file patchs
- // can contain both types of delimiter so unify them then extract the
+ // getBaseFileName() works differently on each platform and file patchs
+ // can contain both types of delimiter so unify them then extract the
// base name (no path or extension)
std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]);
std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]);
const bool strip_extension = true;
std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension);
- // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :)
+ // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :)
const int max_texture_name_length = 64;
if (stripped_uri.length() > max_texture_name_length)
{
stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1);
}
- // We intend to append the type of texture (base color, emissive etc.) to the
+ // We intend to append the type of texture (base color, emissive etc.) to the
// name of the texture but sometimes the creator already did that. To try
// to avoid repeats (not perfect), we look for the texture type in the name
// and if we find it, do not append the type, later on. One way this fails
@@ -2704,15 +2702,15 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c
/**
* Update the metadata for the material based on what we find in the loaded
* file (along with some assumptions and interpretations...). Fields include
- * the name of the material, a material description and the names of the
+ * the name of the material, a material description and the names of the
* composite textures.
*/
void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index)
{
- // Use the name (without any path/extension) of the file that was
- // uploaded as the base of the material name. Then if the name of the
+ // Use the name (without any path/extension) of the file that was
+ // uploaded as the base of the material name. Then if the name of the
// scene is present and not blank, append that and use the result as
- // the name of the material. This is a first pass at creating a
+ // the name of the material. This is a first pass at creating a
// naming scheme that is useful to real content creators and hopefully
// avoid 500 materials in your inventory called "scene" or "Default"
const bool strip_extension = true;
@@ -2743,10 +2741,10 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti
// scene name isn't present so no point using it
}
- // If we have a valid material or scene name, use it to build the short and
- // long versions of the material name. The long version is used
+ // If we have a valid material or scene name, use it to build the short and
+ // long versions of the material name. The long version is used
// as you might expect, for the material name. The short version is
- // used as part of the image/texture name - the theory is that will
+ // used as part of the image/texture name - the theory is that will
// allow content creators to track the material and the corresponding
// textures
if (material_name.length())
@@ -2754,9 +2752,9 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti
mMaterialNameShort = base_filename;
mMaterialName = STRINGIZE(
- base_filename <<
- " " <<
- "(" <<
+ base_filename <<
+ " " <<
+ "(" <<
material_name <<
")"
);
@@ -2772,14 +2770,14 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti
LLInventoryObject::correctInventoryName(mMaterialName);
LLInventoryObject::correctInventoryName(mMaterialNameShort);
- // We also set the title of the floater to match the
+ // We also set the title of the floater to match the
// name of the material
setTitle(mMaterialName);
/**
- * Extract / derive the names of each composite texture. For each, the
+ * Extract / derive the names of each composite texture. For each, the
* index is used to to determine which of the "Images" is used. If the index
- * is -1 then that texture type is not present in the material (Seems to be
+ * is -1 then that texture type is not present in the material (Seems to be
* quite common that a material is missing 1 or more types of texture)
*/
if (model.materials.size() > index)
@@ -2787,8 +2785,8 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti
const tinygltf::Material& first_material = model.materials[index];
mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
- // note: unlike the other textures, base color doesn't have its own entry
- // in the tinyGLTF Material struct. Rather, it is taken from a
+ // note: unlike the other textures, base color doesn't have its own entry
+ // in the tinyGLTF Material struct. Rather, it is taken from a
// sub-texture in the pbrMetallicRoughness member
int index = first_material.pbrMetallicRoughness.baseColorTexture.index;
if (index > -1 && index < model.images.size())
@@ -2942,7 +2940,7 @@ public:
else
{
// mSavedGLTFOverrideMaterials[te] being present but null
- // means we need to use a default value
+ // means we need to use a default value
revert_mat = new LLGLTFMaterial();
}
}
@@ -3283,7 +3281,7 @@ bool LLMaterialEditor::setFromSelection()
// Ovverdired might have been updated,
// refresh state of local textures in overrides
- //
+ //
// Todo: this probably shouldn't be here, but in localbitmap,
// subscried to all material overrides if we want copied
// objects to get properly updated as well
@@ -3306,7 +3304,7 @@ void LLMaterialEditor::loadAsset()
{
item = getItem();
}
-
+
bool fail = false;
if (item)
@@ -3495,8 +3493,7 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con
std::string buffer;
buffer.assign((const char*) img->getData(), img->getDataSize());
- U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
-
+ U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(img);
LLSD key = getKey();
std::function<bool(LLUUID itemId, LLSD response, std::string reason)> failed_upload([key](LLUUID assetId, LLSD response, std::string reason)
{
@@ -3511,16 +3508,16 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con
LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewBufferedResourceUploadInfo>(
buffer,
asset_id,
- name,
- name,
+ name,
+ name,
0,
- LLFolderType::FT_TEXTURE,
+ LLFolderType::FT_TEXTURE,
LLInventoryType::IT_TEXTURE,
LLAssetType::AT_TEXTURE,
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost,
+ expected_upload_cost,
false,
cb,
failed_upload));
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 9761c6ae10..5ee25b76a2 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelface.cpp
* @brief Panel in the tools floater for editing face textures, colors, etc.
*
* $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$
*/
@@ -28,7 +28,7 @@
// file include
#include "llpanelface.h"
-
+
// library includes
#include "llcalc.h"
#include "llerror.h"
@@ -102,15 +102,15 @@ LLPanelFace::Selection LLPanelFace::sMaterialOverrideSelection;
// Constant definitions for comboboxes
// Must match the commbobox definitions in panel_tools_texture.xml
//
-const S32 MATMEDIA_MATERIAL = 0; // Material
-const S32 MATMEDIA_PBR = 1; // PBR
-const S32 MATMEDIA_MEDIA = 2; // Media
-const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
-const S32 MATTYPE_NORMAL = 1; // Normal map
-const S32 MATTYPE_SPECULAR = 2; // Specular map
-const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
-const S32 BUMPY_TEXTURE = 18; // use supplied normal map
-const S32 SHINY_TEXTURE = 4; // use supplied specular map
+const S32 MATMEDIA_MATERIAL = 0; // Material
+const S32 MATMEDIA_PBR = 1; // PBR
+const S32 MATMEDIA_MEDIA = 2; // Media
+const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
+const S32 MATTYPE_NORMAL = 1; // Normal map
+const S32 MATTYPE_SPECULAR = 2; // Specular map
+const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
+const S32 BUMPY_TEXTURE = 18; // use supplied normal map
+const S32 SHINY_TEXTURE = 4; // use supplied specular map
const S32 PBRTYPE_RENDER_MATERIAL_ID = 0; // Render Material ID
const S32 PBRTYPE_BASE_COLOR = 1; // PBR Base Color
const S32 PBRTYPE_METALLIC_ROUGHNESS = 2; // PBR Metallic
@@ -159,7 +159,7 @@ void LLPanelFace::updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*
return true;
}
- std::function<void(LLGLTFMaterial*)> mFunc;
+ std::function<void(LLGLTFMaterial*)> mFunc;
} select_func(func);
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func);
@@ -176,7 +176,7 @@ void readSelectedGLTFMaterial(std::function<T(const LLGLTFMaterial*)> func, T& v
{
const LLTextureEntry* tep = object->getTE(face);
const LLGLTFMaterial* render_material = tep->getGLTFRenderMaterial();
-
+
return mFunc(render_material);
}
@@ -211,9 +211,9 @@ LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
}
}
- channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
- channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
- return channel_to_edit;
+ channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ return channel_to_edit;
}
LLRender::eTexIndex LLPanelFace::getTextureDropChannel()
@@ -240,55 +240,55 @@ LLGLTFMaterial::TextureInfo LLPanelFace::getPBRDropChannel()
// Things the UI provides...
//
-LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
-LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); }
-U32 LLPanelFace::getCurrentShininess() { return getChild<LLComboBox>("combobox shininess")->getCurrentIndex(); }
-U32 LLPanelFace::getCurrentBumpiness() { return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex(); }
-U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex(); }
-U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger(); }
-U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger(); }
-U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger(); }
-F32 LLPanelFace::getCurrentBumpyRot() { return getChild<LLUICtrl>("bumpyRot")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentShinyRot() { return getChild<LLUICtrl>("shinyRot")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentShinyScaleU() { return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentShinyScaleV() { return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(); }
-F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal(); }
+LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
+LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); }
+U32 LLPanelFace::getCurrentShininess() { return getChild<LLComboBox>("combobox shininess")->getCurrentIndex(); }
+U32 LLPanelFace::getCurrentBumpiness() { return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger(); }
+F32 LLPanelFace::getCurrentBumpyRot() { return getChild<LLUICtrl>("bumpyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyRot() { return getChild<LLUICtrl>("shinyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleU() { return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleV() { return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal(); }
//
// Methods
//
-BOOL LLPanelFace::postBuild()
-{
- childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
- childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
- childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
- childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this);
- childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this);
- childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this);
- childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
- childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
- childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this);
- childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this);
-
- childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this);
- childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this);
- childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this);
- childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this);
- childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this);
- childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this);
- childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this);
- childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this);
- childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this);
- childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this);
- childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
- childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
- childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+BOOL LLPanelFace::postBuild()
+{
+ childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
+ childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+ childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
+ childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this);
+ childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this);
+ childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this);
+ childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
+ childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
+ childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this);
+ childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this);
+
+ childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this);
+ childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this);
+ childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this);
+ childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this);
+ childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this);
+ childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this);
+ childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this);
+ childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this);
+ childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this);
+ childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this);
+ childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
+ childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
+ childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
@@ -301,34 +301,34 @@ BOOL LLPanelFace::postBuild()
LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived);
sMaterialOverrideSelection.connect();
- childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
- childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
+ childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
+ childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
childSetAction("pbr_from_inventory", &LLPanelFace::onClickBtnLoadInvPBR, this);
childSetAction("edit_selected_pbr", &LLPanelFace::onClickBtnEditPBR, this);
childSetAction("save_selected_pbr", &LLPanelFace::onClickBtnSavePBR, this);
- LLTextureCtrl* mTextureCtrl;
- LLTextureCtrl* mShinyTextureCtrl;
- LLTextureCtrl* mBumpyTextureCtrl;
- LLColorSwatchCtrl* mColorSwatch;
- LLColorSwatchCtrl* mShinyColorSwatch;
+ LLTextureCtrl* mTextureCtrl;
+ LLTextureCtrl* mShinyTextureCtrl;
+ LLTextureCtrl* mBumpyTextureCtrl;
+ LLColorSwatchCtrl* mColorSwatch;
+ LLColorSwatchCtrl* mShinyColorSwatch;
- LLComboBox* mComboTexGen;
+ LLComboBox* mComboTexGen;
- LLCheckBoxCtrl *mCheckFullbright;
+ LLCheckBoxCtrl *mCheckFullbright;
+
+ LLTextBox* mLabelColorTransp;
+ LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha
- LLTextBox* mLabelColorTransp;
- LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha
+ LLSpinCtrl* mCtrlGlow;
- LLSpinCtrl* mCtrlGlow;
+ setMouseOpaque(FALSE);
- setMouseOpaque(FALSE);
-
- LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (pbr_ctrl)
{
pbr_ctrl->setDefaultImageAssetID(LLUUID::null);
- pbr_ctrl->setBlankImageAssetID(LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID);
+ pbr_ctrl->setBlankImageAssetID(BLANK_MATERIAL_ASSET_ID);
pbr_ctrl->setCommitCallback(boost::bind(&LLPanelFace::onCommitPbr, this, _2));
pbr_ctrl->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelPbr, this, _2));
pbr_ctrl->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectPbr, this, _2));
@@ -344,117 +344,117 @@ BOOL LLPanelFace::postBuild()
pbr_ctrl->setInventoryPickType(PICK_MATERIAL);
}
- mTextureCtrl = getChild<LLTextureCtrl>("texture control");
- if(mTextureCtrl)
- {
- mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE);
- mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
- mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
- mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
- mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
- mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
- mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
-
- mTextureCtrl->setFollowsTop();
- mTextureCtrl->setFollowsLeft();
- mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
- mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- }
-
- mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
- if(mShinyTextureCtrl)
- {
- mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR);
- mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
- mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
- mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
- mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
-
- mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
- mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
- mShinyTextureCtrl->setFollowsTop();
- mShinyTextureCtrl->setFollowsLeft();
- mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
- mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- }
-
- mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
- if(mBumpyTextureCtrl)
- {
- mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL);
- mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL);
- mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
- mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
- mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
- mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
-
- mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
- mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
- mBumpyTextureCtrl->setFollowsTop();
- mBumpyTextureCtrl->setFollowsLeft();
- mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
- mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- }
-
- mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(mColorSwatch)
- {
- mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2));
- mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2));
- mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2));
- mColorSwatch->setFollowsTop();
- mColorSwatch->setFollowsLeft();
- mColorSwatch->setCanApplyImmediately(TRUE);
- }
-
- mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
- if(mShinyColorSwatch)
- {
- mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
- mShinyColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelShinyColor, this, _2));
- mShinyColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectShinyColor, this, _2));
- mShinyColorSwatch->setFollowsTop();
- mShinyColorSwatch->setFollowsLeft();
- mShinyColorSwatch->setCanApplyImmediately(TRUE);
- }
-
- mLabelColorTransp = getChild<LLTextBox>("color trans");
- if(mLabelColorTransp)
- {
- mLabelColorTransp->setFollowsTop();
- mLabelColorTransp->setFollowsLeft();
- }
-
- mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
- if(mCtrlColorTransp)
- {
- mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2));
- mCtrlColorTransp->setPrecision(0);
- mCtrlColorTransp->setFollowsTop();
- mCtrlColorTransp->setFollowsLeft();
- }
-
- mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
- if (mCheckFullbright)
- {
- mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this);
- }
-
- mComboTexGen = getChild<LLComboBox>("combobox texgen");
- if(mComboTexGen)
- {
- mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this);
- mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
- }
+ mTextureCtrl = getChild<LLTextureCtrl>("texture control");
+ if(mTextureCtrl)
+ {
+ mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE);
+ mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
+ mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
+ mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
+ mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mTextureCtrl->setFollowsTop();
+ mTextureCtrl->setFollowsLeft();
+ mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
+ if(mShinyTextureCtrl)
+ {
+ mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR);
+ mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mShinyTextureCtrl->setFollowsTop();
+ mShinyTextureCtrl->setFollowsLeft();
+ mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if(mBumpyTextureCtrl)
+ {
+ mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL);
+ mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL);
+ mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mBumpyTextureCtrl->setFollowsTop();
+ mBumpyTextureCtrl->setFollowsLeft();
+ mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(mColorSwatch)
+ {
+ mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2));
+ mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2));
+ mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2));
+ mColorSwatch->setFollowsTop();
+ mColorSwatch->setFollowsLeft();
+ mColorSwatch->setCanApplyImmediately(TRUE);
+ }
+
+ mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if(mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
+ mShinyColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelShinyColor, this, _2));
+ mShinyColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectShinyColor, this, _2));
+ mShinyColorSwatch->setFollowsTop();
+ mShinyColorSwatch->setFollowsLeft();
+ mShinyColorSwatch->setCanApplyImmediately(TRUE);
+ }
+
+ mLabelColorTransp = getChild<LLTextBox>("color trans");
+ if(mLabelColorTransp)
+ {
+ mLabelColorTransp->setFollowsTop();
+ mLabelColorTransp->setFollowsLeft();
+ }
+
+ mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
+ if(mCtrlColorTransp)
+ {
+ mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2));
+ mCtrlColorTransp->setPrecision(0);
+ mCtrlColorTransp->setFollowsTop();
+ mCtrlColorTransp->setFollowsLeft();
+ }
+
+ mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
+ if (mCheckFullbright)
+ {
+ mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this);
+ }
+
+ mComboTexGen = getChild<LLComboBox>("combobox texgen");
+ if(mComboTexGen)
+ {
+ mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this);
+ mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
+ }
mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
- if(mComboMatMedia)
- {
+ if(mComboMatMedia)
+ {
mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
- }
+ }
- LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
{
radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
@@ -468,25 +468,25 @@ BOOL LLPanelFace::postBuild()
radio_pbr_type->selectNthItem(PBRTYPE_RENDER_MATERIAL_ID);
}
- mCtrlGlow = getChild<LLSpinCtrl>("glow");
- if(mCtrlGlow)
- {
- mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
- }
+ mCtrlGlow = getChild<LLSpinCtrl>("glow");
+ if(mCtrlGlow)
+ {
+ mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
+ }
mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn");
mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn");
-
+
mTitleMedia = getChild<LLMediaCtrl>("title_media");
mTitleMediaText = getChild<LLTextBox>("media_info");
- clearCtrls();
+ clearCtrls();
- return TRUE;
+ return TRUE;
}
LLPanelFace::LLPanelFace()
-: LLPanel(),
+: LLPanel(),
mIsAlpha(false),
mComboMatMedia(NULL),
mTitleMedia(NULL),
@@ -532,131 +532,131 @@ void LLPanelFace::draw()
void LLPanelFace::sendTexture()
{
- LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("texture control");
- if(!mTextureCtrl) return;
- if( !mTextureCtrl->getTentative() )
- {
- // we grab the item id first, because we want to do a
- // permissions check in the selection manager. ARGH!
- LLUUID id = mTextureCtrl->getImageItemID();
- if(id.isNull())
- {
- id = mTextureCtrl->getImageAssetID();
- }
+ LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("texture control");
+ if(!mTextureCtrl) return;
+ if( !mTextureCtrl->getTentative() )
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = mTextureCtrl->getImageItemID();
+ if(id.isNull())
+ {
+ id = mTextureCtrl->getImageAssetID();
+ }
if (!LLSelectMgr::getInstance()->selectionSetImage(id))
{
// need to refresh value in texture ctrl
refresh();
}
- }
+ }
}
void LLPanelFace::sendBump(U32 bumpiness)
-{
- LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- if (bumpiness < BUMPY_TEXTURE)
-{
- LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
- bumpytexture_ctrl->clear();
- bumpytexture_ctrl->setImageAssetID(LLUUID());
- }
+{
+ LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if (bumpiness < BUMPY_TEXTURE)
+{
+ LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
+ bumpytexture_ctrl->clear();
+ bumpytexture_ctrl->setImageAssetID(LLUUID());
+ }
- updateBumpyControls(bumpiness == BUMPY_TEXTURE, true);
+ updateBumpyControls(bumpiness == BUMPY_TEXTURE, true);
- LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID();
+ LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID();
- U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
+ U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
- // Clear legacy bump to None when using an actual normal map
- //
- if (!current_normal_map.isNull())
- bump = 0;
+ // Clear legacy bump to None when using an actual normal map
+ //
+ if (!current_normal_map.isNull())
+ bump = 0;
- // Set the normal map or reset it to null as appropriate
- //
- LLSelectedTEMaterial::setNormalID(this, current_normal_map);
+ // Set the normal map or reset it to null as appropriate
+ //
+ LLSelectedTEMaterial::setNormalID(this, current_normal_map);
- LLSelectMgr::getInstance()->selectionSetBumpmap( bump, bumpytexture_ctrl->getImageItemID() );
+ LLSelectMgr::getInstance()->selectionSetBumpmap( bump, bumpytexture_ctrl->getImageItemID() );
}
void LLPanelFace::sendTexGen()
{
- LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
- if(!mComboTexGen)return;
- U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
- LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
+ LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
+ if(!mComboTexGen)return;
+ U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
+ LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
}
void LLPanelFace::sendShiny(U32 shininess)
{
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
- if (shininess < SHINY_TEXTURE)
+ if (shininess < SHINY_TEXTURE)
{
- texture_ctrl->clear();
- texture_ctrl->setImageAssetID(LLUUID());
- }
-
- LLUUID specmap = getCurrentSpecularMap();
+ texture_ctrl->clear();
+ texture_ctrl->setImageAssetID(LLUUID());
+ }
- U8 shiny = (U8) shininess & TEM_SHINY_MASK;
- if (!specmap.isNull())
- shiny = 0;
+ LLUUID specmap = getCurrentSpecularMap();
- LLSelectedTEMaterial::setSpecularID(this, specmap);
+ U8 shiny = (U8) shininess & TEM_SHINY_MASK;
+ if (!specmap.isNull())
+ shiny = 0;
- LLSelectMgr::getInstance()->selectionSetShiny( shiny, texture_ctrl->getImageItemID() );
+ LLSelectedTEMaterial::setSpecularID(this, specmap);
- updateShinyControls(!specmap.isNull(), true);
+ LLSelectMgr::getInstance()->selectionSetShiny( shiny, texture_ctrl->getImageItemID() );
+ updateShinyControls(!specmap.isNull(), true);
+
}
void LLPanelFace::sendFullbright()
{
- LLCheckBoxCtrl* mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
- if(!mCheckFullbright)return;
- U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
- LLSelectMgr::getInstance()->selectionSetFullbright( fullbright );
+ LLCheckBoxCtrl* mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
+ if(!mCheckFullbright)return;
+ U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
+ LLSelectMgr::getInstance()->selectionSetFullbright( fullbright );
}
void LLPanelFace::sendColor()
{
+
+ LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(!mColorSwatch)return;
+ LLColor4 color = mColorSwatch->get();
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(!mColorSwatch)return;
- LLColor4 color = mColorSwatch->get();
-
- LLSelectMgr::getInstance()->selectionSetColorOnly( color );
+ LLSelectMgr::getInstance()->selectionSetColorOnly( color );
}
void LLPanelFace::sendAlpha()
-{
- LLSpinCtrl* mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
- if(!mCtrlColorTransp)return;
- F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f;
+{
+ LLSpinCtrl* mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
+ if(!mCtrlColorTransp)return;
+ F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f;
- LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha );
+ LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha );
}
void LLPanelFace::sendGlow()
{
- LLSpinCtrl* mCtrlGlow = getChild<LLSpinCtrl>("glow");
- llassert(mCtrlGlow);
- if (mCtrlGlow)
- {
- F32 glow = mCtrlGlow->get();
- LLSelectMgr::getInstance()->selectionSetGlow( glow );
- }
+ LLSpinCtrl* mCtrlGlow = getChild<LLSpinCtrl>("glow");
+ llassert(mCtrlGlow);
+ if (mCtrlGlow)
+ {
+ F32 glow = mCtrlGlow->get();
+ LLSelectMgr::getInstance()->selectionSetGlow( glow );
+ }
}
struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
{
- LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {}
- virtual bool apply(LLViewerObject* object, S32 te)
- {
- BOOL valid;
- F32 value;
+ LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {}
+ virtual bool apply(LLViewerObject* object, S32 te)
+ {
+ BOOL valid;
+ F32 value;
std::string prefix;
// Effectively the same as MATMEDIA_PBR sans using different radio,
@@ -674,179 +674,179 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
prefix = "shiny";
break;
}
-
+
LLSpinCtrl * ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleU");
LLSpinCtrl * ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleV");
LLSpinCtrl * ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetU");
LLSpinCtrl * ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetV");
LLSpinCtrl * ctrlTexRotation = mPanel->getChild<LLSpinCtrl>(prefix + "Rot");
- LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
- LLCheckBoxCtrl* cb_planar_align = mPanel->getChild<LLCheckBoxCtrl>("checkbox planar align");
- bool align_planar = (cb_planar_align && cb_planar_align->get());
-
- llassert(comboTexGen);
- llassert(object);
-
- if (ctrlTexScaleS)
- {
- valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
- if (valid || align_planar)
- {
- value = ctrlTexScaleS->get();
- if (comboTexGen &&
- comboTexGen->getCurrentIndex() == 1)
- {
- value *= 0.5f;
- }
- object->setTEScaleS( te, value );
-
- if (align_planar)
- {
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID());
- }
- }
- }
-
- if (ctrlTexScaleT)
- {
- valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
- if (valid || align_planar)
- {
- value = ctrlTexScaleT->get();
- //if( checkFlipScaleT->get() )
- //{
- // value = -value;
- //}
- if (comboTexGen &&
- comboTexGen->getCurrentIndex() == 1)
- {
- value *= 0.5f;
- }
- object->setTEScaleT( te, value );
-
- if (align_planar)
- {
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID());
- }
- }
- }
-
- if (ctrlTexOffsetS)
- {
- valid = !ctrlTexOffsetS->getTentative();
- if (valid || align_planar)
- {
- value = ctrlTexOffsetS->get();
- object->setTEOffsetS( te, value );
-
- if (align_planar)
- {
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID());
- }
- }
- }
-
- if (ctrlTexOffsetT)
- {
- valid = !ctrlTexOffsetT->getTentative();
- if (valid || align_planar)
- {
- value = ctrlTexOffsetT->get();
- object->setTEOffsetT( te, value );
-
- if (align_planar)
- {
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID());
- }
- }
- }
-
- if (ctrlTexRotation)
- {
- valid = !ctrlTexRotation->getTentative();
- if (valid || align_planar)
- {
- value = ctrlTexRotation->get() * DEG_TO_RAD;
- object->setTERotation( te, value );
-
- if (align_planar)
- {
- LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID());
- }
- }
- }
- return true;
- }
+ LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
+ LLCheckBoxCtrl* cb_planar_align = mPanel->getChild<LLCheckBoxCtrl>("checkbox planar align");
+ bool align_planar = (cb_planar_align && cb_planar_align->get());
+
+ llassert(comboTexGen);
+ llassert(object);
+
+ if (ctrlTexScaleS)
+ {
+ valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
+ if (valid || align_planar)
+ {
+ value = ctrlTexScaleS->get();
+ if (comboTexGen &&
+ comboTexGen->getCurrentIndex() == 1)
+ {
+ value *= 0.5f;
+ }
+ object->setTEScaleS( te, value );
+
+ if (align_planar)
+ {
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID());
+ }
+ }
+ }
+
+ if (ctrlTexScaleT)
+ {
+ valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
+ if (valid || align_planar)
+ {
+ value = ctrlTexScaleT->get();
+ //if( checkFlipScaleT->get() )
+ //{
+ // value = -value;
+ //}
+ if (comboTexGen &&
+ comboTexGen->getCurrentIndex() == 1)
+ {
+ value *= 0.5f;
+ }
+ object->setTEScaleT( te, value );
+
+ if (align_planar)
+ {
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID());
+ }
+ }
+ }
+
+ if (ctrlTexOffsetS)
+ {
+ valid = !ctrlTexOffsetS->getTentative();
+ if (valid || align_planar)
+ {
+ value = ctrlTexOffsetS->get();
+ object->setTEOffsetS( te, value );
+
+ if (align_planar)
+ {
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID());
+ }
+ }
+ }
+
+ if (ctrlTexOffsetT)
+ {
+ valid = !ctrlTexOffsetT->getTentative();
+ if (valid || align_planar)
+ {
+ value = ctrlTexOffsetT->get();
+ object->setTEOffsetT( te, value );
+
+ if (align_planar)
+ {
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID());
+ }
+ }
+ }
+
+ if (ctrlTexRotation)
+ {
+ valid = !ctrlTexRotation->getTentative();
+ if (valid || align_planar)
+ {
+ value = ctrlTexRotation->get() * DEG_TO_RAD;
+ object->setTERotation( te, value );
+
+ if (align_planar)
+ {
+ LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID());
+ }
+ }
+ }
+ return true;
+ }
private:
- LLPanelFace* mPanel;
+ LLPanelFace* mPanel;
};
// Functor that aligns a face to mCenterFace
struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor
{
- LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) :
- mPanel(panel),
- mCenterFace(center_face) {}
-
- virtual bool apply(LLViewerObject* object, S32 te)
- {
- LLFace* facep = object->mDrawable->getFace(te);
- if (!facep)
- {
- return true;
- }
-
- if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
- {
- return true;
- }
-
- bool set_aligned = true;
- if (facep == mCenterFace)
- {
- set_aligned = false;
- }
- if (set_aligned)
- {
- LLVector2 uv_offset, uv_scale;
- F32 uv_rot;
- set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot);
- if (set_aligned)
- {
- object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
- object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
- object->setTERotation(te, uv_rot);
-
- LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID());
-
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
-
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
- }
- }
- if (!set_aligned)
- {
- LLPanelFaceSetTEFunctor setfunc(mPanel);
- setfunc.apply(object, te);
- }
- return true;
- }
+ LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) :
+ mPanel(panel),
+ mCenterFace(center_face) {}
+
+ virtual bool apply(LLViewerObject* object, S32 te)
+ {
+ LLFace* facep = object->mDrawable->getFace(te);
+ if (!facep)
+ {
+ return true;
+ }
+
+ if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
+ {
+ return true;
+ }
+
+ bool set_aligned = true;
+ if (facep == mCenterFace)
+ {
+ set_aligned = false;
+ }
+ if (set_aligned)
+ {
+ LLVector2 uv_offset, uv_scale;
+ F32 uv_rot;
+ set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot);
+ if (set_aligned)
+ {
+ object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
+ object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
+ object->setTERotation(te, uv_rot);
+
+ LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID());
+
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
+
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
+ }
+ }
+ if (!set_aligned)
+ {
+ LLPanelFaceSetTEFunctor setfunc(mPanel);
+ setfunc.apply(object, te);
+ }
+ return true;
+ }
private:
- LLPanelFace* mPanel;
- LLFace* mCenterFace;
+ LLPanelFace* mPanel;
+ LLFace* mCenterFace;
};
struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor
@@ -902,7 +902,7 @@ struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor
}
}
}
-
+
return true;
}
private:
@@ -914,36 +914,36 @@ private:
// Functor that tests if a face is aligned to mCenterFace
struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
{
- LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) :
- mCenterFace(center_face) {}
-
- virtual bool apply(LLViewerObject* object, S32 te)
- {
- LLFace* facep = object->mDrawable->getFace(te);
- if (!facep)
- {
- return false;
- }
-
- if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
- { //volume face does not exist, can't be aligned
- return false;
- }
-
- if (facep == mCenterFace)
- {
- return true;
- }
-
- LLVector2 aligned_st_offset, aligned_st_scale;
- F32 aligned_st_rot;
- if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) )
- {
- const LLTextureEntry* tep = facep->getTextureEntry();
- LLVector2 st_offset, st_scale;
- tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
- tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
- F32 st_rot = tep->getRotation();
+ LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) :
+ mCenterFace(center_face) {}
+
+ virtual bool apply(LLViewerObject* object, S32 te)
+ {
+ LLFace* facep = object->mDrawable->getFace(te);
+ if (!facep)
+ {
+ return false;
+ }
+
+ if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
+ { //volume face does not exist, can't be aligned
+ return false;
+ }
+
+ if (facep == mCenterFace)
+ {
+ return true;
+ }
+
+ LLVector2 aligned_st_offset, aligned_st_scale;
+ F32 aligned_st_rot;
+ if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) )
+ {
+ const LLTextureEntry* tep = facep->getTextureEntry();
+ LLVector2 st_offset, st_scale;
+ tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
+ tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
+ F32 st_rot = tep->getRotation();
bool eq_offset_x = is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12);
bool eq_offset_y = is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12);
@@ -951,49 +951,49 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
bool eq_scale_y = is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12);
bool eq_rot = is_approx_equal_fraction(st_rot, aligned_st_rot, 6);
- // needs a fuzzy comparison, because of fp errors
- if (eq_offset_x &&
- eq_offset_y &&
- eq_scale_x &&
- eq_scale_y &&
- eq_rot)
- {
- return true;
- }
- }
- return false;
- }
+ // needs a fuzzy comparison, because of fp errors
+ if (eq_offset_x &&
+ eq_offset_y &&
+ eq_scale_x &&
+ eq_scale_y &&
+ eq_rot)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
private:
- LLFace* mCenterFace;
+ LLFace* mCenterFace;
};
struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor
{
- virtual bool apply(LLViewerObject* object)
- {
- object->sendTEUpdate();
- return true;
- }
+ virtual bool apply(LLViewerObject* object)
+ {
+ object->sendTEUpdate();
+ return true;
+ }
};
void LLPanelFace::sendTextureInfo()
{
- if ((bool)childGetValue("checkbox planar align").asBoolean())
- {
- LLFace* last_face = NULL;
- bool identical_face =false;
- LLSelectedTE::getFace(last_face, identical_face);
- LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
- LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
- }
- else
- {
- LLPanelFaceSetTEFunctor setfunc(this);
- LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
- }
+ if ((bool)childGetValue("checkbox planar align").asBoolean())
+ {
+ LLFace* last_face = NULL;
+ bool identical_face =false;
+ LLSelectedTE::getFace(last_face, identical_face);
+ LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+ }
+ else
+ {
+ LLPanelFaceSetTEFunctor setfunc(this);
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+ }
- LLPanelFaceSendFunctor sendfunc;
- LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
+ LLPanelFaceSendFunctor sendfunc;
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
void LLPanelFace::alignTestureLayer()
@@ -1009,19 +1009,19 @@ void LLPanelFace::alignTestureLayer()
void LLPanelFace::getState()
{
- updateUI();
+ updateUI();
}
void LLPanelFace::updateUI(bool force_set_values /*false*/)
{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
- LLViewerObject* objectp = node ? node->getObject() : NULL;
+ LLViewerObject* objectp = node ? node->getObject() : NULL;
- if (objectp
- && objectp->getPCode() == LL_PCODE_VOLUME
- && objectp->permModify())
- {
- BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
+ if (objectp
+ && objectp->getPCode() == LL_PCODE_VOLUME
+ && objectp->permModify())
+ {
+ BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
BOOL attachment = objectp->isAttachment();
bool has_pbr_material;
@@ -1030,9 +1030,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
const bool has_material = !has_pbr_material;
- // only turn on auto-adjust button if there is a media renderer and the media is loaded
+ // only turn on auto-adjust button if there is a media renderer and the media is loaded
childSetEnabled("button align", editable);
-
+
if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
{
// When selecting an object with a pbr and UI combo is not set,
@@ -1069,8 +1069,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
static S32 selected_te = -1;
static LLUUID prev_obj_id;
- if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) &&
- !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) &&
+ !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
{
S32 new_selection = -1; // Don't use getLastSelectedTE, it could have been deselected
S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
@@ -1093,11 +1093,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
mComboMatMedia->selectNthItem(MATMEDIA_PBR);
}
- else if (te_has_media)
+ else if (te_has_media)
{
mComboMatMedia->selectNthItem(MATMEDIA_MEDIA);
}
- else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull())
+ else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull())
{
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
@@ -1105,11 +1105,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
prev_obj_id = objectp->getID();
}
}
- else
+ else
{
if (prev_obj_id != objectp->getID())
{
- if (has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL))
+ if (has_pbr_material && (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL))
{
mComboMatMedia->selectNthItem(MATMEDIA_PBR);
}
@@ -1138,24 +1138,24 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR;
const bool texture_info_selected = pbr_selected && radio_pbr_type->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID;
- getChildView("checkbox_sync_settings")->setEnabled(editable);
- childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
+ getChildView("checkbox_sync_settings")->setEnabled(editable);
+ childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
- updateVisibility(objectp);
+ updateVisibility(objectp);
- // Color swatch
- {
- getChildView("color label")->setEnabled(editable);
- }
- LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
+ // Color swatch
+ {
+ getChildView("color label")->setEnabled(editable);
+ }
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
- LLColor4 color = LLColor4::white;
- bool identical_color = false;
+ LLColor4 color = LLColor4::white;
+ bool identical_color = false;
- if (color_swatch)
- {
- LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = color_swatch->get();
+ if (color_swatch)
+ {
+ LLSelectedTE::getColor(color, identical_color);
+ LLColor4 prev_color = color_swatch->get();
color_swatch->setOriginal(color);
color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
@@ -1163,179 +1163,179 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
color_swatch->setValid(editable && !has_pbr_material);
color_swatch->setEnabled( editable && !has_pbr_material);
color_swatch->setCanApplyImmediately( editable && !has_pbr_material);
- }
-
- // Color transparency
- getChildView("color trans")->setEnabled(editable);
-
- F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
- getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable && has_material);
-
- U8 shiny = 0;
- bool identical_shiny = false;
-
- // Shiny
- LLSelectedTE::getShiny(shiny, identical_shiny);
- identical = identical && identical_shiny;
-
- shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE;
-
- LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
- if (combobox_shininess)
- {
- combobox_shininess->selectNthItem((S32)shiny);
- }
-
- getChildView("label shininess")->setEnabled(editable);
- getChildView("combobox shininess")->setEnabled(editable);
-
- getChildView("label glossiness")->setEnabled(editable);
- getChildView("glossiness")->setEnabled(editable);
-
- getChildView("label environment")->setEnabled(editable);
- getChildView("environment")->setEnabled(editable);
- getChildView("label shinycolor")->setEnabled(editable);
-
- getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec);
- getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec);
- getChild<LLUICtrl>("environment")->setTentative(!identical_spec);
- getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
-
- LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
- if (mShinyColorSwatch)
- {
- mShinyColorSwatch->setValid(editable);
- mShinyColorSwatch->setEnabled( editable );
- mShinyColorSwatch->setCanApplyImmediately( editable );
- }
-
- U8 bumpy = 0;
- // Bumpy
- {
- bool identical_bumpy = false;
- LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
-
- LLUUID norm_map_id = getCurrentNormalMap();
- LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness");
-
- bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
-
- if (combobox_bumpiness)
- {
- combobox_bumpiness->selectNthItem((S32)bumpy);
- }
- else
- {
- LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL;
- }
-
- getChildView("combobox bumpiness")->setEnabled(editable);
- getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
- getChildView("label bumpiness")->setEnabled(editable);
- }
-
- // Texture
- {
- mIsAlpha = FALSE;
- LLGLenum image_format = GL_RGB;
- bool identical_image_format = false;
- LLSelectedTE::getImageFormat(image_format, identical_image_format);
-
- mIsAlpha = FALSE;
- switch (image_format)
- {
- case GL_RGBA:
- case GL_ALPHA:
- {
- mIsAlpha = TRUE;
- }
- break;
-
- case GL_RGB: break;
- default:
- {
- LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
- }
- break;
- }
-
- if (LLViewerMedia::getInstance()->textureHasMedia(id))
- {
- getChildView("button align")->setEnabled(editable);
- }
-
- // Diffuse Alpha Mode
-
- // Init to the default that is appropriate for the alpha content of the asset
- //
- U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-
- bool identical_alpha_mode = false;
-
- // See if that's been overridden by a material setting for same...
- //
- LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
-
- LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode");
- if (combobox_alphamode)
- {
- //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
- // Want masking? Want emissive? Tough! You get BLEND!
- alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode;
-
- // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none
- alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-
- combobox_alphamode->selectNthItem(alpha_mode);
- }
- else
- {
- LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL;
- }
-
- updateAlphaControls();
-
- if (texture_ctrl)
- {
- if (identical_diffuse)
- {
- texture_ctrl->setTentative(FALSE);
- texture_ctrl->setEnabled(editable && !has_pbr_material);
- texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
-
- texture_ctrl->setBakeTextureEnabled(TRUE);
- }
- else if (id.isNull())
- {
- // None selected
- texture_ctrl->setTentative(FALSE);
- texture_ctrl->setEnabled(FALSE);
- texture_ctrl->setImageAssetID(LLUUID::null);
- getChildView("combobox alphamode")->setEnabled(FALSE);
- getChildView("label alphamode")->setEnabled(FALSE);
- getChildView("maskcutoff")->setEnabled(FALSE);
- getChildView("label maskcutoff")->setEnabled(FALSE);
-
- texture_ctrl->setBakeTextureEnabled(false);
- }
- else
- {
- // Tentative: multiple selected with different textures
- texture_ctrl->setTentative(TRUE);
- texture_ctrl->setEnabled(editable && !has_pbr_material);
- texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
-
- texture_ctrl->setBakeTextureEnabled(TRUE);
- }
+ }
+
+ // Color transparency
+ getChildView("color trans")->setEnabled(editable);
+
+ F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
+ getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
+ getChildView("ColorTrans")->setEnabled(editable && has_material);
+
+ U8 shiny = 0;
+ bool identical_shiny = false;
+
+ // Shiny
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ identical = identical && identical_shiny;
+
+ shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE;
+
+ LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
+ if (combobox_shininess)
+ {
+ combobox_shininess->selectNthItem((S32)shiny);
+ }
+
+ getChildView("label shininess")->setEnabled(editable);
+ getChildView("combobox shininess")->setEnabled(editable);
+
+ getChildView("label glossiness")->setEnabled(editable);
+ getChildView("glossiness")->setEnabled(editable);
+
+ getChildView("label environment")->setEnabled(editable);
+ getChildView("environment")->setEnabled(editable);
+ getChildView("label shinycolor")->setEnabled(editable);
+
+ getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("environment")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
+
+ LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if (mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setValid(editable);
+ mShinyColorSwatch->setEnabled( editable );
+ mShinyColorSwatch->setCanApplyImmediately( editable );
+ }
+
+ U8 bumpy = 0;
+ // Bumpy
+ {
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
+
+ LLUUID norm_map_id = getCurrentNormalMap();
+ LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness");
+
+ bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
+
+ if (combobox_bumpiness)
+ {
+ combobox_bumpiness->selectNthItem((S32)bumpy);
+ }
+ else
+ {
+ LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL;
+ }
+
+ getChildView("combobox bumpiness")->setEnabled(editable);
+ getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
+ getChildView("label bumpiness")->setEnabled(editable);
+ }
+
+ // Texture
+ {
+ mIsAlpha = FALSE;
+ LLGLenum image_format = GL_RGB;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ mIsAlpha = FALSE;
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ mIsAlpha = TRUE;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
+ }
+ break;
+ }
+
+ if (LLViewerMedia::getInstance()->textureHasMedia(id))
+ {
+ getChildView("button align")->setEnabled(editable);
+ }
+
+ // Diffuse Alpha Mode
+
+ // Init to the default that is appropriate for the alpha content of the asset
+ //
+ U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ bool identical_alpha_mode = false;
+
+ // See if that's been overridden by a material setting for same...
+ //
+ LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
+
+ LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ // Want masking? Want emissive? Tough! You get BLEND!
+ alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode;
+
+ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none
+ alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
+ {
+ LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL;
+ }
+
+ updateAlphaControls();
+
+ if (texture_ctrl)
+ {
+ if (identical_diffuse)
+ {
+ texture_ctrl->setTentative(FALSE);
+ texture_ctrl->setEnabled(editable && !has_pbr_material);
+ texture_ctrl->setImageAssetID(id);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+
+ texture_ctrl->setBakeTextureEnabled(TRUE);
+ }
+ else if (id.isNull())
+ {
+ // None selected
+ texture_ctrl->setTentative(FALSE);
+ texture_ctrl->setEnabled(FALSE);
+ texture_ctrl->setImageAssetID(LLUUID::null);
+ getChildView("combobox alphamode")->setEnabled(FALSE);
+ getChildView("label alphamode")->setEnabled(FALSE);
+ getChildView("maskcutoff")->setEnabled(FALSE);
+ getChildView("label maskcutoff")->setEnabled(FALSE);
+
+ texture_ctrl->setBakeTextureEnabled(false);
+ }
+ else
+ {
+ // Tentative: multiple selected with different textures
+ texture_ctrl->setTentative(TRUE);
+ texture_ctrl->setEnabled(editable && !has_pbr_material);
+ texture_ctrl->setImageAssetID(id);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+
+ texture_ctrl->setBakeTextureEnabled(TRUE);
+ }
if (attachment)
{
@@ -1348,13 +1348,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
}
- }
+ }
- if (shinytexture_ctrl)
- {
- shinytexture_ctrl->setTentative( !identical_spec );
- shinytexture_ctrl->setEnabled( editable && !has_pbr_material);
- shinytexture_ctrl->setImageAssetID( specmap_id );
+ if (shinytexture_ctrl)
+ {
+ shinytexture_ctrl->setTentative( !identical_spec );
+ shinytexture_ctrl->setEnabled( editable && !has_pbr_material);
+ shinytexture_ctrl->setImageAssetID( specmap_id );
if (attachment)
{
@@ -1364,13 +1364,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
shinytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
}
- }
+ }
- if (bumpytexture_ctrl)
- {
- bumpytexture_ctrl->setTentative( !identical_norm );
- bumpytexture_ctrl->setEnabled( editable && !has_pbr_material);
- bumpytexture_ctrl->setImageAssetID( normmap_id );
+ if (bumpytexture_ctrl)
+ {
+ bumpytexture_ctrl->setTentative( !identical_norm );
+ bumpytexture_ctrl->setEnabled( editable && !has_pbr_material);
+ bumpytexture_ctrl->setImageAssetID( normmap_id );
if (attachment)
{
@@ -1380,292 +1380,292 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
bumpytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
}
- }
- }
-
- // planar align
- bool align_planar = false;
- bool identical_planar_aligned = false;
- {
- LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
- align_planar = (cb_planar_align && cb_planar_align->get());
-
- bool enabled = (editable && isIdenticalPlanarTexgen() && !texture_info_selected);
- childSetValue("checkbox planar align", align_planar && enabled);
+ }
+ }
+
+ // planar align
+ bool align_planar = false;
+ bool identical_planar_aligned = false;
+ {
+ LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
+ align_planar = (cb_planar_align && cb_planar_align->get());
+
+ bool enabled = (editable && isIdenticalPlanarTexgen() && !texture_info_selected);
+ childSetValue("checkbox planar align", align_planar && enabled);
childSetVisible("checkbox planar align", enabled);
- childSetEnabled("checkbox planar align", enabled);
- childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
-
- if (align_planar && enabled)
- {
- LLFace* last_face = NULL;
- bool identical_face = false;
- LLSelectedTE::getFace(last_face, identical_face);
-
- LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
- // this will determine if the texture param controls are tentative:
- identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
- }
- }
-
- // Needs to be public and before tex scale settings below to properly reflect
- // behavior when in planar vs default texgen modes in the
- // NORSPEC-84 et al
- //
- LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
- bool identical_texgen = true;
- bool identical_planar_texgen = false;
-
- {
- LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
- identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
- }
-
- // Texture scale
- {
- bool identical_diff_scale_s = false;
- bool identical_spec_scale_s = false;
- bool identical_norm_scale_s = false;
-
- identical = align_planar ? identical_planar_aligned : identical;
-
- F32 diff_scale_s = 1.f;
- F32 spec_scale_s = 1.f;
- F32 norm_scale_s = 1.f;
-
- LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s);
- LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s);
- LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s);
-
- diff_scale_s = editable ? diff_scale_s : 1.0f;
- diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
-
- norm_scale_s = editable ? norm_scale_s : 1.0f;
- norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
-
- spec_scale_s = editable ? spec_scale_s : 1.0f;
- spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
-
- getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s);
- getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
- getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
+ childSetEnabled("checkbox planar align", enabled);
+ childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
+
+ if (align_planar && enabled)
+ {
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+
+ LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
+ // this will determine if the texture param controls are tentative:
+ identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
+ }
+ }
+
+ // Needs to be public and before tex scale settings below to properly reflect
+ // behavior when in planar vs default texgen modes in the
+ // NORSPEC-84 et al
+ //
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = true;
+ bool identical_planar_texgen = false;
+
+ {
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+ }
+
+ // Texture scale
+ {
+ bool identical_diff_scale_s = false;
+ bool identical_spec_scale_s = false;
+ bool identical_norm_scale_s = false;
+
+ identical = align_planar ? identical_planar_aligned : identical;
+
+ F32 diff_scale_s = 1.f;
+ F32 spec_scale_s = 1.f;
+ F32 norm_scale_s = 1.f;
+
+ LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s);
+ LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s);
+ LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s);
+
+ diff_scale_s = editable ? diff_scale_s : 1.0f;
+ diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ norm_scale_s = editable ? norm_scale_s : 1.0f;
+ norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ spec_scale_s = editable ? spec_scale_s : 1.0f;
+ spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s);
+ getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
getChildView("TexScaleU")->setEnabled(editable && has_material);
getChildView("shinyScaleU")->setEnabled(editable && has_material && specmap_id.notNull());
getChildView("bumpyScaleU")->setEnabled(editable && has_material && normmap_id.notNull());
- BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
- BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
- BOOL spec_scale_tentative = !(identical && identical_spec_scale_s);
+ BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
+ BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
+ BOOL spec_scale_tentative = !(identical && identical_spec_scale_s);
- getChild<LLUICtrl>("TexScaleU")->setTentative( LLSD(diff_scale_tentative));
- getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));
- getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));
- }
+ getChild<LLUICtrl>("TexScaleU")->setTentative( LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));
+ }
- {
- bool identical_diff_scale_t = false;
- bool identical_spec_scale_t = false;
- bool identical_norm_scale_t = false;
+ {
+ bool identical_diff_scale_t = false;
+ bool identical_spec_scale_t = false;
+ bool identical_norm_scale_t = false;
- F32 diff_scale_t = 1.f;
- F32 spec_scale_t = 1.f;
- F32 norm_scale_t = 1.f;
+ F32 diff_scale_t = 1.f;
+ F32 spec_scale_t = 1.f;
+ F32 norm_scale_t = 1.f;
- LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t);
- LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t);
- LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t);
+ LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t);
+ LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t);
+ LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t);
- diff_scale_t = editable ? diff_scale_t : 1.0f;
- diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+ diff_scale_t = editable ? diff_scale_t : 1.0f;
+ diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
- norm_scale_t = editable ? norm_scale_t : 1.0f;
- norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+ norm_scale_t = editable ? norm_scale_t : 1.0f;
+ norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
- spec_scale_t = editable ? spec_scale_t : 1.0f;
- spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+ spec_scale_t = editable ? spec_scale_t : 1.0f;
+ spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
- BOOL diff_scale_tentative = !identical_diff_scale_t;
- BOOL norm_scale_tentative = !identical_norm_scale_t;
- BOOL spec_scale_tentative = !identical_spec_scale_t;
+ BOOL diff_scale_tentative = !identical_diff_scale_t;
+ BOOL norm_scale_tentative = !identical_norm_scale_t;
+ BOOL spec_scale_tentative = !identical_spec_scale_t;
getChildView("TexScaleV")->setEnabled(editable && has_material);
getChildView("shinyScaleV")->setEnabled(editable && has_material && specmap_id.notNull());
getChildView("bumpyScaleV")->setEnabled(editable && has_material && normmap_id.notNull());
- if (force_set_values)
- {
- getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(diff_scale_t);
- }
- else
- {
- getChild<LLSpinCtrl>("TexScaleV")->setValue(diff_scale_t);
- }
- getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t);
- getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t);
-
- getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative));
- getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative));
- getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));
- }
-
- // Texture offset
- {
- bool identical_diff_offset_s = false;
- bool identical_norm_offset_s = false;
- bool identical_spec_offset_s = false;
-
- F32 diff_offset_s = 0.0f;
- F32 norm_offset_s = 0.0f;
- F32 spec_offset_s = 0.0f;
-
- LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s);
- LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s);
- LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s);
-
- BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s);
- BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s);
- BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s);
-
- getChild<LLUICtrl>("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f);
- getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f);
- getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f);
-
- getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative));
- getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
- getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
+ if (force_set_values)
+ {
+ getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(diff_scale_t);
+ }
+ else
+ {
+ getChild<LLSpinCtrl>("TexScaleV")->setValue(diff_scale_t);
+ }
+ getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t);
+
+ getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));
+ }
+
+ // Texture offset
+ {
+ bool identical_diff_offset_s = false;
+ bool identical_norm_offset_s = false;
+ bool identical_spec_offset_s = false;
+
+ F32 diff_offset_s = 0.0f;
+ F32 norm_offset_s = 0.0f;
+ F32 spec_offset_s = 0.0f;
+
+ LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s);
+ LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s);
+ LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s);
+
+ BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s);
+ BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s);
+ BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s);
+
+ getChild<LLUICtrl>("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f);
+
+ getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative));
+ getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
+ getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
getChildView("TexOffsetU")->setEnabled(editable && has_material);
getChildView("shinyOffsetU")->setEnabled(editable && has_material && specmap_id.notNull());
getChildView("bumpyOffsetU")->setEnabled(editable && has_material && normmap_id.notNull());
- }
+ }
- {
- bool identical_diff_offset_t = false;
- bool identical_norm_offset_t = false;
- bool identical_spec_offset_t = false;
-
- F32 diff_offset_t = 0.0f;
- F32 norm_offset_t = 0.0f;
- F32 spec_offset_t = 0.0f;
+ {
+ bool identical_diff_offset_t = false;
+ bool identical_norm_offset_t = false;
+ bool identical_spec_offset_t = false;
- LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t);
- LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t);
- LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t);
+ F32 diff_offset_t = 0.0f;
+ F32 norm_offset_t = 0.0f;
+ F32 spec_offset_t = 0.0f;
- BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t);
- BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t);
- BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t);
+ LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t);
+ LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t);
+ LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t);
+
+ BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t);
+ BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t);
+ BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t);
- getChild<LLUICtrl>("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f);
- getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f);
- getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f);
+ getChild<LLUICtrl>("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f);
- getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative));
- getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
- getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
+ getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative));
+ getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
+ getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
getChildView("TexOffsetV")->setEnabled(editable && has_material);
getChildView("shinyOffsetV")->setEnabled(editable && has_material && specmap_id.notNull());
getChildView("bumpyOffsetV")->setEnabled(editable && has_material && normmap_id.notNull());
- }
+ }
- // Texture rotation
- {
- bool identical_diff_rotation = false;
- bool identical_norm_rotation = false;
- bool identical_spec_rotation = false;
+ // Texture rotation
+ {
+ bool identical_diff_rotation = false;
+ bool identical_norm_rotation = false;
+ bool identical_spec_rotation = false;
- F32 diff_rotation = 0.f;
- F32 norm_rotation = 0.f;
- F32 spec_rotation = 0.f;
+ F32 diff_rotation = 0.f;
+ F32 norm_rotation = 0.f;
+ F32 spec_rotation = 0.f;
- LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation);
- LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation);
- LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation);
+ LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation);
+ LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation);
+ LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation);
- BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation);
- BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation);
- BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation);
+ BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation);
+ BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation);
+ BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation);
- F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
- F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
- F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
+ F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
+ F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
+ F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
getChildView("TexRot")->setEnabled(editable && has_material);
getChildView("shinyRot")->setEnabled(editable && has_material && specmap_id.notNull());
getChildView("bumpyRot")->setEnabled(editable && has_material && normmap_id.notNull());
- getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
- getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
- getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative));
-
- getChild<LLUICtrl>("TexRot")->setValue( editable ? diff_rot_deg : 0.0f);
- getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f);
- getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);
- }
-
- {
- F32 glow = 0.f;
- bool identical_glow = false;
- LLSelectedTE::getGlow(glow,identical_glow);
- getChild<LLUICtrl>("glow")->setValue(glow);
- getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
- getChildView("glow")->setEnabled(editable);
- getChildView("glow label")->setEnabled(editable);
- }
-
- {
- LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");
- if (combobox_texgen)
- {
- // Maps from enum to combobox entry index
- combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
- }
- else
- {
- LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL;
- }
-
- getChildView("combobox texgen")->setEnabled(editable);
- getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
- getChildView("tex gen")->setEnabled(editable);
- }
-
- {
- U8 fullbright_flag = 0;
- bool identical_fullbright = false;
-
- LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
-
- getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
- getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material);
- getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
+ getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
+ getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
+ getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative));
+
+ getChild<LLUICtrl>("TexRot")->setValue( editable ? diff_rot_deg : 0.0f);
+ getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f);
+ getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);
+ }
+
+ {
+ F32 glow = 0.f;
+ bool identical_glow = false;
+ LLSelectedTE::getGlow(glow,identical_glow);
+ getChild<LLUICtrl>("glow")->setValue(glow);
+ getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
+ getChildView("glow")->setEnabled(editable);
+ getChildView("glow label")->setEnabled(editable);
+ }
+
+ {
+ LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");
+ if (combobox_texgen)
+ {
+ // Maps from enum to combobox entry index
+ combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
+ }
+ else
+ {
+ LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL;
+ }
+
+ getChildView("combobox texgen")->setEnabled(editable);
+ getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
+ getChildView("tex gen")->setEnabled(editable);
+ }
+
+ {
+ U8 fullbright_flag = 0;
+ bool identical_fullbright = false;
+
+ LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
+
+ getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
+ getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material);
+ getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
mComboMatMedia->setEnabledByValue("Materials", !has_pbr_material);
- }
-
- // Repeats per meter
- {
- F32 repeats_diff = 1.f;
- F32 repeats_norm = 1.f;
- F32 repeats_spec = 1.f;
-
- bool identical_diff_repeats = false;
- bool identical_norm_repeats = false;
- bool identical_spec_repeats = false;
-
- LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats);
- LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats);
- LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);
-
- LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
- if (mComboTexGen)
- {
- S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
+ }
+
+ // Repeats per meter
+ {
+ F32 repeats_diff = 1.f;
+ F32 repeats_norm = 1.f;
+ F32 repeats_spec = 1.f;
+
+ bool identical_diff_repeats = false;
+ bool identical_norm_repeats = false;
+ bool identical_spec_repeats = false;
+
+ LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats);
+ LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats);
+ LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);
+
+ LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
+ if (mComboTexGen)
+ {
+ S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
bool enabled = editable && (index != 1);
bool identical_repeats = true;
S32 material_selection = mComboMatMedia->getCurrentIndex();
- F32 repeats = 1.0f;
+ F32 repeats = 1.0f;
U32 material_type = MATTYPE_DIFFUSE;
if (material_selection == MATMEDIA_MATERIAL)
@@ -1715,194 +1715,195 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
break;
}
- BOOL repeats_tentative = !identical_repeats;
-
- LLSpinCtrl* rpt_ctrl = getChild<LLSpinCtrl>("rptctrl");
- if (force_set_values)
- {
- //onCommit, previosly edited element updates related ones
- rpt_ctrl->forceSetValue(editable ? repeats : 1.0f);
- }
- else
- {
- rpt_ctrl->setValue(editable ? repeats : 1.0f);
- }
- rpt_ctrl->setTentative(LLSD(repeats_tentative));
+ BOOL repeats_tentative = !identical_repeats;
+
+ LLSpinCtrl* rpt_ctrl = getChild<LLSpinCtrl>("rptctrl");
+ if (force_set_values)
+ {
+ //onCommit, previosly edited element updates related ones
+ rpt_ctrl->forceSetValue(editable ? repeats : 1.0f);
+ }
+ else
+ {
+ rpt_ctrl->setValue(editable ? repeats : 1.0f);
+ }
+ rpt_ctrl->setTentative(LLSD(repeats_tentative));
rpt_ctrl->setEnabled(has_material && !identical_planar_texgen && enabled);
- }
- }
+ }
+ }
- // Materials
- {
- LLMaterialPtr material;
- LLSelectedTEMaterial::getCurrent(material, identical);
+ // Materials
+ {
+ LLMaterialPtr material;
+ LLSelectedTEMaterial::getCurrent(material, identical);
if (material && editable)
- {
- LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL;
-
- // Alpha
- LLCtrlSelectionInterface* combobox_alphamode =
- childGetSelectionInterface("combobox alphamode");
- if (combobox_alphamode)
- {
- U32 alpha_mode = material->getDiffuseAlphaMode();
-
- if (transparency > 0.f)
- { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
- alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
- }
-
- if (!mIsAlpha)
- { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
- alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
- }
-
- combobox_alphamode->selectNthItem(alpha_mode);
- }
- else
- {
- LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL;
- }
- getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
- updateAlphaControls();
-
- identical_planar_texgen = isIdenticalPlanarTexgen();
-
- // Shiny (specular)
- F32 offset_x, offset_y, repeat_x, repeat_y, rot;
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
- texture_ctrl->setImageAssetID(material->getSpecularID());
-
- if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
- {
- material->getSpecularOffset(offset_x,offset_y);
- material->getSpecularRepeat(repeat_x,repeat_y);
-
- if (identical_planar_texgen)
- {
- repeat_x *= 2.0f;
- repeat_y *= 2.0f;
- }
-
- rot = material->getSpecularRotation();
- getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
- getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
- getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
- getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
- getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
- getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent());
- getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
-
- updateShinyControls(!material->getSpecularID().isNull(), true);
- }
-
- // Assert desired colorswatch color to match material AFTER updateShinyControls
- // to avoid getting overwritten with the default on some UI state changes.
- //
- if (!material->getSpecularID().isNull())
- {
- LLColorSwatchCtrl* shiny_swatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
- LLColor4 new_color = material->getSpecularLightColor();
- LLColor4 old_color = shiny_swatch->get();
-
- shiny_swatch->setOriginal(new_color);
- shiny_swatch->set(new_color, force_set_values || old_color != new_color || !editable);
- }
-
- // Bumpy (normal)
- texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- texture_ctrl->setImageAssetID(material->getNormalID());
-
- if (!material->getNormalID().isNull())
- {
- material->getNormalOffset(offset_x,offset_y);
- material->getNormalRepeat(repeat_x,repeat_y);
-
- if (identical_planar_texgen)
- {
- repeat_x *= 2.0f;
- repeat_y *= 2.0f;
- }
-
- rot = material->getNormalRotation();
- getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
- getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
- getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
- getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
- getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
-
- updateBumpyControls(!material->getNormalID().isNull(), true);
- }
- }
- }
+ {
+ LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL;
+
+ // Alpha
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ U32 alpha_mode = material->getDiffuseAlphaMode();
+
+ if (transparency > 0.f)
+ { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (!mIsAlpha)
+ { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
+ {
+ LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL;
+ }
+ getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
+ updateAlphaControls();
+
+ identical_planar_texgen = isIdenticalPlanarTexgen();
+
+ // Shiny (specular)
+ F32 offset_x, offset_y, repeat_x, repeat_y, rot;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ texture_ctrl->setImageAssetID(material->getSpecularID());
+
+ if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
+ {
+ material->getSpecularOffset(offset_x,offset_y);
+ material->getSpecularRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getSpecularRotation();
+ getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
+ getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent());
+ getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
+ getChild<LLUICtrl>("mirror")->setValue(material->getEnvironmentIntensity());
+
+ updateShinyControls(!material->getSpecularID().isNull(), true);
+ }
+
+ // Assert desired colorswatch color to match material AFTER updateShinyControls
+ // to avoid getting overwritten with the default on some UI state changes.
+ //
+ if (!material->getSpecularID().isNull())
+ {
+ LLColorSwatchCtrl* shiny_swatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ LLColor4 new_color = material->getSpecularLightColor();
+ LLColor4 old_color = shiny_swatch->get();
+
+ shiny_swatch->setOriginal(new_color);
+ shiny_swatch->set(new_color, force_set_values || old_color != new_color || !editable);
+ }
+
+ // Bumpy (normal)
+ texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ texture_ctrl->setImageAssetID(material->getNormalID());
+
+ if (!material->getNormalID().isNull())
+ {
+ material->getNormalOffset(offset_x,offset_y);
+ material->getNormalRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getNormalRotation();
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
+
+ updateBumpyControls(!material->getNormalID().isNull(), true);
+ }
+ }
+ }
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
BOOL single_volume = (selected_count == 1);
mMenuClipboardColor->setEnabled(editable && single_volume);
- // Set variable values for numeric expressions
- LLCalc* calcp = LLCalc::getInstance();
- calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal());
- calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal());
- calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal());
- calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal());
- calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal());
- calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal());
- calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal());
- }
- else
- {
- // Disable all UICtrls
- clearCtrls();
-
- // Disable non-UICtrls
- LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ // Set variable values for numeric expressions
+ LLCalc* calcp = LLCalc::getInstance();
+ calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal());
+ calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal());
+ calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal());
+ calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal());
+ calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal());
+ calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal());
+ calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal());
+ }
+ else
+ {
+ // Disable all UICtrls
+ clearCtrls();
+
+ // Disable non-UICtrls
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (pbr_ctrl)
{
pbr_ctrl->setImageAssetID(LLUUID::null);
pbr_ctrl->setEnabled(FALSE);
}
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
- if (texture_ctrl)
- {
- texture_ctrl->setImageAssetID( LLUUID::null );
- texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
-// texture_ctrl->setValid(FALSE);
- }
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if (mColorSwatch)
- {
- mColorSwatch->setEnabled( FALSE );
- mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") );
- mColorSwatch->setValid(FALSE);
- }
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- if (radio_mat_type)
- {
- radio_mat_type->setSelectedIndex(0);
- }
- getChildView("color trans")->setEnabled(FALSE);
- getChildView("rptctrl")->setEnabled(FALSE);
- getChildView("tex gen")->setEnabled(FALSE);
- getChildView("label shininess")->setEnabled(FALSE);
- getChildView("label bumpiness")->setEnabled(FALSE);
- getChildView("button align")->setEnabled(FALSE);
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ if (texture_ctrl)
+ {
+ texture_ctrl->setImageAssetID( LLUUID::null );
+ texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
+// texture_ctrl->setValid(FALSE);
+ }
+ LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if (mColorSwatch)
+ {
+ mColorSwatch->setEnabled( FALSE );
+ mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") );
+ mColorSwatch->setValid(FALSE);
+ }
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ if (radio_mat_type)
+ {
+ radio_mat_type->setSelectedIndex(0);
+ }
+ getChildView("color trans")->setEnabled(FALSE);
+ getChildView("rptctrl")->setEnabled(FALSE);
+ getChildView("tex gen")->setEnabled(FALSE);
+ getChildView("label shininess")->setEnabled(FALSE);
+ getChildView("label bumpiness")->setEnabled(FALSE);
+ getChildView("button align")->setEnabled(FALSE);
getChildView("pbr_from_inventory")->setEnabled(FALSE);
getChildView("edit_selected_pbr")->setEnabled(FALSE);
getChildView("save_selected_pbr")->setEnabled(FALSE);
+
+ updateVisibility();
- updateVisibility();
-
- // Set variable values for numeric expressions
- LLCalc* calcp = LLCalc::getInstance();
- calcp->clearVar(LLCalc::TEX_U_SCALE);
- calcp->clearVar(LLCalc::TEX_V_SCALE);
- calcp->clearVar(LLCalc::TEX_U_OFFSET);
- calcp->clearVar(LLCalc::TEX_V_OFFSET);
- calcp->clearVar(LLCalc::TEX_ROTATION);
- calcp->clearVar(LLCalc::TEX_TRANSPARENCY);
- calcp->clearVar(LLCalc::TEX_GLOW);
- }
+ // Set variable values for numeric expressions
+ LLCalc* calcp = LLCalc::getInstance();
+ calcp->clearVar(LLCalc::TEX_U_SCALE);
+ calcp->clearVar(LLCalc::TEX_V_SCALE);
+ calcp->clearVar(LLCalc::TEX_U_OFFSET);
+ calcp->clearVar(LLCalc::TEX_V_OFFSET);
+ calcp->clearVar(LLCalc::TEX_ROTATION);
+ calcp->clearVar(LLCalc::TEX_TRANSPARENCY);
+ calcp->clearVar(LLCalc::TEX_GLOW);
+ }
}
// One-off listener that updates the build floater UI when the agent inventory adds or removes an item
@@ -1911,7 +1912,7 @@ class PBRPickerAgentListener : public LLInventoryObserver
protected:
bool mChangePending = true;
public:
- PBRPickerAgentListener() : LLInventoryObserver()
+ PBRPickerAgentListener() : LLInventoryObserver()
{
gInventory.addObserver(this);
}
@@ -1921,7 +1922,7 @@ public:
return mChangePending;
}
- void changed(U32 mask) override
+ void changed(U32 mask) override
{
if (!(mask & (ADD | REMOVE)))
{
@@ -2028,7 +2029,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
{
mVOInventoryListener = nullptr;
}
- if (!identical_pbr || pbr_id.isNull() || pbr_id == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)
+ if (!identical_pbr || pbr_id.isNull() || pbr_id == BLANK_MATERIAL_ASSET_ID)
{
mAgentInventoryListener = nullptr;
}
@@ -2091,8 +2092,8 @@ void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */)
void LLPanelFace::updateCopyTexButton()
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
- && !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
+ mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
+ && !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
&& (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)
&& LLMaterialEditor::canClipboardObjectsMaterial());
std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
@@ -2101,8 +2102,8 @@ void LLPanelFace::updateCopyTexButton()
void LLPanelFace::refresh()
{
- LL_DEBUGS("Materials") << LL_ENDL;
- getState();
+ LL_DEBUGS("Materials") << LL_ENDL;
+ getState();
}
void LLPanelFace::refreshMedia()
@@ -2223,7 +2224,7 @@ void LLPanelFace::refreshMedia()
// initial media title is the media URL (until we get the name)
media_title = media_data_get.getHomeURL();
}
- // else all faces might be empty.
+ // else all faces might be empty.
}
else // there' re Different Medias' been set on on the faces.
{
@@ -2295,19 +2296,19 @@ void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side)
//
void LLPanelFace::navigateToTitleMedia( const std::string url )
{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
if (impl)
@@ -2315,11 +2316,11 @@ void LLPanelFace::navigateToTitleMedia( const std::string url )
// if it's a page with a movie, we don't want to hear it
impl->setVolume(0);
};
- }
+ }
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
}
bool LLPanelFace::selectedMediaEditable()
@@ -2378,7 +2379,7 @@ void LLPanelFace::updateMediaSettings()
const LLMediaEntry default_media_data;
- // controls
+ // controls
U8 value_u8 = default_media_data.getControls();
struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
{
@@ -2867,58 +2868,58 @@ void LLPanelFace::updateMediaTitle()
// static
F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face)
{
- return (F32)(object->getTE(face)->getGlow());
+ return (F32)(object->getTE(face)->getGlow());
}
void LLPanelFace::onCommitColor(const LLSD& data)
{
- sendColor();
+ sendColor();
}
void LLPanelFace::onCommitShinyColor(const LLSD& data)
{
- LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+ LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
}
void LLPanelFace::onCommitAlpha(const LLSD& data)
{
- sendAlpha();
+ sendAlpha();
}
void LLPanelFace::onCancelColor(const LLSD& data)
{
- LLSelectMgr::getInstance()->selectionRevertColors();
+ LLSelectMgr::getInstance()->selectionRevertColors();
}
void LLPanelFace::onCancelShinyColor(const LLSD& data)
{
- LLSelectMgr::getInstance()->selectionRevertShinyColors();
+ LLSelectMgr::getInstance()->selectionRevertShinyColors();
}
void LLPanelFace::onSelectColor(const LLSD& data)
{
- LLSelectMgr::getInstance()->saveSelectedObjectColors();
- sendColor();
+ LLSelectMgr::getInstance()->saveSelectedObjectColors();
+ sendColor();
}
void LLPanelFace::onSelectShinyColor(const LLSD& data)
{
- LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
- LLSelectMgr::getInstance()->saveSelectedShinyColors();
+ LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+ LLSelectMgr::getInstance()->saveSelectedShinyColors();
}
// static
void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- // Force to default states to side-step problems with menu contents
- // and generally reflecting old state when switching tabs or objects
- //
- self->updateShinyControls(false,true);
- self->updateBumpyControls(false,true);
- self->updateUI();
- self->refreshMedia();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
+ self->updateUI();
+ self->refreshMedia();
}
void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */)
@@ -2927,18 +2928,18 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */)
LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
LLComboBox* combo_shininess = findChild<LLComboBox>("combobox shininess");
LLComboBox* combo_bumpiness = findChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
- {
- LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
- return;
- }
- U32 materials_media = mComboMatMedia->getCurrentIndex();
- U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
+ {
+ LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
+ return;
+ }
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ U32 material_type = radio_mat_type->getSelectedIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
bool show_material = materials_media == MATMEDIA_MATERIAL;
- bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
- bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
- bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
@@ -2952,62 +2953,62 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */)
getChildView("combobox texgen")->setVisible(show_material || show_media || show_pbr_asset);
getChildView("button align textures")->setVisible(show_material || show_media);
- // Media controls
+ // Media controls
mTitleMediaText->setVisible(show_media);
- getChildView("add_media")->setVisible(show_media);
- getChildView("delete_media")->setVisible(show_media);
- getChildView("button align")->setVisible(show_media);
-
- // Diffuse texture controls
- getChildView("texture control")->setVisible(show_texture && show_material);
- getChildView("label alphamode")->setVisible(show_texture && show_material);
- getChildView("combobox alphamode")->setVisible(show_texture && show_material);
- getChildView("label maskcutoff")->setVisible(false);
- getChildView("maskcutoff")->setVisible(false);
- if (show_texture && show_material)
- {
- updateAlphaControls();
- }
+ getChildView("add_media")->setVisible(show_media);
+ getChildView("delete_media")->setVisible(show_media);
+ getChildView("button align")->setVisible(show_media);
+
+ // Diffuse texture controls
+ getChildView("texture control")->setVisible(show_texture && show_material);
+ getChildView("label alphamode")->setVisible(show_texture && show_material);
+ getChildView("combobox alphamode")->setVisible(show_texture && show_material);
+ getChildView("label maskcutoff")->setVisible(false);
+ getChildView("maskcutoff")->setVisible(false);
+ if (show_texture && show_material)
+ {
+ updateAlphaControls();
+ }
// texture scale and position controls
- getChildView("TexScaleU")->setVisible(show_texture);
- getChildView("TexScaleV")->setVisible(show_texture);
- getChildView("TexRot")->setVisible(show_texture);
- getChildView("TexOffsetU")->setVisible(show_texture);
- getChildView("TexOffsetV")->setVisible(show_texture);
-
- // Specular map controls
- getChildView("shinytexture control")->setVisible(show_shininess);
- getChildView("combobox shininess")->setVisible(show_shininess);
- getChildView("label shininess")->setVisible(show_shininess);
- getChildView("label glossiness")->setVisible(false);
- getChildView("glossiness")->setVisible(false);
- getChildView("label environment")->setVisible(false);
- getChildView("environment")->setVisible(false);
- getChildView("label shinycolor")->setVisible(false);
- getChildView("shinycolorswatch")->setVisible(false);
- if (show_shininess)
- {
- updateShinyControls();
- }
- getChildView("shinyScaleU")->setVisible(show_shininess);
- getChildView("shinyScaleV")->setVisible(show_shininess);
- getChildView("shinyRot")->setVisible(show_shininess);
- getChildView("shinyOffsetU")->setVisible(show_shininess);
- getChildView("shinyOffsetV")->setVisible(show_shininess);
-
- // Normal map controls
- if (show_bumpiness)
- {
- updateBumpyControls();
- }
- getChildView("bumpytexture control")->setVisible(show_bumpiness);
- getChildView("combobox bumpiness")->setVisible(show_bumpiness);
- getChildView("label bumpiness")->setVisible(show_bumpiness);
- getChildView("bumpyScaleU")->setVisible(show_bumpiness);
- getChildView("bumpyScaleV")->setVisible(show_bumpiness);
- getChildView("bumpyRot")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
+ getChildView("TexScaleU")->setVisible(show_texture);
+ getChildView("TexScaleV")->setVisible(show_texture);
+ getChildView("TexRot")->setVisible(show_texture);
+ getChildView("TexOffsetU")->setVisible(show_texture);
+ getChildView("TexOffsetV")->setVisible(show_texture);
+
+ // Specular map controls
+ getChildView("shinytexture control")->setVisible(show_shininess);
+ getChildView("combobox shininess")->setVisible(show_shininess);
+ getChildView("label shininess")->setVisible(show_shininess);
+ getChildView("label glossiness")->setVisible(false);
+ getChildView("glossiness")->setVisible(false);
+ getChildView("label environment")->setVisible(false);
+ getChildView("environment")->setVisible(false);
+ getChildView("label shinycolor")->setVisible(false);
+ getChildView("shinycolorswatch")->setVisible(false);
+ if (show_shininess)
+ {
+ updateShinyControls();
+ }
+ getChildView("shinyScaleU")->setVisible(show_shininess);
+ getChildView("shinyScaleV")->setVisible(show_shininess);
+ getChildView("shinyRot")->setVisible(show_shininess);
+ getChildView("shinyOffsetU")->setVisible(show_shininess);
+ getChildView("shinyOffsetV")->setVisible(show_shininess);
+
+ // Normal map controls
+ if (show_bumpiness)
+ {
+ updateBumpyControls();
+ }
+ getChildView("bumpytexture control")->setVisible(show_bumpiness);
+ getChildView("combobox bumpiness")->setVisible(show_bumpiness);
+ getChildView("label bumpiness")->setVisible(show_bumpiness);
+ getChildView("bumpyScaleU")->setVisible(show_bumpiness);
+ getChildView("bumpyScaleV")->setVisible(show_bumpiness);
+ getChildView("bumpyRot")->setVisible(show_bumpiness);
+ getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
+ getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
getChild<LLSpinCtrl>("rptctrl")->setVisible(show_material || show_media);
@@ -3019,11 +3020,11 @@ void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */)
void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- // Force to default states to side-step problems with menu contents
- // and generally reflecting old state when switching tabs or objects
- //
- self->updateShinyControls(false,true);
- self->updateBumpyControls(false,true);
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
self->updateUI();
}
@@ -3040,149 +3041,149 @@ void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
+ LLPanelFace* self = (LLPanelFace*) userdata;
- LLComboBox* mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness");
- if(!mComboBumpiness)
- return;
+ LLComboBox* mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness");
+ if(!mComboBumpiness)
+ return;
- U32 bumpiness = mComboBumpiness->getCurrentIndex();
+ U32 bumpiness = mComboBumpiness->getCurrentIndex();
- self->sendBump(bumpiness);
+ self->sendBump(bumpiness);
}
// static
void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendTexGen();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->sendTexGen();
}
// static
void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox)
{
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
- LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID();
- LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL;
- LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess");
-
- if(mess_with_shiny_combobox)
- {
- if (!comboShiny)
- {
- return;
- }
- if (!shiny_texture_ID.isNull() && is_setting_texture)
- {
- if (!comboShiny->itemExists(USE_TEXTURE))
- {
- comboShiny->add(USE_TEXTURE);
- }
- comboShiny->setSimple(USE_TEXTURE);
- }
- else
- {
- if (comboShiny->itemExists(USE_TEXTURE))
- {
- comboShiny->remove(SHINY_TEXTURE);
- comboShiny->selectFirstItem();
- }
- }
- }
- else
- {
- if (shiny_texture_ID.isNull() && comboShiny && comboShiny->itemExists(USE_TEXTURE))
- {
- comboShiny->remove(SHINY_TEXTURE);
- comboShiny->selectFirstItem();
- }
- }
-
-
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = mComboMatMedia->getCurrentIndex();
- U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_material = (materials_media == MATMEDIA_MATERIAL);
- bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
- U32 shiny_value = comboShiny->getCurrentIndex();
- bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
- getChildView("label glossiness")->setVisible(show_shinyctrls);
- getChildView("glossiness")->setVisible(show_shinyctrls);
- getChildView("label environment")->setVisible(show_shinyctrls);
- getChildView("environment")->setVisible(show_shinyctrls);
- getChildView("label shinycolor")->setVisible(show_shinyctrls);
- getChildView("shinycolorswatch")->setVisible(show_shinyctrls);
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL;
+ LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess");
+
+ if(mess_with_shiny_combobox)
+ {
+ if (!comboShiny)
+ {
+ return;
+ }
+ if (!shiny_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->add(USE_TEXTURE);
+ }
+ comboShiny->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->remove(SHINY_TEXTURE);
+ comboShiny->selectFirstItem();
+ }
+ }
+ }
+ else
+ {
+ if (shiny_texture_ID.isNull() && comboShiny && comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->remove(SHINY_TEXTURE);
+ comboShiny->selectFirstItem();
+ }
+ }
+
+
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ U32 material_type = radio_mat_type->getSelectedIndex();
+ bool show_material = (materials_media == MATMEDIA_MATERIAL);
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ U32 shiny_value = comboShiny->getCurrentIndex();
+ bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
+ getChildView("label glossiness")->setVisible(show_shinyctrls);
+ getChildView("glossiness")->setVisible(show_shinyctrls);
+ getChildView("label environment")->setVisible(show_shinyctrls);
+ getChildView("environment")->setVisible(show_shinyctrls);
+ getChildView("label shinycolor")->setVisible(show_shinyctrls);
+ getChildView("shinycolorswatch")->setVisible(show_shinyctrls);
}
// static
void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox)
{
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
- LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
- LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness");
- if (!comboBumpy)
- {
- return;
- }
-
- if (mess_with_combobox)
- {
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
- LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
-
- if (!bumpy_texture_ID.isNull() && is_setting_texture)
- {
- if (!comboBumpy->itemExists(USE_TEXTURE))
- {
- comboBumpy->add(USE_TEXTURE);
- }
- comboBumpy->setSimple(USE_TEXTURE);
- }
- else
- {
- if (comboBumpy->itemExists(USE_TEXTURE))
- {
- comboBumpy->remove(BUMPY_TEXTURE);
- comboBumpy->selectFirstItem();
- }
- }
- }
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+ LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness");
+ if (!comboBumpy)
+ {
+ return;
+ }
+
+ if (mess_with_combobox)
+ {
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+
+ if (!bumpy_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->add(USE_TEXTURE);
+ }
+ comboBumpy->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->remove(BUMPY_TEXTURE);
+ comboBumpy->selectFirstItem();
+ }
+ }
+ }
}
// static
void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
+ LLPanelFace* self = (LLPanelFace*) userdata;
- LLComboBox* mComboShininess = self->getChild<LLComboBox>("combobox shininess");
- if(!mComboShininess)
- return;
-
- U32 shininess = mComboShininess->getCurrentIndex();
+ LLComboBox* mComboShininess = self->getChild<LLComboBox>("combobox shininess");
+ if(!mComboShininess)
+ return;
+
+ U32 shininess = mComboShininess->getCurrentIndex();
- self->sendShiny(shininess);
+ self->sendShiny(shininess);
}
// static
void LLPanelFace::updateAlphaControls()
{
- LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode");
- if (!comboAlphaMode)
- {
- return;
- }
- U32 alpha_value = comboAlphaMode->getCurrentIndex();
- bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
-
+ LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode");
+ if (!comboAlphaMode)
+ {
+ return;
+ }
+ U32 alpha_value = comboAlphaMode->getCurrentIndex();
+ bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
+
U32 mat_media = MATMEDIA_MATERIAL;
if (mComboMatMedia)
{
mat_media = mComboMatMedia->getCurrentIndex();
}
-
+
U32 mat_type = MATTYPE_DIFFUSE;
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
@@ -3192,31 +3193,31 @@ void LLPanelFace::updateAlphaControls()
show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL);
show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE);
-
- getChildView("label maskcutoff")->setVisible(show_alphactrls);
- getChildView("maskcutoff")->setVisible(show_alphactrls);
+
+ getChildView("label maskcutoff")->setVisible(show_alphactrls);
+ getChildView("maskcutoff")->setVisible(show_alphactrls);
}
// static
void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->updateAlphaControls();
- LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->updateAlphaControls();
+ LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());
}
// static
void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendFullbright();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->sendFullbright();
}
// static
void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendGlow();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->sendGlow();
}
// static
@@ -3305,102 +3306,102 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
void LLPanelFace::onCommitTexture( const LLSD& data )
{
- add(LLStatViewer::EDIT_TEXTURE, 1);
- sendTexture();
+ add(LLStatViewer::EDIT_TEXTURE, 1);
+ sendTexture();
}
void LLPanelFace::onCancelTexture(const LLSD& data)
{
- LLSelectMgr::getInstance()->selectionRevertTextures();
+ LLSelectMgr::getInstance()->selectionRevertTextures();
}
void LLPanelFace::onSelectTexture(const LLSD& data)
{
- LLSelectMgr::getInstance()->saveSelectedObjectTextures();
- sendTexture();
-
- LLGLenum image_format;
- bool identical_image_format = false;
- LLSelectedTE::getImageFormat(image_format, identical_image_format);
-
- LLCtrlSelectionInterface* combobox_alphamode =
- childGetSelectionInterface("combobox alphamode");
-
- U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
- if (combobox_alphamode)
- {
- switch (image_format)
- {
- case GL_RGBA:
- case GL_ALPHA:
- {
- alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
- }
- break;
-
- case GL_RGB: break;
- default:
- {
- LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
- }
- break;
- }
-
- combobox_alphamode->selectNthItem(alpha_mode);
- }
- LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
+ LLSelectMgr::getInstance()->saveSelectedObjectTextures();
+ sendTexture();
+
+ LLGLenum image_format;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ if (combobox_alphamode)
+ {
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
+ }
+ break;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
}
void LLPanelFace::onCloseTexturePicker(const LLSD& data)
{
- LL_DEBUGS("Materials") << data << LL_ENDL;
- updateUI();
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ updateUI();
}
void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
{
- LL_DEBUGS("Materials") << data << LL_ENDL;
- sendShiny(SHINY_TEXTURE);
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
}
void LLPanelFace::onCommitNormalTexture( const LLSD& data )
{
- LL_DEBUGS("Materials") << data << LL_ENDL;
- LLUUID nmap_id = getCurrentNormalMap();
- sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
void LLPanelFace::onCancelSpecularTexture(const LLSD& data)
{
- U8 shiny = 0;
- bool identical_shiny = false;
- LLSelectedTE::getShiny(shiny, identical_shiny);
- LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();
- shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE;
- sendShiny(shiny);
+ U8 shiny = 0;
+ bool identical_shiny = false;
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();
+ shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE;
+ sendShiny(shiny);
}
void LLPanelFace::onCancelNormalTexture(const LLSD& data)
{
- U8 bumpy = 0;
- bool identical_bumpy = false;
- LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
- LLUUID spec_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();
- bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
- sendBump(bumpy);
+ U8 bumpy = 0;
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
+ LLUUID spec_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();
+ bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
+ sendBump(bumpy);
}
void LLPanelFace::onSelectSpecularTexture(const LLSD& data)
{
- LL_DEBUGS("Materials") << data << LL_ENDL;
- sendShiny(SHINY_TEXTURE);
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
}
void LLPanelFace::onSelectNormalTexture(const LLSD& data)
{
- LL_DEBUGS("Materials") << data << LL_ENDL;
- LLUUID nmap_id = getCurrentNormalMap();
- sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
//////////////////////////////////////////////////////////////////////////////
@@ -3477,212 +3478,212 @@ bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const L
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
- LLSelectedTEMaterial::setNormalOffsetX(self,offsetU);
- LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU);
- self->getChild<LLSpinCtrl>("TexOffsetU")->forceSetValue(offsetU);
- self->sendTextureInfo();
+ LLSelectedTEMaterial::setNormalOffsetX(self,offsetU);
+ LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU);
+ self->getChild<LLSpinCtrl>("TexOffsetU")->forceSetValue(offsetU);
+ self->sendTextureInfo();
}
//static
void LLPanelFace::syncOffsetY(LLPanelFace* self, F32 offsetV)
{
- LLSelectedTEMaterial::setNormalOffsetY(self,offsetV);
- LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV);
- self->getChild<LLSpinCtrl>("TexOffsetV")->forceSetValue(offsetV);
- self->sendTextureInfo();
+ LLSelectedTEMaterial::setNormalOffsetY(self,offsetV);
+ LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV);
+ self->getChild<LLSpinCtrl>("TexOffsetV")->forceSetValue(offsetV);
+ self->sendTextureInfo();
}
//static
void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetX(self,self->getCurrentBumpyOffsetU());
- }
- else
- {
- LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
- }
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetX(self,self->getCurrentBumpyOffsetU());
+ }
+ else
+ {
+ LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
+ }
}
//static
void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetY(self,self->getCurrentBumpyOffsetV());
- }
- else
- {
- LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
- }
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetY(self,self->getCurrentBumpyOffsetV());
+ }
+ else
+ {
+ LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
+ }
}
//static
void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetX(self, self->getCurrentShinyOffsetU());
- }
- else
- {
- LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
- }
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetX(self, self->getCurrentShinyOffsetU());
+ }
+ else
+ {
+ LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
+ }
}
//static
void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetY(self,self->getCurrentShinyOffsetV());
- }
- else
- {
- LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
- }
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetY(self,self->getCurrentShinyOffsetV());
+ }
+ else
+ {
+ LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
+ }
}
//static
void LLPanelFace::syncRepeatX(LLPanelFace* self, F32 scaleU)
{
- LLSelectedTEMaterial::setNormalRepeatX(self,scaleU);
- LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU);
- self->sendTextureInfo();
+ LLSelectedTEMaterial::setNormalRepeatX(self,scaleU);
+ LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU);
+ self->sendTextureInfo();
}
//static
void LLPanelFace::syncRepeatY(LLPanelFace* self, F32 scaleV)
{
- LLSelectedTEMaterial::setNormalRepeatY(self,scaleV);
- LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV);
- self->sendTextureInfo();
+ LLSelectedTEMaterial::setNormalRepeatY(self,scaleV);
+ LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV);
+ self->sendTextureInfo();
}
//static
void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- F32 bumpy_scale_u = self->getCurrentBumpyScaleU();
- if (self->isIdenticalPlanarTexgen())
- {
- bumpy_scale_u *= 0.5f;
- }
-
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU());
- syncRepeatX(self, bumpy_scale_u);
- }
- else
- {
- LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
- }
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_u = self->getCurrentBumpyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_u *= 0.5f;
+ }
+
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU());
+ syncRepeatX(self, bumpy_scale_u);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
+ }
}
//static
void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- F32 bumpy_scale_v = self->getCurrentBumpyScaleV();
- if (self->isIdenticalPlanarTexgen())
- {
- bumpy_scale_v *= 0.5f;
- }
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_v = self->getCurrentBumpyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_v *= 0.5f;
+ }
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV());
- syncRepeatY(self, bumpy_scale_v);
- }
- else
- {
- LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
- }
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV());
+ syncRepeatY(self, bumpy_scale_v);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
+ }
}
//static
void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- F32 shiny_scale_u = self->getCurrentShinyScaleU();
- if (self->isIdenticalPlanarTexgen())
- {
- shiny_scale_u *= 0.5f;
- }
-
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU());
- syncRepeatX(self, shiny_scale_u);
- }
- else
- {
- LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
- }
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_u = self->getCurrentShinyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_u *= 0.5f;
+ }
+
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU());
+ syncRepeatX(self, shiny_scale_u);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
+ }
}
//static
void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- F32 shiny_scale_v = self->getCurrentShinyScaleV();
- if (self->isIdenticalPlanarTexgen())
- {
- shiny_scale_v *= 0.5f;
- }
-
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV());
- syncRepeatY(self, shiny_scale_v);
- }
- else
- {
- LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
- }
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_v = self->getCurrentShinyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_v *= 0.5f;
+ }
+
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV());
+ syncRepeatY(self, shiny_scale_v);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
+ }
}
//static
void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot, int te)
{
- LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te);
- LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te);
- self->sendTextureInfo();
+ LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te);
+ LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te);
+ self->sendTextureInfo();
}
//static
void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentBumpyRot());
- syncMaterialRot(self, self->getCurrentBumpyRot());
- }
- else
- {
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentBumpyRot());
+ syncMaterialRot(self, self->getCurrentBumpyRot());
+ }
+ else
+ {
if ((bool)self->childGetValue("checkbox planar align").asBoolean())
{
LLFace* last_face = NULL;
@@ -3695,22 +3696,22 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
{
LLSelectedTEMaterial::setNormalRotation(self, self->getCurrentBumpyRot() * DEG_TO_RAD);
}
- }
+ }
}
//static
void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentShinyRot());
- syncMaterialRot(self, self->getCurrentShinyRot());
- }
- else
- {
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ self->getChild<LLSpinCtrl>("TexRot")->forceSetValue(self->getCurrentShinyRot());
+ syncMaterialRot(self, self->getCurrentShinyRot());
+ }
+ else
+ {
if ((bool)self->childGetValue("checkbox planar align").asBoolean())
{
LLFace* last_face = NULL;
@@ -3723,136 +3724,136 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
{
LLSelectedTEMaterial::setSpecularRotation(self, self->getCurrentShinyRot() * DEG_TO_RAD);
}
- }
+ }
}
//static
void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness());
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness());
}
//static
void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- llassert_always(self);
- LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity());
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity());
}
//static
void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff());
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff());
}
// static
void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendTextureInfo();
- // vertical scale and repeats per meter depends on each other, so force set on changes
- self->updateUI(true);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->sendTextureInfo();
+ // vertical scale and repeats per meter depends on each other, so force set on changes
+ self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureScaleX( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- F32 bumpy_scale_u = self->getChild<LLUICtrl>("TexScaleU")->getValue().asReal();
- if (self->isIdenticalPlanarTexgen())
- {
- bumpy_scale_u *= 0.5f;
- }
- syncRepeatX(self, bumpy_scale_u);
- }
- else
- {
- self->sendTextureInfo();
- }
- self->updateUI(true);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ F32 bumpy_scale_u = self->getChild<LLUICtrl>("TexScaleU")->getValue().asReal();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_u *= 0.5f;
+ }
+ syncRepeatX(self, bumpy_scale_u);
+ }
+ else
+ {
+ self->sendTextureInfo();
+ }
+ self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureScaleY( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- F32 bumpy_scale_v = self->getChild<LLUICtrl>("TexScaleV")->getValue().asReal();
- if (self->isIdenticalPlanarTexgen())
- {
- bumpy_scale_v *= 0.5f;
- }
- syncRepeatY(self, bumpy_scale_v);
- }
- else
- {
- self->sendTextureInfo();
- }
- self->updateUI(true);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ F32 bumpy_scale_v = self->getChild<LLUICtrl>("TexScaleV")->getValue().asReal();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_v *= 0.5f;
+ }
+ syncRepeatY(self, bumpy_scale_v);
+ }
+ else
+ {
+ self->sendTextureInfo();
+ }
+ self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureRot( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
+ LLPanelFace* self = (LLPanelFace*) userdata;
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncMaterialRot(self, self->getChild<LLUICtrl>("TexRot")->getValue().asReal());
- }
- else
- {
- self->sendTextureInfo();
- }
- self->updateUI(true);
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncMaterialRot(self, self->getChild<LLUICtrl>("TexRot")->getValue().asReal());
+ }
+ else
+ {
+ self->sendTextureInfo();
+ }
+ self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureOffsetX( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetX(self, self->getChild<LLUICtrl>("TexOffsetU")->getValue().asReal());
- }
- else
- {
- self->sendTextureInfo();
- }
- self->updateUI(true);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetX(self, self->getChild<LLUICtrl>("TexOffsetU")->getValue().asReal());
+ }
+ else
+ {
+ self->sendTextureInfo();
+ }
+ self->updateUI(true);
}
// static
void LLPanelFace::onCommitTextureOffsetY( LLUICtrl* ctrl, void* userdata )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- syncOffsetY(self, self->getChild<LLUICtrl>("TexOffsetV")->getValue().asReal());
- }
- else
- {
- self->sendTextureInfo();
- }
- self->updateUI(true);
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ syncOffsetY(self, self->getChild<LLUICtrl>("TexOffsetV")->getValue().asReal());
+ }
+ else
+ {
+ self->sendTextureInfo();
+ }
+ self->updateUI(true);
}
// Commit the number of repeats per meter
// static
void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
-
- LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
-
- U32 materials_media = self->mComboMatMedia->getCurrentIndex();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+
+ LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
+
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
U32 material_type = 0;
if (materials_media == MATMEDIA_PBR)
{
@@ -3865,126 +3866,126 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
material_type = radio_mat_type->getSelectedIndex();
}
- F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
-
+ F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
+
F32 obj_scale_s = 1.0f;
F32 obj_scale_t = 1.0f;
- bool identical_scale_s = false;
- bool identical_scale_t = false;
-
- LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
- LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
-
- LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
- LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
- LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
- LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
-
- if (gSavedSettings.getBOOL("SyncMaterialSettings"))
- {
- LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
-
- bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
- bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
-
- LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
- LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
-
- shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
- shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
-
- LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
- LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
- }
- else
- {
- switch (material_type)
- {
- case MATTYPE_DIFFUSE:
- {
- LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
- }
- break;
-
- case MATTYPE_NORMAL:
- {
- bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
- bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
-
- LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
- LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
- }
- break;
-
- case MATTYPE_SPECULAR:
- {
- shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
- shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
-
- LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
- LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
- }
- break;
-
- default:
- llassert(false);
- break;
- }
- }
- // vertical scale and repeats per meter depends on each other, so force set on changes
- self->updateUI(true);
+ bool identical_scale_s = false;
+ bool identical_scale_t = false;
+
+ LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
+ LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
+
+ LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
+ LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
+ LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
+ LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
+
+ if (gSavedSettings.getBOOL("SyncMaterialSettings"))
+ {
+ LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+
+ bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
+
+ shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ else
+ {
+ switch (material_type)
+ {
+ case MATTYPE_DIFFUSE:
+ {
+ LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+ }
+ break;
+
+ case MATTYPE_NORMAL:
+ {
+ bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
+
+ case MATTYPE_SPECULAR:
+ {
+ shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
+
+ default:
+ llassert(false);
+ break;
+ }
+ }
+ // vertical scale and repeats per meter depends on each other, so force set on changes
+ self->updateUI(true);
}
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
{
- virtual bool apply(LLViewerObject* object, S32 te)
- {
- viewer_media_t pMediaImpl;
-
- const LLTextureEntry* tep = object->getTE(te);
- const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
- if ( mep )
- {
- pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());
- }
-
- if ( pMediaImpl.isNull())
- {
- // If we didn't find face media for this face, check whether this face is showing parcel media.
- pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getID());
- }
-
- if ( pMediaImpl.notNull())
- {
- LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
- if(media)
- {
- S32 media_width = media->getWidth();
- S32 media_height = media->getHeight();
- S32 texture_width = media->getTextureWidth();
- S32 texture_height = media->getTextureHeight();
- F32 scale_s = (F32)media_width / (F32)texture_width;
- F32 scale_t = (F32)media_height / (F32)texture_height;
-
- // set scale and adjust offset
- object->setTEScaleS( te, scale_s );
- object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now.
- object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f );
- object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f );
- }
- }
- return true;
- };
+ virtual bool apply(LLViewerObject* object, S32 te)
+ {
+ viewer_media_t pMediaImpl;
+
+ const LLTextureEntry* tep = object->getTE(te);
+ const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+ if ( mep )
+ {
+ pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());
+ }
+
+ if ( pMediaImpl.isNull())
+ {
+ // If we didn't find face media for this face, check whether this face is showing parcel media.
+ pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getID());
+ }
+
+ if ( pMediaImpl.notNull())
+ {
+ LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
+ if(media)
+ {
+ S32 media_width = media->getWidth();
+ S32 media_height = media->getHeight();
+ S32 texture_width = media->getTextureWidth();
+ S32 texture_height = media->getTextureHeight();
+ F32 scale_s = (F32)media_width / (F32)texture_width;
+ F32 scale_t = (F32)media_height / (F32)texture_height;
+
+ // set scale and adjust offset
+ object->setTEScaleS( te, scale_s );
+ object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now.
+ object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f );
+ object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f );
+ }
+ }
+ return true;
+ };
};
void LLPanelFace::onClickAutoFix(void* userdata)
{
- LLPanelFaceSetMediaFunctor setfunc;
- LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+ LLPanelFaceSetMediaFunctor setfunc;
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
- LLPanelFaceSendFunctor sendfunc;
- LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
+ LLPanelFaceSendFunctor sendfunc;
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
void LLPanelFace::onAlignTexture(void* userdata)
@@ -4361,7 +4362,7 @@ void LLPanelFace::onCopyTexture()
{
te_data["te"]["itemfullperm"] = full_perm;
- te_data["te"]["fromlibrary"] = from_library;
+ te_data["te"]["fromlibrary"] = from_library;
// If full permission object, texture is free to copy,
// but otherwise we need to check inventory and extract permissions
@@ -4489,7 +4490,7 @@ void LLPanelFace::onPasteTexture()
}
// we can copy if single face was copied in edit face mode or if face count matches
- if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
&& compare_tes != clipboard.size())
{
LLSD notif_args;
@@ -4871,9 +4872,9 @@ bool LLPanelFace::menuEnableItem(const LLSD& userdata)
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->getState();
- self->sendTextureInfo();
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->getState();
+ self->sendTextureInfo();
}
void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit)
@@ -5122,54 +5123,54 @@ void LLPanelFace::onCommitGLTFTextureOffsetV(LLUICtrl* ctrl)
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
{
- LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
- LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
- if(!radio_mat_type)
- {
- return;
- }
- U32 mattype = radio_mat_type->getSelectedIndex();
- std::string which_control="texture control";
- switch (mattype)
- {
- case MATTYPE_SPECULAR:
- which_control = "shinytexture control";
- break;
- case MATTYPE_NORMAL:
- which_control = "bumpytexture control";
- break;
- // no default needed
- }
- LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL;
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);
- if (texture_ctrl)
- {
- LLUUID obj_owner_id;
- std::string obj_owner_name;
- LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
-
- LLSaleInfo sale_info;
- LLSelectMgr::instance().selectGetSaleInfo(sale_info);
-
- bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
- bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
- bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
- bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
-
- if (can_copy && can_transfer)
- {
- texture_ctrl->setCanApply(true, true);
- return;
- }
-
- // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
- texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
-
- if (gSavedSettings.getBOOL("TextureLivePreview"))
- {
- LLNotificationsUtil::add("LivePreviewUnavailable");
- }
- }
+ LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
+ if(!radio_mat_type)
+ {
+ return;
+ }
+ U32 mattype = radio_mat_type->getSelectedIndex();
+ std::string which_control="texture control";
+ switch (mattype)
+ {
+ case MATTYPE_SPECULAR:
+ which_control = "shinytexture control";
+ break;
+ case MATTYPE_NORMAL:
+ which_control = "bumpytexture control";
+ break;
+ // no default needed
+ }
+ LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);
+ if (texture_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+ if (can_copy && can_transfer)
+ {
+ texture_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailable");
+ }
+ }
}
void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
@@ -5209,81 +5210,81 @@ void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
bool LLPanelFace::isIdenticalPlanarTexgen()
{
- LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
- bool identical_texgen = false;
- LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
- return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = false;
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
}
void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face)
-{
- struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *>
- {
- LLFace* get(LLViewerObject* object, S32 te)
- {
- return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
- }
- } get_te_face_func;
- identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);
+{
+ struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *>
+ {
+ LLFace* get(LLViewerObject* object, S32 te)
+ {
+ return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
+ }
+ } get_te_face_func;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);
}
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)
{
- LLGLenum image_format;
- struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>
- {
- LLGLenum get(LLViewerObject* object, S32 te_index)
- {
- LLViewerTexture* image = object->getTEImage(te_index);
- return image ? image->getPrimaryFormat() : GL_RGB;
- }
- } get_glenum;
- identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format);
- image_format_to_return = image_format;
+ LLGLenum image_format;
+ struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>
+ {
+ LLGLenum get(LLViewerObject* object, S32 te_index)
+ {
+ LLViewerTexture* image = object->getTEImage(te_index);
+ return image ? image->getPrimaryFormat() : GL_RGB;
+ }
+ } get_glenum;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format);
+ image_format_to_return = image_format;
}
void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
-{
- struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID>
- {
- LLUUID get(LLViewerObject* object, S32 te_index)
- {
- LLTextureEntry *te = object->getTE(te_index);
- if (te)
- {
- if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER)
- || (te->getID() == IMG_USE_BAKED_LEFTARM) || (te->getID() == IMG_USE_BAKED_LEFTLEG) || (te->getID() == IMG_USE_BAKED_AUX1) || (te->getID() == IMG_USE_BAKED_AUX2) || (te->getID() == IMG_USE_BAKED_AUX3))
- {
- return te->getID();
- }
- }
-
- LLUUID id;
- LLViewerTexture* image = object->getTEImage(te_index);
- if (image)
- {
- id = image->getID();
- }
-
- if (!id.isNull() && LLViewerMedia::getInstance()->textureHasMedia(id))
- {
- if (te)
- {
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
- if(!tex)
- {
- tex = LLViewerFetchedTexture::sDefaultImagep;
- }
- if (tex)
- {
- id = tex->getID();
- }
- }
- }
- return id;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+{
+ struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ LLTextureEntry *te = object->getTE(te_index);
+ if (te)
+ {
+ if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER)
+ || (te->getID() == IMG_USE_BAKED_LEFTARM) || (te->getID() == IMG_USE_BAKED_LEFTLEG) || (te->getID() == IMG_USE_BAKED_AUX1) || (te->getID() == IMG_USE_BAKED_AUX2) || (te->getID() == IMG_USE_BAKED_AUX3))
+ {
+ return te->getID();
+ }
+ }
+
+ LLUUID id;
+ LLViewerTexture* image = object->getTEImage(te_index);
+ if (image)
+ {
+ id = image->getID();
+ }
+
+ if (!id.isNull() && LLViewerMedia::getInstance()->textureHasMedia(id))
+ {
+ if (te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ if (tex)
+ {
+ id = tex->getID();
+ }
+ }
+ }
+ return id;
+ }
+ } func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
}
void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bool& has_faces_with_pbr, bool& has_faces_without_pbr)
@@ -5316,7 +5317,7 @@ void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bo
{
mIdenticalId = false;
}
-
+
LLGLTFMaterial* te_override = object->getTE(te_index)->getGLTFMaterialOverride();
if (te_override)
{
@@ -5359,140 +5360,140 @@ void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bo
void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
{
- struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
- {
- LLMaterialPtr get(LLViewerObject* object, S32 te_index)
- {
- return object->getTE(te_index)->getMaterialParams();
- }
- } func;
- identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr);
+ struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
+ {
+ LLMaterialPtr get(LLViewerObject* object, S32 te_index)
+ {
+ return object->getTE(te_index)->getMaterialParams();
+ }
+ } func;
+ identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr);
}
void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical)
{
- struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
- U32 s_axis = VX;
- U32 t_axis = VY;
- F32 repeats_s = 1.0f;
- F32 repeats_t = 1.0f;
- if (mat)
- {
- mat->getSpecularRepeat(repeats_s, repeats_t);
- repeats_s /= object->getScale().mV[s_axis];
- repeats_t /= object->getScale().mV[t_axis];
- }
- return llmax(repeats_s, repeats_t);
- }
-
- } max_spec_repeats_func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats);
+ struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getSpecularRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_spec_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats);
}
void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical)
{
- struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
- U32 s_axis = VX;
- U32 t_axis = VY;
- F32 repeats_s = 1.0f;
- F32 repeats_t = 1.0f;
- if (mat)
- {
- mat->getNormalRepeat(repeats_s, repeats_t);
- repeats_s /= object->getScale().mV[s_axis];
- repeats_t /= object->getScale().mV[t_axis];
- }
- return llmax(repeats_s, repeats_t);
- }
-
- } max_norm_repeats_func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
+ struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getNormalRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_norm_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
}
void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha)
{
- struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
- {
- LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
- LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
- virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
-
- U8 get(LLViewerObject* object, S32 face)
- {
- U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-
- LLTextureEntry* tep = object->getTE(face);
- if (tep)
- {
- LLMaterial* mat = tep->getMaterialParams().get();
- if (mat)
- {
- diffuse_mode = mat->getDiffuseAlphaMode();
- }
- }
-
- return diffuse_mode;
- }
- bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
- } get_diff_mode(diffuse_texture_has_alpha);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
+ struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
+ {
+ LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
+ LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
+ virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ LLTextureEntry* tep = object->getTE(face);
+ if (tep)
+ {
+ LLMaterial* mat = tep->getMaterialParams().get();
+ if (mat)
+ {
+ diffuse_mode = mat->getDiffuseAlphaMode();
+ }
+ }
+
+ return diffuse_mode;
+ }
+ bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
+ } get_diff_mode(diffuse_texture_has_alpha);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
}
void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical)
-{
- struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- U32 s_axis = VX;
- U32 t_axis = VY;
- LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
- return object->getScale().mV[s_axis];
- }
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[s_axis];
+ }
- } scale_s_func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s );
+ } scale_s_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s );
}
void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical)
-{
- struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- U32 s_axis = VX;
- U32 t_axis = VY;
- LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
- return object->getScale().mV[t_axis];
- }
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[t_axis];
+ }
- } scale_t_func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t );
+ } scale_t_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t );
}
void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical)
{
- struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- U32 s_axis = VX;
- U32 t_axis = VY;
- LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
- F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
- F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis];
- return llmax(repeats_s, repeats_t);
- }
-
- } max_diff_repeats_func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
+ struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
+ F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis];
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_diff_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 1cdb9950d6..05860b995f 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelface.h
* @brief Panel in the tools floater for editing face textures, colors, etc.
*
* $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$
*/
@@ -65,178 +65,179 @@ class PBRPickerObjectListener;
// boost who?
//
template<
- typename DataType,
- typename SetValueType,
- void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
class LLMaterialEditFunctor
{
public:
- LLMaterialEditFunctor(const DataType& data) : _data(data) {}
- virtual ~LLMaterialEditFunctor() {}
- virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); }
- DataType _data;
+ LLMaterialEditFunctor(const DataType& data) : _data(data) {}
+ virtual ~LLMaterialEditFunctor() {}
+ virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); }
+ DataType _data;
};
template<
- typename DataType,
- DataType (LLMaterial::*MaterialGetFunc)() >
+ typename DataType,
+ DataType (LLMaterial::*MaterialGetFunc)() >
class LLMaterialGetFunctor
{
public:
- LLMaterialGetFunctor() {}
- virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); }
+ LLMaterialGetFunctor() {}
+ virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); }
};
template<
- typename DataType,
- DataType (LLTextureEntry::*TEGetFunc)() >
+ typename DataType,
+ DataType (LLTextureEntry::*TEGetFunc)() >
class LLTEGetFunctor
{
public:
- LLTEGetFunctor() {}
- virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); }
+ LLTEGetFunctor() {}
+ virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); }
};
class LLPanelFace : public LLPanel
{
public:
- virtual BOOL postBuild();
- LLPanelFace();
- virtual ~LLPanelFace();
+ virtual BOOL postBuild();
+ LLPanelFace();
+ virtual ~LLPanelFace();
- void refresh();
- void refreshMedia();
- void unloadMedia();
+ void refresh();
+ void refreshMedia();
+ void unloadMedia();
static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side);
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
/*virtual*/ void draw();
- LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
- {
- LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
- llassert_always(new_material);
+ LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
+ {
+ LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
+ llassert_always(new_material);
- // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture
- //
- new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode());
- return new_material;
- }
+ // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture
+ //
+ new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode());
+ return new_material;
+ }
- LLRender::eTexIndex getTextureChannelToEdit();
+ LLRender::eTexIndex getTextureChannelToEdit();
LLRender::eTexIndex getTextureDropChannel();
LLGLTFMaterial::TextureInfo getPBRDropChannel();
protected:
- void navigateToTitleMedia(const std::string url);
- bool selectedMediaEditable();
- void clearMediaSettings();
- void updateMediaSettings();
- void updateMediaTitle();
-
- void getState();
-
- void sendTexture(); // applies and sends texture
- void sendTextureInfo(); // applies and sends texture scale, offset, etc.
- void sendColor(); // applies and sends color
- void sendAlpha(); // applies and sends transparency
- void sendBump(U32 bumpiness); // applies and sends bump map
- void sendTexGen(); // applies and sends bump map
- void sendShiny(U32 shininess); // applies and sends shininess
- void sendFullbright(); // applies and sends full bright
- void sendGlow();
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
+ void getState();
+
+ void sendTexture(); // applies and sends texture
+ void sendTextureInfo(); // applies and sends texture scale, offset, etc.
+ void sendColor(); // applies and sends color
+ void sendAlpha(); // applies and sends transparency
+ void sendBump(U32 bumpiness); // applies and sends bump map
+ void sendTexGen(); // applies and sends bump map
+ void sendShiny(U32 shininess); // applies and sends shininess
+ void sendFullbright(); // applies and sends full bright
+
+ void sendGlow();
void alignTestureLayer();
void updateCopyTexButton();
- void onCommitPbr(const LLSD& data);
- void onCancelPbr(const LLSD& data);
- void onSelectPbr(const LLSD& data);
+ void onCommitPbr(const LLSD& data);
+ void onCancelPbr(const LLSD& data);
+ void onSelectPbr(const LLSD& data);
static BOOL onDragPbr(LLUICtrl* ctrl, LLInventoryItem* item);
- // this function is to return TRUE if the drag should succeed.
- static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
-
- void onCommitTexture(const LLSD& data);
- void onCancelTexture(const LLSD& data);
- void onSelectTexture(const LLSD& data);
- void onCommitSpecularTexture(const LLSD& data);
- void onCancelSpecularTexture(const LLSD& data);
- void onSelectSpecularTexture(const LLSD& data);
- void onCommitNormalTexture(const LLSD& data);
- void onCancelNormalTexture(const LLSD& data);
- void onSelectNormalTexture(const LLSD& data);
- void onCommitColor(const LLSD& data);
- void onCommitShinyColor(const LLSD& data);
- void onCommitAlpha(const LLSD& data);
- void onCancelColor(const LLSD& data);
- void onCancelShinyColor(const LLSD& data);
- void onSelectColor(const LLSD& data);
- void onSelectShinyColor(const LLSD& data);
-
- void onCloseTexturePicker(const LLSD& data);
+ // this function is to return TRUE if the drag should succeed.
+ static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
+
+ void onCommitTexture(const LLSD& data);
+ void onCancelTexture(const LLSD& data);
+ void onSelectTexture(const LLSD& data);
+ void onCommitSpecularTexture(const LLSD& data);
+ void onCancelSpecularTexture(const LLSD& data);
+ void onSelectSpecularTexture(const LLSD& data);
+ void onCommitNormalTexture(const LLSD& data);
+ void onCancelNormalTexture(const LLSD& data);
+ void onSelectNormalTexture(const LLSD& data);
+ void onCommitColor(const LLSD& data);
+ void onCommitShinyColor(const LLSD& data);
+ void onCommitAlpha(const LLSD& data);
+ void onCancelColor(const LLSD& data);
+ void onCancelShinyColor(const LLSD& data);
+ void onSelectColor(const LLSD& data);
+ void onSelectShinyColor(const LLSD& data);
+
+ void onCloseTexturePicker(const LLSD& data);
static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
- // Make UI reflect state of currently selected material (refresh)
- // and UI mode (e.g. editing normal map v diffuse map)
- //
- // @param force_set_values forces spinners to set value even if they are focused
- void updateUI(bool force_set_values = false);
-
- // Convenience func to determine if all faces in selection have
- // identical planar texgen settings during edits
- //
- bool isIdenticalPlanarTexgen();
-
- // Callback funcs for individual controls
- //
- static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata);
-
- static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata);
-
- static void syncRepeatX(LLPanelFace* self, F32 scaleU);
- static void syncRepeatY(LLPanelFace* self, F32 scaleV);
- static void syncOffsetX(LLPanelFace* self, F32 offsetU);
- static void syncOffsetY(LLPanelFace* self, F32 offsetV);
- static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1);
-
- static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata);
-
- static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata);
-
- static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
- static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
- static void onCommitPbrType(LLUICtrl* ctrl, void* userdata);
- static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
- static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
- static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
- static void onCommitBump( LLUICtrl* ctrl, void* userdata);
- static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
- static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
- static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata);
- static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
- static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
- static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
- static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
+ // Make UI reflect state of currently selected material (refresh)
+ // and UI mode (e.g. editing normal map v diffuse map)
+ //
+ // @param force_set_values forces spinners to set value even if they are focused
+ void updateUI(bool force_set_values = false);
+
+ // Convenience func to determine if all faces in selection have
+ // identical planar texgen settings during edits
+ //
+ bool isIdenticalPlanarTexgen();
+
+ // Callback funcs for individual controls
+ //
+ static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata);
+ static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata);
+ static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata);
+ static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata);
+ static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata);
+ static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void syncRepeatX(LLPanelFace* self, F32 scaleU);
+ static void syncRepeatY(LLPanelFace* self, F32 scaleV);
+ static void syncOffsetX(LLPanelFace* self, F32 offsetU);
+ static void syncOffsetY(LLPanelFace* self, F32 offsetV);
+ static void syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1);
+
+ static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onCommitPbrType(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
+ static void onCommitBump( LLUICtrl* ctrl, void* userdata);
+ static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
+ static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
+ static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata);
+ static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
+ static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
+ static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
+ static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
void onCommitGLTFTextureScaleU(LLUICtrl* ctrl);
void onCommitGLTFTextureScaleV(LLUICtrl* ctrl);
@@ -244,11 +245,11 @@ protected:
void onCommitGLTFTextureOffsetU(LLUICtrl* ctrl);
void onCommitGLTFTextureOffsetV(LLUICtrl* ctrl);
- static void onClickAutoFix(void*);
- static void onAlignTexture(void*);
- static void onClickBtnLoadInvPBR(void* userdata);
- static void onClickBtnEditPBR(void* userdata);
- static void onClickBtnSavePBR(void* userdata);
+ static void onClickAutoFix(void*);
+ static void onAlignTexture(void*);
+ static void onClickBtnLoadInvPBR(void* userdata);
+ static void onClickBtnEditPBR(void* userdata);
+ static void onClickBtnSavePBR(void* userdata);
public: // needs to be accessible to selection manager
void onCopyColor(); // records all selected faces
@@ -262,200 +263,200 @@ protected:
void menuDoToSelected(const LLSD& userdata);
bool menuEnableItem(const LLSD& userdata);
- static F32 valueGlow(LLViewerObject* object, S32 face);
-
+ static F32 valueGlow(LLViewerObject* object, S32 face);
+
private:
- bool isAlpha() { return mIsAlpha; }
-
- // Convenience funcs to keep the visual flack to a minimum
- //
- LLUUID getCurrentNormalMap();
- LLUUID getCurrentSpecularMap();
- U32 getCurrentShininess();
- U32 getCurrentBumpiness();
- U8 getCurrentDiffuseAlphaMode();
- U8 getCurrentAlphaMaskCutoff();
- U8 getCurrentEnvIntensity();
- U8 getCurrentGlossiness();
- F32 getCurrentBumpyRot();
- F32 getCurrentBumpyScaleU();
- F32 getCurrentBumpyScaleV();
- F32 getCurrentBumpyOffsetU();
- F32 getCurrentBumpyOffsetV();
- F32 getCurrentShinyRot();
- F32 getCurrentShinyScaleU();
- F32 getCurrentShinyScaleV();
- F32 getCurrentShinyOffsetU();
- F32 getCurrentShinyOffsetV();
+ bool isAlpha() { return mIsAlpha; }
+
+ // Convenience funcs to keep the visual flack to a minimum
+ //
+ LLUUID getCurrentNormalMap();
+ LLUUID getCurrentSpecularMap();
+ U32 getCurrentShininess();
+ U32 getCurrentBumpiness();
+ U8 getCurrentDiffuseAlphaMode();
+ U8 getCurrentAlphaMaskCutoff();
+ U8 getCurrentEnvIntensity();
+ U8 getCurrentGlossiness();
+ F32 getCurrentBumpyRot();
+ F32 getCurrentBumpyScaleU();
+ F32 getCurrentBumpyScaleV();
+ F32 getCurrentBumpyOffsetU();
+ F32 getCurrentBumpyOffsetV();
+ F32 getCurrentShinyRot();
+ F32 getCurrentShinyScaleU();
+ F32 getCurrentShinyScaleV();
+ F32 getCurrentShinyOffsetU();
+ F32 getCurrentShinyOffsetV();
LLComboBox *mComboMatMedia;
LLMediaCtrl *mTitleMedia;
LLTextBox *mTitleMediaText;
- // Update visibility of controls to match current UI mode
- // (e.g. materials vs media editing)
- //
- // Do NOT call updateUI from within this function.
- //
- void updateVisibility(LLViewerObject* objectp = nullptr);
-
- // Hey look everyone, a type-safe alternative to copy and paste! :)
- //
-
- // Update material parameters by applying 'edit_func' to selected TEs
- //
- template<
- typename DataType,
- typename SetValueType,
- void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
- static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID())
- {
- LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);
- struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
- {
- LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {}
- virtual ~LLSelectedTEEditMaterial() {};
- virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material)
- {
- if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID()))
- {
- LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);
- llassert_always(new_material);
-
- // Determine correct alpha mode for current diffuse texture
- // (i.e. does it have an alpha channel that makes alpha mode useful)
- //
- // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329)
- // need to get per-face answer to this question for sane alpha mode retention on updates.
- //
- bool is_alpha_face = object->isImageAlphaBlended(face);
-
- // need to keep this original answer for valid comparisons in logic below
- //
- U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-
- U8 default_alpha_mode = original_default_alpha_mode;
-
- if (!current_material.isNull())
- {
- default_alpha_mode = current_material->getDiffuseAlphaMode();
- }
-
- // Insure we don't inherit the default of blend by accident...
- // this will be stomped by a legit request to change the alpha mode by the apply() below
- //
- new_material->setDiffuseAlphaMode(default_alpha_mode);
-
- // Do "It"!
- //
- _edit->apply(new_material);
-
- U32 new_alpha_mode = new_material->getDiffuseAlphaMode();
- LLUUID new_normal_map_id = new_material->getNormalID();
- LLUUID new_spec_map_id = new_material->getSpecularID();
-
- if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
- {
- new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
- new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
- }
-
- bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode);
- bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
-
- if (!is_need_material)
- {
- LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
- LLMaterialMgr::getInstance()->remove(object->getID(),face);
- new_material = NULL;
- }
- else
- {
- LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL;
- LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
- }
-
- object->setTEMaterialParams(face, new_material);
- return new_material;
- }
- return NULL;
- }
- LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit;
- LLPanelFace *_panel;
- const LLUUID & _only_for_object_id;
- } editor(p, &edit, only_for_object_id);
- LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te);
- }
-
- template<
- typename DataType,
- typename ReturnType,
- ReturnType (LLMaterial::* const MaterialGetFunc)() const >
- static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
- {
- DataType data_value;
- struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>
- {
- GetTEMaterialVal(DataType default_value) : _default(default_value) {}
- virtual ~GetTEMaterialVal() {}
-
- DataType get(LLViewerObject* object, S32 face)
- {
- DataType ret = _default;
- LLMaterialPtr material_ptr;
- LLTextureEntry* tep = object ? object->getTE(face) : NULL;
- if (tep)
- {
- material_ptr = tep->getMaterialParams();
- if (!material_ptr.isNull())
- {
- ret = (material_ptr->*(MaterialGetFunc))();
- }
- }
- return ret;
- }
- DataType _default;
- } GetFunc(default_value);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance);
- data_to_return = data_value;
- }
-
- template<
- typename DataType,
- typename ReturnType, // some kids just have to different...
- ReturnType (LLTextureEntry::* const TEGetFunc)() const >
- static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
- {
- DataType data_value;
- struct GetTEVal : public LLSelectedTEGetFunctor<DataType>
- {
- GetTEVal(DataType default_value) : _default(default_value) {}
- virtual ~GetTEVal() {}
-
- DataType get(LLViewerObject* object, S32 face) {
- LLTextureEntry* tep = object ? object->getTE(face) : NULL;
- return tep ? ((tep->*(TEGetFunc))()) : _default;
- }
- DataType _default;
- } GetTEValFunc(default_value);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance );
- data_to_return = data_value;
- }
-
- // Update vis and enabling of specific subsets of controls based on material params
- // (e.g. hide the spec controls if no spec texture is applied)
- //
- void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
- void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
- void updateAlphaControls();
-
- /*
- * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
- * If agent selects texture which is not allowed to be applied for the currently selected object,
- * all controls of the floater texture picker which allow to apply the texture will be disabled.
- */
+ // Update visibility of controls to match current UI mode
+ // (e.g. materials vs media editing)
+ //
+ // Do NOT call updateUI from within this function.
+ //
+ void updateVisibility(LLViewerObject* objectp = nullptr);
+
+ // Hey look everyone, a type-safe alternative to copy and paste! :)
+ //
+
+ // Update material parameters by applying 'edit_func' to selected TEs
+ //
+ template<
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+ static void edit(LLPanelFace* p, DataType data, int te = -1, const LLUUID &only_for_object_id = LLUUID())
+ {
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);
+ struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
+ {
+ LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp, const LLUUID &only_for_object_id) : _panel(panel), _edit(editp), _only_for_object_id(only_for_object_id) {}
+ virtual ~LLSelectedTEEditMaterial() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material)
+ {
+ if (_edit && (_only_for_object_id.isNull() || _only_for_object_id == object->getID()))
+ {
+ LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);
+ llassert_always(new_material);
+
+ // Determine correct alpha mode for current diffuse texture
+ // (i.e. does it have an alpha channel that makes alpha mode useful)
+ //
+ // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329)
+ // need to get per-face answer to this question for sane alpha mode retention on updates.
+ //
+ bool is_alpha_face = object->isImageAlphaBlended(face);
+
+ // need to keep this original answer for valid comparisons in logic below
+ //
+ U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ U8 default_alpha_mode = original_default_alpha_mode;
+
+ if (!current_material.isNull())
+ {
+ default_alpha_mode = current_material->getDiffuseAlphaMode();
+ }
+
+ // Insure we don't inherit the default of blend by accident...
+ // this will be stomped by a legit request to change the alpha mode by the apply() below
+ //
+ new_material->setDiffuseAlphaMode(default_alpha_mode);
+
+ // Do "It"!
+ //
+ _edit->apply(new_material);
+
+ U32 new_alpha_mode = new_material->getDiffuseAlphaMode();
+ LLUUID new_normal_map_id = new_material->getNormalID();
+ LLUUID new_spec_map_id = new_material->getSpecularID();
+
+ if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
+ {
+ new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+ }
+
+ bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode);
+ bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
+
+ if (!is_need_material)
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ new_material = NULL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL;
+ LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
+ }
+
+ object->setTEMaterialParams(face, new_material);
+ return new_material;
+ }
+ return NULL;
+ }
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit;
+ LLPanelFace *_panel;
+ const LLUUID & _only_for_object_id;
+ } editor(p, &edit, only_for_object_id);
+ LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te);
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType,
+ ReturnType (LLMaterial::* const MaterialGetFunc)() const >
+ static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
+ {
+ DataType data_value;
+ struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEMaterialVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEMaterialVal() {}
+
+ DataType get(LLViewerObject* object, S32 face)
+ {
+ DataType ret = _default;
+ LLMaterialPtr material_ptr;
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ if (tep)
+ {
+ material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ ret = (material_ptr->*(MaterialGetFunc))();
+ }
+ }
+ return ret;
+ }
+ DataType _default;
+ } GetFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance);
+ data_to_return = data_value;
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType, // some kids just have to different...
+ ReturnType (LLTextureEntry::* const TEGetFunc)() const >
+ static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())
+ {
+ DataType data_value;
+ struct GetTEVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEVal() {}
+
+ DataType get(LLViewerObject* object, S32 face) {
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ return tep ? ((tep->*(TEGetFunc))()) : _default;
+ }
+ DataType _default;
+ } GetTEValFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance );
+ data_to_return = data_value;
+ }
+
+ // Update vis and enabling of specific subsets of controls based on material params
+ // (e.g. hide the spec controls if no spec texture is applied)
+ //
+ void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateAlphaControls();
+
+ /*
+ * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
+ * If agent selects texture which is not allowed to be applied for the currently selected object,
+ * all controls of the floater texture picker which allow to apply the texture will be disabled.
+ */
void onTextureSelectionChanged(LLInventoryItem* itemp);
void onPbrSelectionChanged(LLInventoryItem* itemp);
@@ -470,8 +471,8 @@ private:
LLMenuButton* mMenuClipboardColor;
LLMenuButton* mMenuClipboardTexture;
- bool mIsAlpha;
-
+ bool mIsAlpha;
+
LLSD mClipboardParams;
LLSD mMediaSettings;
@@ -514,17 +515,17 @@ private:
std::unique_ptr<PBRPickerObjectListener> mVOInventoryListener;
public:
- #if defined(DEF_GET_MAT_STATE)
- #undef DEF_GET_MAT_STATE
- #endif
+ #if defined(DEF_GET_MAT_STATE)
+ #undef DEF_GET_MAT_STATE
+ #endif
- #if defined(DEF_GET_TE_STATE)
- #undef DEF_GET_TE_STATE
- #endif
+ #if defined(DEF_GET_TE_STATE)
+ #undef DEF_GET_TE_STATE
+ #endif
- #if defined(DEF_EDIT_MAT_STATE)
- DEF_EDIT_MAT_STATE
- #endif
+ #if defined(DEF_EDIT_MAT_STATE)
+ DEF_EDIT_MAT_STATE
+ #endif
// Accessors for selected TE material state
//
@@ -550,74 +551,74 @@ public:
getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance); \
}
- class LLSelectedTEMaterial
- {
- public:
- static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material);
- static void getMaxSpecularRepeats(F32& repeats, bool& identical);
- static void getMaxNormalRepeats(F32& repeats, bool& identical);
- static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
-
- DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null)
- DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null)
- DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f)
-
- DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f)
- DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f)
-
- DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);
- DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff);
-
- DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX);
- DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY);
- DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX);
- DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY);
- DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation);
-
- DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX);
- DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY);
- DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX);
- DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY);
- DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation);
-
- DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity);
- DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent);
-
- DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
- DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
- DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
- };
-
- class LLSelectedTE
- {
- public:
- static void getFace(class LLFace*& face_to_return, bool& identical_face);
- static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
- static void getTexId(LLUUID& id, bool& identical);
+ class LLSelectedTEMaterial
+ {
+ public:
+ static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material);
+ static void getMaxSpecularRepeats(F32& repeats, bool& identical);
+ static void getMaxNormalRepeats(F32& repeats, bool& identical);
+ static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
+
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null)
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f)
+
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f)
+
+ DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);
+ DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation);
+
+ DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity);
+ DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent);
+
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
+ DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
+ };
+
+ class LLSelectedTE
+ {
+ public:
+ static void getFace(class LLFace*& face_to_return, bool& identical_face);
+ static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
+ static void getTexId(LLUUID& id, bool& identical);
static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr);
- static void getObjectScaleS(F32& scale_s, bool& identical);
- static void getObjectScaleT(F32& scale_t, bool& identical);
- static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
-
- DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0)
- DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0)
- DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0)
- DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f)
- DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f)
- DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f)
- DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f)
- DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f)
- DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f)
- DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT)
- DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black);
- };
+ static void getObjectScaleS(F32& scale_s, bool& identical);
+ static void getObjectScaleT(F32& scale_t, bool& identical);
+ static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
+
+ DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0)
+ DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0)
+ DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0)
+ DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f)
+ DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f)
+ DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f)
+ DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f)
+ DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT)
+ DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black);
+ };
};
#endif
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 5887e793e1..2db431d165 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelmaininventory.cpp
* @brief Implementation of llpanelmaininventory.
*
* $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$
*/
@@ -77,29 +77,29 @@ static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory")
class LLFloaterInventoryFinder : public LLFloater
{
public:
- LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
- virtual void draw();
- /*virtual*/ BOOL postBuild();
- void changeFilter(LLInventoryFilter* filter);
- void updateElementsFromFilter();
- BOOL getCheckShowEmpty();
- BOOL getCheckSinceLogoff();
- U32 getDateSearchDirection();
-
- void onCreatorSelfFilterCommit();
- void onCreatorOtherFilterCommit();
-
- static void onTimeAgo(LLUICtrl*, void *);
- static void onCloseBtn(void* user_data);
- static void selectAllTypes(void* user_data);
- static void selectNoTypes(void* user_data);
+ LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
+ virtual void draw();
+ /*virtual*/ BOOL postBuild();
+ void changeFilter(LLInventoryFilter* filter);
+ void updateElementsFromFilter();
+ BOOL getCheckShowEmpty();
+ BOOL getCheckSinceLogoff();
+ U32 getDateSearchDirection();
+
+ void onCreatorSelfFilterCommit();
+ void onCreatorOtherFilterCommit();
+
+ static void onTimeAgo(LLUICtrl*, void *);
+ static void onCloseBtn(void* user_data);
+ static void selectAllTypes(void* user_data);
+ static void selectNoTypes(void* user_data);
private:
- LLPanelMainInventory* mPanelMainInventory;
- LLSpinCtrl* mSpinSinceDays;
- LLSpinCtrl* mSpinSinceHours;
- LLCheckBoxCtrl* mCreatorSelf;
- LLCheckBoxCtrl* mCreatorOthers;
- LLInventoryFilter* mFilter;
+ LLPanelMainInventory* mPanelMainInventory;
+ LLSpinCtrl* mSpinSinceDays;
+ LLSpinCtrl* mSpinSinceHours;
+ LLCheckBoxCtrl* mCreatorSelf;
+ LLCheckBoxCtrl* mCreatorOthers;
+ LLInventoryFilter* mFilter;
};
///----------------------------------------------------------------------------
@@ -107,15 +107,15 @@ private:
///----------------------------------------------------------------------------
LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
- : LLPanel(p),
- mActivePanel(NULL),
- mWornItemsPanel(NULL),
- mSavedFolderState(NULL),
- mFilterText(""),
- mMenuGearDefault(NULL),
- mMenuVisibility(NULL),
- mMenuAddHandle(),
- mNeedUploadCost(true),
+ : LLPanel(p),
+ mActivePanel(NULL),
+ mWornItemsPanel(NULL),
+ mSavedFolderState(NULL),
+ mFilterText(""),
+ mMenuGearDefault(NULL),
+ mMenuVisibility(NULL),
+ mMenuAddHandle(),
+ mNeedUploadCost(true),
mMenuViewDefault(NULL),
mSingleFolderMode(false),
mForceShowInvLayout(false),
@@ -123,128 +123,128 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mListViewRootUpdatedConnection(),
mGalleryRootUpdatedConnection()
{
- // Menu Callbacks (non contex menus)
- mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
- mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
- mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
- mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
- mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
- mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
- mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
- mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
+ // Menu Callbacks (non contex menus)
+ mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
+ mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
+ mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
+ mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
+ mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
+ mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
mEnableCallbackRegistrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasSettingsInventory(); });
mEnableCallbackRegistrar.add("Inventory.MaterialsEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasMaterialsInventory(); });
- mSavedFolderState = new LLSaveFolderState();
- mSavedFolderState->setApply(FALSE);
+ mSavedFolderState = new LLSaveFolderState();
+ mSavedFolderState->setApply(FALSE);
}
BOOL LLPanelMainInventory::postBuild()
{
- gInventory.addObserver(this);
-
- mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
- mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
-
+ gInventory.addObserver(this);
+
+ mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
+ mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
+
mCounterCtrl = getChild<LLUICtrl>("ItemcountText");
-
- //panel->getFilter().markDefault();
-
- // Set up the default inv. panel/filter settings.
- mActivePanel = getChild<LLInventoryPanel>(ALL_ITEMS);
- if (mActivePanel)
- {
- // "All Items" is the previous only view, so it gets the InventorySortOrder
- mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
- mActivePanel->getFilter().markDefault();
- mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
- mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
- mResortActivePanel = true;
- }
- LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>(RECENT_ITEMS);
- if (recent_items_panel)
- {
- // assign default values until we will be sure that we have setting to restore
- recent_items_panel->setSinceLogoff(TRUE);
- recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
- recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
- recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
- recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems");
- recent_filter.markDefault();
- recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
- }
-
- mWornItemsPanel = getChild<LLInventoryPanel>(WORN_ITEMS);
- if (mWornItemsPanel)
- {
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_WEARABLE;
- filter_types |= 0x1 << LLInventoryType::IT_ATTACHMENT;
- filter_types |= 0x1 << LLInventoryType::IT_OBJECT;
- mWornItemsPanel->setFilterTypes(filter_types);
- mWornItemsPanel->setFilterWorn();
- mWornItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mWornItemsPanel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
- LLInventoryFilter& worn_filter = mWornItemsPanel->getFilter();
- worn_filter.setFilterCategoryTypes(worn_filter.getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
- worn_filter.markDefault();
- mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
- }
- mSearchTypeCombo = getChild<LLComboBox>("search_type");
- if(mSearchTypeCombo)
- {
- mSearchTypeCombo->setCommitCallback(boost::bind(&LLPanelMainInventory::onSelectSearchType, this));
- }
- // Now load the stored settings from disk, if available.
- std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME));
- LL_INFOS("Inventory") << "LLPanelMainInventory::init: reading from " << filterSaveName << LL_ENDL;
- llifstream file(filterSaveName.c_str());
- LLSD savedFilterState;
- if (file.is_open())
- {
- LLSDSerialize::fromXML(savedFilterState, file);
- file.close();
-
- // Load the persistent "Recent Items" settings.
- // Note that the "All Items" settings do not persist.
- if(recent_items_panel)
- {
- if(savedFilterState.has(recent_items_panel->getFilter().getName()))
- {
- LLSD recent_items = savedFilterState.get(
- recent_items_panel->getFilter().getName());
- LLInventoryFilter::Params p;
- LLParamSDParser parser;
- parser.readSD(recent_items, p);
- recent_items_panel->getFilter().fromParams(p);
- recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
- }
- }
- if(mActivePanel)
- {
- if(savedFilterState.has(mActivePanel->getFilter().getName()))
- {
- LLSD items = savedFilterState.get(mActivePanel->getFilter().getName());
- LLInventoryFilter::Params p;
- LLParamSDParser parser;
- parser.readSD(items, p);
- mActivePanel->getFilter().setSearchVisibilityTypes(p);
- }
- }
-
- }
-
- mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
- if (mFilterEditor)
- {
- mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
- }
-
- mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
- mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
+
+ //panel->getFilter().markDefault();
+
+ // Set up the default inv. panel/filter settings.
+ mActivePanel = getChild<LLInventoryPanel>(ALL_ITEMS);
+ if (mActivePanel)
+ {
+ // "All Items" is the previous only view, so it gets the InventorySortOrder
+ mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
+ mActivePanel->getFilter().markDefault();
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
+ mResortActivePanel = true;
+ }
+ LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>(RECENT_ITEMS);
+ if (recent_items_panel)
+ {
+ // assign default values until we will be sure that we have setting to restore
+ recent_items_panel->setSinceLogoff(TRUE);
+ recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
+ recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
+ recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
+ recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems");
+ recent_filter.markDefault();
+ recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
+ }
+
+ mWornItemsPanel = getChild<LLInventoryPanel>(WORN_ITEMS);
+ if (mWornItemsPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_WEARABLE;
+ filter_types |= 0x1 << LLInventoryType::IT_ATTACHMENT;
+ filter_types |= 0x1 << LLInventoryType::IT_OBJECT;
+ mWornItemsPanel->setFilterTypes(filter_types);
+ mWornItemsPanel->setFilterWorn();
+ mWornItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mWornItemsPanel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
+ LLInventoryFilter& worn_filter = mWornItemsPanel->getFilter();
+ worn_filter.setFilterCategoryTypes(worn_filter.getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+ worn_filter.markDefault();
+ mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
+ }
+ mSearchTypeCombo = getChild<LLComboBox>("search_type");
+ if(mSearchTypeCombo)
+ {
+ mSearchTypeCombo->setCommitCallback(boost::bind(&LLPanelMainInventory::onSelectSearchType, this));
+ }
+ // Now load the stored settings from disk, if available.
+ std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME));
+ LL_INFOS("Inventory") << "LLPanelMainInventory::init: reading from " << filterSaveName << LL_ENDL;
+ llifstream file(filterSaveName.c_str());
+ LLSD savedFilterState;
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(savedFilterState, file);
+ file.close();
+
+ // Load the persistent "Recent Items" settings.
+ // Note that the "All Items" settings do not persist.
+ if(recent_items_panel)
+ {
+ if(savedFilterState.has(recent_items_panel->getFilter().getName()))
+ {
+ LLSD recent_items = savedFilterState.get(
+ recent_items_panel->getFilter().getName());
+ LLInventoryFilter::Params p;
+ LLParamSDParser parser;
+ parser.readSD(recent_items, p);
+ recent_items_panel->getFilter().fromParams(p);
+ recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
+ }
+ }
+ if(mActivePanel)
+ {
+ if(savedFilterState.has(mActivePanel->getFilter().getName()))
+ {
+ LLSD items = savedFilterState.get(mActivePanel->getFilter().getName());
+ LLInventoryFilter::Params p;
+ LLParamSDParser parser;
+ parser.readSD(items, p);
+ mActivePanel->getFilter().setSearchVisibilityTypes(p);
+ }
+ }
+
+ }
+
+ mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+ if (mFilterEditor)
+ {
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
+ }
+
+ mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
+ mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
mViewMenuButton = getChild<LLMenuButton>("view_btn");
mBackBtn = getChild<LLButton>("back_btn");
@@ -274,75 +274,73 @@ BOOL LLPanelMainInventory::postBuild()
mGalleryRootUpdatedConnection = mCombinationGalleryPanel->setRootChangedCallback(boost::bind(&LLPanelMainInventory::onCombinationRootChanged, this, true));
mCombinationGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelMainInventory::onCombinationGallerySelectionChanged, this, _1));
- initListCommandsHandlers();
+ initListCommandsHandlers();
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
- const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
- const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
- if (menu)
- {
- menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
- menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
- menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
- }
+ LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+ if (menu)
+ {
+ menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
+ menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
+ }
- // Trigger callback for focus received so we can deselect items in inbox/outbox
- LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
+ // Trigger callback for focus received so we can deselect items in inbox/outbox
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
- return TRUE;
+ return TRUE;
}
// Destroys the object
LLPanelMainInventory::~LLPanelMainInventory( void )
{
- // Save the filters state.
- // Some params types cannot be saved this way
- // for example, LLParamSDParser doesn't know about U64,
- // so some FilterOps params should be revised.
- LLSD filterRoot;
- LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>(ALL_ITEMS);
- if (all_items_panel)
- {
- LLSD filterState;
- LLInventoryPanel::InventoryState p;
- all_items_panel->getFilter().toParams(p.filter);
- all_items_panel->getRootViewModel().getSorter().toParams(p.sort);
- if (p.validateBlock(false))
- {
- LLParamSDParser().writeSD(filterState, p);
- filterRoot[all_items_panel->getName()] = filterState;
- }
- }
-
- LLInventoryPanel* panel = findChild<LLInventoryPanel>(RECENT_ITEMS);
- if (panel)
- {
- LLSD filterState;
- LLInventoryPanel::InventoryState p;
- panel->getFilter().toParams(p.filter);
- panel->getRootViewModel().getSorter().toParams(p.sort);
- if (p.validateBlock(false))
- {
- LLParamSDParser().writeSD(filterState, p);
- filterRoot[panel->getName()] = filterState;
- }
- }
-
- std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME));
- llofstream filtersFile(filterSaveName.c_str());
- if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
- {
- LL_WARNS() << "Could not write to filters save file " << filterSaveName << LL_ENDL;
- }
- else
- {
- filtersFile.close();
- }
-
- gInventory.removeObserver(this);
- delete mSavedFolderState;
+ // Save the filters state.
+ // Some params types cannot be saved this way
+ // for example, LLParamSDParser doesn't know about U64,
+ // so some FilterOps params should be revised.
+ LLSD filterRoot;
+ LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>(ALL_ITEMS);
+ if (all_items_panel)
+ {
+ LLSD filterState;
+ LLInventoryPanel::InventoryState p;
+ all_items_panel->getFilter().toParams(p.filter);
+ all_items_panel->getRootViewModel().getSorter().toParams(p.sort);
+ if (p.validateBlock(false))
+ {
+ LLParamSDParser().writeSD(filterState, p);
+ filterRoot[all_items_panel->getName()] = filterState;
+ }
+ }
+
+ LLInventoryPanel* panel = findChild<LLInventoryPanel>(RECENT_ITEMS);
+ if (panel)
+ {
+ LLSD filterState;
+ LLInventoryPanel::InventoryState p;
+ panel->getFilter().toParams(p.filter);
+ panel->getRootViewModel().getSorter().toParams(p.sort);
+ if (p.validateBlock(false))
+ {
+ LLParamSDParser().writeSD(filterState, p);
+ filterRoot[panel->getName()] = filterState;
+ }
+ }
+
+ std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME));
+ llofstream filtersFile(filterSaveName.c_str());
+ if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
+ {
+ LL_WARNS() << "Could not write to filters save file " << filterSaveName << LL_ENDL;
+ }
+ else
+ {
+ filtersFile.close();
+ }
+
+ gInventory.removeObserver(this);
+ delete mSavedFolderState;
auto menu = mMenuAddHandle.get();
if(menu)
@@ -363,57 +361,57 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel()
{
- return getChild<LLInventoryPanel>(ALL_ITEMS);
+ return getChild<LLInventoryPanel>(ALL_ITEMS);
}
void LLPanelMainInventory::selectAllItemsPanel()
{
- mFilterTabs->selectFirstTab();
+ mFilterTabs->selectFirstTab();
}
bool LLPanelMainInventory::isRecentItemsPanelSelected()
{
- return (RECENT_ITEMS == getActivePanel()->getName());
+ return (RECENT_ITEMS == getActivePanel()->getName());
}
void LLPanelMainInventory::startSearch()
{
- // this forces focus to line editor portion of search editor
- if (mFilterEditor)
- {
- mFilterEditor->focusFirstItem(TRUE);
- }
+ // this forces focus to line editor portion of search editor
+ if (mFilterEditor)
+ {
+ mFilterEditor->focusFirstItem(TRUE);
+ }
}
BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
{
- LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
- if (root_folder)
- {
- // first check for user accepting current search results
- if (mFilterEditor
- && mFilterEditor->hasFocus()
- && (key == KEY_RETURN
- || key == KEY_DOWN)
- && mask == MASK_NONE)
- {
- // move focus to inventory proper
- mActivePanel->setFocus(TRUE);
- root_folder->scrollToShowSelection();
- return TRUE;
- }
-
- if (mActivePanel->hasFocus() && key == KEY_UP)
- {
- startSearch();
- }
+ LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
+ if (root_folder)
+ {
+ // first check for user accepting current search results
+ if (mFilterEditor
+ && mFilterEditor->hasFocus()
+ && (key == KEY_RETURN
+ || key == KEY_DOWN)
+ && mask == MASK_NONE)
+ {
+ // move focus to inventory proper
+ mActivePanel->setFocus(TRUE);
+ root_folder->scrollToShowSelection();
+ return TRUE;
+ }
+
+ if (mActivePanel->hasFocus() && key == KEY_UP)
+ {
+ startSearch();
+ }
if(mSingleFolderMode && key == KEY_LEFT)
{
onBackFolderClicked();
}
- }
+ }
- return LLPanel::handleKeyHere(key, mask);
+ return LLPanel::handleKeyHere(key, mask);
}
@@ -422,12 +420,12 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
void LLPanelMainInventory::doToSelected(const LLSD& userdata)
{
- getPanel()->doToSelected(userdata);
+ getPanel()->doToSelected(userdata);
}
void LLPanelMainInventory::closeAllFolders()
{
- getPanel()->getRootFolder()->closeAllFolders();
+ getPanel()->getRootFolder()->closeAllFolders();
}
S32 get_instance_num()
@@ -442,13 +440,13 @@ LLFloaterSidePanelContainer* LLPanelMainInventory::newWindow()
{
S32 instance_num = get_instance_num();
- if (!gAgentCamera.cameraMouselook())
- {
+ if (!gAgentCamera.cameraMouselook())
+ {
LLFloaterSidePanelContainer* floater = LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
LLSidepanelInventory* sidepanel_inventory = floater->findChild<LLSidepanelInventory>("main_panel");
sidepanel_inventory->initInventoryViews();
- return floater;
- }
+ return floater;
+ }
return NULL;
}
@@ -478,7 +476,7 @@ void LLPanelMainInventory::newFolderWindow(LLUUID folder_id, LLUUID item_to_sele
}
}
}
-
+
S32 instance_num = get_instance_num();
LLFloaterSidePanelContainer* inventory_container = LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
@@ -506,7 +504,7 @@ void LLPanelMainInventory::newFolderWindow(LLUUID folder_id, LLUUID item_to_sele
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
- reset_inventory_filter();
+ reset_inventory_filter();
if(mSingleFolderMode)
{
if(isListViewMode() || isCombinationViewMode())
@@ -567,14 +565,14 @@ void LLPanelMainInventory::doCreate(const LLSD& userdata)
void LLPanelMainInventory::resetFilters()
{
- LLFloaterInventoryFinder *finder = getFinder();
- getCurrentFilter().resetDefault();
- if (finder)
- {
- finder->updateElementsFromFilter();
- }
+ LLFloaterInventoryFinder *finder = getFinder();
+ getCurrentFilter().resetDefault();
+ if (finder)
+ {
+ finder->updateElementsFromFilter();
+ }
- setFilterTextFromFilter();
+ setFilterTextFromFilter();
}
void LLPanelMainInventory::resetAllItemsFilters()
@@ -602,44 +600,44 @@ void LLPanelMainInventory::findLinks(const LLUUID& item_id, const std::string& i
void LLPanelMainInventory::setSortBy(const LLSD& userdata)
{
- U32 sort_order_mask = getActivePanel()->getSortOrder();
- std::string sort_type = userdata.asString();
- if (sort_type == "name")
- {
- sort_order_mask &= ~LLInventoryFilter::SO_DATE;
- }
- else if (sort_type == "date")
- {
- sort_order_mask |= LLInventoryFilter::SO_DATE;
- }
- else if (sort_type == "foldersalwaysbyname")
- {
- if ( sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME )
- {
- sort_order_mask &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
- }
- else
- {
- sort_order_mask |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
- }
- }
- else if (sort_type == "systemfolderstotop")
- {
- if ( sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
- {
- sort_order_mask &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
- }
- else
- {
- sort_order_mask |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
- }
- }
+ U32 sort_order_mask = getActivePanel()->getSortOrder();
+ std::string sort_type = userdata.asString();
+ if (sort_type == "name")
+ {
+ sort_order_mask &= ~LLInventoryFilter::SO_DATE;
+ }
+ else if (sort_type == "date")
+ {
+ sort_order_mask |= LLInventoryFilter::SO_DATE;
+ }
+ else if (sort_type == "foldersalwaysbyname")
+ {
+ if ( sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME )
+ {
+ sort_order_mask &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
+ }
+ else
+ {
+ sort_order_mask |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
+ }
+ }
+ else if (sort_type == "systemfolderstotop")
+ {
+ if ( sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
+ {
+ sort_order_mask &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+ }
+ else
+ {
+ sort_order_mask |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+ }
+ }
if(mSingleFolderMode && !isListViewMode())
{
mCombinationGalleryPanel->setSortOrder(sort_order_mask, true);
}
- getActivePanel()->setSortOrder(sort_order_mask);
+ getActivePanel()->setSortOrder(sort_order_mask);
if (isRecentItemsPanelSelected())
{
gSavedSettings.setU32("RecentItemsSortOrder", sort_order_mask);
@@ -652,23 +650,23 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata)
void LLPanelMainInventory::onSelectSearchType()
{
- std::string new_type = mSearchTypeCombo->getValue();
- if (new_type == "search_by_name")
- {
- setSearchType(LLInventoryFilter::SEARCHTYPE_NAME);
- }
- if (new_type == "search_by_creator")
- {
- setSearchType(LLInventoryFilter::SEARCHTYPE_CREATOR);
- }
- if (new_type == "search_by_description")
- {
- setSearchType(LLInventoryFilter::SEARCHTYPE_DESCRIPTION);
- }
- if (new_type == "search_by_UUID")
- {
- setSearchType(LLInventoryFilter::SEARCHTYPE_UUID);
- }
+ std::string new_type = mSearchTypeCombo->getValue();
+ if (new_type == "search_by_name")
+ {
+ setSearchType(LLInventoryFilter::SEARCHTYPE_NAME);
+ }
+ if (new_type == "search_by_creator")
+ {
+ setSearchType(LLInventoryFilter::SEARCHTYPE_CREATOR);
+ }
+ if (new_type == "search_by_description")
+ {
+ setSearchType(LLInventoryFilter::SEARCHTYPE_DESCRIPTION);
+ }
+ if (new_type == "search_by_UUID")
+ {
+ setSearchType(LLInventoryFilter::SEARCHTYPE_UUID);
+ }
}
void LLPanelMainInventory::setSearchType(LLInventoryFilter::ESearchType type)
@@ -705,70 +703,70 @@ void LLPanelMainInventory::updateSearchTypeCombo()
search_type = getActivePanel()->getSearchType();
}
- switch(search_type)
- {
- case LLInventoryFilter::SEARCHTYPE_CREATOR:
- mSearchTypeCombo->setValue("search_by_creator");
- break;
- case LLInventoryFilter::SEARCHTYPE_DESCRIPTION:
- mSearchTypeCombo->setValue("search_by_description");
- break;
- case LLInventoryFilter::SEARCHTYPE_UUID:
- mSearchTypeCombo->setValue("search_by_UUID");
- break;
- case LLInventoryFilter::SEARCHTYPE_NAME:
- default:
- mSearchTypeCombo->setValue("search_by_name");
- break;
- }
+ switch(search_type)
+ {
+ case LLInventoryFilter::SEARCHTYPE_CREATOR:
+ mSearchTypeCombo->setValue("search_by_creator");
+ break;
+ case LLInventoryFilter::SEARCHTYPE_DESCRIPTION:
+ mSearchTypeCombo->setValue("search_by_description");
+ break;
+ case LLInventoryFilter::SEARCHTYPE_UUID:
+ mSearchTypeCombo->setValue("search_by_UUID");
+ break;
+ case LLInventoryFilter::SEARCHTYPE_NAME:
+ default:
+ mSearchTypeCombo->setValue("search_by_name");
+ break;
+ }
}
// static
BOOL LLPanelMainInventory::filtersVisible(void* user_data)
{
- LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
- if(!self) return FALSE;
+ LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
+ if(!self) return FALSE;
- return self->getFinder() != NULL;
+ return self->getFinder() != NULL;
}
void LLPanelMainInventory::onClearSearch()
{
- BOOL initially_active = FALSE;
- LLFloater *finder = getFinder();
- if (mActivePanel && (getActivePanel() != mWornItemsPanel))
- {
- initially_active = mActivePanel->getFilter().isNotDefault();
- setFilterSubString(LLStringUtil::null);
- mActivePanel->setFilterTypes(0xffffffffffffffffULL);
- mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
- }
-
- if (finder)
- {
- LLFloaterInventoryFinder::selectAllTypes(finder);
- }
-
- // re-open folders that were initially open in case filter was active
- if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode)
- {
- mSavedFolderState->setApply(TRUE);
- mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
- LLOpenFoldersWithSelection opener;
- mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
- mActivePanel->getRootFolder()->scrollToShowSelection();
- }
- mFilterSubString = "";
-
- LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory();
- if (sidepanel_inventory)
- {
- LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
- if (inbox_panel)
- {
- inbox_panel->onClearSearch();
- }
- }
+ BOOL initially_active = FALSE;
+ LLFloater *finder = getFinder();
+ if (mActivePanel && (getActivePanel() != mWornItemsPanel))
+ {
+ initially_active = mActivePanel->getFilter().isNotDefault();
+ setFilterSubString(LLStringUtil::null);
+ mActivePanel->setFilterTypes(0xffffffffffffffffULL);
+ mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
+ }
+
+ if (finder)
+ {
+ LLFloaterInventoryFinder::selectAllTypes(finder);
+ }
+
+ // re-open folders that were initially open in case filter was active
+ if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode)
+ {
+ mSavedFolderState->setApply(TRUE);
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ LLOpenFoldersWithSelection opener;
+ mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
+ mActivePanel->getRootFolder()->scrollToShowSelection();
+ }
+ mFilterSubString = "";
+
+ LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory();
+ if (sidepanel_inventory)
+ {
+ LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
+ if (inbox_panel)
+ {
+ inbox_panel->onClearSearch();
+ }
+ }
}
void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
@@ -784,15 +782,15 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
mCombinationGalleryPanel->setFilterSubString(search_string);
}
- if (search_string == "")
- {
- onClearSearch();
- }
+ if (search_string == "")
+ {
+ onClearSearch();
+ }
- if (!mActivePanel)
- {
- return;
- }
+ if (!mActivePanel)
+ {
+ return;
+ }
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
{
@@ -800,215 +798,215 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
LLInventoryModelBackgroundFetch::instance().start();
}
- mFilterSubString = search_string;
- if (mActivePanel->getFilterSubString().empty() && mFilterSubString.empty())
- {
- // current filter and new filter empty, do nothing
- return;
- }
+ mFilterSubString = search_string;
+ if (mActivePanel->getFilterSubString().empty() && mFilterSubString.empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
- // save current folder open state if no filter currently applied
- if (!mActivePanel->getFilter().isNotDefault())
- {
- mSavedFolderState->setApply(FALSE);
- mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
- }
+ // save current folder open state if no filter currently applied
+ if (!mActivePanel->getFilter().isNotDefault())
+ {
+ mSavedFolderState->setApply(FALSE);
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ }
- // set new filter string
- setFilterSubString(mFilterSubString);
+ // set new filter string
+ setFilterSubString(mFilterSubString);
LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory();
- if (sidepanel_inventory)
- {
- LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
- if (inbox_panel)
- {
- inbox_panel->onFilterEdit(search_string);
- }
- }
+ if (sidepanel_inventory)
+ {
+ LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
+ if (inbox_panel)
+ {
+ inbox_panel->onFilterEdit(search_string);
+ }
+ }
}
//static
BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
{
- LLPanelMainInventory* active_view = NULL;
-
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
- {
- LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
- if (iv)
- {
- if (gFocusMgr.childHasKeyboardFocus(iv))
- {
- active_view = iv;
- break;
- }
- }
- }
-
- if (!active_view)
- {
- return FALSE;
- }
-
- std::string search_string(find_text);
-
- if (search_string.empty())
- {
- return FALSE;
- }
-
- if (active_view->getPanel() &&
- active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
- {
- return TRUE;
- }
-
- return FALSE;
+ LLPanelMainInventory* active_view = NULL;
+
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+ {
+ LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
+ if (iv)
+ {
+ if (gFocusMgr.childHasKeyboardFocus(iv))
+ {
+ active_view = iv;
+ break;
+ }
+ }
+ }
+
+ if (!active_view)
+ {
+ return FALSE;
+ }
+
+ std::string search_string(find_text);
+
+ if (search_string.empty())
+ {
+ return FALSE;
+ }
+
+ if (active_view->getPanel() &&
+ active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
}
void LLPanelMainInventory::onFilterSelected()
{
- // Find my index
+ // Find my index
setActivePanel();
- if (!mActivePanel)
- {
- return;
- }
-
- if (getActivePanel() == mWornItemsPanel)
- {
- mActivePanel->openAllFolders();
- }
- updateSearchTypeCombo();
- setFilterSubString(mFilterSubString);
- LLInventoryFilter& filter = getCurrentFilter();
- LLFloaterInventoryFinder *finder = getFinder();
- if (finder)
- {
- finder->changeFilter(&filter);
+ if (!mActivePanel)
+ {
+ return;
+ }
+
+ if (getActivePanel() == mWornItemsPanel)
+ {
+ mActivePanel->openAllFolders();
+ }
+ updateSearchTypeCombo();
+ setFilterSubString(mFilterSubString);
+ LLInventoryFilter& filter = getCurrentFilter();
+ LLFloaterInventoryFinder *finder = getFinder();
+ if (finder)
+ {
+ finder->changeFilter(&filter);
if (mSingleFolderMode)
{
finder->setTitle(getLocalizedRootName());
}
- }
- if (filter.isActive() && !LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
- {
+ }
+ if (filter.isActive() && !LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
+ {
llassert(false); // this should have been done on startup
- LLInventoryModelBackgroundFetch::instance().start();
- }
- setFilterTextFromFilter();
+ LLInventoryModelBackgroundFetch::instance().start();
+ }
+ setFilterTextFromFilter();
}
-const std::string LLPanelMainInventory::getFilterSubString()
-{
- return mActivePanel->getFilterSubString();
+const std::string LLPanelMainInventory::getFilterSubString()
+{
+ return mActivePanel->getFilterSubString();
}
-void LLPanelMainInventory::setFilterSubString(const std::string& string)
-{
- mActivePanel->setFilterSubString(string);
+void LLPanelMainInventory::setFilterSubString(const std::string& string)
+{
+ mActivePanel->setFilterSubString(string);
}
BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- // Check to see if we are auto scrolling from the last frame
- LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
- BOOL needsToScroll = panel->getScrollableContainer()->canAutoScroll(x, y);
- if(mFilterTabs)
- {
- if(needsToScroll)
- {
- mFilterTabs->startDragAndDropDelayTimer();
- }
- }
-
- BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
- return handled;
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ // Check to see if we are auto scrolling from the last frame
+ LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
+ BOOL needsToScroll = panel->getScrollableContainer()->canAutoScroll(x, y);
+ if(mFilterTabs)
+ {
+ if(needsToScroll)
+ {
+ mFilterTabs->startDragAndDropDelayTimer();
+ }
+ }
+
+ BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+ return handled;
}
// virtual
void LLPanelMainInventory::changed(U32)
{
- updateItemcountText();
+ updateItemcountText();
}
void LLPanelMainInventory::setFocusFilterEditor()
{
- if(mFilterEditor)
- {
- mFilterEditor->setFocus(true);
- }
+ if(mFilterEditor)
+ {
+ mFilterEditor->setFocus(true);
+ }
}
// virtual
void LLPanelMainInventory::draw()
{
- if (mActivePanel && mFilterEditor)
- {
- mFilterEditor->setText(mFilterSubString);
- }
- if (mActivePanel && mResortActivePanel)
- {
- // EXP-756: Force resorting of the list the first time we draw the list:
- // In the case of date sorting, we don't have enough information at initialization time
- // to correctly sort the folders. Later manual resort doesn't do anything as the order value is
- // set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order.
- U32 order = mActivePanel->getSortOrder();
- mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME);
- mActivePanel->setSortOrder(order);
- mResortActivePanel = false;
- }
- LLPanel::draw();
- updateItemcountText();
+ if (mActivePanel && mFilterEditor)
+ {
+ mFilterEditor->setText(mFilterSubString);
+ }
+ if (mActivePanel && mResortActivePanel)
+ {
+ // EXP-756: Force resorting of the list the first time we draw the list:
+ // In the case of date sorting, we don't have enough information at initialization time
+ // to correctly sort the folders. Later manual resort doesn't do anything as the order value is
+ // set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order.
+ U32 order = mActivePanel->getSortOrder();
+ mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME);
+ mActivePanel->setSortOrder(order);
+ mResortActivePanel = false;
+ }
+ LLPanel::draw();
+ updateItemcountText();
updateCombinationVisibility();
}
void LLPanelMainInventory::updateItemcountText()
{
- if(mItemCount != gInventory.getItemCount())
- {
- mItemCount = gInventory.getItemCount();
- mItemCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
- }
-
- if(mCategoryCount != gInventory.getCategoryCount())
- {
- mCategoryCount = gInventory.getCategoryCount();
- mCategoryCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
- }
-
- LLStringUtil::format_map_t string_args;
- string_args["[ITEM_COUNT]"] = mItemCountString;
- string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
- string_args["[FILTER]"] = getFilterText();
-
- std::string text = "";
-
- if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
- {
- text = getString("ItemcountFetching", string_args);
- }
- else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
- {
- text = getString("ItemcountCompleted", string_args);
- }
- else
- {
- text = getString("ItemcountUnknown", string_args);
- }
+ if(mItemCount != gInventory.getItemCount())
+ {
+ mItemCount = gInventory.getItemCount();
+ mItemCountString = "";
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
+ }
+
+ if(mCategoryCount != gInventory.getCategoryCount())
+ {
+ mCategoryCount = gInventory.getCategoryCount();
+ mCategoryCountString = "";
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
+ }
+
+ LLStringUtil::format_map_t string_args;
+ string_args["[ITEM_COUNT]"] = mItemCountString;
+ string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
+ string_args["[FILTER]"] = getFilterText();
+
+ std::string text = "";
+
+ if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
+ {
+ text = getString("ItemcountFetching", string_args);
+ }
+ else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ {
+ text = getString("ItemcountCompleted", string_args);
+ }
+ else
+ {
+ text = getString("ItemcountUnknown", string_args);
+ }
if (mSingleFolderMode)
{
@@ -1024,40 +1022,40 @@ void LLPanelMainInventory::updateItemcountText()
text = getString("ItemcountCompleted", string_args);
}
}
-
+
mCounterCtrl->setValue(text);
mCounterCtrl->setToolTip(text);
}
void LLPanelMainInventory::onFocusReceived()
{
- LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- if (!sidepanel_inventory)
- {
- LL_WARNS() << "Could not find Inventory Panel in My Inventory floater" << LL_ENDL;
- return;
- }
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (!sidepanel_inventory)
+ {
+ LL_WARNS() << "Could not find Inventory Panel in My Inventory floater" << LL_ENDL;
+ return;
+ }
- sidepanel_inventory->clearSelections(false, true);
+ sidepanel_inventory->clearSelections(false, true);
}
-void LLPanelMainInventory::setFilterTextFromFilter()
-{
- mFilterText = getCurrentFilter().getFilterText();
+void LLPanelMainInventory::setFilterTextFromFilter()
+{
+ mFilterText = getCurrentFilter().getFilterText();
}
void LLPanelMainInventory::toggleFindOptions()
{
- LLFloater *floater = getFinder();
- if (!floater)
- {
- LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
- mFinderHandle = finder->getHandle();
- finder->openFloater();
+ LLFloater *floater = getFinder();
+ if (!floater)
+ {
+ LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
+ mFinderHandle = finder->getHandle();
+ finder->openFloater();
- LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- if (parent_floater)
- parent_floater->addDependentFloater(mFinderHandle);
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ parent_floater->addDependentFloater(mFinderHandle);
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
{
@@ -1069,232 +1067,232 @@ void LLPanelMainInventory::toggleFindOptions()
{
finder->setTitle(getLocalizedRootName());
}
- }
- else
- {
- floater->closeFloater();
- }
+ }
+ else
+ {
+ floater->closeFloater();
+ }
}
void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
{
- getChild<LLInventoryPanel>(ALL_ITEMS)->setSelectCallback(cb);
- getChild<LLInventoryPanel>(RECENT_ITEMS)->setSelectCallback(cb);
+ getChild<LLInventoryPanel>(ALL_ITEMS)->setSelectCallback(cb);
+ getChild<LLInventoryPanel>(RECENT_ITEMS)->setSelectCallback(cb);
}
void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
{
- updateListCommands();
- panel->onSelectionChange(items, user_action);
+ updateListCommands();
+ panel->onSelectionChange(items, user_action);
}
///----------------------------------------------------------------------------
/// LLFloaterInventoryFinder
///----------------------------------------------------------------------------
-LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
-{
- return (LLFloaterInventoryFinder*)mFinderHandle.get();
+LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
+{
+ return (LLFloaterInventoryFinder*)mFinderHandle.get();
}
-LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :
- LLFloater(LLSD()),
- mPanelMainInventory(inventory_view),
- mFilter(&inventory_view->getPanel()->getFilter())
+LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :
+ LLFloater(LLSD()),
+ mPanelMainInventory(inventory_view),
+ mFilter(&inventory_view->getPanel()->getFilter())
{
- buildFromFile("floater_inventory_view_finder.xml");
- updateElementsFromFilter();
+ buildFromFile("floater_inventory_view_finder.xml");
+ updateElementsFromFilter();
}
BOOL LLFloaterInventoryFinder::postBuild()
{
- const LLRect& viewrect = mPanelMainInventory->getRect();
- setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
+ const LLRect& viewrect = mPanelMainInventory->getRect();
+ setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
- childSetAction("All", selectAllTypes, this);
- childSetAction("None", selectNoTypes, this);
+ childSetAction("All", selectAllTypes, this);
+ childSetAction("None", selectNoTypes, this);
- mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
- childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
+ mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
+ childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
- mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
- childSetCommitCallback("spin_days_ago", onTimeAgo, this);
+ mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
+ childSetCommitCallback("spin_days_ago", onTimeAgo, this);
- mCreatorSelf = getChild<LLCheckBoxCtrl>("check_created_by_me");
- mCreatorOthers = getChild<LLCheckBoxCtrl>("check_created_by_others");
- mCreatorSelf->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorSelfFilterCommit, this));
- mCreatorOthers->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorOtherFilterCommit, this));
+ mCreatorSelf = getChild<LLCheckBoxCtrl>("check_created_by_me");
+ mCreatorOthers = getChild<LLCheckBoxCtrl>("check_created_by_others");
+ mCreatorSelf->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorSelfFilterCommit, this));
+ mCreatorOthers->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorOtherFilterCommit, this));
- childSetAction("Close", onCloseBtn, this);
+ childSetAction("Close", onCloseBtn, this);
- updateElementsFromFilter();
- return TRUE;
+ updateElementsFromFilter();
+ return TRUE;
}
void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
{
- LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
- if (!self) return;
-
- if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
- {
- self->getChild<LLUICtrl>("check_since_logoff")->setValue(false);
-
- U32 days = (U32)self->mSpinSinceDays->get();
- U32 hours = (U32)self->mSpinSinceHours->get();
- if (hours >= 24)
- {
- // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible.
- // There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in
- // this case add to days. Any value > 24 means they have input the hours manually, so do not add to the
- // current day value.
- if (24 == hours) // Got to 24 via spinner clicking or text input of 24
- {
- days = days + hours / 24;
- }
- else // Text input, so do not add to days
- {
- days = hours / 24;
- }
- hours = (U32)hours % 24;
- self->mSpinSinceHours->setFocus(false);
- self->mSpinSinceDays->setFocus(false);
- self->mSpinSinceDays->set((F32)days);
- self->mSpinSinceHours->set((F32)hours);
- self->mSpinSinceHours->setFocus(true);
- }
- }
+ LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+ if (!self) return;
+
+ if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
+ {
+ self->getChild<LLUICtrl>("check_since_logoff")->setValue(false);
+
+ U32 days = (U32)self->mSpinSinceDays->get();
+ U32 hours = (U32)self->mSpinSinceHours->get();
+ if (hours >= 24)
+ {
+ // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible.
+ // There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in
+ // this case add to days. Any value > 24 means they have input the hours manually, so do not add to the
+ // current day value.
+ if (24 == hours) // Got to 24 via spinner clicking or text input of 24
+ {
+ days = days + hours / 24;
+ }
+ else // Text input, so do not add to days
+ {
+ days = hours / 24;
+ }
+ hours = (U32)hours % 24;
+ self->mSpinSinceHours->setFocus(false);
+ self->mSpinSinceDays->setFocus(false);
+ self->mSpinSinceDays->set((F32)days);
+ self->mSpinSinceHours->set((F32)hours);
+ self->mSpinSinceHours->setFocus(true);
+ }
+ }
}
void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
{
- mFilter = filter;
- updateElementsFromFilter();
+ mFilter = filter;
+ updateElementsFromFilter();
}
void LLFloaterInventoryFinder::updateElementsFromFilter()
{
- if (!mFilter)
- return;
-
- // Get data needed for filter display
- U32 filter_types = mFilter->getFilterObjectTypes();
- LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
- U32 hours = mFilter->getHoursAgo();
- U32 date_search_direction = mFilter->getDateSearchDirection();
-
- LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType();
- bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF));
- bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS));
-
- // update the ui elements
- setTitle(mFilter->getName());
-
- getChild<LLUICtrl>("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
-
- getChild<LLUICtrl>("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
- getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
- getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
- getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
- getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
- getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
- getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
- getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
- 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));
+ if (!mFilter)
+ return;
+
+ // Get data needed for filter display
+ U32 filter_types = mFilter->getFilterObjectTypes();
+ LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
+ U32 hours = mFilter->getHoursAgo();
+ U32 date_search_direction = mFilter->getDateSearchDirection();
+
+ LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType();
+ bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF));
+ bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS));
+
+ // update the ui elements
+ setTitle(mFilter->getName());
+
+ getChild<LLUICtrl>("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
+
+ getChild<LLUICtrl>("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
+ getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
+ getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
+ getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
+ getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
+ getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
+ getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
+ 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_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
- getChild<LLUICtrl>("check_created_by_me")->setValue(show_created_by_me);
- getChild<LLUICtrl>("check_created_by_others")->setValue(show_created_by_others);
+ getChild<LLUICtrl>("check_created_by_me")->setValue(show_created_by_me);
+ getChild<LLUICtrl>("check_created_by_others")->setValue(show_created_by_others);
- getChild<LLUICtrl>("check_since_logoff")->setValue(mFilter->isSinceLogoff());
- mSpinSinceHours->set((F32)(hours % 24));
- mSpinSinceDays->set((F32)(hours / 24));
- getChild<LLRadioGroup>("date_search_direction")->setSelectedIndex(date_search_direction);
+ getChild<LLUICtrl>("check_since_logoff")->setValue(mFilter->isSinceLogoff());
+ mSpinSinceHours->set((F32)(hours % 24));
+ mSpinSinceDays->set((F32)(hours / 24));
+ getChild<LLRadioGroup>("date_search_direction")->setSelectedIndex(date_search_direction);
}
void LLFloaterInventoryFinder::draw()
{
- U64 filter = 0xffffffffffffffffULL;
- BOOL filtered_by_all_types = TRUE;
-
- if (!getChild<LLUICtrl>("check_animation")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
- filtered_by_all_types = FALSE;
- }
-
-
- if (!getChild<LLUICtrl>("check_calling_card")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_clothing")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_gesture")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_landmark")->getValue())
-
-
- {
- filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_material")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_notecard")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_object")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
- filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_script")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_LSL);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_sound")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_SOUND);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_texture")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
- filtered_by_all_types = FALSE;
- }
-
- if (!getChild<LLUICtrl>("check_snapshot")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
- filtered_by_all_types = FALSE;
- }
+ U64 filter = 0xffffffffffffffffULL;
+ BOOL filtered_by_all_types = TRUE;
+
+ if (!getChild<LLUICtrl>("check_animation")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
+ filtered_by_all_types = FALSE;
+ }
+
+
+ if (!getChild<LLUICtrl>("check_calling_card")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_clothing")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_gesture")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_landmark")->getValue())
+
+
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_material")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_notecard")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_object")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
+ filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_script")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LSL);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_sound")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SOUND);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_texture")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!getChild<LLUICtrl>("check_snapshot")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
+ filtered_by_all_types = FALSE;
+ }
if (!getChild<LLUICtrl>("check_settings")->getValue())
{
@@ -1302,11 +1300,11 @@ void LLFloaterInventoryFinder::draw()
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
- filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
- }
+ 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
+ filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
+ }
bool is_sf_mode = mPanelMainInventory->isSingleFolderMode();
@@ -1330,28 +1328,28 @@ void LLFloaterInventoryFinder::draw()
mPanelMainInventory->getPanel()->setFilterTypes(filter);
}
- if (getCheckSinceLogoff())
- {
- mSpinSinceDays->set(0);
- mSpinSinceHours->set(0);
- }
- U32 days = (U32)mSpinSinceDays->get();
- U32 hours = (U32)mSpinSinceHours->get();
- if (hours >= 24)
- {
- days = hours / 24;
- hours = (U32)hours % 24;
- // A UI element that has focus will not display a new value set to it
- mSpinSinceHours->setFocus(false);
- mSpinSinceDays->setFocus(false);
- mSpinSinceDays->set((F32)days);
- mSpinSinceHours->set((F32)hours);
- mSpinSinceHours->setFocus(true);
- }
- hours += days * 24;
-
-
- mPanelMainInventory->setFilterTextFromFilter();
+ if (getCheckSinceLogoff())
+ {
+ mSpinSinceDays->set(0);
+ mSpinSinceHours->set(0);
+ }
+ U32 days = (U32)mSpinSinceDays->get();
+ U32 hours = (U32)mSpinSinceHours->get();
+ if (hours >= 24)
+ {
+ days = hours / 24;
+ hours = (U32)hours % 24;
+ // A UI element that has focus will not display a new value set to it
+ mSpinSinceHours->setFocus(false);
+ mSpinSinceDays->setFocus(false);
+ mSpinSinceDays->set((F32)days);
+ mSpinSinceHours->set((F32)hours);
+ mSpinSinceHours->setFocus(true);
+ }
+ hours += days * 24;
+
+
+ mPanelMainInventory->setFilterTextFromFilter();
if(is_sf_mode && mPanelMainInventory->isGalleryViewMode())
{
mPanelMainInventory->mCombinationGalleryPanel->getFilter().setHoursAgo(hours);
@@ -1371,109 +1369,109 @@ void LLFloaterInventoryFinder::draw()
mPanelMainInventory->getPanel()->setDateSearchDirection(getDateSearchDirection());
}
- LLPanel::draw();
+ LLPanel::draw();
}
void LLFloaterInventoryFinder::onCreatorSelfFilterCommit()
{
- bool show_creator_self = mCreatorSelf->getValue();
- bool show_creator_other = mCreatorOthers->getValue();
+ bool show_creator_self = mCreatorSelf->getValue();
+ bool show_creator_other = mCreatorOthers->getValue();
- if(show_creator_self && show_creator_other)
- {
+ if(show_creator_self && show_creator_other)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_ALL);
- }
- else if(show_creator_self)
- {
+ }
+ else if(show_creator_self)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_SELF);
- }
- else if(!show_creator_self || !show_creator_other)
- {
+ }
+ else if(!show_creator_self || !show_creator_other)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_OTHERS);
- mCreatorOthers->set(TRUE);
- }
+ mCreatorOthers->set(TRUE);
+ }
}
void LLFloaterInventoryFinder::onCreatorOtherFilterCommit()
{
- bool show_creator_self = mCreatorSelf->getValue();
- bool show_creator_other = mCreatorOthers->getValue();
+ bool show_creator_self = mCreatorSelf->getValue();
+ bool show_creator_other = mCreatorOthers->getValue();
- if(show_creator_self && show_creator_other)
- {
+ if(show_creator_self && show_creator_other)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_ALL);
- }
- else if(show_creator_other)
- {
+ }
+ else if(show_creator_other)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_OTHERS);
- }
- else if(!show_creator_other || !show_creator_self)
- {
+ }
+ else if(!show_creator_other || !show_creator_self)
+ {
mPanelMainInventory->getCurrentFilter().setFilterCreator(LLInventoryFilter::FILTERCREATOR_SELF);
- mCreatorSelf->set(TRUE);
- }
+ mCreatorSelf->set(TRUE);
+ }
}
BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
{
- return getChild<LLUICtrl>("check_show_empty")->getValue();
+ return getChild<LLUICtrl>("check_show_empty")->getValue();
}
BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
{
- return getChild<LLUICtrl>("check_since_logoff")->getValue();
+ return getChild<LLUICtrl>("check_since_logoff")->getValue();
}
U32 LLFloaterInventoryFinder::getDateSearchDirection()
{
- return getChild<LLRadioGroup>("date_search_direction")->getSelectedIndex();
+ return getChild<LLRadioGroup>("date_search_direction")->getSelectedIndex();
}
void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
{
- LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
- finderp->closeFloater();
+ LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
+ finderp->closeFloater();
}
// static
void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
{
- LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
- if(!self) return;
-
- self->getChild<LLUICtrl>("check_animation")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_calling_card")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_sound")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_texture")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
+ LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+ if(!self) return;
+
+ self->getChild<LLUICtrl>("check_animation")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_calling_card")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_sound")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_texture")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
self->getChild<LLUICtrl>("check_settings")->setValue(TRUE);
}
//static
void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
{
- LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
- if(!self) return;
-
- self->getChild<LLUICtrl>("check_animation")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_calling_card")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_sound")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_texture")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_snapshot")->setValue(FALSE);
+ LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+ if(!self) return;
+
+ self->getChild<LLUICtrl>("check_animation")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_calling_card")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
+ 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);
}
@@ -1482,28 +1480,28 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
void LLPanelMainInventory::initListCommandsHandlers()
{
- childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
+ childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
childSetAction("view_mode_btn", boost::bind(&LLPanelMainInventory::onViewModeClick, this));
childSetAction("up_btn", boost::bind(&LLPanelMainInventory::onUpFolderClicked, this));
childSetAction("back_btn", boost::bind(&LLPanelMainInventory::onBackFolderClicked, this));
childSetAction("forward_btn", boost::bind(&LLPanelMainInventory::onForwardFolderClicked, this));
- mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
- mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
- mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
+ mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
+ mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2));
- mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_BOTTOM_LEFT, true);
+ mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_BOTTOM_LEFT, true);
mMenuViewDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_view_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mViewMenuButton->setMenu(mMenuViewDefault, LLMenuButton::MP_BOTTOM_LEFT, true);
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mMenuAddHandle = menu->getHandle();
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mMenuAddHandle = menu->getHandle();
- mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true);
- // Update the trash button when selected item(s) get worn or taken off.
- LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
+ // Update the trash button when selected item(s) get worn or taken off.
+ LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
}
void LLPanelMainInventory::updateListCommands()
@@ -1515,15 +1513,15 @@ void LLPanelMainInventory::onAddButtonClick()
// Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
// unless "Always show folders" is checked in the filter options.
- LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
- if (menu)
- {
+ LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+ if (menu)
+ {
disableAddIfNeeded();
- setUploadCostIfNeeded();
+ setUploadCostIfNeeded();
- showActionMenu(menu,"add_btn");
- }
+ showActionMenu(menu,"add_btn");
+ }
}
void LLPanelMainInventory::setActivePanel()
@@ -1737,22 +1735,22 @@ LLUUID LLPanelMainInventory::getSingleFolderViewRoot()
void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
{
- if (menu)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLView* spawning_view = getChild<LLView> (spawning_view_name);
- S32 menu_x, menu_y;
- //show menu in co-ordinates of panel
- spawning_view->localPointToOtherView(0, 0, &menu_x, &menu_y, this);
- LLMenuGL::showPopup(this, menu, menu_x, menu_y);
- }
+ if (menu)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLView* spawning_view = getChild<LLView> (spawning_view_name);
+ S32 menu_x, menu_y;
+ //show menu in co-ordinates of panel
+ spawning_view->localPointToOtherView(0, 0, &menu_x, &menu_y, this);
+ LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+ }
}
void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
{
- std::string command_name = userdata.asString();
- getActivePanel()->doToSelected(command_name);
+ std::string command_name = userdata.asString();
+ getActivePanel()->doToSelected(command_name);
}
void LLPanelMainInventory::saveTexture(const LLSD& userdata)
@@ -1773,89 +1771,89 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
}
- LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
- if (preview_texture)
- {
- preview_texture->openToSave();
- }
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
+ if (preview_texture)
+ {
+ preview_texture->openToSave();
+ }
}
void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
- if (!isActionEnabled(userdata))
- return;
-
- const std::string command_name = userdata.asString();
-
- if (command_name == "new_window")
- {
- newWindow();
- }
- if (command_name == "sort_by_name")
- {
- const LLSD arg = "name";
- setSortBy(arg);
- }
- if (command_name == "sort_by_recent")
- {
- const LLSD arg = "date";
- setSortBy(arg);
- }
- if (command_name == "sort_folders_by_name")
- {
- const LLSD arg = "foldersalwaysbyname";
- setSortBy(arg);
- }
- if (command_name == "sort_system_folders_to_top")
- {
- const LLSD arg = "systemfolderstotop";
- setSortBy(arg);
- }
- if (command_name == "show_filters")
- {
- toggleFindOptions();
- }
- if (command_name == "reset_filters")
- {
- resetFilters();
- }
- if (command_name == "close_folders")
- {
- closeAllFolders();
- }
- if (command_name == "empty_trash")
- {
- const std::string notification = "ConfirmEmptyTrash";
- gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH);
- }
- if (command_name == "empty_lostnfound")
- {
- const std::string notification = "ConfirmEmptyLostAndFound";
- gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND);
- }
- if (command_name == "save_texture")
- {
- saveTexture(userdata);
- }
- // This doesn't currently work, since the viewer can't change an assetID an item.
- if (command_name == "regenerate_link")
- {
- LLInventoryPanel *active_panel = getActivePanel();
- LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem();
- if (!current_item)
- {
- return;
- }
- const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- if (item)
- {
- item->regenerateLink();
- }
- active_panel->setSelection(item_id, TAKE_FOCUS_NO);
- }
- if (command_name == "find_original")
- {
+ if (!isActionEnabled(userdata))
+ return;
+
+ const std::string command_name = userdata.asString();
+
+ if (command_name == "new_window")
+ {
+ newWindow();
+ }
+ if (command_name == "sort_by_name")
+ {
+ const LLSD arg = "name";
+ setSortBy(arg);
+ }
+ if (command_name == "sort_by_recent")
+ {
+ const LLSD arg = "date";
+ setSortBy(arg);
+ }
+ if (command_name == "sort_folders_by_name")
+ {
+ const LLSD arg = "foldersalwaysbyname";
+ setSortBy(arg);
+ }
+ if (command_name == "sort_system_folders_to_top")
+ {
+ const LLSD arg = "systemfolderstotop";
+ setSortBy(arg);
+ }
+ if (command_name == "show_filters")
+ {
+ toggleFindOptions();
+ }
+ if (command_name == "reset_filters")
+ {
+ resetFilters();
+ }
+ if (command_name == "close_folders")
+ {
+ closeAllFolders();
+ }
+ if (command_name == "empty_trash")
+ {
+ const std::string notification = "ConfirmEmptyTrash";
+ gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH);
+ }
+ if (command_name == "empty_lostnfound")
+ {
+ const std::string notification = "ConfirmEmptyLostAndFound";
+ gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND);
+ }
+ if (command_name == "save_texture")
+ {
+ saveTexture(userdata);
+ }
+ // This doesn't currently work, since the viewer can't change an assetID an item.
+ if (command_name == "regenerate_link")
+ {
+ LLInventoryPanel *active_panel = getActivePanel();
+ LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ {
+ return;
+ }
+ const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item)
+ {
+ item->regenerateLink();
+ }
+ active_panel->setSelection(item_id, TAKE_FOCUS_NO);
+ }
+ if (command_name == "find_original")
+ {
if(mSingleFolderMode && isGalleryViewMode())
{
LLInventoryObject *obj = gInventory.getObject(mCombinationGalleryPanel->getFirstSelectedItemID());
@@ -1866,17 +1864,17 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
else
{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item)
- {
- return;
- }
- static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ {
+ return;
+ }
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
}
- }
+ }
- if (command_name == "find_links")
- {
+ if (command_name == "find_links")
+ {
if(mSingleFolderMode && isGalleryViewMode())
{
LLFloaterSidePanelContainer* inventory_container = newWindow();
@@ -1908,10 +1906,10 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
const std::string &item_name = current_item->getViewModelItem()->getName();
findLinks(item_id, item_name);
}
- }
+ }
- if (command_name == "replace_links")
- {
+ if (command_name == "replace_links")
+ {
LLSD params;
if(mSingleFolderMode && isGalleryViewMode())
{
@@ -1919,23 +1917,23 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
else
{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (current_item)
- {
- LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem();
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (current_item)
+ {
+ LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem();
- if (bridge)
- {
- LLInventoryObject* obj = bridge->getInventoryObject();
- if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER)
- {
- params = LLSD(obj->getUUID());
- }
- }
+ if (bridge)
+ {
+ LLInventoryObject* obj = bridge->getInventoryObject();
+ if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER)
+ {
+ params = LLSD(obj->getUUID());
+ }
+ }
+ }
}
- }
- LLFloaterReg::showInstance("linkreplace", params);
- }
+ LLFloaterReg::showInstance("linkreplace", params);
+ }
if (command_name == "close_inv_windows")
{
@@ -1956,20 +1954,20 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
getCurrentFilter().toggleSearchVisibilityOutfits();
}
- if (command_name == "toggle_search_trash")
- {
+ if (command_name == "toggle_search_trash")
+ {
getCurrentFilter().toggleSearchVisibilityTrash();
- }
+ }
- if (command_name == "toggle_search_library")
- {
+ if (command_name == "toggle_search_library")
+ {
getCurrentFilter().toggleSearchVisibilityLibrary();
- }
+ }
- if (command_name == "include_links")
- {
+ if (command_name == "include_links")
+ {
getCurrentFilter().toggleSearchVisibilityLinks();
- }
+ }
if (command_name == "share")
{
@@ -2003,15 +2001,15 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
{
- if(!new_visibility)
- {
- LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
- if (menu)
- {
- menu->setVisible(FALSE);
- }
- getActivePanel()->getRootFolder()->finishRenamingItem();
- }
+ if(!new_visibility)
+ {
+ LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+ if (menu)
+ {
+ menu->setVisible(FALSE);
+ }
+ getActivePanel()->getRootFolder()->finishRenamingItem();
+ }
}
bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
@@ -2029,124 +2027,124 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
}
}
- if(inv_item)
- {
- bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
+ if(inv_item)
+ {
+ bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
LLInventoryType::EType curr_type = inv_item->getInventoryType();
- return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
- }
+ return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
+ }
- return false;
+ return false;
}
BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
- const std::string command_name = userdata.asString();
- if (command_name == "not_empty")
- {
- BOOL status = FALSE;
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (current_item)
- {
- const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
- LLInventoryModel::cat_array_t* cat_array;
- LLInventoryModel::item_array_t* item_array;
- gInventory.getDirectDescendentsOf(item_id, cat_array, item_array);
- status = (0 == cat_array->size() && 0 == item_array->size());
- }
- return status;
- }
- if (command_name == "delete")
- {
- return getActivePanel()->isSelectionRemovable();
- }
- if (command_name == "save_texture")
- {
- return isSaveTextureEnabled(userdata);
- }
- if (command_name == "find_original")
- {
+ const std::string command_name = userdata.asString();
+ if (command_name == "not_empty")
+ {
+ BOOL status = FALSE;
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (current_item)
+ {
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(item_id, cat_array, item_array);
+ status = (0 == cat_array->size() && 0 == item_array->size());
+ }
+ return status;
+ }
+ if (command_name == "delete")
+ {
+ return getActivePanel()->isSelectionRemovable();
+ }
+ if (command_name == "save_texture")
+ {
+ return isSaveTextureEnabled(userdata);
+ }
+ if (command_name == "find_original")
+ {
LLUUID item_id;
if(mSingleFolderMode && isGalleryViewMode())
{
item_id = mCombinationGalleryPanel->getFirstSelectedItemID();
}
else{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item) return FALSE;
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item) return FALSE;
item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
}
- const LLViewerInventoryItem *item = gInventory.getItem(item_id);
- if (item && item->getIsLinkType() && !item->getIsBrokenLink())
- {
- return TRUE;
- }
- return FALSE;
- }
+ const LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item && item->getIsLinkType() && !item->getIsBrokenLink())
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
- if (command_name == "find_links")
- {
+ if (command_name == "find_links")
+ {
LLUUID item_id;
if(mSingleFolderMode && isGalleryViewMode())
{
item_id = mCombinationGalleryPanel->getFirstSelectedItemID();
}
else{
- LLFolderView* root = getActivePanel()->getRootFolder();
- std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
- if (selection_set.size() != 1) return FALSE;
- LLFolderViewItem* current_item = root->getCurSelectedItem();
- if (!current_item) return FALSE;
- item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
- }
- const LLInventoryObject *obj = gInventory.getObject(item_id);
- if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
- {
- return TRUE;
- }
- return FALSE;
- }
- // This doesn't currently work, since the viewer can't change an assetID an item.
- if (command_name == "regenerate_link")
- {
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item) return FALSE;
- const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
- const LLViewerInventoryItem *item = gInventory.getItem(item_id);
- if (item && item->getIsBrokenLink())
- {
- return TRUE;
- }
- return FALSE;
- }
-
- if (command_name == "share")
- {
+ LLFolderView* root = getActivePanel()->getRootFolder();
+ std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
+ if (selection_set.size() != 1) return FALSE;
+ LLFolderViewItem* current_item = root->getCurSelectedItem();
+ if (!current_item) return FALSE;
+ item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ }
+ const LLInventoryObject *obj = gInventory.getObject(item_id);
+ if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ // This doesn't currently work, since the viewer can't change an assetID an item.
+ if (command_name == "regenerate_link")
+ {
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item) return FALSE;
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ const LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item && item->getIsBrokenLink())
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ if (command_name == "share")
+ {
if(mSingleFolderMode && isGalleryViewMode())
{
return can_share_item(mCombinationGalleryPanel->getFirstSelectedItemID());
}
else{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item) return FALSE;
- LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- return parent ? parent->canShare() : FALSE;
- }
- }
- if (command_name == "empty_trash")
- {
- const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
- return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
- }
- if (command_name == "empty_lostnfound")
- {
- const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
- return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
- }
-
- return TRUE;
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item) return FALSE;
+ LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ return parent ? parent->canShare() : FALSE;
+ }
+ }
+ if (command_name == "empty_trash")
+ {
+ const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
+ return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
+ }
+ if (command_name == "empty_lostnfound")
+ {
+ const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+ LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
+ return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
+ }
+
+ return TRUE;
}
bool LLPanelMainInventory::isActionVisible(const LLSD& userdata)
@@ -2166,47 +2164,47 @@ bool LLPanelMainInventory::isActionVisible(const LLSD& userdata)
BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
{
- U32 sort_order_mask = (mSingleFolderMode && isGalleryViewMode()) ? mCombinationGalleryPanel->getSortOrder() : getActivePanel()->getSortOrder();
- const std::string command_name = userdata.asString();
- if (command_name == "sort_by_name")
- {
- return ~sort_order_mask & LLInventoryFilter::SO_DATE;
- }
+ U32 sort_order_mask = (mSingleFolderMode && isGalleryViewMode()) ? mCombinationGalleryPanel->getSortOrder() : getActivePanel()->getSortOrder();
+ const std::string command_name = userdata.asString();
+ if (command_name == "sort_by_name")
+ {
+ return ~sort_order_mask & LLInventoryFilter::SO_DATE;
+ }
- if (command_name == "sort_by_recent")
- {
- return sort_order_mask & LLInventoryFilter::SO_DATE;
- }
+ if (command_name == "sort_by_recent")
+ {
+ return sort_order_mask & LLInventoryFilter::SO_DATE;
+ }
- if (command_name == "sort_folders_by_name")
- {
- return sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME;
- }
+ if (command_name == "sort_folders_by_name")
+ {
+ return sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME;
+ }
- if (command_name == "sort_system_folders_to_top")
- {
- return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
- }
+ if (command_name == "sort_system_folders_to_top")
+ {
+ return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+ }
if (command_name == "toggle_search_outfits")
{
return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_OUTFITS) != 0;
}
- if (command_name == "toggle_search_trash")
- {
- return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0;
- }
+ if (command_name == "toggle_search_trash")
+ {
+ return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0;
+ }
- if (command_name == "toggle_search_library")
- {
- return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0;
- }
+ if (command_name == "toggle_search_library")
+ {
+ return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0;
+ }
- if (command_name == "include_links")
- {
+ if (command_name == "include_links")
+ {
return (getCurrentFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;
- }
+ }
if (command_name == "list_view")
{
@@ -2221,22 +2219,20 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
return isCombinationViewMode();
}
- return FALSE;
+ return FALSE;
}
void LLPanelMainInventory::setUploadCostIfNeeded()
{
- LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
- if(mNeedUploadCost && menu)
- {
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
- const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
- const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
+ LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+ if(mNeedUploadCost && menu)
+ {
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
- menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
- menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
- }
+ menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
+ menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
+ }
}
bool is_add_allowed(LLUUID folder_id)
@@ -2416,7 +2412,7 @@ void LLPanelMainInventory::updateCombinationVisibility()
{
mCombinationGalleryPanel->handleModifiedFilter();
}
-
+
getActivePanel()->getRootFolder();
if (mReshapeInvLayout
@@ -2540,7 +2536,7 @@ void LLPanelMainInventory::setViewMode(EViewModeType mode)
sort_order = mCombinationInventoryPanel->getSortOrder();
break;
}
-
+
LLUUID cur_root = getCurrentSFVRoot();
mViewMode = mode;
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 7a483a44ea..91c33b461f 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelvolume.cpp
* @brief Object editing (position, scale, etc.) in the tools floater
*
* $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$
*/
@@ -90,137 +90,137 @@ const F32 DEFAULT_GRAVITY_MULTIPLIER = 1.f;
const F32 DEFAULT_DENSITY = 1000.f;
// "Features" Tab
-BOOL LLPanelVolume::postBuild()
+BOOL LLPanelVolume::postBuild()
{
- // Flexible Objects Parameters
- {
- childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL);
- childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL);
- childSetCommitCallback("FlexNumSections",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexGravity",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexGravity")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexFriction",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexFriction")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexWind",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexWind")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexTension",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexTension")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexForceX",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexForceX")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexForceY",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexForceY")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("FlexForceZ",onCommitFlexible,this);
- getChild<LLUICtrl>("FlexForceZ")->setValidateBeforeCommit(precommitValidate);
- }
-
- // LIGHT Parameters
- {
- childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this);
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch){
- LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2));
- LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2));
- childSetCommitCallback("colorswatch",onCommitLight,this);
- }
-
- LLTextureCtrl* LightTexPicker = getChild<LLTextureCtrl>("light texture control");
- if (LightTexPicker)
- {
- LightTexPicker->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelTexture, this, _2));
- LightTexPicker->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectTexture, this, _2));
- childSetCommitCallback("light texture control", onCommitLight, this);
- }
-
- childSetCommitCallback("Light Intensity",onCommitLight,this);
- getChild<LLUICtrl>("Light Intensity")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("Light Radius",onCommitLight,this);
- getChild<LLUICtrl>("Light Radius")->setValidateBeforeCommit(precommitValidate);
- childSetCommitCallback("Light Falloff",onCommitLight,this);
- getChild<LLUICtrl>("Light Falloff")->setValidateBeforeCommit(precommitValidate);
-
- childSetCommitCallback("Light FOV", onCommitLight, this);
- getChild<LLUICtrl>("Light FOV")->setValidateBeforeCommit( precommitValidate);
- childSetCommitCallback("Light Focus", onCommitLight, this);
- getChild<LLUICtrl>("Light Focus")->setValidateBeforeCommit( precommitValidate);
- childSetCommitCallback("Light Ambiance", onCommitLight, this);
- getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
- }
-
+ // Flexible Objects Parameters
+ {
+ childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL);
+ childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL);
+ childSetCommitCallback("FlexNumSections",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexGravity",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexGravity")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexFriction",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexFriction")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexWind",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexWind")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexTension",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexTension")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexForceX",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexForceX")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexForceY",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexForceY")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("FlexForceZ",onCommitFlexible,this);
+ getChild<LLUICtrl>("FlexForceZ")->setValidateBeforeCommit(precommitValidate);
+ }
+
+ // LIGHT Parameters
+ {
+ childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this);
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch){
+ LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2));
+ LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2));
+ childSetCommitCallback("colorswatch",onCommitLight,this);
+ }
+
+ LLTextureCtrl* LightTexPicker = getChild<LLTextureCtrl>("light texture control");
+ if (LightTexPicker)
+ {
+ LightTexPicker->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelTexture, this, _2));
+ LightTexPicker->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectTexture, this, _2));
+ childSetCommitCallback("light texture control", onCommitLight, this);
+ }
+
+ childSetCommitCallback("Light Intensity",onCommitLight,this);
+ getChild<LLUICtrl>("Light Intensity")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("Light Radius",onCommitLight,this);
+ getChild<LLUICtrl>("Light Radius")->setValidateBeforeCommit(precommitValidate);
+ childSetCommitCallback("Light Falloff",onCommitLight,this);
+ getChild<LLUICtrl>("Light Falloff")->setValidateBeforeCommit(precommitValidate);
+
+ childSetCommitCallback("Light FOV", onCommitLight, this);
+ getChild<LLUICtrl>("Light FOV")->setValidateBeforeCommit( precommitValidate);
+ childSetCommitCallback("Light Focus", onCommitLight, this);
+ getChild<LLUICtrl>("Light Focus")->setValidateBeforeCommit( precommitValidate);
+ childSetCommitCallback("Light Ambiance", onCommitLight, this);
+ getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
+ }
+
// REFLECTION PROBE Parameters
{
childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
- childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
+ childSetCommitCallback("Probe Update Type", onCommitProbe, this);
childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
}
- // PHYSICS Parameters
- {
- // PhysicsShapeType combobox
- mComboPhysicsShapeType = getChild<LLComboBox>("Physics Shape Type Combo Ctrl");
- mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType));
-
- // PhysicsGravity
- mSpinPhysicsGravity = getChild<LLSpinCtrl>("Physics Gravity");
- mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity));
+ // PHYSICS Parameters
+ {
+ // PhysicsShapeType combobox
+ mComboPhysicsShapeType = getChild<LLComboBox>("Physics Shape Type Combo Ctrl");
+ mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType));
+
+ // PhysicsGravity
+ mSpinPhysicsGravity = getChild<LLSpinCtrl>("Physics Gravity");
+ mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity));
- // PhysicsFriction
- mSpinPhysicsFriction = getChild<LLSpinCtrl>("Physics Friction");
- mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction));
+ // PhysicsFriction
+ mSpinPhysicsFriction = getChild<LLSpinCtrl>("Physics Friction");
+ mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction));
- // PhysicsDensity
- mSpinPhysicsDensity = getChild<LLSpinCtrl>("Physics Density");
- mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity));
+ // PhysicsDensity
+ mSpinPhysicsDensity = getChild<LLSpinCtrl>("Physics Density");
+ mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity));
- // PhysicsRestitution
- mSpinPhysicsRestitution = getChild<LLSpinCtrl>("Physics Restitution");
- mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution));
- }
+ // PhysicsRestitution
+ mSpinPhysicsRestitution = getChild<LLSpinCtrl>("Physics Restitution");
+ mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution));
+ }
mMenuClipboardFeatures = getChild<LLMenuButton>("clipboard_features_params_btn");
mMenuClipboardLight = getChild<LLMenuButton>("clipboard_light_params_btn");
- std::map<std::string, std::string> material_name_map;
- material_name_map["Stone"]= LLTrans::getString("Stone");
- material_name_map["Metal"]= LLTrans::getString("Metal");
- material_name_map["Glass"]= LLTrans::getString("Glass");
- material_name_map["Wood"]= LLTrans::getString("Wood");
- material_name_map["Flesh"]= LLTrans::getString("Flesh");
- material_name_map["Plastic"]= LLTrans::getString("Plastic");
- material_name_map["Rubber"]= LLTrans::getString("Rubber");
- material_name_map["Light"]= LLTrans::getString("Light");
-
- LLMaterialTable::basic.initTableTransNames(material_name_map);
-
- // material type popup
- mComboMaterial = getChild<LLComboBox>("material");
- childSetCommitCallback("material",onCommitMaterial,this);
- mComboMaterial->removeall();
-
- for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin();
- iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter)
- {
- LLMaterialInfo* minfop = *iter;
- if (minfop->mMCode != LL_MCODE_LIGHT)
- {
- mComboMaterial->add(minfop->mName);
- }
- }
- mComboMaterialItemCount = mComboMaterial->getItemCount();
-
- // Start with everyone disabled
- clearCtrls();
-
- return TRUE;
+ std::map<std::string, std::string> material_name_map;
+ material_name_map["Stone"]= LLTrans::getString("Stone");
+ material_name_map["Metal"]= LLTrans::getString("Metal");
+ material_name_map["Glass"]= LLTrans::getString("Glass");
+ material_name_map["Wood"]= LLTrans::getString("Wood");
+ material_name_map["Flesh"]= LLTrans::getString("Flesh");
+ material_name_map["Plastic"]= LLTrans::getString("Plastic");
+ material_name_map["Rubber"]= LLTrans::getString("Rubber");
+ material_name_map["Light"]= LLTrans::getString("Light");
+
+ LLMaterialTable::basic.initTableTransNames(material_name_map);
+
+ // material type popup
+ mComboMaterial = getChild<LLComboBox>("material");
+ childSetCommitCallback("material",onCommitMaterial,this);
+ mComboMaterial->removeall();
+
+ for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin();
+ iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter)
+ {
+ LLMaterialInfo* minfop = *iter;
+ if (minfop->mMCode != LL_MCODE_LIGHT)
+ {
+ mComboMaterial->add(minfop->mName);
+ }
+ }
+ mComboMaterialItemCount = mComboMaterial->getItemCount();
+
+ // Start with everyone disabled
+ clearCtrls();
+
+ return TRUE;
}
LLPanelVolume::LLPanelVolume()
- : LLPanel(),
- mComboMaterialItemCount(0)
+ : LLPanel(),
+ mComboMaterialItemCount(0)
{
- setMouseOpaque(FALSE);
+ setMouseOpaque(FALSE);
mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2));
mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2));
@@ -229,142 +229,142 @@ LLPanelVolume::LLPanelVolume()
LLPanelVolume::~LLPanelVolume()
{
- // Children all cleaned up by default view destructor.
+ // Children all cleaned up by default view destructor.
}
void LLPanelVolume::getState( )
{
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
- LLViewerObject* root_objectp = objectp;
- if(!objectp)
- {
- objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- // *FIX: shouldn't we just keep the child?
- if (objectp)
- {
- LLViewerObject* parentp = objectp->getRootEdit();
-
- if (parentp)
- {
- root_objectp = parentp;
- }
- else
- {
- root_objectp = objectp;
- }
- }
- }
-
- LLVOVolume *volobjp = NULL;
- if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
- {
- volobjp = (LLVOVolume *)objectp;
- }
- LLVOVolume *root_volobjp = NULL;
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
+ LLViewerObject* root_objectp = objectp;
+ if(!objectp)
+ {
+ objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ // *FIX: shouldn't we just keep the child?
+ if (objectp)
+ {
+ LLViewerObject* parentp = objectp->getRootEdit();
+
+ if (parentp)
+ {
+ root_objectp = parentp;
+ }
+ else
+ {
+ root_objectp = objectp;
+ }
+ }
+ }
+
+ LLVOVolume *volobjp = NULL;
+ if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+ LLVOVolume *root_volobjp = NULL;
if (root_objectp && (root_objectp->getPCode() == LL_PCODE_VOLUME))
{
root_volobjp = (LLVOVolume *)root_objectp;
}
-
- if( !objectp )
- {
- //forfeit focus
- if (gFocusMgr.childHasKeyboardFocus(this))
- {
- gFocusMgr.setKeyboardFocus(NULL);
- }
-
- // Disable all text input fields
- clearCtrls();
-
- return;
- }
-
- LLUUID owner_id;
- std::string owner_name;
- LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
-
- // BUG? Check for all objects being editable?
- BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
- BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )
- && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1;
- BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) &&
+
+ if( !objectp )
+ {
+ //forfeit focus
+ if (gFocusMgr.childHasKeyboardFocus(this))
+ {
+ gFocusMgr.setKeyboardFocus(NULL);
+ }
+
+ // Disable all text input fields
+ clearCtrls();
+
+ return;
+ }
+
+ LLUUID owner_id;
+ std::string owner_name;
+ LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+
+ // BUG? Check for all objects being editable?
+ BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
+ BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )
+ && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1;
+ BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) &&
LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1;
- // Select Single Message
- if (single_volume)
- {
- getChildView("edit_object")->setVisible(true);
- getChildView("edit_object")->setEnabled(true);
- getChildView("select_single")->setVisible(false);
- }
- else
- {
- getChildView("edit_object")->setVisible(false);
- getChildView("select_single")->setVisible(true);
- getChildView("select_single")->setEnabled(true);
- }
-
- // Light properties
- BOOL is_light = volobjp && volobjp->getIsLight();
- getChild<LLUICtrl>("Light Checkbox Ctrl")->setValue(is_light);
- getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
-
- if (is_light && editable && single_volume)
- {
- //mLabelColor ->setEnabled( TRUE );
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LightColorSwatch->setEnabled( TRUE );
- LightColorSwatch->setValid( TRUE );
- LightColorSwatch->set(volobjp->getLightSRGBBaseColor());
- }
-
- LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
- if (LightTextureCtrl)
- {
- LightTextureCtrl->setEnabled(TRUE);
- LightTextureCtrl->setValid(TRUE);
- LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID());
- }
-
- getChildView("Light Intensity")->setEnabled(true);
- getChildView("Light Radius")->setEnabled(true);
- getChildView("Light Falloff")->setEnabled(true);
-
- getChildView("Light FOV")->setEnabled(true);
- getChildView("Light Focus")->setEnabled(true);
- getChildView("Light Ambiance")->setEnabled(true);
-
- getChild<LLUICtrl>("Light Intensity")->setValue(volobjp->getLightIntensity());
- getChild<LLUICtrl>("Light Radius")->setValue(volobjp->getLightRadius());
- getChild<LLUICtrl>("Light Falloff")->setValue(volobjp->getLightFalloff());
-
- LLVector3 params = volobjp->getSpotLightParams();
- getChild<LLUICtrl>("Light FOV")->setValue(params.mV[0]);
- getChild<LLUICtrl>("Light Focus")->setValue(params.mV[1]);
- getChild<LLUICtrl>("Light Ambiance")->setValue(params.mV[2]);
-
- mLightSavedColor = volobjp->getLightSRGBBaseColor();
- }
- else
- {
- getChild<LLSpinCtrl>("Light Intensity", true)->clear();
- getChild<LLSpinCtrl>("Light Radius", true)->clear();
- getChild<LLSpinCtrl>("Light Falloff", true)->clear();
-
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LightColorSwatch->setEnabled( FALSE );
- LightColorSwatch->setValid( FALSE );
- }
- LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
- if (LightTextureCtrl)
- {
- LightTextureCtrl->setEnabled(FALSE);
- LightTextureCtrl->setValid(FALSE);
+ // Select Single Message
+ if (single_volume)
+ {
+ getChildView("edit_object")->setVisible(true);
+ getChildView("edit_object")->setEnabled(true);
+ getChildView("select_single")->setVisible(false);
+ }
+ else
+ {
+ getChildView("edit_object")->setVisible(false);
+ getChildView("select_single")->setVisible(true);
+ getChildView("select_single")->setEnabled(true);
+ }
+
+ // Light properties
+ BOOL is_light = volobjp && volobjp->getIsLight();
+ getChild<LLUICtrl>("Light Checkbox Ctrl")->setValue(is_light);
+ getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
+
+ if (is_light && editable && single_volume)
+ {
+ //mLabelColor ->setEnabled( TRUE );
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LightColorSwatch->setEnabled( TRUE );
+ LightColorSwatch->setValid( TRUE );
+ LightColorSwatch->set(volobjp->getLightSRGBBaseColor());
+ }
+
+ LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+ if (LightTextureCtrl)
+ {
+ LightTextureCtrl->setEnabled(TRUE);
+ LightTextureCtrl->setValid(TRUE);
+ LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID());
+ }
+
+ getChildView("Light Intensity")->setEnabled(true);
+ getChildView("Light Radius")->setEnabled(true);
+ getChildView("Light Falloff")->setEnabled(true);
+
+ getChildView("Light FOV")->setEnabled(true);
+ getChildView("Light Focus")->setEnabled(true);
+ getChildView("Light Ambiance")->setEnabled(true);
+
+ getChild<LLUICtrl>("Light Intensity")->setValue(volobjp->getLightIntensity());
+ getChild<LLUICtrl>("Light Radius")->setValue(volobjp->getLightRadius());
+ getChild<LLUICtrl>("Light Falloff")->setValue(volobjp->getLightFalloff());
+
+ LLVector3 params = volobjp->getSpotLightParams();
+ getChild<LLUICtrl>("Light FOV")->setValue(params.mV[0]);
+ getChild<LLUICtrl>("Light Focus")->setValue(params.mV[1]);
+ getChild<LLUICtrl>("Light Ambiance")->setValue(params.mV[2]);
+
+ mLightSavedColor = volobjp->getLightSRGBBaseColor();
+ }
+ else
+ {
+ getChild<LLSpinCtrl>("Light Intensity", true)->clear();
+ getChild<LLSpinCtrl>("Light Radius", true)->clear();
+ getChild<LLSpinCtrl>("Light Falloff", true)->clear();
+
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LightColorSwatch->setEnabled( FALSE );
+ LightColorSwatch->setValid( FALSE );
+ }
+ LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+ if (LightTextureCtrl)
+ {
+ LightTextureCtrl->setEnabled(FALSE);
+ LightTextureCtrl->setValid(FALSE);
if (objectp->isAttachment())
{
@@ -374,16 +374,16 @@ void LLPanelVolume::getState( )
{
LightTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
}
- }
+ }
- getChildView("Light Intensity")->setEnabled(false);
- getChildView("Light Radius")->setEnabled(false);
- getChildView("Light Falloff")->setEnabled(false);
+ getChildView("Light Intensity")->setEnabled(false);
+ getChildView("Light Radius")->setEnabled(false);
+ getChildView("Light Falloff")->setEnabled(false);
- getChildView("Light FOV")->setEnabled(false);
- getChildView("Light Focus")->setEnabled(false);
- getChildView("Light Ambiance")->setEnabled(false);
- }
+ getChildView("Light FOV")->setEnabled(false);
+ getChildView("Light Focus")->setEnabled(false);
+ getChildView("Light Ambiance")->setEnabled(false);
+ }
// Reflection Probe
BOOL is_probe = volobjp && volobjp->isReflectionProbe();
@@ -392,17 +392,25 @@ void LLPanelVolume::getState( )
bool probe_enabled = is_probe && editable && single_volume;
+ bool mirrors_enabled = LLPipeline::RenderMirrors;
+
+ getChildView("Probe Update Type")->setVisible(mirrors_enabled);
+ getChildView("Probe Update Label")->setVisible(mirrors_enabled);
+ getChildView("Probe Dynamic")->setVisible(!mirrors_enabled);
+
getChildView("Probe Dynamic")->setEnabled(probe_enabled);
+ getChildView("Probe Update Type")->setEnabled(probe_enabled);
getChildView("Probe Volume Type")->setEnabled(probe_enabled);
getChildView("Probe Ambiance")->setEnabled(probe_enabled);
getChildView("Probe Near Clip")->setEnabled(probe_enabled);
+ getChildView("Probe Update Label")->setEnabled(probe_enabled);
if (!probe_enabled)
{
getChild<LLComboBox>("Probe Volume Type", true)->clear();
getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
- getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
+ getChild<LLComboBox>("Probe Update Type", true)->clear();
}
else
{
@@ -416,19 +424,39 @@ void LLPanelVolume::getState( )
volume_type = "Sphere";
}
+
+ std::string update_type = "Static";
+
+ if (volobjp->getReflectionProbeIsDynamic() && !volobjp->getReflectionProbeIsMirror())
+ {
+ update_type = "Dynamic";
+ }
+ else if (volobjp->getReflectionProbeIsMirror() && !volobjp->getReflectionProbeIsDynamic())
+ {
+ update_type = "Mirror";
+
+ }
+ else if (volobjp->getReflectionProbeIsDynamic() && volobjp->getReflectionProbeIsMirror())
+ {
+ update_type = "Dynamic Mirror";
+ }
+
+ getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror");
+ getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror");
+
getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
- getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
+ getChild<LLComboBox>("Probe Update Type", true)->setValue(update_type);
}
// Animated Mesh
- BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
- getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
+ BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
+ getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
BOOL enabled_animated_object_box = FALSE;
if (root_volobjp && root_volobjp == volobjp)
{
- enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable;
+ enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable;
#if 0
if (!enabled_animated_object_box)
{
@@ -441,7 +469,7 @@ void LLPanelVolume::getState( )
}
}
#endif
- if (enabled_animated_object_box && !is_animated_mesh &&
+ if (enabled_animated_object_box && !is_animated_mesh &&
root_volobjp->isAttachment() && !gAgentAvatarp->canAttachMoreAnimatedObjects())
{
// Turning this attachment animated would cause us to exceed the limit.
@@ -449,182 +477,182 @@ void LLPanelVolume::getState( )
}
}
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(enabled_animated_object_box);
-
- //refresh any bakes
- if (root_volobjp)
- {
- root_volobjp->refreshBakeTexture();
-
- LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- if (objectp)
- {
- objectp->refreshBakeTexture();
- }
- }
-
- if (gAgentAvatarp)
- {
- gAgentAvatarp->updateMeshVisibility();
- }
- }
-
- // Flexible properties
- BOOL is_flexible = volobjp && volobjp->isFlexible();
- getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
- if (is_flexible || (volobjp && volobjp->canBeFlexible()))
- {
- getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced());
- }
- else
- {
- getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
- }
- if (is_flexible && editable && single_volume)
- {
- getChildView("FlexNumSections")->setVisible(true);
- getChildView("FlexGravity")->setVisible(true);
- getChildView("FlexTension")->setVisible(true);
- getChildView("FlexFriction")->setVisible(true);
- getChildView("FlexWind")->setVisible(true);
- getChildView("FlexForceX")->setVisible(true);
- getChildView("FlexForceY")->setVisible(true);
- getChildView("FlexForceZ")->setVisible(true);
-
- getChildView("FlexNumSections")->setEnabled(true);
- getChildView("FlexGravity")->setEnabled(true);
- getChildView("FlexTension")->setEnabled(true);
- getChildView("FlexFriction")->setEnabled(true);
- getChildView("FlexWind")->setEnabled(true);
- getChildView("FlexForceX")->setEnabled(true);
- getChildView("FlexForceY")->setEnabled(true);
- getChildView("FlexForceZ")->setEnabled(true);
-
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
-
- getChild<LLUICtrl>("FlexNumSections")->setValue((F32)attributes->getSimulateLOD());
- getChild<LLUICtrl>("FlexGravity")->setValue(attributes->getGravity());
- getChild<LLUICtrl>("FlexTension")->setValue(attributes->getTension());
- getChild<LLUICtrl>("FlexFriction")->setValue(attributes->getAirFriction());
- getChild<LLUICtrl>("FlexWind")->setValue(attributes->getWindSensitivity());
- getChild<LLUICtrl>("FlexForceX")->setValue(attributes->getUserForce().mV[VX]);
- getChild<LLUICtrl>("FlexForceY")->setValue(attributes->getUserForce().mV[VY]);
- getChild<LLUICtrl>("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]);
- }
- else
- {
- getChild<LLSpinCtrl>("FlexNumSections", true)->clear();
- getChild<LLSpinCtrl>("FlexGravity", true)->clear();
- getChild<LLSpinCtrl>("FlexTension", true)->clear();
- getChild<LLSpinCtrl>("FlexFriction", true)->clear();
- getChild<LLSpinCtrl>("FlexWind", true)->clear();
- getChild<LLSpinCtrl>("FlexForceX", true)->clear();
- getChild<LLSpinCtrl>("FlexForceY", true)->clear();
- getChild<LLSpinCtrl>("FlexForceZ", true)->clear();
-
- getChildView("FlexNumSections")->setEnabled(false);
- getChildView("FlexGravity")->setEnabled(false);
- getChildView("FlexTension")->setEnabled(false);
- getChildView("FlexFriction")->setEnabled(false);
- getChildView("FlexWind")->setEnabled(false);
- getChildView("FlexForceX")->setEnabled(false);
- getChildView("FlexForceY")->setEnabled(false);
- getChildView("FlexForceZ")->setEnabled(false);
- }
-
- // Material properties
-
- // Update material part
- // slightly inefficient - materials are unique per object, not per TE
- U8 material_code = 0;
- struct f : public LLSelectedTEGetFunctor<U8>
- {
- U8 get(LLViewerObject* object, S32 te)
- {
- return object->getMaterial();
- }
- } func;
- bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code );
- std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
- if (editable && single_volume && material_same)
- {
- mComboMaterial->setEnabled( TRUE );
- if (material_code == LL_MCODE_LIGHT)
- {
- if (mComboMaterial->getItemCount() == mComboMaterialItemCount)
- {
- mComboMaterial->add(LEGACY_FULLBRIGHT_DESC);
- }
- mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC);
- }
- else
- {
- if (mComboMaterial->getItemCount() != mComboMaterialItemCount)
- {
- mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC);
- }
-
- mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code)));
- }
- }
- else
- {
- mComboMaterial->setEnabled( FALSE );
- }
-
- // Physics properties
-
- mSpinPhysicsGravity->set(objectp->getPhysicsGravity());
- mSpinPhysicsGravity->setEnabled(editable);
-
- mSpinPhysicsFriction->set(objectp->getPhysicsFriction());
- mSpinPhysicsFriction->setEnabled(editable);
-
- mSpinPhysicsDensity->set(objectp->getPhysicsDensity());
- mSpinPhysicsDensity->setEnabled(editable);
-
- mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution());
- mSpinPhysicsRestitution->setEnabled(editable);
-
- // update the physics shape combo to include allowed physics shapes
- mComboPhysicsShapeType->removeall();
- mComboPhysicsShapeType->add(getString("None"), LLSD(1));
-
- BOOL isMesh = FALSE;
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- if (sculpt_params)
- {
- U8 sculpt_type = sculpt_params->getSculptType();
- U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
- isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH);
- }
-
- if(isMesh && objectp)
- {
- const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
- LLUUID mesh_id = volume_params.getSculptID();
- if(gMeshRepo.hasPhysicsShape(mesh_id))
- {
- // if a mesh contains an uploaded or decomposed physics mesh,
- // allow 'Prim'
- mComboPhysicsShapeType->add(getString("Prim"), LLSD(0));
- }
- }
- else
- {
- // simple prims always allow physics shape prim
- mComboPhysicsShapeType->add(getString("Prim"), LLSD(0));
- }
-
- mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2));
- mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType()));
- mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()));
-
- mObject = objectp;
- mRootObject = root_objectp;
+
+ //refresh any bakes
+ if (root_volobjp)
+ {
+ root_volobjp->refreshBakeTexture();
+
+ LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ if (objectp)
+ {
+ objectp->refreshBakeTexture();
+ }
+ }
+
+ if (gAgentAvatarp)
+ {
+ gAgentAvatarp->updateMeshVisibility();
+ }
+ }
+
+ // Flexible properties
+ BOOL is_flexible = volobjp && volobjp->isFlexible();
+ getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
+ if (is_flexible || (volobjp && volobjp->canBeFlexible()))
+ {
+ getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced());
+ }
+ else
+ {
+ getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
+ }
+ if (is_flexible && editable && single_volume)
+ {
+ getChildView("FlexNumSections")->setVisible(true);
+ getChildView("FlexGravity")->setVisible(true);
+ getChildView("FlexTension")->setVisible(true);
+ getChildView("FlexFriction")->setVisible(true);
+ getChildView("FlexWind")->setVisible(true);
+ getChildView("FlexForceX")->setVisible(true);
+ getChildView("FlexForceY")->setVisible(true);
+ getChildView("FlexForceZ")->setVisible(true);
+
+ getChildView("FlexNumSections")->setEnabled(true);
+ getChildView("FlexGravity")->setEnabled(true);
+ getChildView("FlexTension")->setEnabled(true);
+ getChildView("FlexFriction")->setEnabled(true);
+ getChildView("FlexWind")->setEnabled(true);
+ getChildView("FlexForceX")->setEnabled(true);
+ getChildView("FlexForceY")->setEnabled(true);
+ getChildView("FlexForceZ")->setEnabled(true);
+
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+
+ getChild<LLUICtrl>("FlexNumSections")->setValue((F32)attributes->getSimulateLOD());
+ getChild<LLUICtrl>("FlexGravity")->setValue(attributes->getGravity());
+ getChild<LLUICtrl>("FlexTension")->setValue(attributes->getTension());
+ getChild<LLUICtrl>("FlexFriction")->setValue(attributes->getAirFriction());
+ getChild<LLUICtrl>("FlexWind")->setValue(attributes->getWindSensitivity());
+ getChild<LLUICtrl>("FlexForceX")->setValue(attributes->getUserForce().mV[VX]);
+ getChild<LLUICtrl>("FlexForceY")->setValue(attributes->getUserForce().mV[VY]);
+ getChild<LLUICtrl>("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]);
+ }
+ else
+ {
+ getChild<LLSpinCtrl>("FlexNumSections", true)->clear();
+ getChild<LLSpinCtrl>("FlexGravity", true)->clear();
+ getChild<LLSpinCtrl>("FlexTension", true)->clear();
+ getChild<LLSpinCtrl>("FlexFriction", true)->clear();
+ getChild<LLSpinCtrl>("FlexWind", true)->clear();
+ getChild<LLSpinCtrl>("FlexForceX", true)->clear();
+ getChild<LLSpinCtrl>("FlexForceY", true)->clear();
+ getChild<LLSpinCtrl>("FlexForceZ", true)->clear();
+
+ getChildView("FlexNumSections")->setEnabled(false);
+ getChildView("FlexGravity")->setEnabled(false);
+ getChildView("FlexTension")->setEnabled(false);
+ getChildView("FlexFriction")->setEnabled(false);
+ getChildView("FlexWind")->setEnabled(false);
+ getChildView("FlexForceX")->setEnabled(false);
+ getChildView("FlexForceY")->setEnabled(false);
+ getChildView("FlexForceZ")->setEnabled(false);
+ }
+
+ // Material properties
+
+ // Update material part
+ // slightly inefficient - materials are unique per object, not per TE
+ U8 material_code = 0;
+ struct f : public LLSelectedTEGetFunctor<U8>
+ {
+ U8 get(LLViewerObject* object, S32 te)
+ {
+ return object->getMaterial();
+ }
+ } func;
+ bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code );
+ std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
+ if (editable && single_volume && material_same)
+ {
+ mComboMaterial->setEnabled( TRUE );
+ if (material_code == LL_MCODE_LIGHT)
+ {
+ if (mComboMaterial->getItemCount() == mComboMaterialItemCount)
+ {
+ mComboMaterial->add(LEGACY_FULLBRIGHT_DESC);
+ }
+ mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC);
+ }
+ else
+ {
+ if (mComboMaterial->getItemCount() != mComboMaterialItemCount)
+ {
+ mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC);
+ }
+
+ mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code)));
+ }
+ }
+ else
+ {
+ mComboMaterial->setEnabled( FALSE );
+ }
+
+ // Physics properties
+
+ mSpinPhysicsGravity->set(objectp->getPhysicsGravity());
+ mSpinPhysicsGravity->setEnabled(editable);
+
+ mSpinPhysicsFriction->set(objectp->getPhysicsFriction());
+ mSpinPhysicsFriction->setEnabled(editable);
+
+ mSpinPhysicsDensity->set(objectp->getPhysicsDensity());
+ mSpinPhysicsDensity->setEnabled(editable);
+
+ mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution());
+ mSpinPhysicsRestitution->setEnabled(editable);
+
+ // update the physics shape combo to include allowed physics shapes
+ mComboPhysicsShapeType->removeall();
+ mComboPhysicsShapeType->add(getString("None"), LLSD(1));
+
+ BOOL isMesh = FALSE;
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ {
+ U8 sculpt_type = sculpt_params->getSculptType();
+ U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
+ isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH);
+ }
+
+ if(isMesh && objectp)
+ {
+ const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
+ LLUUID mesh_id = volume_params.getSculptID();
+ if(gMeshRepo.hasPhysicsShape(mesh_id))
+ {
+ // if a mesh contains an uploaded or decomposed physics mesh,
+ // allow 'Prim'
+ mComboPhysicsShapeType->add(getString("Prim"), LLSD(0));
+ }
+ }
+ else
+ {
+ // simple prims always allow physics shape prim
+ mComboPhysicsShapeType->add(getString("Prim"), LLSD(0));
+ }
+
+ mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2));
+ mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType()));
+ mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()));
+
+ mObject = objectp;
+ mRootObject = root_objectp;
mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume
mMenuClipboardLight->setEnabled(editable && single_volume && volobjp);
@@ -633,99 +661,99 @@ void LLPanelVolume::getState( )
// static
bool LLPanelVolume::precommitValidate( const LLSD& data )
{
- // TODO: Richard will fill this in later.
- return TRUE; // FALSE means that validation failed and new value should not be commited.
+ // TODO: Richard will fill this in later.
+ return TRUE; // FALSE means that validation failed and new value should not be commited.
}
void LLPanelVolume::refresh()
{
- getState();
- if (mObject.notNull() && mObject->isDead())
- {
- mObject = NULL;
- }
-
- if (mRootObject.notNull() && mRootObject->isDead())
- {
- mRootObject = NULL;
- }
-
- bool enable_mesh = false;
-
- LLSD sim_features;
- LLViewerRegion *region = gAgent.getRegion();
- if(region)
- {
- LLSD sim_features;
- region->getSimulatorFeatures(sim_features);
- enable_mesh = sim_features.has("PhysicsShapeTypes");
- }
- getChildView("label physicsshapetype")->setVisible(enable_mesh);
- getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh);
- getChildView("Physics Gravity")->setVisible(enable_mesh);
- getChildView("Physics Friction")->setVisible(enable_mesh);
- getChildView("Physics Density")->setVisible(enable_mesh);
- getChildView("Physics Restitution")->setVisible(enable_mesh);
-
+ getState();
+ if (mObject.notNull() && mObject->isDead())
+ {
+ mObject = NULL;
+ }
+
+ if (mRootObject.notNull() && mRootObject->isDead())
+ {
+ mRootObject = NULL;
+ }
+
+ bool enable_mesh = false;
+
+ LLSD sim_features;
+ LLViewerRegion *region = gAgent.getRegion();
+ if(region)
+ {
+ LLSD sim_features;
+ region->getSimulatorFeatures(sim_features);
+ enable_mesh = sim_features.has("PhysicsShapeTypes");
+ }
+ getChildView("label physicsshapetype")->setVisible(enable_mesh);
+ getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh);
+ getChildView("Physics Gravity")->setVisible(enable_mesh);
+ getChildView("Physics Friction")->setVisible(enable_mesh);
+ getChildView("Physics Density")->setVisible(enable_mesh);
+ getChildView("Physics Restitution")->setVisible(enable_mesh);
+
/* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */
}
void LLPanelVolume::draw()
{
- LLPanel::draw();
+ LLPanel::draw();
}
// virtual
void LLPanelVolume::clearCtrls()
{
- LLPanel::clearCtrls();
-
- getChildView("select_single")->setEnabled(false);
- getChildView("select_single")->setVisible(true);
- getChildView("edit_object")->setEnabled(false);
- getChildView("edit_object")->setVisible(false);
- getChildView("Light Checkbox Ctrl")->setEnabled(false);;
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LightColorSwatch->setEnabled( FALSE );
- LightColorSwatch->setValid( FALSE );
- }
- LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
- if(LightTextureCtrl)
- {
- LightTextureCtrl->setEnabled( FALSE );
- LightTextureCtrl->setValid( FALSE );
- }
-
- getChildView("Light Intensity")->setEnabled(false);
- getChildView("Light Radius")->setEnabled(false);
- getChildView("Light Falloff")->setEnabled(false);
+ LLPanel::clearCtrls();
+
+ getChildView("select_single")->setEnabled(false);
+ getChildView("select_single")->setVisible(true);
+ getChildView("edit_object")->setEnabled(false);
+ getChildView("edit_object")->setVisible(false);
+ getChildView("Light Checkbox Ctrl")->setEnabled(false);;
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LightColorSwatch->setEnabled( FALSE );
+ LightColorSwatch->setValid( FALSE );
+ }
+ LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+ if(LightTextureCtrl)
+ {
+ LightTextureCtrl->setEnabled( FALSE );
+ LightTextureCtrl->setValid( FALSE );
+ }
+
+ getChildView("Light Intensity")->setEnabled(false);
+ getChildView("Light Radius")->setEnabled(false);
+ getChildView("Light Falloff")->setEnabled(false);
getChildView("Reflection Probe")->setEnabled(false);;
getChildView("Probe Volume Type")->setEnabled(false);
- getChildView("Probe Dynamic")->setEnabled(false);
+ getChildView("Probe Update Type")->setEnabled(false);
getChildView("Probe Ambiance")->setEnabled(false);
getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
- getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
- getChildView("FlexNumSections")->setEnabled(false);
- getChildView("FlexGravity")->setEnabled(false);
- getChildView("FlexTension")->setEnabled(false);
- getChildView("FlexFriction")->setEnabled(false);
- getChildView("FlexWind")->setEnabled(false);
- getChildView("FlexForceX")->setEnabled(false);
- getChildView("FlexForceY")->setEnabled(false);
- getChildView("FlexForceZ")->setEnabled(false);
-
- mSpinPhysicsGravity->setEnabled(FALSE);
- mSpinPhysicsFriction->setEnabled(FALSE);
- mSpinPhysicsDensity->setEnabled(FALSE);
- mSpinPhysicsRestitution->setEnabled(FALSE);
-
- mComboMaterial->setEnabled( FALSE );
+ getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
+ getChildView("FlexNumSections")->setEnabled(false);
+ getChildView("FlexGravity")->setEnabled(false);
+ getChildView("FlexTension")->setEnabled(false);
+ getChildView("FlexFriction")->setEnabled(false);
+ getChildView("FlexWind")->setEnabled(false);
+ getChildView("FlexForceX")->setEnabled(false);
+ getChildView("FlexForceY")->setEnabled(false);
+ getChildView("FlexForceZ")->setEnabled(false);
+
+ mSpinPhysicsGravity->setEnabled(FALSE);
+ mSpinPhysicsFriction->setEnabled(FALSE);
+ mSpinPhysicsDensity->setEnabled(FALSE);
+ mSpinPhysicsRestitution->setEnabled(FALSE);
+
+ mComboMaterial->setEnabled( FALSE );
}
//
@@ -734,16 +762,16 @@ void LLPanelVolume::clearCtrls()
void LLPanelVolume::sendIsLight()
{
- LLViewerObject* objectp = mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- LLVOVolume *volobjp = (LLVOVolume *)objectp;
-
- BOOL value = getChild<LLUICtrl>("Light Checkbox Ctrl")->getValue();
- volobjp->setIsLight(value);
- LL_INFOS() << "update light sent" << LL_ENDL;
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+
+ BOOL value = getChild<LLUICtrl>("Light Checkbox Ctrl")->getValue();
+ volobjp->setIsLight(value);
+ LL_INFOS() << "update light sent" << LL_ENDL;
}
void notify_cant_select_reflection_probe()
@@ -829,97 +857,97 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
void LLPanelVolume::sendIsFlexible()
{
- LLViewerObject* objectp = mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- LLVOVolume *volobjp = (LLVOVolume *)objectp;
-
- BOOL is_flexible = getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->getValue();
- //BOOL is_flexible = mCheckFlexible1D->get();
-
- if (is_flexible)
- {
- //LLFirstUse::useFlexible();
-
- if (objectp->getClickAction() == CLICK_ACTION_SIT)
- {
- LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE);
- }
-
- }
-
- if (volobjp->setIsFlexible(is_flexible))
- {
- mObject->sendShapeUpdate();
- LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
- }
-
- LL_INFOS() << "update flexible sent" << LL_ENDL;
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+
+ BOOL is_flexible = getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->getValue();
+ //BOOL is_flexible = mCheckFlexible1D->get();
+
+ if (is_flexible)
+ {
+ //LLFirstUse::useFlexible();
+
+ if (objectp->getClickAction() == CLICK_ACTION_SIT)
+ {
+ LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE);
+ }
+
+ }
+
+ if (volobjp->setIsFlexible(is_flexible))
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+
+ LL_INFOS() << "update flexible sent" << LL_ENDL;
}
void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata)
{
- U8 type = ctrl->getValue().asInteger();
- LLSelectMgr::getInstance()->selectionSetPhysicsType(type);
+ U8 type = ctrl->getValue().asInteger();
+ LLSelectMgr::getInstance()->selectionSetPhysicsType(type);
- refreshCost();
+ refreshCost();
}
void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata)
{
- F32 val = ctrl->getValue().asReal();
- LLSelectMgr::getInstance()->selectionSetGravity(val);
+ F32 val = ctrl->getValue().asReal();
+ LLSelectMgr::getInstance()->selectionSetGravity(val);
}
void LLPanelVolume::sendPhysicsFriction(LLUICtrl* ctrl, void* userdata)
{
- F32 val = ctrl->getValue().asReal();
- LLSelectMgr::getInstance()->selectionSetFriction(val);
+ F32 val = ctrl->getValue().asReal();
+ LLSelectMgr::getInstance()->selectionSetFriction(val);
}
void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata)
{
- F32 val = ctrl->getValue().asReal();
- LLSelectMgr::getInstance()->selectionSetRestitution(val);
+ F32 val = ctrl->getValue().asReal();
+ LLSelectMgr::getInstance()->selectionSetRestitution(val);
}
void LLPanelVolume::sendPhysicsDensity(LLUICtrl* ctrl, void* userdata)
{
- F32 val = ctrl->getValue().asReal();
- LLSelectMgr::getInstance()->selectionSetDensity(val);
+ F32 val = ctrl->getValue().asReal();
+ LLSelectMgr::getInstance()->selectionSetDensity(val);
}
void LLPanelVolume::refreshCost()
{
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
-
- if (obj)
- {
- obj->getObjectCost();
- }
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+
+ if (obj)
+ {
+ obj->getObjectCost();
+ }
}
void LLPanelVolume::onLightCancelColor(const LLSD& data)
{
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LightColorSwatch->setColor(mLightSavedColor);
- }
- onLightSelectColor(data);
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LightColorSwatch->setColor(mLightSavedColor);
+ }
+ onLightSelectColor(data);
}
void LLPanelVolume::onLightCancelTexture(const LLSD& data)
{
- LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
- LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
+ LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+ LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
- if (volobjp && LightTextureCtrl)
- {
- // Cancel the light texture as requested
- // NORSPEC-292
+ if (volobjp && LightTextureCtrl)
+ {
+ // Cancel the light texture as requested
+ // NORSPEC-292
//
// Texture picker triggers cancel both in case of actual cancel and in case of
// selection of "None" texture.
@@ -934,44 +962,44 @@ void LLPanelVolume::onLightCancelTexture(const LLSD& data)
getChild<LLUICtrl>("Light Focus")->setValue(spot_params.mV[1]);
getChild<LLUICtrl>("Light Ambiance")->setValue(spot_params.mV[2]);
}
- }
+ }
}
void LLPanelVolume::onLightSelectColor(const LLSD& data)
{
- LLViewerObject* objectp = mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- LLVOVolume *volobjp = (LLVOVolume *)objectp;
-
-
- LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LLColor4 clr = LightColorSwatch->get();
- LLColor3 clr3( clr );
- volobjp->setLightSRGBColor(clr3);
- mLightSavedColor = clr;
- }
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+
+
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LLColor4 clr = LightColorSwatch->get();
+ LLColor3 clr3( clr );
+ volobjp->setLightSRGBColor(clr3);
+ mLightSavedColor = clr;
+ }
}
void LLPanelVolume::onLightSelectTexture(const LLSD& data)
{
- if (mObject.isNull() || (mObject->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
-
-
- LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
- if(LightTextureCtrl)
- {
- LLUUID id = LightTextureCtrl->getImageAssetID();
- setLightTextureID(id, LightTextureCtrl->getImageItemID(), volobjp);
- }
+ if (mObject.isNull() || (mObject->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
+
+
+ LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+ if(LightTextureCtrl)
+ {
+ LLUUID id = LightTextureCtrl->getImageAssetID();
+ setLightTextureID(id, LightTextureCtrl->getImageItemID(), volobjp);
+ }
}
void LLPanelVolume::onCopyFeatures()
@@ -1174,6 +1202,7 @@ void LLPanelVolume::onCopyLight()
clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
+ clipboard["reflection_probe"]["mirror"] = volobjp->getReflectionProbeIsMirror();
}
mClipboardParams["light"] = clipboard;
@@ -1231,6 +1260,7 @@ void LLPanelVolume::onPasteLight()
volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
+ volobjp->setReflectionProbeIsMirror(clipboard["reflection_probe"]["mirror"].asBoolean());
}
else
{
@@ -1293,100 +1323,100 @@ bool LLPanelVolume::menuEnableItem(const LLSD& userdata)
// static
void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
- LLPanelVolume* self = (LLPanelVolume*)userdata;
- LLComboBox* box = (LLComboBox*) ctrl;
-
- if (box)
- {
- // apply the currently selected material to the object
- const std::string& material_name = box->getSimple();
- std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
- if (material_name != LEGACY_FULLBRIGHT_DESC)
- {
- U8 material_code = LLMaterialTable::basic.getMCode(material_name);
- if (self)
- {
- LLViewerObject* objectp = self->mObject;
- if (objectp)
- {
- objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER);
- objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code));
- //currently density is always set to 1000 serverside regardless of chosen material,
- //actual material density should be used here, if this behavior change
- objectp->setPhysicsDensity(DEFAULT_DENSITY);
- objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code));
- }
- }
- LLSelectMgr::getInstance()->selectionSetMaterial(material_code);
- }
- }
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ LLComboBox* box = (LLComboBox*) ctrl;
+
+ if (box)
+ {
+ // apply the currently selected material to the object
+ const std::string& material_name = box->getSimple();
+ std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
+ if (material_name != LEGACY_FULLBRIGHT_DESC)
+ {
+ U8 material_code = LLMaterialTable::basic.getMCode(material_name);
+ if (self)
+ {
+ LLViewerObject* objectp = self->mObject;
+ if (objectp)
+ {
+ objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER);
+ objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code));
+ //currently density is always set to 1000 serverside regardless of chosen material,
+ //actual material density should be used here, if this behavior change
+ objectp->setPhysicsDensity(DEFAULT_DENSITY);
+ objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code));
+ }
+ }
+ LLSelectMgr::getInstance()->selectionSetMaterial(material_code);
+ }
+ }
}
// static
void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- LLViewerObject* objectp = self->mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- LLVOVolume *volobjp = (LLVOVolume *)objectp;
-
-
- volobjp->setLightIntensity((F32)self->getChild<LLUICtrl>("Light Intensity")->getValue().asReal());
- volobjp->setLightRadius((F32)self->getChild<LLUICtrl>("Light Radius")->getValue().asReal());
- volobjp->setLightFalloff((F32)self->getChild<LLUICtrl>("Light Falloff")->getValue().asReal());
-
- LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch");
- if(LightColorSwatch)
- {
- LLColor4 clr = LightColorSwatch->get();
- volobjp->setLightSRGBColor(LLColor3(clr));
- }
-
- LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control");
- if(LightTextureCtrl)
- {
- LLUUID id = LightTextureCtrl->getImageAssetID();
+ LLPanelVolume* self = (LLPanelVolume*) userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+
+
+ volobjp->setLightIntensity((F32)self->getChild<LLUICtrl>("Light Intensity")->getValue().asReal());
+ volobjp->setLightRadius((F32)self->getChild<LLUICtrl>("Light Radius")->getValue().asReal());
+ volobjp->setLightFalloff((F32)self->getChild<LLUICtrl>("Light Falloff")->getValue().asReal());
+
+ LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch");
+ if(LightColorSwatch)
+ {
+ LLColor4 clr = LightColorSwatch->get();
+ volobjp->setLightSRGBColor(LLColor3(clr));
+ }
+
+ LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control");
+ if(LightTextureCtrl)
+ {
+ LLUUID id = LightTextureCtrl->getImageAssetID();
LLUUID item_id = LightTextureCtrl->getImageItemID();
- if (id.notNull())
- {
- if (!volobjp->isLightSpotlight())
- { //this commit is making this a spot light, set UI to default params
+ if (id.notNull())
+ {
+ if (!volobjp->isLightSpotlight())
+ { //this commit is making this a spot light, set UI to default params
setLightTextureID(id, item_id, volobjp);
- LLVector3 spot_params = volobjp->getSpotLightParams();
- self->getChild<LLUICtrl>("Light FOV")->setValue(spot_params.mV[0]);
- self->getChild<LLUICtrl>("Light Focus")->setValue(spot_params.mV[1]);
- self->getChild<LLUICtrl>("Light Ambiance")->setValue(spot_params.mV[2]);
- }
- else
- { //modifying existing params, this time volobjp won't change params on its own.
+ LLVector3 spot_params = volobjp->getSpotLightParams();
+ self->getChild<LLUICtrl>("Light FOV")->setValue(spot_params.mV[0]);
+ self->getChild<LLUICtrl>("Light Focus")->setValue(spot_params.mV[1]);
+ self->getChild<LLUICtrl>("Light Ambiance")->setValue(spot_params.mV[2]);
+ }
+ else
+ { //modifying existing params, this time volobjp won't change params on its own.
if (volobjp->getLightTextureID() != id)
{
setLightTextureID(id, item_id, volobjp);
}
- LLVector3 spot_params;
- spot_params.mV[0] = (F32) self->getChild<LLUICtrl>("Light FOV")->getValue().asReal();
- spot_params.mV[1] = (F32) self->getChild<LLUICtrl>("Light Focus")->getValue().asReal();
- spot_params.mV[2] = (F32) self->getChild<LLUICtrl>("Light Ambiance")->getValue().asReal();
- volobjp->setSpotLightParams(spot_params);
- }
- }
- else if (volobjp->isLightSpotlight())
- { //no longer a spot light
- setLightTextureID(id, item_id, volobjp);
- //self->getChildView("Light FOV")->setEnabled(FALSE);
- //self->getChildView("Light Focus")->setEnabled(FALSE);
- //self->getChildView("Light Ambiance")->setEnabled(FALSE);
- }
- }
-
-
+ LLVector3 spot_params;
+ spot_params.mV[0] = (F32) self->getChild<LLUICtrl>("Light FOV")->getValue().asReal();
+ spot_params.mV[1] = (F32) self->getChild<LLUICtrl>("Light Focus")->getValue().asReal();
+ spot_params.mV[2] = (F32) self->getChild<LLUICtrl>("Light Ambiance")->getValue().asReal();
+ volobjp->setSpotLightParams(spot_params);
+ }
+ }
+ else if (volobjp->isLightSpotlight())
+ { //no longer a spot light
+ setLightTextureID(id, item_id, volobjp);
+ //self->getChildView("Light FOV")->setEnabled(FALSE);
+ //self->getChildView("Light Focus")->setEnabled(FALSE);
+ //self->getChildView("Light Ambiance")->setEnabled(FALSE);
+ }
+ }
+
+
}
-//static
+//static
void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
{
LLPanelVolume* self = (LLPanelVolume*)userdata;
@@ -1399,7 +1429,16 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
- volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
+
+ std::string update_type = self->getChild<LLUICtrl>("Probe Update Type")->getValue().asString();
+
+ bool is_mirror = update_type.find("Mirror") != std::string::npos;
+
+ volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos);
+ volobjp->setReflectionProbeIsMirror(is_mirror);
+
+ self->getChildView("Probe Ambiance")->setEnabled(!is_mirror);
+ self->getChildView("Probe Near Clip")->setEnabled(!is_mirror);
std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
@@ -1430,7 +1469,7 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
profile = LL_PCODE_PROFILE_SQUARE;
path = LL_PCODE_PATH_LINE;
}
-
+
LLVolumeParams params;
params.getProfileParams().setCurveType(profile);
params.getPathParams().setCurveType(path);
@@ -1442,8 +1481,8 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
// static
void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- self->sendIsLight();
+ LLPanelVolume* self = (LLPanelVolume*) userdata;
+ self->sendIsLight();
}
// static
@@ -1468,7 +1507,7 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
- }
+ }
volobjp->setLightTextureID(asset_id);
}
}
@@ -1486,47 +1525,47 @@ void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata)
// static
void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- LLViewerObject* objectp = self->mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
-
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
- if (attributes)
- {
- LLFlexibleObjectData new_attributes;
- new_attributes = *attributes;
-
-
- new_attributes.setSimulateLOD(self->getChild<LLUICtrl>("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get());
- new_attributes.setGravity((F32)self->getChild<LLUICtrl>("FlexGravity")->getValue().asReal());
- new_attributes.setTension((F32)self->getChild<LLUICtrl>("FlexTension")->getValue().asReal());
- new_attributes.setAirFriction((F32)self->getChild<LLUICtrl>("FlexFriction")->getValue().asReal());
- new_attributes.setWindSensitivity((F32)self->getChild<LLUICtrl>("FlexWind")->getValue().asReal());
- F32 fx = (F32)self->getChild<LLUICtrl>("FlexForceX")->getValue().asReal();
- F32 fy = (F32)self->getChild<LLUICtrl>("FlexForceY")->getValue().asReal();
- F32 fz = (F32)self->getChild<LLUICtrl>("FlexForceZ")->getValue().asReal();
- LLVector3 force(fx,fy,fz);
-
- new_attributes.setUserForce(force);
- objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
- }
-
- // Values may fail validation
- self->refresh();
+ LLPanelVolume* self = (LLPanelVolume*) userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ LLFlexibleObjectData new_attributes;
+ new_attributes = *attributes;
+
+
+ new_attributes.setSimulateLOD(self->getChild<LLUICtrl>("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get());
+ new_attributes.setGravity((F32)self->getChild<LLUICtrl>("FlexGravity")->getValue().asReal());
+ new_attributes.setTension((F32)self->getChild<LLUICtrl>("FlexTension")->getValue().asReal());
+ new_attributes.setAirFriction((F32)self->getChild<LLUICtrl>("FlexFriction")->getValue().asReal());
+ new_attributes.setWindSensitivity((F32)self->getChild<LLUICtrl>("FlexWind")->getValue().asReal());
+ F32 fx = (F32)self->getChild<LLUICtrl>("FlexForceX")->getValue().asReal();
+ F32 fy = (F32)self->getChild<LLUICtrl>("FlexForceY")->getValue().asReal();
+ F32 fz = (F32)self->getChild<LLUICtrl>("FlexForceZ")->getValue().asReal();
+ LLVector3 force(fx,fy,fz);
+
+ new_attributes.setUserForce(force);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
+ }
+
+ // Values may fail validation
+ self->refresh();
}
void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*)
{
- LLViewerObject* objectp = mObject;
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
}
- LLVOVolume *volobjp = (LLVOVolume *)objectp;
- BOOL animated_mesh = getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->getValue();
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ BOOL animated_mesh = getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->getValue();
U32 flags = volobjp->getExtendedMeshFlags();
U32 new_flags = flags;
if (animated_mesh)
@@ -1542,49 +1581,49 @@ void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*)
volobjp->setExtendedMeshFlags(new_flags);
}
- //refresh any bakes
- if (volobjp)
- {
- volobjp->refreshBakeTexture();
-
- LLViewerObject::const_child_list_t& child_list = volobjp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- if (objectp)
- {
- objectp->refreshBakeTexture();
- }
- }
-
- if (gAgentAvatarp)
- {
- gAgentAvatarp->updateMeshVisibility();
- }
- }
+ //refresh any bakes
+ if (volobjp)
+ {
+ volobjp->refreshBakeTexture();
+
+ LLViewerObject::const_child_list_t& child_list = volobjp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ if (objectp)
+ {
+ objectp->refreshBakeTexture();
+ }
+ }
+
+ if (gAgentAvatarp)
+ {
+ gAgentAvatarp->updateMeshVisibility();
+ }
+ }
}
void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*)
{
- if (mObject->flagObjectPermanent())
- {
- LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2));
- }
- else
- {
- sendIsFlexible();
- }
+ if (mObject->flagObjectPermanent())
+ {
+ LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2));
+ }
+ else
+ {
+ sendIsFlexible();
+ }
}
void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse)
{
- if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
- {
- sendIsFlexible();
- }
- else
- {
- getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE);
- }
+ if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
+ {
+ sendIsFlexible();
+ }
+ else
+ {
+ getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE);
+ }
}
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 26aabb9d4c..30a61144b9 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -49,21 +49,24 @@ LLReflectionMap::~LLReflectionMap()
}
}
-void LLReflectionMap::update(U32 resolution, U32 face)
+void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip, bool useClipPlane, LLPlane clipPlane)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
mLastUpdateTime = gFrameTimeSeconds;
llassert(mCubeArray.notNull());
llassert(mCubeIndex != -1);
//llassert(LLPipeline::sRenderDeferred);
-
+
// make sure we don't walk off the edge of the render target
while (resolution > gPipeline.mRT->deferredScreen.getWidth() ||
resolution > gPipeline.mRT->deferredScreen.getHeight())
{
resolution /= 2;
}
- gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
+
+ F32 clip = (near_clip > 0) ? near_clip : getNearClip();
+
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane);
}
void LLReflectionMap::autoAdjustOrigin()
@@ -140,7 +143,7 @@ void LLReflectionMap::autoAdjustOrigin()
LLVector3 origin(fp);
F32 height = LLWorld::instance().resolveLandHeightAgent(origin) + 2.f;
fp[2] = llmax(fp[2], height);
-
+
// make sure radius encompasses all objects
LLSimdScalar r2 = 0.0;
for (int i = 0; i < 8; ++i)
@@ -160,10 +163,10 @@ void LLReflectionMap::autoAdjustOrigin()
// make sure near clip doesn't poke through ground
fp[2] = llmax(fp[2], height+mRadius*0.5f);
-
+
}
}
- else if (mViewerObject)
+ else if (mViewerObject && !mViewerObject->isDead())
{
mPriority = 1;
mOrigin.load3(mViewerObject->getPositionAgent().mV);
@@ -232,7 +235,7 @@ F32 LLReflectionMap::getNearClip()
bool LLReflectionMap::getIsDynamic()
{
if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
- mViewerObject &&
+ mViewerObject &&
mViewerObject->getVolume())
{
return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
@@ -242,7 +245,7 @@ bool LLReflectionMap::getIsDynamic()
}
bool LLReflectionMap::getBox(LLMatrix4& box)
-{
+{
if (mViewerObject)
{
LLVolume* volume = mViewerObject->getVolume();
@@ -265,7 +268,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
// construct object to camera space (with scale)
mv = mv * rm * scale;
- // inverse is camera space to object unit cube
+ // inverse is camera space to object unit cube
mv = mv.inverse();
box = LLMatrix4(mv.m);
@@ -332,7 +335,7 @@ void LLReflectionMap::doOcclusion(const LLVector4a& eye)
mOccluded = false;
return;
}
-
+
if (mOcclusionQuery == 0)
{ // no query was previously issued, allocate one and issue
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGenQueries");
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index 924cf6233f..9e888f20d0 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -36,14 +36,23 @@ class alignas(16) LLReflectionMap : public LLRefCount
{
LL_ALIGN_NEW
public:
- // allocate an environment map of the given resolution
+
+ enum class ProbeType
+ {
+ ALL = 0,
+ RADIANCE,
+ IRRADIANCE,
+ REFLECTION
+ };
+
+ // allocate an environment map of the given resolution
LLReflectionMap();
~LLReflectionMap();
// update this environment map
// resolution - size of cube map to generate
- void update(U32 resolution, U32 face);
+ void update(U32 resolution, U32 face, bool force_dynamic = false, F32 near_clip = -1.f, bool useClipPlane = false, LLPlane clipPlane = LLPlane(LLVector3(0, 0, 0), LLVector3(0, 0, 1)));
// for volume partition probes, try to place this probe in the best spot
void autoAdjustOrigin();
@@ -77,7 +86,7 @@ public:
// point at which environment map was last generated from (in agent space)
LLVector4a mOrigin;
-
+
// distance from main viewer camera
F32 mDistance = -1.f;
@@ -97,7 +106,7 @@ public:
// cube map used to sample this environment map
LLPointer<LLCubeMapArray> mCubeArray;
S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array
-
+
// probe has had at least one full update and is ready to render
bool mComplete = false;
@@ -127,5 +136,7 @@ public:
GLuint mOcclusionQuery = 0;
bool mOccluded = false;
U32 mOcclusionPendingFrames = 0;
+
+ ProbeType mType;
};
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 669989e6e1..5a8f44f5c2 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -27,6 +27,9 @@
#include "llviewerprecompiledheaders.h"
#include "llreflectionmapmanager.h"
+
+#include <vector>
+
#include "llviewercamera.h"
#include "llspatialpartition.h"
#include "llviewerregion.h"
@@ -35,6 +38,86 @@
#include "llviewercontrol.h"
#include "llenvironment.h"
#include "llstartup.h"
+#include "llviewermenufile.h"
+#include "llnotificationsutil.h"
+
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable : 4702) // compiler complains unreachable code
+#endif
+#define TINYEXR_USE_MINIZ 0
+#include "zlib.h"
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr/tinyexr.h"
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
+
+LLPointer<LLImageGL> gEXRImage;
+
+void load_exr(const std::string& filename)
+{
+ // reset reflection maps when previewing a new HDRI
+ gPipeline.mReflectionMapManager.reset();
+ gPipeline.mReflectionMapManager.initReflectionMaps();
+
+ float* out; // width * height * RGBA
+ int width;
+ int height;
+ const char* err = NULL; // or nullptr in C++11
+
+ int ret = LoadEXRWithLayer(&out, &width, &height, filename.c_str(), /* layername */ nullptr, &err);
+ if (ret == TINYEXR_SUCCESS)
+ {
+ U32 texName = 0;
+ LLImageGL::generateTextures(1, &texName);
+
+ gEXRImage = new LLImageGL(texName, 4, GL_TEXTURE_2D, GL_RGB16F, GL_RGB16F, GL_FLOAT, LLTexUnit::TAM_CLAMP);
+ gEXRImage->setHasMipMaps(TRUE);
+ gEXRImage->setUseMipMaps(TRUE);
+ gEXRImage->setFilteringOption(LLTexUnit::TFO_TRILINEAR);
+
+ gGL.getTexUnit(0)->bind(gEXRImage);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_FLOAT, out);
+ free(out); // release memory of image data
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ }
+ else
+ {
+ LLSD notif_args;
+ notif_args["WHAT"] = filename;
+ notif_args["REASON"] = "Unknown";
+ if (err)
+ {
+ notif_args["REASON"] = std::string(err);
+ FreeEXRErrorMessage(err); // release memory of error message.
+ }
+ LLNotificationsUtil::add("CannotLoad", notif_args);
+ }
+}
+
+void hdri_preview()
+{
+ LLFilePickerReplyThread::startPicker(
+ [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)
+ {
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+ if (filenames.size() > 0)
+ {
+ load_exr(filenames[0]);
+ }
+ },
+ LLFilePicker::FFLOAD_HDRI,
+ true);
+}
extern BOOL gCubeSnapshot;
extern BOOL gTeleportDisplay;
@@ -130,6 +213,11 @@ void LLReflectionMapManager::update()
return;
}
+ if (mPaused && gFrameTimeSeconds > mResumeTime)
+ {
+ resume();
+ }
+
initReflectionMaps();
if (!mRenderTarget.isComplete())
@@ -143,7 +231,7 @@ void LLReflectionMapManager::update()
{
U32 res = mProbeResolution;
U32 count = log2((F32)res) + 0.5f;
-
+
mMipChain.resize(count);
for (int i = 0; i < count; ++i)
{
@@ -153,7 +241,7 @@ void LLReflectionMapManager::update()
}
llassert(mProbes[0] == mDefaultProbe);
-
+
LLVector4a camera_pos;
camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
@@ -168,7 +256,7 @@ void LLReflectionMapManager::update()
}
mKillList.clear();
-
+
// process create list
for (auto& probe : mCreateList)
{
@@ -184,12 +272,12 @@ void LLReflectionMapManager::update()
bool did_update = false;
-
+
static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
-
+
LLReflectionMap* closestDynamic = nullptr;
LLReflectionMap* oldestProbe = nullptr;
@@ -251,7 +339,7 @@ void LLReflectionMapManager::update()
--i;
continue;
}
-
+
if (probe != mDefaultProbe &&
(!probe->isRelevant() || mPaused))
{ // skip irrelevant probes (or all non-default probes if paused)
@@ -354,7 +442,7 @@ void LLReflectionMapManager::update()
{
LLReflectionMap* probe = oldestProbe;
llassert(probe->mCubeIndex != -1);
-
+
probe->autoAdjustOrigin();
sUpdateCount++;
@@ -543,7 +631,7 @@ void LLReflectionMapManager::doProbeUpdate()
llassert(mUpdatingProbe != nullptr);
updateProbeFace(mUpdatingProbe, mUpdatingFace);
-
+
bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject;
if (++mUpdatingFace == 6)
@@ -596,11 +684,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
touch_default_probe(probe);
gPipeline.pushRenderTypeMask();
-
+
//only render sky, water, terrain, and clouds
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
-
+
probe->update(mRenderTarget.getWidth(), face);
gPipeline.popRenderTypeMask();
@@ -609,7 +697,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
{
probe->update(mRenderTarget.getWidth(), face);
}
-
+
gPipeline.mRT = &gPipeline.mMainRT;
S32 sourceIdx = mReflectionProbeCount;
@@ -686,12 +774,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
}
-
+
gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2));
-
+
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
+
res /= 2;
S32 mip = i - (mMipChain.size() - mips);
@@ -734,6 +822,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
mTexture->bind(channel);
gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
+ gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, 1.f);
U32 res = mMipChain[0].getWidth();
@@ -780,7 +869,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
-
+
mVertexBuffer->setBuffer();
int start_mip = 0;
// find the mip target to start with based on irradiance map resolution
@@ -827,9 +916,10 @@ void LLReflectionMapManager::reset()
mReset = true;
}
-void LLReflectionMapManager::pause()
+void LLReflectionMapManager::pause(F32 duration)
{
mPaused = true;
+ mResumeTime = gFrameTimeSeconds + duration;
}
void LLReflectionMapManager::resume()
@@ -856,7 +946,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
//remove from existing neighbors
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear");
-
+
for (auto& other : probe->mNeighbors)
{
auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
@@ -902,6 +992,8 @@ void LLReflectionMapManager::updateUniforms()
// the box probe
LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT];
+ LLMatrix4 heroBox;
+
// for sphere probes, origin (xyz) and radius (w) of refmaps in clip space
LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT];
@@ -912,6 +1004,8 @@ void LLReflectionMapManager::updateUniforms()
// w - znear
LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT];
+ LLVector4 heroSphere;
+
// indices used by probe:
// [i][0] - cubemap array index for this probe
// [i][1] - index into "refNeighbor" for probes that intersect this probe
@@ -925,6 +1019,10 @@ void LLReflectionMapManager::updateUniforms()
GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth
// numbrer of active refmaps
GLint refmapCount;
+
+ GLint heroShape;
+ GLint heroMipCount;
+ GLint heroProbeCount;
};
mReflectionMaps.resize(mReflectionProbeCount);
@@ -954,14 +1052,13 @@ void LLReflectionMapManager::updateUniforms()
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
- static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust);
+ F32 minimum_ambiance = psky->getReflectionProbeAmbiance(should_auto_adjust);
bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
F32 radscale = is_ambiance_pass ? 0.5f : 1.f;
-
+
for (auto* refmap : mReflectionMaps)
{
if (refmap == nullptr)
@@ -1012,7 +1109,6 @@ void LLReflectionMapManager::updateUniforms()
{
refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
}
-
}
modelview.affineTransform(refmap->mOrigin, oa);
rpd.refSphere[count].set(oa.getF32ptr());
@@ -1093,7 +1189,7 @@ void LLReflectionMapManager::updateUniforms()
{
// fill in gaps in refBucket
S32 probe_idx = mReflectionProbeCount;
-
+
for (int i = 0; i < 256; ++i)
{
if (i < count)
@@ -1115,6 +1211,16 @@ void LLReflectionMapManager::updateUniforms()
rpd.refmapCount = count;
+ gPipeline.mHeroProbeManager.updateUniforms();
+
+ // Get the hero data.
+
+ rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox;
+ rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere;
+ rpd.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape;
+ rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount;
+ rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount;
+
//copy rpd into uniform buffer object
if (mUBO == 0)
{
@@ -1262,6 +1368,8 @@ void LLReflectionMapManager::initReflectionMaps()
if (mTexture.isNull() || mReflectionProbeCount != count || mReset)
{
+ gEXRImage = nullptr;
+
mReset = false;
mReflectionProbeCount = count;
mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512));
@@ -1319,7 +1427,6 @@ void LLReflectionMapManager::initReflectionMaps()
mDefaultProbe->mComplete = default_complete;
touch_default_probe(mDefaultProbe);
-
}
if (mVertexBuffer.isNull())
@@ -1329,9 +1436,9 @@ void LLReflectionMapManager::initReflectionMaps()
buff->allocateBuffer(4, 0);
LLStrider<LLVector3> v;
-
+
buff->getVertexStrider(v);
-
+
v[0] = LLVector3(-1, -1, -1);
v[1] = LLVector3(1, -1, -1);
v[2] = LLVector3(-1, 1, -1);
@@ -1359,7 +1466,7 @@ void LLReflectionMapManager::cleanup()
mReflectionMaps.clear();
mUpdatingFace = 0;
-
+
mDefaultProbe = nullptr;
mUpdatingProbe = nullptr;
@@ -1383,3 +1490,39 @@ void LLReflectionMapManager::doOcclusion()
}
}
}
+
+void LLReflectionMapManager::forceDefaultProbeAndUpdateUniforms(bool force)
+{
+ static std::vector<bool> mProbeWasOccluded;
+
+ if (force)
+ {
+ llassert(mProbeWasOccluded.empty());
+
+ for (size_t i = 0; i < mProbes.size(); ++i)
+ {
+ auto& probe = mProbes[i];
+ mProbeWasOccluded.push_back(probe->mOccluded);
+ if (probe != nullptr && probe != mDefaultProbe)
+ {
+ probe->mOccluded = true;
+ }
+ }
+
+ updateUniforms();
+ }
+ else
+ {
+ llassert(mProbes.size() == mProbeWasOccluded.size());
+
+ const size_t n = llmin(mProbes.size(), mProbeWasOccluded.size());
+ for (size_t i = 0; i < n; ++i)
+ {
+ auto& probe = mProbes[i];
+ llassert(probe->mOccluded == (probe != mDefaultProbe));
+ probe->mOccluded = mProbeWasOccluded[i];
+ }
+ mProbeWasOccluded.clear();
+ mProbeWasOccluded.shrink_to_fit();
+ }
+}
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index bd4204468a..5c0651bc24 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -43,6 +43,8 @@ class LLViewerObject;
// reflection probe mininum scale
#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
+void renderReflectionProbe(LLReflectionMap* probe);
+
class alignas(16) LLReflectionMapManager
{
LL_ALIGN_NEW
@@ -65,7 +67,7 @@ public:
// add a probe for the given spatial group
LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr);
-
+
// Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size()
// If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr.
// maps -- presized array of Reflection Map pointers
@@ -85,7 +87,8 @@ public:
void reset();
// pause all updates other than the default probe
- void pause();
+ // duration - number of seconds to pause (default 10)
+ void pause(F32 duration = 10.f);
// unpause (see pause)
void resume();
@@ -106,8 +109,14 @@ public:
// perform occlusion culling on all active reflection probes
void doOcclusion();
+ // *HACK: "cull" all reflection probes except the default one. Only call
+ // this if you don't intend to call updateUniforms directly. Call again
+ // with false when done.
+ void forceDefaultProbeAndUpdateUniforms(bool force = true);
+
private:
friend class LLPipeline;
+ friend class LLHeroProbeManager;
// initialize mCubeFree array to default values
void initCubeFree();
@@ -151,7 +160,7 @@ private:
// update the specified face of the specified probe
void updateProbeFace(LLReflectionMap* probe, U32 face);
-
+
// list of active reflection maps
std::vector<LLPointer<LLReflectionMap> > mProbes;
@@ -200,5 +209,6 @@ private:
// if true, only update the default probe
bool mPaused = false;
+ F32 mResumeTime = 0.f;
};
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 885f4d993e..20b00974e1 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llselectmgr.cpp
* @brief A manager for selected objects and faces.
*
* $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$
*/
@@ -120,13 +120,13 @@ const S32 MAX_CHILDREN_PER_TASK = 255;
BOOL LLSelectMgr::sRectSelectInclusive = TRUE;
BOOL LLSelectMgr::sRenderHiddenSelections = TRUE;
BOOL LLSelectMgr::sRenderLightRadius = FALSE;
-F32 LLSelectMgr::sHighlightThickness = 0.f;
-F32 LLSelectMgr::sHighlightUScale = 0.f;
-F32 LLSelectMgr::sHighlightVScale = 0.f;
-F32 LLSelectMgr::sHighlightAlpha = 0.f;
-F32 LLSelectMgr::sHighlightAlphaTest = 0.f;
-F32 LLSelectMgr::sHighlightUAnim = 0.f;
-F32 LLSelectMgr::sHighlightVAnim = 0.f;
+F32 LLSelectMgr::sHighlightThickness = 0.f;
+F32 LLSelectMgr::sHighlightUScale = 0.f;
+F32 LLSelectMgr::sHighlightVScale = 0.f;
+F32 LLSelectMgr::sHighlightAlpha = 0.f;
+F32 LLSelectMgr::sHighlightAlphaTest = 0.f;
+F32 LLSelectMgr::sHighlightUAnim = 0.f;
+F32 LLSelectMgr::sHighlightVAnim = 0.f;
LLColor4 LLSelectMgr::sSilhouetteParentColor;
LLColor4 LLSelectMgr::sSilhouetteChildColor;
LLColor4 LLSelectMgr::sHighlightInspectColor;
@@ -137,15 +137,15 @@ LLColor4 LLSelectMgr::sContextSilhouetteColor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// struct LLDeRezInfo
//
-// Used to keep track of important derez info.
+// Used to keep track of important derez info.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct LLDeRezInfo
{
- EDeRezDestination mDestination;
- LLUUID mDestinationID;
- LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) :
- mDestination(dest), mDestinationID(dest_id) {}
+ EDeRezDestination mDestination;
+ LLUUID mDestinationID;
+ LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) :
+ mDestination(dest), mDestinationID(dest_id) {}
};
//
@@ -206,7 +206,7 @@ LLSelectionCallbackData::LLSelectionCallbackData()
void LLSelectMgr::cleanupGlobals()
{
- LLSelectMgr::getInstance()->clearSelections();
+ LLSelectMgr::getInstance()->clearSelections();
}
//-----------------------------------------------------------------------------
@@ -218,38 +218,38 @@ LLSelectMgr::LLSelectMgr()
mAllowSelectAvatar( LLCachedControl<bool>(gSavedSettings, "AllowSelectAvatar", FALSE)),
mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
{
- mTEMode = FALSE;
- mTextureChannel = LLRender::DIFFUSE_MAP;
- mLastCameraPos.clearVec();
-
- sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
- sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale");
- sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale");
- sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha") * 2;
- sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest");
- sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim");
- sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim");
+ mTEMode = FALSE;
+ mTextureChannel = LLRender::DIFFUSE_MAP;
+ mLastCameraPos.clearVec();
- sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor");
- sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor");
- sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor");
- sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor");
- sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor");
- sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f;
+ sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
+ sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale");
+ sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale");
+ sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha") * 2;
+ sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest");
+ sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim");
+ sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim");
- sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
+ sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor");
+ sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor");
+ sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor");
+ sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor");
+ sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor");
+ sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f;
- mRenderSilhouettes = TRUE;
+ sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
+
+ mRenderSilhouettes = TRUE;
- mGridMode = GRID_MODE_WORLD;
- gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
+ mGridMode = GRID_MODE_WORLD;
+ gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
- mSelectedObjects = new LLObjectSelection();
- mHoverObjects = new LLObjectSelection();
- mHighlightedObjects = new LLObjectSelection();
+ mSelectedObjects = new LLObjectSelection();
+ mHoverObjects = new LLObjectSelection();
+ mHighlightedObjects = new LLObjectSelection();
- mForceSelection = FALSE;
- mShowSelection = FALSE;
+ mForceSelection = FALSE;
+ mShowSelection = FALSE;
}
@@ -258,47 +258,47 @@ LLSelectMgr::LLSelectMgr()
//-----------------------------------------------------------------------------
LLSelectMgr::~LLSelectMgr()
{
- clearSelections();
+ clearSelections();
}
void LLSelectMgr::clearSelections()
{
- mHoverObjects->deleteAllNodes();
- mSelectedObjects->deleteAllNodes();
- mHighlightedObjects->deleteAllNodes();
- mRectSelectedObjects.clear();
- mGridObjects.deleteAllNodes();
+ mHoverObjects->deleteAllNodes();
+ mSelectedObjects->deleteAllNodes();
+ mHighlightedObjects->deleteAllNodes();
+ mRectSelectedObjects.clear();
+ mGridObjects.deleteAllNodes();
- LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);
+ LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);
}
void LLSelectMgr::update()
{
- mSelectedObjects->cleanupNodes();
+ mSelectedObjects->cleanupNodes();
}
void LLSelectMgr::updateEffects()
{
- //keep reference grid objects active
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLDrawable* drawable = object->mDrawable;
- if (drawable)
- {
- gPipeline.markMoved(drawable);
- }
- return true;
- }
- } func;
- mGridObjects.applyToObjects(&func);
-
- if (mEffectsTimer.getElapsedTimeF32() > 1.f)
- {
- mSelectedObjects->updateEffects();
- mEffectsTimer.reset();
- }
+ //keep reference grid objects active
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ LLDrawable* drawable = object->mDrawable;
+ if (drawable)
+ {
+ gPipeline.markMoved(drawable);
+ }
+ return true;
+ }
+ } func;
+ mGridObjects.applyToObjects(&func);
+
+ if (mEffectsTimer.getElapsedTimeF32() > 1.f)
+ {
+ mSelectedObjects->updateEffects();
+ mEffectsTimer.reset();
+ }
}
void LLSelectMgr::resetObjectOverrides()
@@ -339,31 +339,31 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
void LLSelectMgr::overrideObjectUpdates()
{
- //override any position updates from simulator on objects being edited
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* selectNode)
- {
- LLViewerObject* object = selectNode->getObject();
- if (object && object->permMove() && !object->isPermanentEnforced())
- {
- if (!selectNode->mLastPositionLocal.isExactlyZero())
- {
- object->setPosition(selectNode->mLastPositionLocal);
- }
- if (selectNode->mLastRotation != LLQuaternion())
- {
- object->setRotation(selectNode->mLastRotation);
- }
- if (!selectNode->mLastScale.isExactlyZero())
- {
- object->setScale(selectNode->mLastScale);
- }
- }
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
+ //override any position updates from simulator on objects being edited
+ struct f : public LLSelectedNodeFunctor
+ {
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (object && object->permMove() && !object->isPermanentEnforced())
+ {
+ if (!selectNode->mLastPositionLocal.isExactlyZero())
+ {
+ object->setPosition(selectNode->mLastPositionLocal);
+ }
+ if (selectNode->mLastRotation != LLQuaternion())
+ {
+ object->setRotation(selectNode->mLastRotation);
+ }
+ if (!selectNode->mLastScale.isExactlyZero())
+ {
+ object->setScale(selectNode->mLastScale);
+ }
+ }
+ return true;
+ }
+ } func;
+ getSelection()->applyToNodes(&func);
}
void LLSelectMgr::resetAvatarOverrides()
@@ -397,7 +397,7 @@ void LLSelectMgr::overrideAvatarUpdates()
}
// remove selected avatars from this list,
- // but set object overrides to make sure avatar won't snap back
+ // but set object overrides to make sure avatar won't snap back
struct f : public LLSelectedNodeFunctor
{
f(LLSelectMgr* p) : mManager(p) {}
@@ -456,64 +456,64 @@ void LLSelectMgr::overrideAvatarUpdates()
//-----------------------------------------------------------------------------
// Select just the object, not any other group members.
//-----------------------------------------------------------------------------
-LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face)
+LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face, S32 gltf_node, S32 gltf_primitive)
{
- llassert( object );
+ llassert( object );
- //remember primary object
- mSelectedObjects->mPrimaryObject = object;
+ //remember primary object
+ mSelectedObjects->mPrimaryObject = object;
- // Don't add an object that is already in the list
- if (object->isSelected() ) {
- // make sure point at position is updated
- updatePointAt();
- gEditMenuHandler = this;
- return NULL;
- }
+ // Don't add an object that is already in the list
+ if (object->isSelected() ) {
+ // make sure point at position is updated
+ updatePointAt();
+ gEditMenuHandler = this;
+ return NULL;
+ }
- if (!canSelectObject(object))
- {
- //make_ui_sound("UISndInvalidOp");
- return NULL;
- }
+ if (!canSelectObject(object))
+ {
+ //make_ui_sound("UISndInvalidOp");
+ return NULL;
+ }
- // LL_INFOS() << "Adding object to selected object list" << LL_ENDL;
-
- // Place it in the list and tag it.
- // This will refresh dialogs.
- addAsIndividual(object, face);
-
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- // *FIX: shouldn't zero out these either
- object->setVelocity(LLVector3::zero);
- object->setAcceleration(LLVector3::zero);
- //object->setAngularVelocity(LLVector3::zero);
- object->resetRot();
-
- // Always send to simulator, so you get a copy of the
- // permissions structure back.
- gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- LLViewerRegion* regionp = object->getRegion();
- gMessageSystem->sendReliable( regionp->getHost());
-
- updatePointAt();
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
-
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
+ // LL_INFOS() << "Adding object to selected object list" << LL_ENDL;
+
+ // Place it in the list and tag it.
+ // This will refresh dialogs.
+ addAsIndividual(object, face, TRUE, gltf_node, gltf_primitive);
- return mSelectedObjects;
+ // Stop the object from moving (this anticipates changes on the
+ // simulator in LLTask::userSelect)
+ // *FIX: shouldn't zero out these either
+ object->setVelocity(LLVector3::zero);
+ object->setAcceleration(LLVector3::zero);
+ //object->setAngularVelocity(LLVector3::zero);
+ object->resetRot();
+
+ // Always send to simulator, so you get a copy of the
+ // permissions structure back.
+ gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
+ LLViewerRegion* regionp = object->getRegion();
+ gMessageSystem->sendReliable( regionp->getHost());
+
+ updatePointAt();
+ updateSelectionCenter();
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+
+ // have selection manager handle edit menu immediately after
+ // user selects an object
+ if (mSelectedObjects->getObjectCount())
+ {
+ gEditMenuHandler = this;
+ }
+
+ return mSelectedObjects;
}
//-----------------------------------------------------------------------------
@@ -521,149 +521,149 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S3
//-----------------------------------------------------------------------------
LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, BOOL add_to_end, BOOL ignore_select_owned)
{
- llassert( obj );
-
- //remember primary object
- mSelectedObjects->mPrimaryObject = obj;
-
- // This may be incorrect if things weren't family selected before... - djs 07/08/02
- // Don't add an object that is already in the list
- if (obj->isSelected() )
- {
- // make sure pointat position is updated
- updatePointAt();
- gEditMenuHandler = this;
- return NULL;
- }
-
- if (!canSelectObject(obj,ignore_select_owned))
- {
- //make_ui_sound("UISndInvalidOp");
- return NULL;
- }
-
- // Since we're selecting a family, start at the root, but
- // don't include an avatar.
- LLViewerObject* root = obj;
-
- while(!root->isAvatar() && root->getParent())
- {
- LLViewerObject* parent = (LLViewerObject*)root->getParent();
- if (parent->isAvatar())
- {
- break;
- }
- root = parent;
- }
-
- // Collect all of the objects
- std::vector<LLViewerObject*> objects;
-
- root->addThisAndNonJointChildren(objects);
- addAsFamily(objects, add_to_end);
-
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
-
- dialog_refresh_all();
-
- // Always send to simulator, so you get a copy of the permissions
- // structure back.
- sendSelect();
-
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- root->setVelocity(LLVector3::zero);
- root->setAcceleration(LLVector3::zero);
- //root->setAngularVelocity(LLVector3::zero);
- root->resetRot();
-
- // leave component mode
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- gSavedSettings.setBOOL("EditLinkedParts", FALSE);
- promoteSelectionToRoot();
- }
-
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
-
- return mSelectedObjects;
+ llassert( obj );
+
+ //remember primary object
+ mSelectedObjects->mPrimaryObject = obj;
+
+ // This may be incorrect if things weren't family selected before... - djs 07/08/02
+ // Don't add an object that is already in the list
+ if (obj->isSelected() )
+ {
+ // make sure pointat position is updated
+ updatePointAt();
+ gEditMenuHandler = this;
+ return NULL;
+ }
+
+ if (!canSelectObject(obj,ignore_select_owned))
+ {
+ //make_ui_sound("UISndInvalidOp");
+ return NULL;
+ }
+
+ // Since we're selecting a family, start at the root, but
+ // don't include an avatar.
+ LLViewerObject* root = obj;
+
+ while(!root->isAvatar() && root->getParent())
+ {
+ LLViewerObject* parent = (LLViewerObject*)root->getParent();
+ if (parent->isAvatar())
+ {
+ break;
+ }
+ root = parent;
+ }
+
+ // Collect all of the objects
+ std::vector<LLViewerObject*> objects;
+
+ root->addThisAndNonJointChildren(objects);
+ addAsFamily(objects, add_to_end);
+
+ updateSelectionCenter();
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ updatePointAt();
+
+ dialog_refresh_all();
+
+ // Always send to simulator, so you get a copy of the permissions
+ // structure back.
+ sendSelect();
+
+ // Stop the object from moving (this anticipates changes on the
+ // simulator in LLTask::userSelect)
+ root->setVelocity(LLVector3::zero);
+ root->setAcceleration(LLVector3::zero);
+ //root->setAngularVelocity(LLVector3::zero);
+ root->resetRot();
+
+ // leave component mode
+ if (gSavedSettings.getBOOL("EditLinkedParts"))
+ {
+ gSavedSettings.setBOOL("EditLinkedParts", FALSE);
+ promoteSelectionToRoot();
+ }
+
+ // have selection manager handle edit menu immediately after
+ // user selects an object
+ if (mSelectedObjects->getObjectCount())
+ {
+ gEditMenuHandler = this;
+ }
+
+ return mSelectedObjects;
}
//-----------------------------------------------------------------------------
// Select the object, parents and children.
//-----------------------------------------------------------------------------
LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list,
- BOOL send_to_sim)
-{
- // Collect all of the objects, children included
- std::vector<LLViewerObject*> objects;
-
- //clear primary object (no primary object)
- mSelectedObjects->mPrimaryObject = NULL;
-
- if (object_list.size() < 1)
- {
- return NULL;
- }
-
- // NOTE -- we add the objects in REVERSE ORDER
- // to preserve the order in the mSelectedObjects list
- for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin();
- riter != object_list.rend(); ++riter)
- {
- LLViewerObject *object = *riter;
-
- llassert( object );
-
- if (!canSelectObject(object)) continue;
-
- object->addThisAndNonJointChildren(objects);
- addAsFamily(objects);
-
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- object->setVelocity(LLVector3::zero);
- object->setAcceleration(LLVector3::zero);
- //object->setAngularVelocity(LLVector3::zero);
- object->resetRot();
- }
-
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
- dialog_refresh_all();
-
- // Almost always send to simulator, so you get a copy of the permissions
- // structure back.
- // JC: The one case where you don't want to do this is if you're selecting
- // all the objects on a sim.
- if (send_to_sim)
- {
- sendSelect();
- }
-
- // leave component mode
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- gSavedSettings.setBOOL("EditLinkedParts", FALSE);
- promoteSelectionToRoot();
- }
-
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
-
- return mSelectedObjects;
+ BOOL send_to_sim)
+{
+ // Collect all of the objects, children included
+ std::vector<LLViewerObject*> objects;
+
+ //clear primary object (no primary object)
+ mSelectedObjects->mPrimaryObject = NULL;
+
+ if (object_list.size() < 1)
+ {
+ return NULL;
+ }
+
+ // NOTE -- we add the objects in REVERSE ORDER
+ // to preserve the order in the mSelectedObjects list
+ for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin();
+ riter != object_list.rend(); ++riter)
+ {
+ LLViewerObject *object = *riter;
+
+ llassert( object );
+
+ if (!canSelectObject(object)) continue;
+
+ object->addThisAndNonJointChildren(objects);
+ addAsFamily(objects);
+
+ // Stop the object from moving (this anticipates changes on the
+ // simulator in LLTask::userSelect)
+ object->setVelocity(LLVector3::zero);
+ object->setAcceleration(LLVector3::zero);
+ //object->setAngularVelocity(LLVector3::zero);
+ object->resetRot();
+ }
+
+ updateSelectionCenter();
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ updatePointAt();
+ dialog_refresh_all();
+
+ // Almost always send to simulator, so you get a copy of the permissions
+ // structure back.
+ // JC: The one case where you don't want to do this is if you're selecting
+ // all the objects on a sim.
+ if (send_to_sim)
+ {
+ sendSelect();
+ }
+
+ // leave component mode
+ if (gSavedSettings.getBOOL("EditLinkedParts"))
+ {
+ gSavedSettings.setBOOL("EditLinkedParts", FALSE);
+ promoteSelectionToRoot();
+ }
+
+ // have selection manager handle edit menu immediately after
+ // user selects an object
+ if (mSelectedObjects->getObjectCount())
+ {
+ gEditMenuHandler = this;
+ }
+
+ return mSelectedObjects;
}
// Use for when the simulator kills an object. This version also
@@ -672,138 +672,138 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLV
// Caller needs to call dialog_refresh_all if necessary.
BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
{
- BOOL object_found = FALSE;
- LLTool *tool = NULL;
-
- tool = LLToolMgr::getInstance()->getCurrentTool();
-
- // It's possible that the tool is editing an object that is not selected
- LLViewerObject* tool_editing_object = tool->getEditingObject();
- if( tool_editing_object && tool_editing_object->mID == id)
- {
- tool->stopEditing();
- object_found = TRUE;
- }
-
- // Iterate through selected objects list and kill the object
- if( !object_found )
- {
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
- LLViewerObject* object = (*curiter)->getObject();
- if (object->mID == id)
- {
- if (tool)
- {
- tool->stopEditing();
- }
-
- // lose the selection, don't tell simulator, it knows
- deselectObjectAndFamily(object, FALSE);
- object_found = TRUE;
- break; // must break here, may have removed multiple objects from list
- }
- else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id)
- {
- // It's possible the item being removed has an avatar sitting on it
- // So remove the avatar that is sitting on the object.
- deselectObjectAndFamily(object, FALSE);
- break; // must break here, may have removed multiple objects from list
- }
- }
- }
-
- return object_found;
+ BOOL object_found = FALSE;
+ LLTool *tool = NULL;
+
+ tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ // It's possible that the tool is editing an object that is not selected
+ LLViewerObject* tool_editing_object = tool->getEditingObject();
+ if( tool_editing_object && tool_editing_object->mID == id)
+ {
+ tool->stopEditing();
+ object_found = TRUE;
+ }
+
+ // Iterate through selected objects list and kill the object
+ if( !object_found )
+ {
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); )
+ {
+ LLObjectSelection::iterator curiter = iter++;
+ LLViewerObject* object = (*curiter)->getObject();
+ if (object->mID == id)
+ {
+ if (tool)
+ {
+ tool->stopEditing();
+ }
+
+ // lose the selection, don't tell simulator, it knows
+ deselectObjectAndFamily(object, FALSE);
+ object_found = TRUE;
+ break; // must break here, may have removed multiple objects from list
+ }
+ else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id)
+ {
+ // It's possible the item being removed has an avatar sitting on it
+ // So remove the avatar that is sitting on the object.
+ deselectObjectAndFamily(object, FALSE);
+ break; // must break here, may have removed multiple objects from list
+ }
+ }
+ }
+
+ return object_found;
}
bool LLSelectMgr::linkObjects()
{
- if (!LLSelectMgr::getInstance()->selectGetAllRootsValid())
- {
- LLNotificationsUtil::add("UnableToLinkWhileDownloading");
- return true;
- }
-
- S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
- if (object_count > MAX_CHILDREN_PER_TASK + 1)
- {
- LLSD args;
- args["COUNT"] = llformat("%d", object_count);
- int max = MAX_CHILDREN_PER_TASK+1;
- args["MAX"] = llformat("%d", max);
- LLNotificationsUtil::add("UnableToLinkObjects", args);
- return true;
- }
-
- if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2)
- {
- LLNotificationsUtil::add("CannotLinkIncompleteSet");
- return true;
- }
-
- if (!LLSelectMgr::getInstance()->selectGetRootsModify())
- {
- LLNotificationsUtil::add("CannotLinkModify");
- return true;
- }
-
- if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- {
- LLNotificationsUtil::add("CannotLinkPermanent");
- return true;
- }
-
- LLUUID owner_id;
- std::string owner_name;
- if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name))
- {
- // we don't actually care if you're the owner, but novices are
- // the most likely to be stumped by this one, so offer the
- // easiest and most likely solution.
- LLNotificationsUtil::add("CannotLinkDifferentOwners");
- return true;
- }
-
- if (!LLSelectMgr::getInstance()->selectGetSameRegion())
- {
- LLNotificationsUtil::add("CannotLinkAcrossRegions");
- return true;
- }
-
- LLSelectMgr::getInstance()->sendLink();
-
- return true;
+ if (!LLSelectMgr::getInstance()->selectGetAllRootsValid())
+ {
+ LLNotificationsUtil::add("UnableToLinkWhileDownloading");
+ return true;
+ }
+
+ S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (object_count > MAX_CHILDREN_PER_TASK + 1)
+ {
+ LLSD args;
+ args["COUNT"] = llformat("%d", object_count);
+ int max = MAX_CHILDREN_PER_TASK+1;
+ args["MAX"] = llformat("%d", max);
+ LLNotificationsUtil::add("UnableToLinkObjects", args);
+ return true;
+ }
+
+ if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2)
+ {
+ LLNotificationsUtil::add("CannotLinkIncompleteSet");
+ return true;
+ }
+
+ if (!LLSelectMgr::getInstance()->selectGetRootsModify())
+ {
+ LLNotificationsUtil::add("CannotLinkModify");
+ return true;
+ }
+
+ if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ {
+ LLNotificationsUtil::add("CannotLinkPermanent");
+ return true;
+ }
+
+ LLUUID owner_id;
+ std::string owner_name;
+ if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name))
+ {
+ // we don't actually care if you're the owner, but novices are
+ // the most likely to be stumped by this one, so offer the
+ // easiest and most likely solution.
+ LLNotificationsUtil::add("CannotLinkDifferentOwners");
+ return true;
+ }
+
+ if (!LLSelectMgr::getInstance()->selectGetSameRegion())
+ {
+ LLNotificationsUtil::add("CannotLinkAcrossRegions");
+ return true;
+ }
+
+ LLSelectMgr::getInstance()->sendLink();
+
+ return true;
}
bool LLSelectMgr::unlinkObjects()
{
- S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm");
- S32 unlink_object_count = mSelectedObjects->getObjectCount(); // clears out nodes with NULL objects
- if (unlink_object_count >= min_objects_for_confirm
- && unlink_object_count > mSelectedObjects->getRootObjectCount())
- {
- // total count > root count means that there are childer inside and that there are linksets that will be unlinked
- LLNotificationsUtil::add("ConfirmUnlink", LLSD(), LLSD(), boost::bind(&LLSelectMgr::confirmUnlinkObjects, this, _1, _2));
- return true;
- }
+ S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm");
+ S32 unlink_object_count = mSelectedObjects->getObjectCount(); // clears out nodes with NULL objects
+ if (unlink_object_count >= min_objects_for_confirm
+ && unlink_object_count > mSelectedObjects->getRootObjectCount())
+ {
+ // total count > root count means that there are childer inside and that there are linksets that will be unlinked
+ LLNotificationsUtil::add("ConfirmUnlink", LLSD(), LLSD(), boost::bind(&LLSelectMgr::confirmUnlinkObjects, this, _1, _2));
+ return true;
+ }
- LLSelectMgr::getInstance()->sendDelink();
- return true;
+ LLSelectMgr::getInstance()->sendDelink();
+ return true;
}
void LLSelectMgr::confirmUnlinkObjects(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- // if Cancel pressed
- if (option == 1)
- {
- return;
- }
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
- LLSelectMgr::getInstance()->sendDelink();
- return;
+ LLSelectMgr::getInstance()->sendDelink();
+ return;
}
// in order to link, all objects must have the same owner, and the
@@ -820,158 +820,158 @@ void LLSelectMgr::confirmUnlinkObjects(const LLSD& notification, const LLSD& res
// triangle count cannot exceed the designated limit.
bool LLSelectMgr::enableLinkObjects()
{
- bool new_value = false;
- // check if there are at least 2 objects selected, and that the
- // user can modify at least one of the selected objects.
-
- // in component mode, can't link
- if (!gSavedSettings.getBOOL("EditLinkedParts"))
- {
- if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit();
- return object->permModify() && !object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced());
- }
- } func;
- const bool firstonly = true;
- new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- }
- }
+ bool new_value = false;
+ // check if there are at least 2 objects selected, and that the
+ // user can modify at least one of the selected objects.
+
+ // in component mode, can't link
+ if (!gSavedSettings.getBOOL("EditLinkedParts"))
+ {
+ if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2)
+ {
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit();
+ return object->permModify() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced());
+ }
+ } func;
+ const bool firstonly = true;
+ new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
+ }
+ }
if (!LLSelectMgr::getInstance()->getSelection()->checkAnimatedObjectLinkable())
{
new_value = false;
}
- return new_value;
+ return new_value;
}
bool LLSelectMgr::enableUnlinkObjects()
{
- LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject();
- LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit();
+ LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject();
+ LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit();
- bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() &&
- first_editable_object &&
- !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced());
+ bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() &&
+ first_editable_object &&
+ !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced());
- return new_value;
+ return new_value;
}
void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object)
{
- // bail if nothing selected or if object wasn't selected in the first place
- if(!object) return;
- if(!object->isSelected()) return;
-
- // Collect all of the objects, and remove them
- std::vector<LLViewerObject*> objects;
-
- if (include_entire_object)
- {
- // Since we're selecting a family, start at the root, but
- // don't include an avatar.
- LLViewerObject* root = object;
-
- while(!root->isAvatar() && root->getParent())
- {
- LLViewerObject* parent = (LLViewerObject*)root->getParent();
- if (parent->isAvatar())
- {
- break;
- }
- root = parent;
- }
-
- object = root;
- }
- else
- {
- object = (LLViewerObject*)object->getRoot();
- }
-
- object->addThisAndAllChildren(objects);
- remove(objects);
-
- if (!send_to_sim) return;
-
- //-----------------------------------------------------------
- // Inform simulator of deselection
- //-----------------------------------------------------------
- LLViewerRegion* regionp = object->getRegion();
-
- BOOL start_new_message = TRUE;
- S32 select_count = 0;
-
- LLMessageSystem* msg = gMessageSystem;
- for (U32 i = 0; i < objects.size(); i++)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_ObjectDeselect);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- select_count++;
- start_new_message = FALSE;
- }
-
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID());
- select_count++;
-
- // Zap the angular velocity, as the sim will set it to zero
- objects[i]->setAngularVelocity( 0,0,0 );
- objects[i]->setVelocity( 0,0,0 );
-
- if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET)
- {
- msg->sendReliable(regionp->getHost() );
- select_count = 0;
- start_new_message = TRUE;
- }
- }
-
- if (!start_new_message)
- {
- msg->sendReliable(regionp->getHost() );
- }
-
- updatePointAt();
- updateSelectionCenter();
+ // bail if nothing selected or if object wasn't selected in the first place
+ if(!object) return;
+ if(!object->isSelected()) return;
+
+ // Collect all of the objects, and remove them
+ std::vector<LLViewerObject*> objects;
+
+ if (include_entire_object)
+ {
+ // Since we're selecting a family, start at the root, but
+ // don't include an avatar.
+ LLViewerObject* root = object;
+
+ while(!root->isAvatar() && root->getParent())
+ {
+ LLViewerObject* parent = (LLViewerObject*)root->getParent();
+ if (parent->isAvatar())
+ {
+ break;
+ }
+ root = parent;
+ }
+
+ object = root;
+ }
+ else
+ {
+ object = (LLViewerObject*)object->getRoot();
+ }
+
+ object->addThisAndAllChildren(objects);
+ remove(objects);
+
+ if (!send_to_sim) return;
+
+ //-----------------------------------------------------------
+ // Inform simulator of deselection
+ //-----------------------------------------------------------
+ LLViewerRegion* regionp = object->getRegion();
+
+ BOOL start_new_message = TRUE;
+ S32 select_count = 0;
+
+ LLMessageSystem* msg = gMessageSystem;
+ for (U32 i = 0; i < objects.size(); i++)
+ {
+ if (start_new_message)
+ {
+ msg->newMessageFast(_PREHASH_ObjectDeselect);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ select_count++;
+ start_new_message = FALSE;
+ }
+
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID());
+ select_count++;
+
+ // Zap the angular velocity, as the sim will set it to zero
+ objects[i]->setAngularVelocity( 0,0,0 );
+ objects[i]->setVelocity( 0,0,0 );
+
+ if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET)
+ {
+ msg->sendReliable(regionp->getHost() );
+ select_count = 0;
+ start_new_message = TRUE;
+ }
+ }
+
+ if (!start_new_message)
+ {
+ msg->sendReliable(regionp->getHost() );
+ }
+
+ updatePointAt();
+ updateSelectionCenter();
}
void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim)
{
- // bail if nothing selected or if object wasn't selected in the first place
- if (!object) return;
- if (!object->isSelected() ) return;
+ // bail if nothing selected or if object wasn't selected in the first place
+ if (!object) return;
+ if (!object->isSelected() ) return;
- // Zap the angular velocity, as the sim will set it to zero
- object->setAngularVelocity( 0,0,0 );
- object->setVelocity( 0,0,0 );
+ // Zap the angular velocity, as the sim will set it to zero
+ object->setAngularVelocity( 0,0,0 );
+ object->setVelocity( 0,0,0 );
- if (send_to_sim)
- {
- LLViewerRegion* region = object->getRegion();
- gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- gMessageSystem->sendReliable(region->getHost());
- }
+ if (send_to_sim)
+ {
+ LLViewerRegion* region = object->getRegion();
+ gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
+ gMessageSystem->sendReliable(region->getHost());
+ }
- // This will refresh dialogs.
- remove( object );
+ // This will refresh dialogs.
+ remove( object );
- updatePointAt();
- updateSelectionCenter();
+ updatePointAt();
+ updateSelectionCenter();
}
@@ -981,501 +981,508 @@ void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim)
void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end)
{
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
-
- // Can't select yourself
- if (objectp->mID == gAgentID
- && !mAllowSelectAvatar)
- {
- continue;
- }
-
- if (!objectp->isSelected())
- {
- LLSelectNode *nodep = new LLSelectNode(objectp, TRUE);
- if (add_to_end)
- {
- mSelectedObjects->addNodeAtEnd(nodep);
- }
- else
- {
- mSelectedObjects->addNode(nodep);
- }
- objectp->setSelected(TRUE);
-
- if (objectp->getNumTEs() > 0)
- {
- nodep->selectAllTEs(TRUE);
- objectp->setAllTESelected(true);
- }
- else
- {
- // object has no faces, so don't mess with faces
- }
- }
- else
- {
- // we want this object to be selected for real
- // so clear transient flag
- LLSelectNode* select_node = mSelectedObjects->findNode(objectp);
- if (select_node)
- {
- select_node->setTransient(FALSE);
- }
- }
- }
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
+ iter != objects.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+
+ // Can't select yourself
+ if (objectp->mID == gAgentID
+ && !mAllowSelectAvatar)
+ {
+ continue;
+ }
+
+ if (!objectp->isSelected())
+ {
+ LLSelectNode *nodep = new LLSelectNode(objectp, TRUE);
+ if (add_to_end)
+ {
+ mSelectedObjects->addNodeAtEnd(nodep);
+ }
+ else
+ {
+ mSelectedObjects->addNode(nodep);
+ }
+ objectp->setSelected(TRUE);
+
+ if (objectp->getNumTEs() > 0)
+ {
+ nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
+ }
+ else
+ {
+ // object has no faces, so don't mess with faces
+ }
+ }
+ else
+ {
+ // we want this object to be selected for real
+ // so clear transient flag
+ LLSelectNode* select_node = mSelectedObjects->findNode(objectp);
+ if (select_node)
+ {
+ select_node->setTransient(FALSE);
+ }
+ }
+ }
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
}
//-----------------------------------------------------------------------------
// addAsIndividual() - a single object, face, etc
//-----------------------------------------------------------------------------
-void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable)
-{
- // check to see if object is already in list
- LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
-
- // if not in list, add it
- if (!nodep)
- {
- nodep = new LLSelectNode(objectp, TRUE);
- mSelectedObjects->addNode(nodep);
- llassert_always(nodep->getObject());
- }
- else
- {
- // make this a full-fledged selection
- nodep->setTransient(FALSE);
- // Move it to the front of the list
- mSelectedObjects->moveNodeToFront(nodep);
- }
-
- // Make sure the object is tagged as selected
- objectp->setSelected( TRUE );
-
- // And make sure we don't consider it as part of a family
- nodep->mIndividualSelection = TRUE;
-
- // Handle face selection
- if (objectp->getNumTEs() <= 0)
- {
- // object has no faces, so don't do anything
- }
- else if (face == SELECT_ALL_TES)
- {
- nodep->selectAllTEs(TRUE);
- objectp->setAllTESelected(true);
- }
- else if (0 <= face && face < SELECT_MAX_TES)
- {
- nodep->selectTE(face, TRUE);
- objectp->setTESelected(face, true);
- }
- else
- {
- LL_ERRS() << "LLSelectMgr::add face " << face << " out-of-range" << LL_ENDL;
- return;
- }
-
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updateSelectionCenter();
- dialog_refresh_all();
+void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable, S32 gltf_node, S32 gltf_primitive)
+{
+ // check to see if object is already in list
+ LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
+
+ // if not in list, add it
+ if (!nodep)
+ {
+ nodep = new LLSelectNode(objectp, TRUE);
+ mSelectedObjects->addNode(nodep);
+ llassert_always(nodep->getObject());
+ }
+ else
+ {
+ // make this a full-fledged selection
+ nodep->setTransient(FALSE);
+ // Move it to the front of the list
+ mSelectedObjects->moveNodeToFront(nodep);
+ }
+
+ // Make sure the object is tagged as selected
+ objectp->setSelected( TRUE );
+
+ // And make sure we don't consider it as part of a family
+ nodep->mIndividualSelection = TRUE;
+
+ // Handle face selection
+ if (objectp->getNumTEs() <= 0)
+ {
+ // object has no faces, so don't do anything
+ }
+ else if (face == SELECT_ALL_TES)
+ {
+ nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
+ }
+ else if (0 <= face && face < SELECT_MAX_TES)
+ {
+ nodep->selectTE(face, TRUE);
+ objectp->setTESelected(face, true);
+ }
+ else
+ {
+ LL_ERRS() << "LLSelectMgr::add face " << face << " out-of-range" << LL_ENDL;
+ return;
+ }
+
+ // Handle glTF node selection
+ if (gltf_node >= 0)
+ {
+ nodep->selectGLTFNode(gltf_node, gltf_primitive, TRUE);
+
+ }
+
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ updateSelectionCenter();
+ dialog_refresh_all();
}
LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face)
{
- if (!objectp)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
-
- // Can't select yourself
- if (objectp->mID == gAgentID)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
-
- // Can't select land
- if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
-
- mHoverObjects->mPrimaryObject = objectp;
-
- objectp = objectp->getRootEdit();
-
- // is the requested object the same as the existing hover object root?
- // NOTE: there is only ever one linked set in mHoverObjects
- if (mHoverObjects->getFirstRootObject() != objectp)
- {
-
- // Collect all of the objects
- std::vector<LLViewerObject*> objects;
- objectp = objectp->getRootEdit();
- objectp->addThisAndNonJointChildren(objects);
-
- mHoverObjects->deleteAllNodes();
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* cur_objectp = *iter;
- if(!cur_objectp || cur_objectp->isDead())
- {
- continue;
- }
- LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
- nodep->selectTE(face, TRUE);
- mHoverObjects->addNodeAtEnd(nodep);
- }
-
- requestObjectPropertiesFamily(objectp);
- }
-
- return mHoverObjects;
+ if (!objectp)
+ {
+ mHoverObjects->deleteAllNodes();
+ return NULL;
+ }
+
+ // Can't select yourself
+ if (objectp->mID == gAgentID)
+ {
+ mHoverObjects->deleteAllNodes();
+ return NULL;
+ }
+
+ // Can't select land
+ if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+ {
+ mHoverObjects->deleteAllNodes();
+ return NULL;
+ }
+
+ mHoverObjects->mPrimaryObject = objectp;
+
+ objectp = objectp->getRootEdit();
+
+ // is the requested object the same as the existing hover object root?
+ // NOTE: there is only ever one linked set in mHoverObjects
+ if (mHoverObjects->getFirstRootObject() != objectp)
+ {
+
+ // Collect all of the objects
+ std::vector<LLViewerObject*> objects;
+ objectp = objectp->getRootEdit();
+ objectp->addThisAndNonJointChildren(objects);
+
+ mHoverObjects->deleteAllNodes();
+ for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
+ iter != objects.end(); ++iter)
+ {
+ LLViewerObject* cur_objectp = *iter;
+ if(!cur_objectp || cur_objectp->isDead())
+ {
+ continue;
+ }
+ LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
+ nodep->selectTE(face, TRUE);
+ mHoverObjects->addNodeAtEnd(nodep);
+ }
+
+ requestObjectPropertiesFamily(objectp);
+ }
+
+ return mHoverObjects;
}
LLSelectNode *LLSelectMgr::getHoverNode()
{
- return mHoverObjects->getFirstRootNode();
+ return mHoverObjects->getFirstRootNode();
}
LLSelectNode *LLSelectMgr::getPrimaryHoverNode()
{
- return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject];
+ return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject];
}
void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
{
- if (!objectp)
- {
- return;
- }
-
- if (objectp->getPCode() != LL_PCODE_VOLUME)
- {
- return;
- }
+ if (!objectp)
+ {
+ return;
+ }
+ if (objectp->getPCode() != LL_PCODE_VOLUME)
+ {
+ return;
+ }
+
if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
|| (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
- {
- // only select my own objects
- return;
- }
+ {
+ // only select my own objects
+ return;
+ }
- mRectSelectedObjects.insert(objectp);
+ mRectSelectedObjects.insert(objectp);
}
void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
{
- if (!objectp)
- {
- return;
- }
+ if (!objectp)
+ {
+ return;
+ }
- LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
+ LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
- highlightObjectOnly(root_obj);
+ highlightObjectOnly(root_obj);
- LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- highlightObjectOnly(child);
- }
+ LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ highlightObjectOnly(child);
+ }
}
// Note that this ignores the "select owned only" flag
// It's also more efficient than calling the single-object version over and over.
void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& objects)
{
- for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin();
- iter1 != objects.end(); ++iter1)
- {
- LLViewerObject* object = *iter1;
-
- if (!object)
- {
- continue;
- }
- if (object->getPCode() != LL_PCODE_VOLUME)
- {
- continue;
- }
-
- LLViewerObject* root = (LLViewerObject*)object->getRoot();
- mRectSelectedObjects.insert(root);
-
- LLViewerObject::const_child_list_t& child_list = root->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin();
- iter2 != child_list.end(); iter2++)
- {
- LLViewerObject* child = *iter2;
- mRectSelectedObjects.insert(child);
- }
- }
+ for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin();
+ iter1 != objects.end(); ++iter1)
+ {
+ LLViewerObject* object = *iter1;
+
+ if (!object)
+ {
+ continue;
+ }
+ if (object->getPCode() != LL_PCODE_VOLUME)
+ {
+ continue;
+ }
+
+ LLViewerObject* root = (LLViewerObject*)object->getRoot();
+ mRectSelectedObjects.insert(root);
+
+ LLViewerObject::const_child_list_t& child_list = root->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin();
+ iter2 != child_list.end(); iter2++)
+ {
+ LLViewerObject* child = *iter2;
+ mRectSelectedObjects.insert(child);
+ }
+ }
}
void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp)
{
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
- mRectSelectedObjects.erase(objectp);
+ mRectSelectedObjects.erase(objectp);
}
void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
{
- if (!objectp)
- {
- return;
- }
+ if (!objectp)
+ {
+ return;
+ }
- LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
+ LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
- unhighlightObjectOnly(root_obj);
+ unhighlightObjectOnly(root_obj);
- LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- unhighlightObjectOnly(child);
- }
+ LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ unhighlightObjectOnly(child);
+ }
}
void LLSelectMgr::unhighlightAll()
{
- mRectSelectedObjects.clear();
- mHighlightedObjects->deleteAllNodes();
+ mRectSelectedObjects.clear();
+ mHighlightedObjects->deleteAllNodes();
}
LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
{
- if (!mHighlightedObjects->getNumNodes())
- {
- return NULL;
- }
+ if (!mHighlightedObjects->getNumNodes())
+ {
+ return NULL;
+ }
- //clear primary object
- mSelectedObjects->mPrimaryObject = NULL;
+ //clear primary object
+ mSelectedObjects->mPrimaryObject = NULL;
- for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin();
- iter != getHighlightedObjects()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
+ for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin();
+ iter != getHighlightedObjects()->end(); )
+ {
+ LLObjectSelection::iterator curiter = iter++;
+
+ LLSelectNode *nodep = *curiter;
+ LLViewerObject* objectp = nodep->getObject();
- LLSelectNode *nodep = *curiter;
- LLViewerObject* objectp = nodep->getObject();
+ if (!canSelectObject(objectp))
+ {
+ continue;
+ }
- if (!canSelectObject(objectp))
- {
- continue;
- }
+ // already selected
+ if (objectp->isSelected())
+ {
+ continue;
+ }
- // already selected
- if (objectp->isSelected())
- {
- continue;
- }
-
- LLSelectNode* new_nodep = new LLSelectNode(*nodep);
- mSelectedObjects->addNode(new_nodep);
+ LLSelectNode* new_nodep = new LLSelectNode(*nodep);
+ mSelectedObjects->addNode(new_nodep);
- // flag this object as selected
- objectp->setSelected(TRUE);
- objectp->setAllTESelected(true);
+ // flag this object as selected
+ objectp->setSelected(TRUE);
+ objectp->setAllTESelected(true);
- mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
+ mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
- // request properties on root objects
- if (objectp->isRootEdit())
- {
- requestObjectPropertiesFamily(objectp);
- }
- }
+ // request properties on root objects
+ if (objectp->isRootEdit())
+ {
+ requestObjectPropertiesFamily(objectp);
+ }
+ }
- // pack up messages to let sim know these objects are selected
- sendSelect();
- unhighlightAll();
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
+ // pack up messages to let sim know these objects are selected
+ sendSelect();
+ unhighlightAll();
+ updateSelectionCenter();
+ saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ updatePointAt();
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
+ if (mSelectedObjects->getObjectCount())
+ {
+ gEditMenuHandler = this;
+ }
- return mSelectedObjects;
+ return mSelectedObjects;
}
void LLSelectMgr::deselectHighlightedObjects()
{
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
- iter != mRectSelectedObjects.end(); iter++)
- {
- LLViewerObject *objectp = *iter;
- if (!select_linked_set)
- {
- deselectObjectOnly(objectp);
- }
- else
- {
- LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot();
- if (root_object->isSelected())
- {
- deselectObjectAndFamily(root_object);
- }
- }
- }
-
- unhighlightAll();
+ BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
+ for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
+ iter != mRectSelectedObjects.end(); iter++)
+ {
+ LLViewerObject *objectp = *iter;
+ if (!select_linked_set)
+ {
+ deselectObjectOnly(objectp);
+ }
+ else
+ {
+ LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot();
+ if (root_object->isSelected())
+ {
+ deselectObjectAndFamily(root_object);
+ }
+ }
+ }
+
+ unhighlightAll();
}
void LLSelectMgr::addGridObject(LLViewerObject* objectp)
{
- LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
- mGridObjects.addNodeAtEnd(nodep);
+ LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
+ mGridObjects.addNodeAtEnd(nodep);
- LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- nodep = new LLSelectNode(child, FALSE);
- mGridObjects.addNodeAtEnd(nodep);
- }
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ nodep = new LLSelectNode(child, FALSE);
+ mGridObjects.addNodeAtEnd(nodep);
+ }
}
void LLSelectMgr::clearGridObjects()
{
- mGridObjects.deleteAllNodes();
+ mGridObjects.deleteAllNodes();
}
void LLSelectMgr::setGridMode(EGridMode mode)
{
- mGridMode = mode;
- gSavedSettings.setS32("GridMode", mode);
- updateSelectionCenter();
+ mGridMode = mode;
+ gSavedSettings.setS32("GridMode", mode);
+ updateSelectionCenter();
}
void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale, bool for_snap_guides)
{
- mGridObjects.cleanupNodes();
-
- LLViewerObject* first_grid_object = mGridObjects.getFirstObject();
-
- if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
- {
- //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
- mGridOrigin = mSavedSelectionBBox.getCenterAgent();
- mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
-
- // DEV-12570 Just taking the saved selection box rotation prevents
- // wild rotations of linked sets while in local grid mode
- //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull())
- {
- mGridRotation = mSavedSelectionBBox.getRotation();
- }
- /*else //set to the root object
- {
- mGridRotation = root->getRenderRotation();
- }*/
- }
- else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
- {
- LLSelectNode *node = mSelectedObjects->findNode(first_grid_object);
- if (!for_snap_guides && node)
- {
- mGridRotation = node->mSavedRotation;
- }
- else
- {
- mGridRotation = first_grid_object->getRenderRotation();
- }
-
- LLVector4a min_extents(F32_MAX);
- LLVector4a max_extents(-F32_MAX);
- BOOL grid_changed = FALSE;
- for (LLObjectSelection::iterator iter = mGridObjects.begin();
- iter != mGridObjects.end(); ++iter)
- {
- LLViewerObject* object = (*iter)->getObject();
- LLDrawable* drawable = object->mDrawable;
- if (drawable)
- {
- const LLVector4a* ext = drawable->getSpatialExtents();
- update_min_max(min_extents, max_extents, ext[0]);
- update_min_max(min_extents, max_extents, ext[1]);
- grid_changed = TRUE;
- }
- }
- if (grid_changed)
- {
- LLVector4a center, size;
- center.setAdd(min_extents, max_extents);
- center.mul(0.5f);
- size.setSub(max_extents, min_extents);
- size.mul(0.5f);
-
- mGridOrigin.set(center.getF32ptr());
- LLDrawable* drawable = first_grid_object->mDrawable;
- if (drawable && drawable->isActive())
- {
- mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
- }
- mGridScale.set(size.getF32ptr());
- }
- }
- else // GRID_MODE_WORLD or just plain default
- {
- const BOOL non_root_ok = TRUE;
- LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok);
-
- mGridOrigin.clearVec();
- mGridRotation.loadIdentity();
-
- mSelectedObjects->mSelectType = getSelectTypeForObject( first_object );
-
- switch (mSelectedObjects->mSelectType)
- {
- case SELECT_TYPE_ATTACHMENT:
- if (first_object && first_object->getRootEdit()->mDrawable.notNull())
- {
- // this means this object *has* to be an attachment
- LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent();
- mGridOrigin = attachment_point_xform->getWorldPosition();
- mGridRotation = attachment_point_xform->getWorldRotation();
- mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
- }
- break;
- case SELECT_TYPE_HUD:
- mGridScale = LLVector3(1.f, 1.f, 1.f) * llmin(gSavedSettings.getF32("GridResolution"), 0.5f);
- break;
- case SELECT_TYPE_WORLD:
- mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
- break;
- }
- }
- llassert(mGridOrigin.isFinite());
-
- origin = mGridOrigin;
- rotation = mGridRotation;
- scale = mGridScale;
+ mGridObjects.cleanupNodes();
+
+ LLViewerObject* first_grid_object = mGridObjects.getFirstObject();
+
+ if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
+ {
+ //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
+ mGridOrigin = mSavedSelectionBBox.getCenterAgent();
+ mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
+
+ // DEV-12570 Just taking the saved selection box rotation prevents
+ // wild rotations of linked sets while in local grid mode
+ //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull())
+ {
+ mGridRotation = mSavedSelectionBBox.getRotation();
+ }
+ /*else //set to the root object
+ {
+ mGridRotation = root->getRenderRotation();
+ }*/
+ }
+ else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
+ {
+ LLSelectNode *node = mSelectedObjects->findNode(first_grid_object);
+ if (!for_snap_guides && node)
+ {
+ mGridRotation = node->mSavedRotation;
+ }
+ else
+ {
+ mGridRotation = first_grid_object->getRenderRotation();
+ }
+
+ LLVector4a min_extents(F32_MAX);
+ LLVector4a max_extents(-F32_MAX);
+ BOOL grid_changed = FALSE;
+ for (LLObjectSelection::iterator iter = mGridObjects.begin();
+ iter != mGridObjects.end(); ++iter)
+ {
+ LLViewerObject* object = (*iter)->getObject();
+ LLDrawable* drawable = object->mDrawable;
+ if (drawable)
+ {
+ const LLVector4a* ext = drawable->getSpatialExtents();
+ update_min_max(min_extents, max_extents, ext[0]);
+ update_min_max(min_extents, max_extents, ext[1]);
+ grid_changed = TRUE;
+ }
+ }
+ if (grid_changed)
+ {
+ LLVector4a center, size;
+ center.setAdd(min_extents, max_extents);
+ center.mul(0.5f);
+ size.setSub(max_extents, min_extents);
+ size.mul(0.5f);
+
+ mGridOrigin.set(center.getF32ptr());
+ LLDrawable* drawable = first_grid_object->mDrawable;
+ if (drawable && drawable->isActive())
+ {
+ mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
+ }
+ mGridScale.set(size.getF32ptr());
+ }
+ }
+ else // GRID_MODE_WORLD or just plain default
+ {
+ const BOOL non_root_ok = TRUE;
+ LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok);
+
+ mGridOrigin.clearVec();
+ mGridRotation.loadIdentity();
+
+ mSelectedObjects->mSelectType = getSelectTypeForObject( first_object );
+
+ switch (mSelectedObjects->mSelectType)
+ {
+ case SELECT_TYPE_ATTACHMENT:
+ if (first_object && first_object->getRootEdit()->mDrawable.notNull())
+ {
+ // this means this object *has* to be an attachment
+ LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent();
+ mGridOrigin = attachment_point_xform->getWorldPosition();
+ mGridRotation = attachment_point_xform->getWorldRotation();
+ mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
+ }
+ break;
+ case SELECT_TYPE_HUD:
+ mGridScale = LLVector3(1.f, 1.f, 1.f) * llmin(gSavedSettings.getF32("GridResolution"), 0.5f);
+ break;
+ case SELECT_TYPE_WORLD:
+ mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
+ break;
+ }
+ }
+ llassert(mGridOrigin.isFinite());
+
+ origin = mGridOrigin;
+ rotation = mGridRotation;
+ scale = mGridScale;
}
//-----------------------------------------------------------------------------
@@ -1484,20 +1491,20 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects)
{
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
- if (nodep)
- {
- objectp->setSelected(FALSE);
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- }
- }
- updateSelectionCenter();
- dialog_refresh_all();
+ for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
+ iter != objects.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
+ if (nodep)
+ {
+ objectp->setSelected(FALSE);
+ mSelectedObjects->removeNode(nodep);
+ nodep = NULL;
+ }
+ }
+ updateSelectionCenter();
+ dialog_refresh_all();
}
@@ -1506,59 +1513,59 @@ void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects)
//-----------------------------------------------------------------------------
void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
{
- // get object node (and verify it is in the selected list)
- LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
- if (!nodep)
- {
- return;
- }
-
- // if face = all, remove object from list
- if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES))
- {
- // Remove all faces (or the object doesn't have faces) so remove the node
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- objectp->setSelected( FALSE );
- }
- else if (0 <= te && te < SELECT_MAX_TES)
- {
- // ...valid face, check to see if it was on
- if (nodep->isTESelected(te))
- {
- nodep->selectTE(te, FALSE);
- objectp->setTESelected(te, false);
- }
- else
- {
- LL_ERRS() << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << LL_ENDL;
- return;
- }
-
- // ...check to see if this operation turned off all faces
- BOOL found = FALSE;
- for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++)
- {
- found = found || nodep->isTESelected(i);
- }
-
- // ...all faces now turned off, so remove
- if (!found)
- {
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- objectp->setSelected( FALSE );
- // *FIXME: Doesn't update simulator that object is no longer selected
- }
- }
- else
- {
- // ...out of range face
- LL_ERRS() << "LLSelectMgr::remove - TE " << te << " out of range" << LL_ENDL;
- }
-
- updateSelectionCenter();
- dialog_refresh_all();
+ // get object node (and verify it is in the selected list)
+ LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
+ if (!nodep)
+ {
+ return;
+ }
+
+ // if face = all, remove object from list
+ if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES))
+ {
+ // Remove all faces (or the object doesn't have faces) so remove the node
+ mSelectedObjects->removeNode(nodep);
+ nodep = NULL;
+ objectp->setSelected( FALSE );
+ }
+ else if (0 <= te && te < SELECT_MAX_TES)
+ {
+ // ...valid face, check to see if it was on
+ if (nodep->isTESelected(te))
+ {
+ nodep->selectTE(te, FALSE);
+ objectp->setTESelected(te, false);
+ }
+ else
+ {
+ LL_ERRS() << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << LL_ENDL;
+ return;
+ }
+
+ // ...check to see if this operation turned off all faces
+ BOOL found = FALSE;
+ for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++)
+ {
+ found = found || nodep->isTESelected(i);
+ }
+
+ // ...all faces now turned off, so remove
+ if (!found)
+ {
+ mSelectedObjects->removeNode(nodep);
+ nodep = NULL;
+ objectp->setSelected( FALSE );
+ // *FIXME: Doesn't update simulator that object is no longer selected
+ }
+ }
+ else
+ {
+ // ...out of range face
+ LL_ERRS() << "LLSelectMgr::remove - TE " << te << " out of range" << LL_ENDL;
+ }
+
+ updateSelectionCenter();
+ dialog_refresh_all();
}
@@ -1567,17 +1574,17 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
//-----------------------------------------------------------------------------
void LLSelectMgr::removeAll()
{
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setSelected( FALSE );
- }
-
- mSelectedObjects->deleteAllNodes();
+ for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ iter != mSelectedObjects->end(); iter++ )
+ {
+ LLViewerObject *objectp = (*iter)->getObject();
+ objectp->setSelected( FALSE );
+ }
- updateSelectionCenter();
- dialog_refresh_all();
+ mSelectedObjects->deleteAllNodes();
+
+ updateSelectionCenter();
+ dialog_refresh_all();
}
//-----------------------------------------------------------------------------
@@ -1585,41 +1592,41 @@ void LLSelectMgr::removeAll()
//-----------------------------------------------------------------------------
void LLSelectMgr::promoteSelectionToRoot()
{
- std::set<LLViewerObject*> selection_set;
+ std::set<LLViewerObject*> selection_set;
- BOOL selection_changed = FALSE;
+ BOOL selection_changed = FALSE;
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
- LLSelectNode* nodep = *curiter;
- LLViewerObject* object = nodep->getObject();
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); )
+ {
+ LLObjectSelection::iterator curiter = iter++;
+ LLSelectNode* nodep = *curiter;
+ LLViewerObject* object = nodep->getObject();
- if (nodep->mIndividualSelection)
- {
- selection_changed = TRUE;
- }
+ if (nodep->mIndividualSelection)
+ {
+ selection_changed = TRUE;
+ }
- LLViewerObject* parentp = object;
- while(parentp->getParent() && !(parentp->isRootEdit()))
- {
- parentp = (LLViewerObject*)parentp->getParent();
- }
+ LLViewerObject* parentp = object;
+ while(parentp->getParent() && !(parentp->isRootEdit()))
+ {
+ parentp = (LLViewerObject*)parentp->getParent();
+ }
+
+ selection_set.insert(parentp);
+ }
- selection_set.insert(parentp);
- }
-
- if (selection_changed)
- {
- deselectAll();
+ if (selection_changed)
+ {
+ deselectAll();
- std::set<LLViewerObject*>::iterator set_iter;
- for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter)
- {
- selectObjectAndFamily(*set_iter);
- }
- }
+ std::set<LLViewerObject*>::iterator set_iter;
+ for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter)
+ {
+ selectObjectAndFamily(*set_iter);
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -1627,25 +1634,25 @@ void LLSelectMgr::promoteSelectionToRoot()
//-----------------------------------------------------------------------------
void LLSelectMgr::demoteSelectionToIndividuals()
{
- std::vector<LLViewerObject*> objects;
+ std::vector<LLViewerObject*> objects;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLViewerObject* object = (*iter)->getObject();
- object->addThisAndNonJointChildren(objects);
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++)
+ {
+ LLViewerObject* object = (*iter)->getObject();
+ object->addThisAndNonJointChildren(objects);
+ }
- if (!objects.empty())
- {
- deselectAll();
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- selectObjectOnly(objectp);
- }
- }
+ if (!objects.empty())
+ {
+ deselectAll();
+ for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
+ iter != objects.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ selectObjectOnly(objectp);
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -1653,49 +1660,49 @@ void LLSelectMgr::demoteSelectionToIndividuals()
//-----------------------------------------------------------------------------
void LLSelectMgr::dump()
{
- LL_INFOS() << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << LL_ENDL;
-
- LL_INFOS() << "TE mode " << mTEMode << LL_ENDL;
-
- S32 count = 0;
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLViewerObject* objectp = (*iter)->getObject();
- LL_INFOS() << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << LL_ENDL;
- LL_INFOS() << " hasLSL " << objectp->flagScripted() << LL_ENDL;
- LL_INFOS() << " hasTouch " << objectp->flagHandleTouch() << LL_ENDL;
- LL_INFOS() << " hasMoney " << objectp->flagTakesMoney() << LL_ENDL;
- LL_INFOS() << " getposition " << objectp->getPosition() << LL_ENDL;
- LL_INFOS() << " getpositionAgent " << objectp->getPositionAgent() << LL_ENDL;
- LL_INFOS() << " getpositionRegion " << objectp->getPositionRegion() << LL_ENDL;
- LL_INFOS() << " getpositionGlobal " << objectp->getPositionGlobal() << LL_ENDL;
- LLDrawable* drawablep = objectp->mDrawable;
- LL_INFOS() << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << LL_ENDL;
- LL_INFOS() << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << LL_ENDL;
- count++;
- }
-
- // Face iterator
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- for (S32 te = 0; te < objectp->getNumTEs(); ++te )
- {
- if (node->isTESelected(te))
- {
- LL_INFOS() << "Object " << objectp << " te " << te << LL_ENDL;
- }
- }
- }
-
- LL_INFOS() << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << LL_ENDL;
-
- LL_INFOS() << "Center global " << mSelectionCenterGlobal << LL_ENDL;
+ LL_INFOS() << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << LL_ENDL;
+
+ LL_INFOS() << "TE mode " << mTEMode << LL_ENDL;
+
+ S32 count = 0;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLViewerObject* objectp = (*iter)->getObject();
+ LL_INFOS() << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << LL_ENDL;
+ LL_INFOS() << " hasLSL " << objectp->flagScripted() << LL_ENDL;
+ LL_INFOS() << " hasTouch " << objectp->flagHandleTouch() << LL_ENDL;
+ LL_INFOS() << " hasMoney " << objectp->flagTakesMoney() << LL_ENDL;
+ LL_INFOS() << " getposition " << objectp->getPosition() << LL_ENDL;
+ LL_INFOS() << " getpositionAgent " << objectp->getPositionAgent() << LL_ENDL;
+ LL_INFOS() << " getpositionRegion " << objectp->getPositionRegion() << LL_ENDL;
+ LL_INFOS() << " getpositionGlobal " << objectp->getPositionGlobal() << LL_ENDL;
+ LLDrawable* drawablep = objectp->mDrawable;
+ LL_INFOS() << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << LL_ENDL;
+ LL_INFOS() << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << LL_ENDL;
+ count++;
+ }
+
+ // Face iterator
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+ for (S32 te = 0; te < objectp->getNumTEs(); ++te )
+ {
+ if (node->isTESelected(te))
+ {
+ LL_INFOS() << "Object " << objectp << " te " << te << LL_ENDL;
+ }
+ }
+ }
+
+ LL_INFOS() << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << LL_ENDL;
+
+ LL_INFOS() << "Center global " << mSelectionCenterGlobal << LL_ENDL;
}
//-----------------------------------------------------------------------------
@@ -1703,7 +1710,7 @@ void LLSelectMgr::dump()
//-----------------------------------------------------------------------------
void LLSelectMgr::cleanup()
{
- mSilhouetteImagep = NULL;
+ mSilhouetteImagep = NULL;
}
@@ -1713,54 +1720,54 @@ void LLSelectMgr::cleanup()
struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
{
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
};
void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
{
- if (!item)
- {
- return;
- }
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
-
- for (iterator iter = begin(); iter != end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = (*iter)->getObject();
- if (!object)
- {
- continue;
- }
-
- S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
- bool texture_copied = false;
+ if (!item)
+ {
+ return;
+ }
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool texture_copied = false;
bool updated = false;
- for (S32 te = 0; te < num_tes; ++te)
- {
- if (node->isTESelected(te))
- {
- //(no-copy) textures must be moved to the object's inventory only once
- // without making any copies
- if (!texture_copied)
- {
- LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
- texture_copied = true;
- }
-
- // apply texture for the selected faces
- add(LLStatViewer::EDIT_TEXTURE, 1);
- object->setTEImage(te, image);
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy) textures must be moved to the object's inventory only once
+ // without making any copies
+ if (!texture_copied)
+ {
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ texture_copied = true;
+ }
+
+ // apply texture for the selected faces
+ add(LLStatViewer::EDIT_TEXTURE, 1);
+ object->setTEImage(te, image);
updated = true;
- }
- }
+ }
+ }
if (updated) // not nessesary? sendTEUpdate update supposed to be done by sendfunc
{
@@ -1769,7 +1776,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
// send the update to the simulator
object->sendTEUpdate();
}
- }
+ }
}
bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item)
@@ -1782,7 +1789,7 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i
LLUUID asset_id = item->getAssetUUID();
if (asset_id.isNull())
{
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
bool material_copied_all_faces = true;
@@ -1811,7 +1818,7 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i
if (!material_copied)
{
// Applying the material is not possible for this object given the current inventory
- material_copied_all_faces = false;
+ material_copied_all_faces = false;
break;
}
@@ -1835,30 +1842,30 @@ bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* i
// *TODO: re-arch texture applying out of lltooldraganddrop
bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
{
- // First for (no copy) textures and multiple object selection
- LLViewerInventoryItem* item = gInventory.getItem(imageid);
- if(item
- && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
- && (mSelectedObjects->getNumNodes() > 1) )
- {
+ // First for (no copy) textures and multiple object selection
+ LLViewerInventoryItem* item = gInventory.getItem(imageid);
+ if(item
+ && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
+ && (mSelectedObjects->getNumNodes() > 1) )
+ {
LL_DEBUGS() << "Attempted to apply no-copy texture " << imageid
<< " to multiple objects" << LL_ENDL;
LLNotificationsUtil::add("FailedToApplyTextureNoCopyToMultiple");
return false;
- }
-
- struct f : public LLSelectedTEFunctor
- {
- LLViewerInventoryItem* mItem;
- LLUUID mImageID;
- f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
- bool apply(LLViewerObject* objectp, S32 te)
- {
- if(!objectp || !objectp->permModify())
- {
- return false;
- }
+ }
+
+ struct f : public LLSelectedTEFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ LLUUID mImageID;
+ f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if(!objectp || !objectp->permModify())
+ {
+ return false;
+ }
// Might be better to run willObjectAcceptInventory
if (mItem && objectp->isAttachment())
@@ -1873,58 +1880,58 @@ bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
}
- if (mItem)
- {
+ if (mItem)
+ {
LLToolDragAndDrop::dropTextureOneFace(objectp,
te,
mItem,
LLToolDragAndDrop::SOURCE_AGENT,
LLUUID::null,
false);
- }
- else // not an inventory item
- {
- // Texture picker defaults aren't inventory items
- // * Don't need to worry about permissions for them
- // * Can just apply the texture and be done with it.
- objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
- }
-
- return true;
- }
- };
-
- if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
- {
- getSelection()->applyNoCopyTextureToTEs(item);
- }
- else
- {
- f setfunc(item, imageid);
- getSelection()->applyToTEs(&setfunc);
- }
-
-
- struct g : public LLSelectedObjectFunctor
- {
- LLViewerInventoryItem* mItem;
- g(LLViewerInventoryItem* item) : mItem(item) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (!mItem)
- {
- object->sendTEUpdate();
- // 1 particle effect per object
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setTargetObject(object);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- }
- return true;
- }
- } sendfunc(item);
- getSelection()->applyToObjects(&sendfunc);
+ }
+ else // not an inventory item
+ {
+ // Texture picker defaults aren't inventory items
+ // * Don't need to worry about permissions for them
+ // * Can just apply the texture and be done with it.
+ objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ }
+
+ return true;
+ }
+ };
+
+ if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ getSelection()->applyNoCopyTextureToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, imageid);
+ getSelection()->applyToTEs(&setfunc);
+ }
+
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ g(LLViewerInventoryItem* item) : mItem(item) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (!mItem)
+ {
+ object->sendTEUpdate();
+ // 1 particle effect per object
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(object);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
+ return true;
+ }
+ } sendfunc(item);
+ getSelection()->applyToObjects(&sendfunc);
return true;
}
@@ -1987,7 +1994,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
asset_id = mItem->getAssetUUID();
if (asset_id.isNull())
{
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
}
@@ -2028,7 +2035,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
if (!mItem)
{
- // 1 particle effect per object
+ // 1 particle effect per object
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
effectp->setSourceObject(gAgentAvatarp);
effectp->setTargetObject(object);
@@ -2053,23 +2060,23 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetColor(const LLColor4 &color)
{
- struct f : public LLSelectedTEFunctor
- {
- LLColor4 mColor;
- f(const LLColor4& c) : mColor(c) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- object->setTEColor(te, mColor);
- }
- return true;
- }
- } setfunc(color);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ LLColor4 mColor;
+ f(const LLColor4& c) : mColor(c) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ object->setTEColor(te, mColor);
+ }
+ return true;
+ }
+ } setfunc(color);
+ getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
//-----------------------------------------------------------------------------
@@ -2077,26 +2084,26 @@ void LLSelectMgr::selectionSetColor(const LLColor4 &color)
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
{
- struct f : public LLSelectedTEFunctor
- {
- LLColor4 mColor;
- f(const LLColor4& c) : mColor(c) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLColor4 prev_color = object->getTE(te)->getColor();
- mColor.mV[VALPHA] = prev_color.mV[VALPHA];
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, mColor);
- }
- return true;
- }
- } setfunc(color);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ LLColor4 mColor;
+ f(const LLColor4& c) : mColor(c) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLColor4 prev_color = object->getTE(te)->getColor();
+ mColor.mV[VALPHA] = prev_color.mV[VALPHA];
+ // update viewer side color in anticipation of update from simulator
+ object->setTEColor(te, mColor);
+ }
+ return true;
+ }
+ } setfunc(color);
+ getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
//-----------------------------------------------------------------------------
@@ -2104,125 +2111,125 @@ void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha)
{
- struct f : public LLSelectedTEFunctor
- {
- F32 mAlpha;
- f(const F32& a) : mAlpha(a) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLColor4 prev_color = object->getTE(te)->getColor();
- prev_color.mV[VALPHA] = mAlpha;
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, prev_color);
- }
- return true;
- }
- } setfunc(alpha);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ F32 mAlpha;
+ f(const F32& a) : mAlpha(a) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLColor4 prev_color = object->getTE(te)->getColor();
+ prev_color.mV[VALPHA] = mAlpha;
+ // update viewer side color in anticipation of update from simulator
+ object->setTEColor(te, prev_color);
+ }
+ return true;
+ }
+ } setfunc(alpha);
+ getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionRevertColors()
{
- struct f : public LLSelectedTEFunctor
- {
- LLObjectSelectionHandle mSelectedObjects;
- f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLSelectNode* nodep = mSelectedObjects->findNode(object);
- if (nodep && te < (S32)nodep->mSavedColors.size())
- {
- LLColor4 color = nodep->mSavedColors[te];
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, color);
- }
- }
- return true;
- }
- } setfunc(mSelectedObjects);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLSelectNode* nodep = mSelectedObjects->findNode(object);
+ if (nodep && te < (S32)nodep->mSavedColors.size())
+ {
+ LLColor4 color = nodep->mSavedColors[te];
+ // update viewer side color in anticipation of update from simulator
+ object->setTEColor(te, color);
+ }
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionRevertShinyColors()
{
- struct f : public LLSelectedTEFunctor
- {
- LLObjectSelectionHandle mSelectedObjects;
- f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLSelectNode* nodep = mSelectedObjects->findNode(object);
- if (nodep && te < (S32)nodep->mSavedShinyColors.size())
- {
- LLColor4 color = nodep->mSavedShinyColors[te];
- // update viewer side color in anticipation of update from simulator
- LLMaterialPtr old_mat = object->getTE(te)->getMaterialParams();
- if (!old_mat.isNull())
- {
- LLMaterialPtr new_mat = gFloaterTools->getPanelFace()->createDefaultMaterial(old_mat);
- new_mat->setSpecularLightColor(color);
- object->getTE(te)->setMaterialParams(new_mat);
- LLMaterialMgr::getInstance()->put(object->getID(), te, *new_mat);
- }
- }
- }
- return true;
- }
- } setfunc(mSelectedObjects);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLSelectNode* nodep = mSelectedObjects->findNode(object);
+ if (nodep && te < (S32)nodep->mSavedShinyColors.size())
+ {
+ LLColor4 color = nodep->mSavedShinyColors[te];
+ // update viewer side color in anticipation of update from simulator
+ LLMaterialPtr old_mat = object->getTE(te)->getMaterialParams();
+ if (!old_mat.isNull())
+ {
+ LLMaterialPtr new_mat = gFloaterTools->getPanelFace()->createDefaultMaterial(old_mat);
+ new_mat->setSpecularLightColor(color);
+ object->getTE(te)->setMaterialParams(new_mat);
+ LLMaterialMgr::getInstance()->put(object->getID(), te, *new_mat);
+ }
+ }
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
BOOL LLSelectMgr::selectionRevertTextures()
{
- struct f : public LLSelectedTEFunctor
- {
- LLObjectSelectionHandle mSelectedObjects;
- f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLSelectNode* nodep = mSelectedObjects->findNode(object);
- if (nodep && te < (S32)nodep->mSavedTextures.size())
- {
- LLUUID id = nodep->mSavedTextures[te];
- // update textures on viewer side
- if (id.isNull())
- {
- // this was probably a no-copy texture, leave image as-is
- return FALSE;
- }
- else
- {
- object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
-
- }
- }
- }
- return true;
- }
- } setfunc(mSelectedObjects);
- BOOL revert_successful = getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
-
- return revert_successful;
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ LLSelectNode* nodep = mSelectedObjects->findNode(object);
+ if (nodep && te < (S32)nodep->mSavedTextures.size())
+ {
+ LLUUID id = nodep->mSavedTextures[te];
+ // update textures on viewer side
+ if (id.isNull())
+ {
+ // this was probably a no-copy texture, leave image as-is
+ return FALSE;
+ }
+ else
+ {
+ object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+
+ }
+ }
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ BOOL revert_successful = getSelection()->applyToTEs(&setfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
+
+ return revert_successful;
}
void LLSelectMgr::selectionRevertGLTFMaterials()
@@ -2253,7 +2260,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
{
// Restore overrides and base material
LLGLTFMaterialList::queueApply(objectp, te, asset_id, nodep->mSavedGLTFOverrideMaterials[te]);
- }
+ }
else
{
//blank override out
@@ -2269,23 +2276,23 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
- struct f : public LLSelectedTEFunctor
- {
- U8 mBump;
- f(const U8& b) : mBump(b) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEBumpmap(te, mBump);
- }
- return true;
- }
- } setfunc(bumpmap);
+ struct f : public LLSelectedTEFunctor
+ {
+ U8 mBump;
+ f(const U8& b) : mBump(b) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ // update viewer side color in anticipation of update from simulator
+ object->setTEBumpmap(te, mBump);
+ }
+ return true;
+ }
+ } setfunc(bumpmap);
LLViewerInventoryItem* item = gInventory.getItem(image_id);
- if(item
+ if(item
&& !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
&& (mSelectedObjects->getNumNodes() > 1) )
{
@@ -2311,53 +2318,53 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetTexGen(U8 texgen)
{
- struct f : public LLSelectedTEFunctor
- {
- U8 mTexgen;
- f(const U8& t) : mTexgen(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTETexGen(te, mTexgen);
- }
- return true;
- }
- } setfunc(texgen);
- getSelection()->applyToTEs(&setfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ U8 mTexgen;
+ f(const U8& t) : mTexgen(t) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ // update viewer side color in anticipation of update from simulator
+ object->setTETexGen(te, mTexgen);
+ }
+ return true;
+ }
+ } setfunc(texgen);
+ getSelection()->applyToTEs(&setfunc);
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
{
- struct f : public LLSelectedTEFunctor
- {
- U8 mShiny;
- f(const U8& t) : mShiny(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEShiny(te, mShiny);
- }
- return true;
- }
- } setfunc(shiny);
+ struct f : public LLSelectedTEFunctor
+ {
+ U8 mShiny;
+ f(const U8& t) : mShiny(t) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ // update viewer side color in anticipation of update from simulator
+ object->setTEShiny(te, mShiny);
+ }
+ return true;
+ }
+ } setfunc(shiny);
LLViewerInventoryItem* item = gInventory.getItem(image_id);
- if(item
+ if(item
&& !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
&& (mSelectedObjects->getNumNodes() > 1) )
{
@@ -2384,235 +2391,235 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
}
getSelection()->applyToTEs(&setfunc);
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetFullbright(U8 fullbright)
{
- struct f : public LLSelectedTEFunctor
- {
- U8 mFullbright;
- f(const U8& t) : mFullbright(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEFullbright(te, mFullbright);
- }
- return true;
- }
- } setfunc(fullbright);
- getSelection()->applyToTEs(&setfunc);
-
- struct g : public LLSelectedObjectFunctor
- {
- U8 mFullbright;
- g(const U8& t) : mFullbright(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- if (mFullbright)
- {
- U8 material = object->getMaterial();
- U8 mcode = material & LL_MCODE_MASK;
- if (mcode == LL_MCODE_LIGHT)
- {
- mcode = LL_MCODE_GLASS;
- material = (material & ~LL_MCODE_MASK) | mcode;
- object->setMaterial(material);
- object->sendMaterialUpdate();
- }
- }
- }
- return true;
- }
- } sendfunc(fullbright);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedTEFunctor
+ {
+ U8 mFullbright;
+ f(const U8& t) : mFullbright(t) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ // update viewer side color in anticipation of update from simulator
+ object->setTEFullbright(te, mFullbright);
+ }
+ return true;
+ }
+ } setfunc(fullbright);
+ getSelection()->applyToTEs(&setfunc);
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ U8 mFullbright;
+ g(const U8& t) : mFullbright(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ if (mFullbright)
+ {
+ U8 material = object->getMaterial();
+ U8 mcode = material & LL_MCODE_MASK;
+ if (mcode == LL_MCODE_LIGHT)
+ {
+ mcode = LL_MCODE_GLASS;
+ material = (material & ~LL_MCODE_MASK) | mcode;
+ object->setMaterial(material);
+ object->sendMaterialUpdate();
+ }
+ }
+ }
+ return true;
+ }
+ } sendfunc(fullbright);
+ getSelection()->applyToObjects(&sendfunc);
}
// This function expects media_data to be a map containing relevant
// media data name/value pairs (e.g. home_url, etc.)
void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data)
-{
- struct f : public LLSelectedTEFunctor
- {
- U8 mMediaFlags;
- const LLSD &mMediaData;
- f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // If we are adding media, then check the current state of the
- // media data on this face.
- // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this
- // face.
- // - If it does not have media, and we ARE setting the HOME URL, add media to this face.
- // - If it does already have media, add/update media to/on this face
- // If we are removing media, just do it (ignore the passed-in LLSD).
- if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA)
- {
- llassert(mMediaData.isMap());
- const LLTextureEntry *texture_entry = object->getTE(te);
- if (!mMediaData.isMap() ||
- ((NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY)))
- {
- // skip adding/updating media
- }
- else {
- // Add/update media
- object->setTEMediaFlags(te, mMediaFlags);
- LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
- llassert(NULL != vo);
- if (NULL != vo)
- {
- vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
- }
- }
- }
- else
- {
- // delete media (or just set the flags)
- object->setTEMediaFlags(te, mMediaFlags);
- }
- }
- return true;
- }
- } setfunc(media_type, media_data);
- getSelection()->applyToTEs(&setfunc);
-
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
- llassert(NULL != vo);
- // It's okay to skip this object if hasMedia() is false...
- // the sendTEUpdate() above would remove all media data if it were
- // there.
+{
+ struct f : public LLSelectedTEFunctor
+ {
+ U8 mMediaFlags;
+ const LLSD &mMediaData;
+ f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+ if (object->permModify())
+ {
+ // If we are adding media, then check the current state of the
+ // media data on this face.
+ // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this
+ // face.
+ // - If it does not have media, and we ARE setting the HOME URL, add media to this face.
+ // - If it does already have media, add/update media to/on this face
+ // If we are removing media, just do it (ignore the passed-in LLSD).
+ if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA)
+ {
+ llassert(mMediaData.isMap());
+ const LLTextureEntry *texture_entry = object->getTE(te);
+ if (!mMediaData.isMap() ||
+ ((NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY)))
+ {
+ // skip adding/updating media
+ }
+ else {
+ // Add/update media
+ object->setTEMediaFlags(te, mMediaFlags);
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ llassert(NULL != vo);
+ if (NULL != vo)
+ {
+ vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ }
+ else
+ {
+ // delete media (or just set the flags)
+ object->setTEMediaFlags(te, mMediaFlags);
+ }
+ }
+ return true;
+ }
+ } setfunc(media_type, media_data);
+ getSelection()->applyToTEs(&setfunc);
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ llassert(NULL != vo);
+ // It's okay to skip this object if hasMedia() is false...
+ // the sendTEUpdate() above would remove all media data if it were
+ // there.
if (NULL != vo && vo->hasMedia())
{
// Send updated media data FOR THE ENTIRE OBJECT
vo->sendMediaDataUpdate();
}
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
void LLSelectMgr::selectionSetGlow(F32 glow)
{
- struct f1 : public LLSelectedTEFunctor
- {
- F32 mGlow;
- f1(F32 glow) : mGlow(glow) {};
- bool apply(LLViewerObject* object, S32 face)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEGlow(face, mGlow);
- }
- return true;
- }
- } func1(glow);
- mSelectedObjects->applyToTEs( &func1 );
-
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
+ struct f1 : public LLSelectedTEFunctor
+ {
+ F32 mGlow;
+ f1(F32 glow) : mGlow(glow) {};
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object->permModify())
+ {
+ // update viewer side color in anticipation of update from simulator
+ object->setTEGlow(face, mGlow);
+ }
+ return true;
+ }
+ } func1(glow);
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int te)
{
- struct f1 : public LLSelectedTEFunctor
- {
- LLMaterialPtr mMaterial;
- f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {}
+ struct f1 : public LLSelectedTEFunctor
+ {
+ LLMaterialPtr mMaterial;
+ f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {}
- bool apply(LLViewerObject* object, S32 te)
- {
+ bool apply(LLViewerObject* object, S32 te)
+ {
if (_specific_te == -1 || (te == _specific_te))
{
- if (object && object->permModify() && _material_func)
- {
- LLTextureEntry* tep = object->getTE(te);
- if (tep)
- {
- LLMaterialPtr current_material = tep->getMaterialParams();
- _material_func->apply(object, te, tep, current_material);
- }
- }
+ if (object && object->permModify() && _material_func)
+ {
+ LLTextureEntry* tep = object->getTE(te);
+ if (tep)
+ {
+ LLMaterialPtr current_material = tep->getMaterialParams();
+ _material_func->apply(object, te, tep, current_material);
+ }
+ }
}
- return true;
- }
+ return true;
+ }
- LLSelectedTEMaterialFunctor* _material_func;
+ LLSelectedTEMaterialFunctor* _material_func;
int _specific_te;
- } func1(material_func, te);
- mSelectedObjects->applyToTEs( &func1 );
-
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
+ } func1(material_func, te);
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
void LLSelectMgr::selectionRemoveMaterial()
{
- struct f1 : public LLSelectedTEFunctor
- {
- bool apply(LLViewerObject* object, S32 face)
- {
- if (object->permModify())
- {
- LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
- LLMaterialMgr::getInstance()->remove(object->getID(),face);
- object->setTEMaterialParams(face, NULL);
- }
- return true;
- }
- } func1;
- mSelectedObjects->applyToTEs( &func1 );
-
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
+ struct f1 : public LLSelectedTEFunctor
+ {
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object->permModify())
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ object->setTEMaterialParams(face, NULL);
+ }
+ return true;
+ }
+ } func1;
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
}
@@ -2621,17 +2628,17 @@ void LLSelectMgr::selectionRemoveMaterial()
//-----------------------------------------------------------------------------
LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
{
- for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
- iter != getSelection()->valid_end(); iter++ )
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object)
- {
- return nodep->mPermissions;
- }
- }
+ for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
+ iter != getSelection()->valid_end(); iter++ )
+ {
+ LLSelectNode* nodep = *iter;
+ if (nodep->getObject() == object)
+ {
+ return nodep->mPermissions;
+ }
+ }
- return NULL;
+ return NULL;
}
@@ -2640,115 +2647,115 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectionGetGlow(F32 *glow)
{
- BOOL identical;
- F32 lglow = 0.f;
- struct f1 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getGlow();
- }
- } func;
- identical = mSelectedObjects->getSelectedTEValue( &func, lglow );
+ BOOL identical;
+ F32 lglow = 0.f;
+ struct f1 : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ return object->getTE(face)->getGlow();
+ }
+ } func;
+ identical = mSelectedObjects->getSelectedTEValue( &func, lglow );
- *glow = lglow;
- return identical;
+ *glow = lglow;
+ return identical;
}
void LLSelectMgr::selectionSetPhysicsType(U8 type)
{
- struct f : public LLSelectedObjectFunctor
- {
- U8 mType;
- f(const U8& t) : mType(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsShapeType(mType);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(type);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ U8 mType;
+ f(const U8& t) : mType(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->setPhysicsShapeType(mType);
+ object->updateFlags(TRUE);
+ }
+ return true;
+ }
+ } sendfunc(type);
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetFriction(F32 friction)
{
- struct f : public LLSelectedObjectFunctor
- {
- F32 mFriction;
- f(const F32& friction) : mFriction(friction) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsFriction(mFriction);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(friction);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ F32 mFriction;
+ f(const F32& friction) : mFriction(friction) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->setPhysicsFriction(mFriction);
+ object->updateFlags(TRUE);
+ }
+ return true;
+ }
+ } sendfunc(friction);
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetGravity(F32 gravity )
{
- struct f : public LLSelectedObjectFunctor
- {
- F32 mGravity;
- f(const F32& gravity) : mGravity(gravity) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsGravity(mGravity);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(gravity);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ F32 mGravity;
+ f(const F32& gravity) : mGravity(gravity) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->setPhysicsGravity(mGravity);
+ object->updateFlags(TRUE);
+ }
+ return true;
+ }
+ } sendfunc(gravity);
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetDensity(F32 density )
{
- struct f : public LLSelectedObjectFunctor
- {
- F32 mDensity;
- f(const F32& density ) : mDensity(density) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsDensity(mDensity);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(density);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ F32 mDensity;
+ f(const F32& density ) : mDensity(density) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->setPhysicsDensity(mDensity);
+ object->updateFlags(TRUE);
+ }
+ return true;
+ }
+ } sendfunc(density);
+ getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetRestitution(F32 restitution)
{
- struct f : public LLSelectedObjectFunctor
- {
- F32 mRestitution;
- f(const F32& restitution ) : mRestitution(restitution) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsRestitution(mRestitution);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(restitution);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ F32 mRestitution;
+ f(const F32& restitution ) : mRestitution(restitution) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->setPhysicsRestitution(mRestitution);
+ object->updateFlags(TRUE);
+ }
+ return true;
+ }
+ } sendfunc(restitution);
+ getSelection()->applyToObjects(&sendfunc);
}
@@ -2757,136 +2764,136 @@ void LLSelectMgr::selectionSetRestitution(F32 restitution)
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetMaterial(U8 material)
{
- struct f : public LLSelectedObjectFunctor
- {
- U8 mMaterial;
- f(const U8& t) : mMaterial(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- U8 cur_material = object->getMaterial();
- U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK);
- object->setMaterial(material);
- object->sendMaterialUpdate();
- }
- return true;
- }
- } sendfunc(material);
- getSelection()->applyToObjects(&sendfunc);
+ struct f : public LLSelectedObjectFunctor
+ {
+ U8 mMaterial;
+ f(const U8& t) : mMaterial(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ U8 cur_material = object->getMaterial();
+ U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK);
+ object->setMaterial(material);
+ object->sendMaterialUpdate();
+ }
+ return true;
+ }
+ } sendfunc(material);
+ getSelection()->applyToObjects(&sendfunc);
}
// TRUE if all selected objects have this PCode
BOOL LLSelectMgr::selectionAllPCode(LLPCode code)
{
- struct f : public LLSelectedObjectFunctor
- {
- LLPCode mCode;
- f(const LLPCode& t) : mCode(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->getPCode() != mCode)
- {
- return FALSE;
- }
- return true;
- }
- } func(code);
- BOOL res = getSelection()->applyToObjects(&func);
- return res;
+ struct f : public LLSelectedObjectFunctor
+ {
+ LLPCode mCode;
+ f(const LLPCode& t) : mCode(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->getPCode() != mCode)
+ {
+ return FALSE;
+ }
+ return true;
+ }
+ } func(code);
+ BOOL res = getSelection()->applyToObjects(&func);
+ return res;
}
bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out)
{
- LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return FALSE;
+ LLViewerObject *object = mSelectedObjects->getFirstRootObject();
+ if (!object) return FALSE;
- bool include_in_search = object->getIncludeInSearch();
+ bool include_in_search = object->getIncludeInSearch();
- bool identical = true;
+ bool identical = true;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLViewerObject* object = (*iter)->getObject();
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++)
+ {
+ LLViewerObject* object = (*iter)->getObject();
- if ( include_in_search != object->getIncludeInSearch())
- {
- identical = false;
- break;
- }
- }
+ if ( include_in_search != object->getIncludeInSearch())
+ {
+ identical = false;
+ break;
+ }
+ }
- *include_in_search_out = include_in_search;
- return identical;
+ *include_in_search_out = include_in_search;
+ return identical;
}
void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search)
{
- LLViewerObject* object = NULL;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- object = (*iter)->getObject();
- object->setIncludeInSearch(include_in_search);
- }
- sendListToRegions(
- "ObjectIncludeInSearch",
- packAgentAndSessionID,
- packObjectIncludeInSearch,
+ LLViewerObject* object = NULL;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++)
+ {
+ object = (*iter)->getObject();
+ object->setIncludeInSearch(include_in_search);
+ }
+ sendListToRegions(
+ "ObjectIncludeInSearch",
+ packAgentAndSessionID,
+ packObjectIncludeInSearch,
logNoOp,
- &include_in_search,
- SEND_ONLY_ROOTS);
+ &include_in_search,
+ SEND_ONLY_ROOTS);
}
BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action)
{
- LLViewerObject *object = mSelectedObjects->getFirstObject();
- if (!object)
- {
- return FALSE;
- }
-
- U8 action = object->getClickAction();
- *out_action = action;
-
- struct f : public LLSelectedObjectFunctor
- {
- U8 mAction;
- f(const U8& t) : mAction(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if ( mAction != object->getClickAction())
- {
- return false;
- }
- return true;
- }
- } func(action);
- BOOL res = getSelection()->applyToObjects(&func);
- return res;
+ LLViewerObject *object = mSelectedObjects->getFirstObject();
+ if (!object)
+ {
+ return FALSE;
+ }
+
+ U8 action = object->getClickAction();
+ *out_action = action;
+
+ struct f : public LLSelectedObjectFunctor
+ {
+ U8 mAction;
+ f(const U8& t) : mAction(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if ( mAction != object->getClickAction())
+ {
+ return false;
+ }
+ return true;
+ }
+ } func(action);
+ BOOL res = getSelection()->applyToObjects(&func);
+ return res;
}
void LLSelectMgr::selectionSetClickAction(U8 action)
{
- struct f : public LLSelectedObjectFunctor
- {
- U8 mAction;
- f(const U8& t) : mAction(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- object->setClickAction(mAction);
- return true;
- }
- } func(action);
- getSelection()->applyToObjects(&func);
-
- sendListToRegions("ObjectClickAction",
- packAgentAndSessionID,
- packObjectClickAction,
+ struct f : public LLSelectedObjectFunctor
+ {
+ U8 mAction;
+ f(const U8& t) : mAction(t) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ object->setClickAction(mAction);
+ return true;
+ }
+ } func(action);
+ getSelection()->applyToObjects(&func);
+
+ sendListToRegions("ObjectClickAction",
+ packAgentAndSessionID,
+ packObjectClickAction,
logNoOp,
- &action,
- SEND_INDIVIDUALS);
+ &action,
+ SEND_INDIVIDUALS);
}
@@ -2898,54 +2905,54 @@ typedef std::pair<const std::string, const std::string> godlike_request_t;
void LLSelectMgr::sendGodlikeRequest(const std::string& request, const std::string& param)
{
- // If the agent is neither godlike nor an estate owner, the server
- // will reject the request.
- std::string message_type;
- if (gAgent.isGodlike())
- {
- message_type = "GodlikeMessage";
- }
- else
- {
- message_type = "EstateOwnerMessage";
- }
-
- godlike_request_t data(request, param);
- if(!mSelectedObjects->getRootObjectCount())
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage(message_type.c_str());
- LLSelectMgr::packGodlikeHead(&data);
- gAgent.sendReliableMessage();
- }
- else
- {
- sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, logNoOp, &data, SEND_ONLY_ROOTS);
- }
+ // If the agent is neither godlike nor an estate owner, the server
+ // will reject the request.
+ std::string message_type;
+ if (gAgent.isGodlike())
+ {
+ message_type = "GodlikeMessage";
+ }
+ else
+ {
+ message_type = "EstateOwnerMessage";
+ }
+
+ godlike_request_t data(request, param);
+ if(!mSelectedObjects->getRootObjectCount())
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage(message_type.c_str());
+ LLSelectMgr::packGodlikeHead(&data);
+ gAgent.sendReliableMessage();
+ }
+ else
+ {
+ sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, logNoOp, &data, SEND_ONLY_ROOTS);
+ }
}
void LLSelectMgr::packGodlikeHead(void* user_data)
{
- LLMessageSystem* msg = gMessageSystem;
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUID("TransactionID", LLUUID::null);
- godlike_request_t* data = (godlike_request_t*)user_data;
- msg->nextBlock("MethodData");
- msg->addString("Method", data->first);
- msg->addUUID("Invoice", LLUUID::null);
-
- // The parameters used to be restricted to either string or
- // integer. This mimics that behavior under the new 'string-only'
- // parameter list by not packing a string if there wasn't one
- // specified. The object ids will be packed in the
- // packObjectIDAsParam() method.
- if(data->second.size() > 0)
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", data->second);
- }
+ LLMessageSystem* msg = gMessageSystem;
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID("TransactionID", LLUUID::null);
+ godlike_request_t* data = (godlike_request_t*)user_data;
+ msg->nextBlock("MethodData");
+ msg->addString("Method", data->first);
+ msg->addUUID("Invoice", LLUUID::null);
+
+ // The parameters used to be restricted to either string or
+ // integer. This mimics that behavior under the new 'string-only'
+ // parameter list by not packing a string if there wasn't one
+ // specified. The object ids will be packed in the
+ // packObjectIDAsParam() method.
+ if(data->second.size() > 0)
+ {
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", data->second);
+ }
}
// static
@@ -2968,9 +2975,9 @@ void LLSelectMgr::logDetachRequest(LLSelectNode* node, void *)
// static
void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
{
- std::string buf = llformat("%u", node->getObject()->getLocalID());
- gMessageSystem->nextBlock("ParamList");
- gMessageSystem->addString("Parameter", buf);
+ std::string buf = llformat("%u", node->getObject()->getLocalID());
+ gMessageSystem->nextBlock("ParamList");
+ gMessageSystem->addString("Parameter", buf);
}
//-----------------------------------------------------------------------------
@@ -2978,34 +2985,34 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
{
- struct f : public LLSelectedTEFunctor
- {
- F32 mRepeatsPerMeter;
- f(const F32& t) : mRepeatsPerMeter(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
+ struct f : public LLSelectedTEFunctor
+ {
+ F32 mRepeatsPerMeter;
+ f(const F32& t) : mRepeatsPerMeter(t) {}
+ bool apply(LLViewerObject* object, S32 te)
+ {
+
+ if (object->permModify())
+ {
+ // Compute S,T to axis mapping
+ U32 s_axis, t_axis;
+ if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis))
+ {
+ return TRUE;
+ }
- if (object->permModify())
- {
- // Compute S,T to axis mapping
- U32 s_axis, t_axis;
- if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis))
- {
- return TRUE;
- }
+ F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter;
+ F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter;
- F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter;
- F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter;
+ object->setTEScale(te, new_s, new_t);
+ }
+ return true;
+ }
+ } setfunc(repeats_per_meter);
+ getSelection()->applyToTEs(&setfunc);
- object->setTEScale(te, new_s, new_t);
- }
- return true;
- }
- } setfunc(repeats_per_meter);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
+ LLSelectMgrSendFunctor sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
}
@@ -3018,113 +3025,113 @@ void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
//-----------------------------------------------------------------------------
void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++)
- {
- LLSelectNode* selectNode = *iter;
- LLViewerObject* object = selectNode->getObject();
-
- if (!object)
- {
- continue;
- }
-
- if (!object->permModify())
- {
- continue;
- }
-
- if (object->getNumTEs() == 0)
- {
- continue;
- }
-
- BOOL send = FALSE;
-
- for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++)
- {
- const LLTextureEntry* tep = object->getTE(te_num);
-
- BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR;
- if (planar == stretch)
- {
- // Figure out how S,T changed with scale operation
- U32 s_axis, t_axis;
- if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis))
- {
- continue;
- }
-
- LLVector3 object_scale = object->getScale();
- LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num];
-
- // We like these to track together. NORSPEC-96
- //
- LLVector3 normal_scale_ratio = diffuse_scale_ratio;
- LLVector3 specular_scale_ratio = diffuse_scale_ratio;
-
- // Apply new scale to face
- if (planar)
- {
- F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
- F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
-
- F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
- F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
-
- F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
- F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
-
- object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t);
-
- LLTextureEntry* tep = object->getTE(te_num);
-
- if (tep && !tep->getMaterialParams().isNull())
- {
- LLMaterialPtr orig = tep->getMaterialParams();
- LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
- p->setNormalRepeat(normal_scale_s, normal_scale_t);
- p->setSpecularRepeat(specular_scale_s, specular_scale_t);
-
- LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
- }
- }
- else
- {
-
- F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
- F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
-
- F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
- F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
-
- F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
- F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
-
- object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t);
-
- LLTextureEntry* tep = object->getTE(te_num);
-
- if (tep && !tep->getMaterialParams().isNull())
- {
- LLMaterialPtr orig = tep->getMaterialParams();
- LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
-
- p->setNormalRepeat(normal_scale_s, normal_scale_t);
- p->setSpecularRepeat(specular_scale_s, specular_scale_t);
-
- LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
- }
- }
- send = send_to_sim;
- }
- }
-
- if (send)
- {
- object->sendTEUpdate();
- }
- }
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++)
+ {
+ LLSelectNode* selectNode = *iter;
+ LLViewerObject* object = selectNode->getObject();
+
+ if (!object)
+ {
+ continue;
+ }
+
+ if (!object->permModify())
+ {
+ continue;
+ }
+
+ if (object->getNumTEs() == 0)
+ {
+ continue;
+ }
+
+ BOOL send = FALSE;
+
+ for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++)
+ {
+ const LLTextureEntry* tep = object->getTE(te_num);
+
+ BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR;
+ if (planar == stretch)
+ {
+ // Figure out how S,T changed with scale operation
+ U32 s_axis, t_axis;
+ if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis))
+ {
+ continue;
+ }
+
+ LLVector3 object_scale = object->getScale();
+ LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num];
+
+ // We like these to track together. NORSPEC-96
+ //
+ LLVector3 normal_scale_ratio = diffuse_scale_ratio;
+ LLVector3 specular_scale_ratio = diffuse_scale_ratio;
+
+ // Apply new scale to face
+ if (planar)
+ {
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
+ }
+ else
+ {
+
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
+
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
+ }
+ send = send_to_sim;
+ }
+ }
+
+ if (send)
+ {
+ object->sendTEUpdate();
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -3133,16 +3140,16 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetAllRootsValid()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); ++iter )
- {
- LLSelectNode* node = *iter;
- if( !node->mValid )
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); ++iter )
+ {
+ LLSelectNode* node = *iter;
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
@@ -3152,16 +3159,16 @@ BOOL LLSelectMgr::selectGetAllRootsValid()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetAllValid()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); ++iter )
- {
- LLSelectNode* node = *iter;
- if( !node->mValid )
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); ++iter )
+ {
+ LLSelectNode* node = *iter;
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3172,17 +3179,17 @@ BOOL LLSelectMgr::selectGetAllValid()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetAllValidAndObjectsFound()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3191,21 +3198,21 @@ BOOL LLSelectMgr::selectGetAllValidAndObjectsFound()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetModify()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( !object->permModify() )
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->permModify() )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3214,22 +3221,22 @@ BOOL LLSelectMgr::selectGetModify()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsModify()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( !object->permModify() )
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->permModify() )
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3268,21 +3275,21 @@ BOOL LLSelectMgr::selectGetSameRegion()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetNonPermanentEnforced()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( object->isPermanentEnforced())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->isPermanentEnforced())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3291,22 +3298,22 @@ BOOL LLSelectMgr::selectGetNonPermanentEnforced()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( object->isPermanentEnforced())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->isPermanentEnforced())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3314,21 +3321,21 @@ BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetPermanent()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( !object->flagObjectPermanent())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3337,22 +3344,22 @@ BOOL LLSelectMgr::selectGetPermanent()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsPermanent()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( !object->flagObjectPermanent())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3360,21 +3367,21 @@ BOOL LLSelectMgr::selectGetRootsPermanent()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetCharacter()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( !object->flagCharacter())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3383,22 +3390,22 @@ BOOL LLSelectMgr::selectGetCharacter()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsCharacter()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( !object->flagCharacter())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3406,21 +3413,21 @@ BOOL LLSelectMgr::selectGetRootsCharacter()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetNonPathfinding()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( object->flagObjectPermanent() || object->flagCharacter())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent() || object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3429,22 +3436,22 @@ BOOL LLSelectMgr::selectGetNonPathfinding()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsNonPathfinding()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( object->flagObjectPermanent() || object->flagCharacter())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent() || object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3452,21 +3459,21 @@ BOOL LLSelectMgr::selectGetRootsNonPathfinding()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetNonPermanent()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( object->flagObjectPermanent())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3475,22 +3482,22 @@ BOOL LLSelectMgr::selectGetNonPermanent()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsNonPermanent()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( object->flagObjectPermanent())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3498,45 +3505,45 @@ BOOL LLSelectMgr::selectGetRootsNonPermanent()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetNonCharacter()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( object->flagCharacter())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// selectGetRootsNonCharacter() - return TRUE if all root objects are not
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetRootsNonCharacter() - return TRUE if all root objects are not
// character
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsNonCharacter()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if( object->flagCharacter())
- {
- return FALSE;
- }
- }
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
- return TRUE;
+ return TRUE;
}
@@ -3546,30 +3553,30 @@ BOOL LLSelectMgr::selectGetRootsNonCharacter()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetEditableLinksets()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if (object->flagUsePhysics() ||
- object->flagTemporaryOnRez() ||
- object->flagCharacter() ||
- object->flagVolumeDetect() ||
- object->flagAnimSource() ||
- (object->getRegion() != gAgent.getRegion()) ||
- (!gAgent.isGodlike() &&
- !gAgent.canManageEstate() &&
- !object->permYouOwner() &&
- !object->permMove()))
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if (object->flagUsePhysics() ||
+ object->flagTemporaryOnRez() ||
+ object->flagCharacter() ||
+ object->flagVolumeDetect() ||
+ object->flagAnimSource() ||
+ (object->getRegion() != gAgent.getRegion()) ||
+ (!gAgent.isGodlike() &&
+ !gAgent.canManageEstate() &&
+ !object->permYouOwner() &&
+ !object->permMove()))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3578,22 +3585,22 @@ BOOL LLSelectMgr::selectGetEditableLinksets()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetViewableCharacters()
{
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !object || !node->mValid )
- {
- return FALSE;
- }
- if( !object->flagCharacter() ||
- (object->getRegion() != gAgent.getRegion()))
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter() ||
+ (object->getRegion() != gAgent.getRegion()))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3602,21 +3609,21 @@ BOOL LLSelectMgr::selectGetViewableCharacters()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsTransfer()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if(!object->permTransfer())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if(!object->permTransfer())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3625,88 +3632,88 @@ BOOL LLSelectMgr::selectGetRootsTransfer()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetRootsCopy()
{
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if( !node->mValid )
- {
- return FALSE;
- }
- if(!object->permCopy())
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if(!object->permCopy())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
struct LLSelectGetFirstTest
{
- LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { }
- virtual ~LLSelectGetFirstTest() { }
-
- // returns false to break out of the iteration.
- bool checkMatchingNode(LLSelectNode* node)
- {
- if (!node || !node->mValid)
- {
- return false;
- }
-
- if (mFirst)
- {
- mFirstValue = getValueFromNode(node);
- mFirst = false;
- }
- else
- {
- if ( mFirstValue != getValueFromNode(node) )
- {
- mIdentical = false;
- // stop testing once we know not all selected are identical.
- return false;
- }
- }
- // continue testing.
- return true;
- }
-
- bool mIdentical;
- LLUUID mFirstValue;
+ LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { }
+ virtual ~LLSelectGetFirstTest() { }
+
+ // returns false to break out of the iteration.
+ bool checkMatchingNode(LLSelectNode* node)
+ {
+ if (!node || !node->mValid)
+ {
+ return false;
+ }
+
+ if (mFirst)
+ {
+ mFirstValue = getValueFromNode(node);
+ mFirst = false;
+ }
+ else
+ {
+ if ( mFirstValue != getValueFromNode(node) )
+ {
+ mIdentical = false;
+ // stop testing once we know not all selected are identical.
+ return false;
+ }
+ }
+ // continue testing.
+ return true;
+ }
+
+ bool mIdentical;
+ LLUUID mFirstValue;
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0;
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0;
private:
- bool mFirst;
+ bool mFirst;
};
void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)
{
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
- iter != getSelection()->valid_end(); ++iter )
- {
- if (!test->checkMatchingNode(*iter))
- {
- break;
- }
- }
- }
- else
- {
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); ++iter )
- {
- if (!test->checkMatchingNode(*iter))
- {
- break;
- }
- }
- }
+ if (gSavedSettings.getBOOL("EditLinkedParts"))
+ {
+ for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
+ iter != getSelection()->valid_end(); ++iter )
+ {
+ if (!test->checkMatchingNode(*iter))
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
+ iter != getSelection()->root_object_end(); ++iter )
+ {
+ if (!test->checkMatchingNode(*iter))
+ {
+ break;
+ }
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -3716,35 +3723,35 @@ void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)
struct LLSelectGetFirstCreator : public LLSelectGetFirstTest
{
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node)
- {
- return node->mPermissions->getCreator();
- }
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ return node->mPermissions->getCreator();
+ }
};
BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
{
- LLSelectGetFirstCreator test;
- getFirst(&test);
-
- if (test.mFirstValue.isNull())
- {
- name = LLTrans::getString("AvatarNameNobody");
- return FALSE;
- }
-
- result_id = test.mFirstValue;
+ LLSelectGetFirstCreator test;
+ getFirst(&test);
- if (test.mIdentical)
- {
- name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
- }
- else
- {
- name = LLTrans::getString("AvatarNameMultiple");
- }
+ if (test.mFirstValue.isNull())
+ {
+ name = LLTrans::getString("AvatarNameNobody");
+ return FALSE;
+ }
+
+ result_id = test.mFirstValue;
+
+ if (test.mIdentical)
+ {
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+ }
+ else
+ {
+ name = LLTrans::getString("AvatarNameMultiple");
+ }
- return test.mIdentical;
+ return test.mIdentical;
}
//-----------------------------------------------------------------------------
@@ -3754,44 +3761,44 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
struct LLSelectGetFirstOwner : public LLSelectGetFirstTest
{
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node)
- {
- // Don't use 'getOwnership' since we return a reference, not a copy.
- // Will return LLUUID::null if unowned (which is not allowed and should never happen.)
- return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner();
- }
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ // Don't use 'getOwnership' since we return a reference, not a copy.
+ // Will return LLUUID::null if unowned (which is not allowed and should never happen.)
+ return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner();
+ }
};
BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
{
- LLSelectGetFirstOwner test;
- getFirst(&test);
-
- if (test.mFirstValue.isNull())
- {
- return FALSE;
- }
-
- result_id = test.mFirstValue;
-
- if (test.mIdentical)
- {
- bool group_owned = selectIsGroupOwned();
- if (group_owned)
- {
- name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString();
- }
- else
- {
- name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
- }
- }
- else
- {
- name = LLTrans::getString("AvatarNameMultiple");
- }
-
- return test.mIdentical;
+ LLSelectGetFirstOwner test;
+ getFirst(&test);
+
+ if (test.mFirstValue.isNull())
+ {
+ return FALSE;
+ }
+
+ result_id = test.mFirstValue;
+
+ if (test.mIdentical)
+ {
+ bool group_owned = selectIsGroupOwned();
+ if (group_owned)
+ {
+ name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString();
+ }
+ else
+ {
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+ }
+ }
+ else
+ {
+ name = LLTrans::getString("AvatarNameMultiple");
+ }
+
+ return test.mIdentical;
}
//-----------------------------------------------------------------------------
@@ -3801,34 +3808,34 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest
{
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node)
- {
- return node->mPermissions->getLastOwner();
- }
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ return node->mPermissions->getLastOwner();
+ }
};
BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
{
- LLSelectGetFirstLastOwner test;
- getFirst(&test);
+ LLSelectGetFirstLastOwner test;
+ getFirst(&test);
- if (test.mFirstValue.isNull())
- {
- return FALSE;
- }
-
- result_id = test.mFirstValue;
+ if (test.mFirstValue.isNull())
+ {
+ return FALSE;
+ }
- if (test.mIdentical)
- {
- name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
- }
- else
- {
- name.assign( "" );
- }
+ result_id = test.mFirstValue;
+
+ if (test.mIdentical)
+ {
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+ }
+ else
+ {
+ name.assign( "" );
+ }
- return test.mIdentical;
+ return test.mIdentical;
}
//-----------------------------------------------------------------------------
@@ -3838,45 +3845,45 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
struct LLSelectGetFirstGroup : public LLSelectGetFirstTest
{
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node)
- {
- return node->mPermissions->getGroup();
- }
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ return node->mPermissions->getGroup();
+ }
};
BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
{
- LLSelectGetFirstGroup test;
- getFirst(&test);
+ LLSelectGetFirstGroup test;
+ getFirst(&test);
- result_id = test.mFirstValue;
- return test.mIdentical;
+ result_id = test.mFirstValue;
+ return test.mIdentical;
}
//-----------------------------------------------------------------------------
// selectIsGroupOwned()
-// Only operates on root nodes unless editing linked parts.
+// Only operates on root nodes unless editing linked parts.
// Returns TRUE if the first selected is group owned.
//-----------------------------------------------------------------------------
struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest
{
protected:
- virtual const LLUUID& getValueFromNode(LLSelectNode* node)
- {
- if (node->mPermissions->isGroupOwned())
- {
- return node->mPermissions->getGroup();
- }
- return LLUUID::null;
- }
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ if (node->mPermissions->isGroupOwned())
+ {
+ return node->mPermissions->getGroup();
+ }
+ return LLUUID::null;
+ }
};
BOOL LLSelectMgr::selectIsGroupOwned()
{
- LLSelectGetFirstGroupOwner test;
- getFirst(&test);
+ LLSelectGetFirstGroupOwner test;
+ getFirst(&test);
- return test.mFirstValue.notNull() ? TRUE : FALSE;
+ return test.mFirstValue.notNull() ? TRUE : FALSE;
}
//-----------------------------------------------------------------------------
@@ -3890,255 +3897,255 @@ BOOL LLSelectMgr::selectIsGroupOwned()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off)
{
- U32 mask;
- U32 mask_and = 0xffffffff;
- U32 mask_or = 0x00000000;
- BOOL all_valid = FALSE;
-
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
-
- if (!node->mValid)
- {
- all_valid = FALSE;
- break;
- }
-
- all_valid = TRUE;
-
- switch( which_perm )
- {
- case PERM_BASE:
- mask = node->mPermissions->getMaskBase();
- break;
- case PERM_OWNER:
- mask = node->mPermissions->getMaskOwner();
- break;
- case PERM_GROUP:
- mask = node->mPermissions->getMaskGroup();
- break;
- case PERM_EVERYONE:
- mask = node->mPermissions->getMaskEveryone();
- break;
- case PERM_NEXT_OWNER:
- mask = node->mPermissions->getMaskNextOwner();
- break;
- default:
- mask = 0x0;
- break;
- }
- mask_and &= mask;
- mask_or |= mask;
- }
-
- if (all_valid)
- {
- // ...TRUE through all ANDs means all TRUE
- *mask_on = mask_and;
-
- // ...FALSE through all ORs means all FALSE
- *mask_off = ~mask_or;
- return TRUE;
- }
- else
- {
- *mask_on = 0;
- *mask_off = 0;
- return FALSE;
- }
+ U32 mask;
+ U32 mask_and = 0xffffffff;
+ U32 mask_or = 0x00000000;
+ BOOL all_valid = FALSE;
+
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
+ if (!node->mValid)
+ {
+ all_valid = FALSE;
+ break;
+ }
+
+ all_valid = TRUE;
+
+ switch( which_perm )
+ {
+ case PERM_BASE:
+ mask = node->mPermissions->getMaskBase();
+ break;
+ case PERM_OWNER:
+ mask = node->mPermissions->getMaskOwner();
+ break;
+ case PERM_GROUP:
+ mask = node->mPermissions->getMaskGroup();
+ break;
+ case PERM_EVERYONE:
+ mask = node->mPermissions->getMaskEveryone();
+ break;
+ case PERM_NEXT_OWNER:
+ mask = node->mPermissions->getMaskNextOwner();
+ break;
+ default:
+ mask = 0x0;
+ break;
+ }
+ mask_and &= mask;
+ mask_or |= mask;
+ }
+
+ if (all_valid)
+ {
+ // ...TRUE through all ANDs means all TRUE
+ *mask_on = mask_and;
+
+ // ...FALSE through all ORs means all FALSE
+ *mask_off = ~mask_or;
+ return TRUE;
+ }
+ else
+ {
+ *mask_on = 0;
+ *mask_off = 0;
+ return FALSE;
+ }
}
BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm)
{
- BOOL first = TRUE;
- LLPermissions perm;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (!node->mValid)
- {
- return FALSE;
- }
+ BOOL first = TRUE;
+ LLPermissions perm;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (!node->mValid)
+ {
+ return FALSE;
+ }
- if (first)
- {
- perm = *(node->mPermissions);
- first = FALSE;
- }
- else
- {
- perm.accumulate(*(node->mPermissions));
- }
- }
+ if (first)
+ {
+ perm = *(node->mPermissions);
+ first = FALSE;
+ }
+ else
+ {
+ perm.accumulate(*(node->mPermissions));
+ }
+ }
- result_perm = perm;
+ result_perm = perm;
- return TRUE;
+ return TRUE;
}
void LLSelectMgr::selectDelete()
{
- S32 deleteable_count = 0;
-
- BOOL locked_but_deleteable_object = FALSE;
- BOOL no_copy_but_deleteable_object = FALSE;
- BOOL all_owned_by_you = TRUE;
-
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++)
- {
- LLViewerObject* obj = (*iter)->getObject();
-
- if( obj->isAttachment() )
- {
- continue;
- }
-
- deleteable_count++;
-
- // Check to see if you can delete objects which are locked.
- if(!obj->permMove())
- {
- locked_but_deleteable_object = TRUE;
- }
- if(!obj->permCopy())
- {
- no_copy_but_deleteable_object = TRUE;
- }
- if(!obj->permYouOwner())
- {
- all_owned_by_you = FALSE;
- }
- }
-
- if( 0 == deleteable_count )
- {
- make_ui_sound("UISndInvalidOp");
- return;
- }
-
- LLNotification::Params params("ConfirmObjectDeleteLock");
- params.functor.function(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection()));
-
- if(locked_but_deleteable_object ||
- no_copy_but_deleteable_object ||
- !all_owned_by_you)
- {
- // convert any transient pie-menu selections to full selection so this operation
- // has some context
- // NOTE: if user cancels delete operation, this will potentially leave objects selected outside of build mode
- // but this is ok, if not ideal
- convertTransient();
-
- //This is messy, but needed to get all english our of the UI.
- if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you)
- {
- //Locked only
- params.name("ConfirmObjectDeleteLock");
- }
- else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
- {
- //No Copy only
- params.name("ConfirmObjectDeleteNoCopy");
- }
- else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
- {
- //not owned only
- params.name("ConfirmObjectDeleteNoOwn");
- }
- else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
- {
- //locked and no copy
- params.name("ConfirmObjectDeleteLockNoCopy");
- }
- else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
- {
- //locked and not owned
- params.name("ConfirmObjectDeleteLockNoOwn");
- }
- else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you)
- {
- //no copy and not owned
- params.name("ConfirmObjectDeleteNoCopyNoOwn");
- }
- else
- {
- //locked, no copy and not owned
- params.name("ConfirmObjectDeleteLockNoCopyNoOwn");
- }
-
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
+ S32 deleteable_count = 0;
+
+ BOOL locked_but_deleteable_object = FALSE;
+ BOOL no_copy_but_deleteable_object = FALSE;
+ BOOL all_owned_by_you = TRUE;
+
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++)
+ {
+ LLViewerObject* obj = (*iter)->getObject();
+
+ if( obj->isAttachment() )
+ {
+ continue;
+ }
+
+ deleteable_count++;
+
+ // Check to see if you can delete objects which are locked.
+ if(!obj->permMove())
+ {
+ locked_but_deleteable_object = TRUE;
+ }
+ if(!obj->permCopy())
+ {
+ no_copy_but_deleteable_object = TRUE;
+ }
+ if(!obj->permYouOwner())
+ {
+ all_owned_by_you = FALSE;
+ }
+ }
+
+ if( 0 == deleteable_count )
+ {
+ make_ui_sound("UISndInvalidOp");
+ return;
+ }
+
+ LLNotification::Params params("ConfirmObjectDeleteLock");
+ params.functor.function(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection()));
+
+ if(locked_but_deleteable_object ||
+ no_copy_but_deleteable_object ||
+ !all_owned_by_you)
+ {
+ // convert any transient pie-menu selections to full selection so this operation
+ // has some context
+ // NOTE: if user cancels delete operation, this will potentially leave objects selected outside of build mode
+ // but this is ok, if not ideal
+ convertTransient();
+
+ //This is messy, but needed to get all english our of the UI.
+ if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you)
+ {
+ //Locked only
+ params.name("ConfirmObjectDeleteLock");
+ }
+ else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
+ {
+ //No Copy only
+ params.name("ConfirmObjectDeleteNoCopy");
+ }
+ else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
+ {
+ //not owned only
+ params.name("ConfirmObjectDeleteNoOwn");
+ }
+ else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
+ {
+ //locked and no copy
+ params.name("ConfirmObjectDeleteLockNoCopy");
+ }
+ else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
+ {
+ //locked and not owned
+ params.name("ConfirmObjectDeleteLockNoOwn");
+ }
+ else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you)
+ {
+ //no copy and not owned
+ params.name("ConfirmObjectDeleteNoCopyNoOwn");
+ }
+ else
+ {
+ //locked, no copy and not owned
+ params.name("ConfirmObjectDeleteLockNoCopyNoOwn");
+ }
+
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
// static
bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (!handle->getObjectCount())
- {
- LL_WARNS() << "Nothing to delete!" << LL_ENDL;
- return false;
- }
-
- switch(option)
- {
- case 0:
- {
- // TODO: Make sure you have delete permissions on all of them.
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- // attempt to derez into the trash.
- LLDeRezInfo info(DRD_TRASH, trash_id);
- LLSelectMgr::getInstance()->sendListToRegions("DeRezObject",
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (!handle->getObjectCount())
+ {
+ LL_WARNS() << "Nothing to delete!" << LL_ENDL;
+ return false;
+ }
+
+ switch(option)
+ {
+ case 0:
+ {
+ // TODO: Make sure you have delete permissions on all of them.
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ // attempt to derez into the trash.
+ LLDeRezInfo info(DRD_TRASH, trash_id);
+ LLSelectMgr::getInstance()->sendListToRegions("DeRezObject",
packDeRezHeader,
packObjectLocalID,
logNoOp,
(void*) &info,
SEND_ONLY_ROOTS);
- // VEFFECT: Delete Object - one effect for all deletes
- if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
- {
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
- effectp->setPositionGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal() );
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- F32 duration = 0.5f;
- duration += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount() / 64.f;
- effectp->setDuration(duration);
- }
-
- gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
-
- // Keep track of how many objects have been deleted.
- add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount());
- }
- break;
- case 1:
- default:
- break;
- }
- return false;
+ // VEFFECT: Delete Object - one effect for all deletes
+ if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
+ {
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+ effectp->setPositionGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal() );
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ F32 duration = 0.5f;
+ duration += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount() / 64.f;
+ effectp->setDuration(duration);
+ }
+
+ gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
+
+ // Keep track of how many objects have been deleted.
+ add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount());
+ }
+ break;
+ case 1:
+ default:
+ break;
+ }
+ return false;
}
void LLSelectMgr::selectForceDelete()
{
- sendListToRegions(
- "ObjectDelete",
- packDeleteHeader,
- packObjectLocalID,
+ sendListToRegions(
+ "ObjectDelete",
+ packDeleteHeader,
+ packObjectLocalID,
logNoOp,
- (void*)TRUE,
- SEND_ONLY_ROOTS);
+ (void*)TRUE,
+ SEND_ONLY_ROOTS);
}
BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify)
@@ -4175,154 +4182,154 @@ BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify)
}
void LLSelectMgr::selectGetAggregateSaleInfo(U32 &num_for_sale,
- BOOL &is_for_sale_mixed,
- BOOL &is_sale_price_mixed,
- S32 &total_sale_price,
- S32 &individual_sale_price)
-{
- num_for_sale = 0;
- is_for_sale_mixed = FALSE;
- is_sale_price_mixed = FALSE;
- total_sale_price = 0;
- individual_sale_price = 0;
-
-
- // Empty set.
- if (getSelection()->root_begin() == getSelection()->root_end())
- return;
-
- LLSelectNode *node = *(getSelection()->root_begin());
- const BOOL first_node_for_sale = node->mSaleInfo.isForSale();
- const S32 first_node_sale_price = node->mSaleInfo.getSalePrice();
-
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- const BOOL node_for_sale = node->mSaleInfo.isForSale();
- const S32 node_sale_price = node->mSaleInfo.getSalePrice();
-
- // Set mixed if the fields don't match the first node's fields.
- if (node_for_sale != first_node_for_sale)
- is_for_sale_mixed = TRUE;
- if (node_sale_price != first_node_sale_price)
- is_sale_price_mixed = TRUE;
-
- if (node_for_sale)
- {
- total_sale_price += node_sale_price;
- num_for_sale ++;
- }
- }
-
- individual_sale_price = first_node_sale_price;
- if (is_for_sale_mixed)
- {
- is_sale_price_mixed = TRUE;
- individual_sale_price = 0;
- }
+ BOOL &is_for_sale_mixed,
+ BOOL &is_sale_price_mixed,
+ S32 &total_sale_price,
+ S32 &individual_sale_price)
+{
+ num_for_sale = 0;
+ is_for_sale_mixed = FALSE;
+ is_sale_price_mixed = FALSE;
+ total_sale_price = 0;
+ individual_sale_price = 0;
+
+
+ // Empty set.
+ if (getSelection()->root_begin() == getSelection()->root_end())
+ return;
+
+ LLSelectNode *node = *(getSelection()->root_begin());
+ const BOOL first_node_for_sale = node->mSaleInfo.isForSale();
+ const S32 first_node_sale_price = node->mSaleInfo.getSalePrice();
+
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ const BOOL node_for_sale = node->mSaleInfo.isForSale();
+ const S32 node_sale_price = node->mSaleInfo.getSalePrice();
+
+ // Set mixed if the fields don't match the first node's fields.
+ if (node_for_sale != first_node_for_sale)
+ is_for_sale_mixed = TRUE;
+ if (node_sale_price != first_node_sale_price)
+ is_sale_price_mixed = TRUE;
+
+ if (node_for_sale)
+ {
+ total_sale_price += node_sale_price;
+ num_for_sale ++;
+ }
+ }
+
+ individual_sale_price = first_node_sale_price;
+ if (is_for_sale_mixed)
+ {
+ is_sale_price_mixed = TRUE;
+ individual_sale_price = 0;
+ }
}
// returns TRUE if all nodes are valid. method also stores an
// accumulated sale info.
BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info)
{
- BOOL first = TRUE;
- LLSaleInfo sale_info;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (!node->mValid)
- {
- return FALSE;
- }
-
- if (first)
- {
- sale_info = node->mSaleInfo;
- first = FALSE;
- }
- else
- {
- sale_info.accumulate(node->mSaleInfo);
- }
- }
-
- result_sale_info = sale_info;
-
- return TRUE;
+ BOOL first = TRUE;
+ LLSaleInfo sale_info;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (!node->mValid)
+ {
+ return FALSE;
+ }
+
+ if (first)
+ {
+ sale_info = node->mSaleInfo;
+ first = FALSE;
+ }
+ else
+ {
+ sale_info.accumulate(node->mSaleInfo);
+ }
+ }
+
+ result_sale_info = sale_info;
+
+ return TRUE;
}
BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm)
{
- BOOL first = TRUE;
- LLAggregatePermissions perm;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (!node->mValid)
- {
- return FALSE;
- }
-
- if (first)
- {
- perm = node->mAggregatePerm;
- first = FALSE;
- }
- else
- {
- perm.aggregate(node->mAggregatePerm);
- }
- }
-
- result_perm = perm;
-
- return TRUE;
+ BOOL first = TRUE;
+ LLAggregatePermissions perm;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (!node->mValid)
+ {
+ return FALSE;
+ }
+
+ if (first)
+ {
+ perm = node->mAggregatePerm;
+ first = FALSE;
+ }
+ else
+ {
+ perm.aggregate(node->mAggregatePerm);
+ }
+ }
+
+ result_perm = perm;
+
+ return TRUE;
}
BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& result_perm)
{
- BOOL first = TRUE;
- LLAggregatePermissions perm;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (!node->mValid)
- {
- return FALSE;
- }
-
- LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm;
- if (first)
- {
- perm = t_perm;
- first = FALSE;
- }
- else
- {
- perm.aggregate(t_perm);
- }
- }
-
- result_perm = perm;
-
- return TRUE;
+ BOOL first = TRUE;
+ LLAggregatePermissions perm;
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (!node->mValid)
+ {
+ return FALSE;
+ }
+
+ LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm;
+ if (first)
+ {
+ perm = t_perm;
+ first = FALSE;
+ }
+ else
+ {
+ perm.aggregate(t_perm);
+ }
+ }
+
+ result_perm = perm;
+
+ return TRUE;
}
BOOL LLSelectMgr::isMovableAvatarSelected()
{
- if (mAllowSelectAvatar && getSelection()->getObjectCount() == 1)
- {
+ if (mAllowSelectAvatar && getSelection()->getObjectCount() == 1)
+ {
// nothing but avatar should be selected, so check that
// there is only one selected object and it is a root
LLViewerObject* obj = getSelection()->getFirstRootObject();
- return obj && obj->isAvatar() && getSelection()->getFirstMoveableNode(TRUE);
- }
- return FALSE;
+ return obj && obj->isAvatar() && getSelection()->getFirstMoveableNode(TRUE);
+ }
+ return FALSE;
}
//--------------------------------------------------------------------
@@ -4334,119 +4341,119 @@ BOOL LLSelectMgr::isMovableAvatarSelected()
// messages.
struct LLDuplicateData
{
- LLVector3 offset;
- U32 flags;
+ LLVector3 offset;
+ U32 flags;
};
void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
{
- if (mSelectedObjects->isAttachment())
- {
- //RN: do not duplicate attachments
- make_ui_sound("UISndInvalidOp");
- return;
- }
- if (!canDuplicate())
- {
- LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true);
- if (node)
- {
- LLSD args;
- args["OBJ_NAME"] = node->mName;
- LLNotificationsUtil::add("NoCopyPermsNoObject", args);
- return;
- }
- }
- LLDuplicateData data;
-
- data.offset = offset;
- data.flags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
-
- sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS);
-
- if (select_copy)
- {
- // the new copy will be coming in selected
- deselectAll();
- }
- else
- {
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- node->mDuplicated = TRUE;
- node->mDuplicatePos = node->getObject()->getPositionGlobal();
- node->mDuplicateRot = node->getObject()->getRotation();
- }
- }
+ if (mSelectedObjects->isAttachment())
+ {
+ //RN: do not duplicate attachments
+ make_ui_sound("UISndInvalidOp");
+ return;
+ }
+ if (!canDuplicate())
+ {
+ LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true);
+ if (node)
+ {
+ LLSD args;
+ args["OBJ_NAME"] = node->mName;
+ LLNotificationsUtil::add("NoCopyPermsNoObject", args);
+ return;
+ }
+ }
+ LLDuplicateData data;
+
+ data.offset = offset;
+ data.flags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
+
+ sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS);
+
+ if (select_copy)
+ {
+ // the new copy will be coming in selected
+ deselectAll();
+ }
+ else
+ {
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ node->mDuplicated = TRUE;
+ node->mDuplicatePos = node->getObject()->getPositionGlobal();
+ node->mDuplicateRot = node->getObject()->getRotation();
+ }
+ }
}
void LLSelectMgr::repeatDuplicate()
{
- if (mSelectedObjects->isAttachment())
- {
- //RN: do not duplicate attachments
- make_ui_sound("UISndInvalidOp");
- return;
- }
-
- std::vector<LLViewerObject*> non_duplicated_objects;
-
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (!node->mDuplicated)
- {
- non_duplicated_objects.push_back(node->getObject());
- }
- }
-
- // make sure only previously duplicated objects are selected
- for (std::vector<LLViewerObject*>::iterator iter = non_duplicated_objects.begin();
- iter != non_duplicated_objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- deselectObjectAndFamily(objectp);
- }
-
- // duplicate objects in place
- LLDuplicateData data;
-
- data.offset = LLVector3::zero;
- data.flags = 0x0;
-
- sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS);
-
- // move current selection based on delta from duplication position and update duplication position
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++ )
- {
- LLSelectNode* node = *iter;
- if (node->mDuplicated)
- {
- LLQuaternion cur_rot = node->getObject()->getRotation();
- LLQuaternion rot_delta = (~node->mDuplicateRot * cur_rot);
- LLQuaternion new_rot = cur_rot * rot_delta;
- LLVector3d cur_pos = node->getObject()->getPositionGlobal();
- LLVector3d new_pos = cur_pos + ((cur_pos - node->mDuplicatePos) * rot_delta);
-
- node->mDuplicatePos = node->getObject()->getPositionGlobal();
- node->mDuplicateRot = node->getObject()->getRotation();
- node->getObject()->setPositionGlobal(new_pos);
- node->getObject()->setRotation(new_rot);
- }
- }
-
- sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
-}
-
-// static
+ if (mSelectedObjects->isAttachment())
+ {
+ //RN: do not duplicate attachments
+ make_ui_sound("UISndInvalidOp");
+ return;
+ }
+
+ std::vector<LLViewerObject*> non_duplicated_objects;
+
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (!node->mDuplicated)
+ {
+ non_duplicated_objects.push_back(node->getObject());
+ }
+ }
+
+ // make sure only previously duplicated objects are selected
+ for (std::vector<LLViewerObject*>::iterator iter = non_duplicated_objects.begin();
+ iter != non_duplicated_objects.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ deselectObjectAndFamily(objectp);
+ }
+
+ // duplicate objects in place
+ LLDuplicateData data;
+
+ data.offset = LLVector3::zero;
+ data.flags = 0x0;
+
+ sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, logNoOp, &data, SEND_ONLY_ROOTS);
+
+ // move current selection based on delta from duplication position and update duplication position
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ if (node->mDuplicated)
+ {
+ LLQuaternion cur_rot = node->getObject()->getRotation();
+ LLQuaternion rot_delta = (~node->mDuplicateRot * cur_rot);
+ LLQuaternion new_rot = cur_rot * rot_delta;
+ LLVector3d cur_pos = node->getObject()->getPositionGlobal();
+ LLVector3d new_pos = cur_pos + ((cur_pos - node->mDuplicatePos) * rot_delta);
+
+ node->mDuplicatePos = node->getObject()->getPositionGlobal();
+ node->mDuplicateRot = node->getObject()->getRotation();
+ node->getObject()->setPositionGlobal(new_pos);
+ node->getObject()->setRotation(new_rot);
+ }
+ }
+
+ sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
+}
+
+// static
void LLSelectMgr::packDuplicate( LLSelectNode* node, void *duplicate_data )
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
}
@@ -4458,71 +4465,71 @@ void LLSelectMgr::packDuplicate( LLSelectNode* node, void *duplicate_data )
// ray.
struct LLDuplicateOnRayData
{
- LLVector3 mRayStartRegion;
- LLVector3 mRayEndRegion;
- BOOL mBypassRaycast;
- BOOL mRayEndIsIntersection;
- LLUUID mRayTargetID;
- BOOL mCopyCenters;
- BOOL mCopyRotates;
- U32 mFlags;
+ LLVector3 mRayStartRegion;
+ LLVector3 mRayEndRegion;
+ BOOL mBypassRaycast;
+ BOOL mRayEndIsIntersection;
+ LLUUID mRayTargetID;
+ BOOL mCopyCenters;
+ BOOL mCopyRotates;
+ U32 mFlags;
};
void LLSelectMgr::selectDuplicateOnRay(const LLVector3 &ray_start_region,
- const LLVector3 &ray_end_region,
- BOOL bypass_raycast,
- BOOL ray_end_is_intersection,
- const LLUUID &ray_target_id,
- BOOL copy_centers,
- BOOL copy_rotates,
- BOOL select_copy)
-{
- if (mSelectedObjects->isAttachment())
- {
- // do not duplicate attachments
- make_ui_sound("UISndInvalidOp");
- return;
- }
-
- LLDuplicateOnRayData data;
-
- data.mRayStartRegion = ray_start_region;
- data.mRayEndRegion = ray_end_region;
- data.mBypassRaycast = bypass_raycast;
- data.mRayEndIsIntersection = ray_end_is_intersection;
- data.mRayTargetID = ray_target_id;
- data.mCopyCenters = copy_centers;
- data.mCopyRotates = copy_rotates;
- data.mFlags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
-
- sendListToRegions("ObjectDuplicateOnRay",
+ const LLVector3 &ray_end_region,
+ BOOL bypass_raycast,
+ BOOL ray_end_is_intersection,
+ const LLUUID &ray_target_id,
+ BOOL copy_centers,
+ BOOL copy_rotates,
+ BOOL select_copy)
+{
+ if (mSelectedObjects->isAttachment())
+ {
+ // do not duplicate attachments
+ make_ui_sound("UISndInvalidOp");
+ return;
+ }
+
+ LLDuplicateOnRayData data;
+
+ data.mRayStartRegion = ray_start_region;
+ data.mRayEndRegion = ray_end_region;
+ data.mBypassRaycast = bypass_raycast;
+ data.mRayEndIsIntersection = ray_end_is_intersection;
+ data.mRayTargetID = ray_target_id;
+ data.mCopyCenters = copy_centers;
+ data.mCopyRotates = copy_rotates;
+ data.mFlags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
+
+ sendListToRegions("ObjectDuplicateOnRay",
packDuplicateOnRayHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS);
- if (select_copy)
- {
- // the new copy will be coming in selected
- deselectAll();
- }
+ if (select_copy)
+ {
+ // the new copy will be coming in selected
+ deselectAll();
+ }
}
// static
void LLSelectMgr::packDuplicateOnRayHead(void *user_data)
{
- LLMessageSystem *msg = gMessageSystem;
- LLDuplicateOnRayData *data = (LLDuplicateOnRayData *)user_data;
+ LLMessageSystem *msg = gMessageSystem;
+ LLDuplicateOnRayData *data = (LLDuplicateOnRayData *)user_data;
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
- msg->addVector3Fast(_PREHASH_RayStart, data->mRayStartRegion );
- msg->addVector3Fast(_PREHASH_RayEnd, data->mRayEndRegion );
- msg->addBOOLFast(_PREHASH_BypassRaycast, data->mBypassRaycast );
- msg->addBOOLFast(_PREHASH_RayEndIsIntersection, data->mRayEndIsIntersection );
- msg->addBOOLFast(_PREHASH_CopyCenters, data->mCopyCenters );
- msg->addBOOLFast(_PREHASH_CopyRotates, data->mCopyRotates );
- msg->addUUIDFast(_PREHASH_RayTargetID, data->mRayTargetID );
- msg->addU32Fast(_PREHASH_DuplicateFlags, data->mFlags );
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
+ msg->addVector3Fast(_PREHASH_RayStart, data->mRayStartRegion );
+ msg->addVector3Fast(_PREHASH_RayEnd, data->mRayEndRegion );
+ msg->addBOOLFast(_PREHASH_BypassRaycast, data->mBypassRaycast );
+ msg->addBOOLFast(_PREHASH_RayEndIsIntersection, data->mRayEndIsIntersection );
+ msg->addBOOLFast(_PREHASH_CopyCenters, data->mCopyCenters );
+ msg->addBOOLFast(_PREHASH_CopyRotates, data->mCopyRotates );
+ msg->addUUIDFast(_PREHASH_RayTargetID, data->mRayTargetID );
+ msg->addU32Fast(_PREHASH_DuplicateFlags, data->mFlags );
}
@@ -4533,61 +4540,61 @@ void LLSelectMgr::packDuplicateOnRayHead(void *user_data)
void LLSelectMgr::sendMultipleUpdate(U32 type)
{
- if (type == UPD_NONE) return;
- // send individual updates when selecting textures or individual objects
- ESendType send_type = (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) ? SEND_ONLY_ROOTS : SEND_ROOTS_FIRST;
- if (send_type == SEND_ONLY_ROOTS)
- {
- // tell simulator to apply to whole linked sets
- type |= UPD_LINKED_SETS;
- }
-
- sendListToRegions(
- "MultipleObjectUpdate",
- packAgentAndSessionID,
- packMultipleUpdate,
+ if (type == UPD_NONE) return;
+ // send individual updates when selecting textures or individual objects
+ ESendType send_type = (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) ? SEND_ONLY_ROOTS : SEND_ROOTS_FIRST;
+ if (send_type == SEND_ONLY_ROOTS)
+ {
+ // tell simulator to apply to whole linked sets
+ type |= UPD_LINKED_SETS;
+ }
+
+ sendListToRegions(
+ "MultipleObjectUpdate",
+ packAgentAndSessionID,
+ packMultipleUpdate,
logNoOp,
- &type,
- send_type);
+ &type,
+ send_type);
}
// static
void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data)
{
- LLViewerObject* object = node->getObject();
- U32 *type32 = (U32 *)user_data;
- U8 type = (U8)*type32;
- U8 data[256];
-
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- gMessageSystem->addU8Fast(_PREHASH_Type, type );
-
- S32 offset = 0;
-
- // JC: You MUST pack the data in this order. The receiving
- // routine process_multiple_update_message on simulator will
- // extract them in this order.
-
- if (type & UPD_POSITION)
- {
- htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
- offset += 12;
- }
- if (type & UPD_ROTATION)
- {
- LLQuaternion quat = object->getRotation();
- LLVector3 vec = quat.packToVector3();
- htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
- offset += 12;
- }
- if (type & UPD_SCALE)
- {
- //LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL;
- htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
- offset += 12;
- }
- gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset);
+ LLViewerObject* object = node->getObject();
+ U32 *type32 = (U32 *)user_data;
+ U8 type = (U8)*type32;
+ U8 data[256];
+
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
+ gMessageSystem->addU8Fast(_PREHASH_Type, type );
+
+ S32 offset = 0;
+
+ // JC: You MUST pack the data in this order. The receiving
+ // routine process_multiple_update_message on simulator will
+ // extract them in this order.
+
+ if (type & UPD_POSITION)
+ {
+ htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
+ offset += 12;
+ }
+ if (type & UPD_ROTATION)
+ {
+ LLQuaternion quat = object->getRotation();
+ LLVector3 vec = quat.packToVector3();
+ htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
+ offset += 12;
+ }
+ if (type & UPD_SCALE)
+ {
+ //LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL;
+ htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
+ offset += 12;
+ }
+ gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset);
}
//------------------------------------------------------------------------
@@ -4595,36 +4602,36 @@ void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data)
//------------------------------------------------------------------------
struct LLOwnerData
{
- LLUUID owner_id;
- LLUUID group_id;
- BOOL override;
+ LLUUID owner_id;
+ LLUUID group_id;
+ BOOL override;
};
void LLSelectMgr::sendOwner(const LLUUID& owner_id,
- const LLUUID& group_id,
- BOOL override)
+ const LLUUID& group_id,
+ BOOL override)
{
- LLOwnerData data;
+ LLOwnerData data;
- data.owner_id = owner_id;
- data.group_id = group_id;
- data.override = override;
+ data.owner_id = owner_id;
+ data.group_id = group_id;
+ data.override = override;
- sendListToRegions("ObjectOwner", packOwnerHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS);
+ sendListToRegions("ObjectOwner", packOwnerHead, packObjectLocalID, logNoOp, &data, SEND_ONLY_ROOTS);
}
// static
void LLSelectMgr::packOwnerHead(void *user_data)
{
- LLOwnerData *data = (LLOwnerData *)user_data;
+ LLOwnerData *data = (LLOwnerData *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
- gMessageSystem->addBOOLFast(_PREHASH_Override, data->override);
- gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id);
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
+ gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
+ gMessageSystem->addBOOLFast(_PREHASH_Override, data->override);
+ gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id);
+ gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id);
}
//------------------------------------------------------------------------
@@ -4633,8 +4640,8 @@ void LLSelectMgr::packOwnerHead(void *user_data)
void LLSelectMgr::sendGroup(const LLUUID& group_id)
{
- LLUUID local_group_id(group_id);
- sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, logNoOp, &local_group_id, SEND_ONLY_ROOTS);
+ LLUUID local_group_id(group_id);
+ sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, logNoOp, &local_group_id, SEND_ONLY_ROOTS);
}
@@ -4644,9 +4651,9 @@ void LLSelectMgr::sendGroup(const LLUUID& group_id)
struct LLBuyData
{
- std::vector<LLViewerObject*> mObjectsSent;
- LLUUID mCategoryID;
- LLSaleInfo mSaleInfo;
+ std::vector<LLViewerObject*> mObjectsSent;
+ LLUUID mCategoryID;
+ LLSaleInfo mSaleInfo;
};
// *NOTE: does not work for multiple object buy, which UI does not
@@ -4655,26 +4662,26 @@ struct LLBuyData
// info -as displayed in the UI- for every item.
void LLSelectMgr::sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info)
{
- LLBuyData buy;
- buy.mCategoryID = category_id;
- buy.mSaleInfo = sale_info;
- sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, logNoOp, &buy, SEND_ONLY_ROOTS);
+ LLBuyData buy;
+ buy.mCategoryID = category_id;
+ buy.mSaleInfo = sale_info;
+ sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, logNoOp, &buy, SEND_ONLY_ROOTS);
}
// static
void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data)
{
- LLBuyData* buy = (LLBuyData*)data;
+ LLBuyData* buy = (LLBuyData*)data;
- LLViewerObject* object = node->getObject();
- if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end())
- {
- buy->mObjectsSent.push_back(object);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType());
- gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice());
- }
+ LLViewerObject* object = node->getObject();
+ if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end())
+ {
+ buy->mObjectsSent.push_back(object);
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
+ gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType());
+ gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice());
+ }
}
//------------------------------------------------------------------------
@@ -4683,37 +4690,37 @@ void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data)
struct LLPermData
{
- U8 mField;
- BOOL mSet;
- U32 mMask;
- BOOL mOverride;
+ U8 mField;
+ BOOL mSet;
+ U32 mMask;
+ BOOL mOverride;
};
// TODO: Make this able to fail elegantly.
void LLSelectMgr::selectionSetObjectPermissions(U8 field,
- BOOL set,
- U32 mask,
- BOOL override)
+ BOOL set,
+ U32 mask,
+ BOOL override)
{
- LLPermData data;
+ LLPermData data;
- data.mField = field;
- data.mSet = set;
- data.mMask = mask;
- data.mOverride = override;
+ data.mField = field;
+ data.mSet = set;
+ data.mMask = mask;
+ data.mOverride = override;
- sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, logNoOp, &data, SEND_ONLY_ROOTS);
+ sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, logNoOp, &data, SEND_ONLY_ROOTS);
}
void LLSelectMgr::packPermissionsHead(void* user_data)
{
- LLPermData* data = (LLPermData*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
- gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride);
-}
+ LLPermData* data = (LLPermData*)user_data;
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
+ gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride);
+}
// Now that you've added a bunch of objects, send a select message
@@ -4721,204 +4728,204 @@ void LLSelectMgr::packPermissionsHead(void* user_data)
/*
void LLSelectMgr::sendSelect()
{
- LL_ERRS() << "Not implemented" << LL_ENDL;
+ LL_ERRS() << "Not implemented" << LL_ENDL;
}
*/
void LLSelectMgr::deselectAll()
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
-
- // Zap the angular velocity, as the sim will set it to zero
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setAngularVelocity( 0,0,0 );
- objectp->setVelocity( 0,0,0 );
- }
-
- sendListToRegions(
- "ObjectDeselect",
- packAgentAndSessionID,
- packObjectLocalID,
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
+
+ // Zap the angular velocity, as the sim will set it to zero
+ for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ iter != mSelectedObjects->end(); iter++ )
+ {
+ LLViewerObject *objectp = (*iter)->getObject();
+ objectp->setAngularVelocity( 0,0,0 );
+ objectp->setVelocity( 0,0,0 );
+ }
+
+ sendListToRegions(
+ "ObjectDeselect",
+ packAgentAndSessionID,
+ packObjectLocalID,
logNoOp,
- NULL,
- SEND_INDIVIDUALS);
+ NULL,
+ SEND_INDIVIDUALS);
- removeAll();
+ removeAll();
+
+ mLastSentSelectionCenterGlobal.clearVec();
- mLastSentSelectionCenterGlobal.clearVec();
-
- updatePointAt();
+ updatePointAt();
}
void LLSelectMgr::deselectAllForStandingUp()
{
- /*
- This function is similar deselectAll() except for the first if statement
- which was removed. This is needed as a workaround for DEV-2854
- */
-
- // Zap the angular velocity, as the sim will set it to zero
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setAngularVelocity( 0,0,0 );
- objectp->setVelocity( 0,0,0 );
- }
-
- sendListToRegions(
- "ObjectDeselect",
- packAgentAndSessionID,
- packObjectLocalID,
+ /*
+ This function is similar deselectAll() except for the first if statement
+ which was removed. This is needed as a workaround for DEV-2854
+ */
+
+ // Zap the angular velocity, as the sim will set it to zero
+ for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ iter != mSelectedObjects->end(); iter++ )
+ {
+ LLViewerObject *objectp = (*iter)->getObject();
+ objectp->setAngularVelocity( 0,0,0 );
+ objectp->setVelocity( 0,0,0 );
+ }
+
+ sendListToRegions(
+ "ObjectDeselect",
+ packAgentAndSessionID,
+ packObjectLocalID,
logNoOp,
- NULL,
- SEND_INDIVIDUALS);
-
- removeAll();
+ NULL,
+ SEND_INDIVIDUALS);
- mLastSentSelectionCenterGlobal.clearVec();
+ removeAll();
+
+ mLastSentSelectionCenterGlobal.clearVec();
- updatePointAt();
+ updatePointAt();
}
void LLSelectMgr::deselectUnused()
{
- // no more outstanding references to this selection
- if (mSelectedObjects->getNumRefs() == 1)
- {
- deselectAll();
- }
+ // no more outstanding references to this selection
+ if (mSelectedObjects->getNumRefs() == 1)
+ {
+ deselectAll();
+ }
}
void LLSelectMgr::convertTransient()
{
- LLObjectSelection::iterator node_it;
- for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it)
- {
- LLSelectNode *nodep = *node_it;
- nodep->setTransient(FALSE);
- }
+ LLObjectSelection::iterator node_it;
+ for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it)
+ {
+ LLSelectNode *nodep = *node_it;
+ nodep->setTransient(FALSE);
+ }
}
void LLSelectMgr::deselectAllIfTooFar()
{
- if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD)
- {
- return;
- }
-
- // HACK: Don't deselect when we're navigating to rate an object's
- // owner or creator. JC
- if (gMenuObject->getVisible())
- {
- return;
- }
-
- LLVector3d selectionCenter = getSelectionCenterGlobal();
- if (gSavedSettings.getBOOL("LimitSelectDistance")
- && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar())
- && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject())
- && !mSelectedObjects->isAttachment()
- && !selectionCenter.isExactlyZero())
- {
- F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance");
- F32 deselect_dist_sq = deselect_dist * deselect_dist;
-
- LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter;
- F32 select_dist_sq = (F32) select_delta.magVecSquared();
-
- if (select_dist_sq > deselect_dist_sq)
- {
- if (mDebugSelectMgr)
- {
- LL_INFOS() << "Selection manager: auto-deselecting, select_dist = " << (F32) sqrt(select_dist_sq) << LL_ENDL;
- LL_INFOS() << "agent pos global = " << gAgent.getPositionGlobal() << LL_ENDL;
- LL_INFOS() << "selection pos global = " << selectionCenter << LL_ENDL;
- }
-
- deselectAll();
- }
- }
+ if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD)
+ {
+ return;
+ }
+
+ // HACK: Don't deselect when we're navigating to rate an object's
+ // owner or creator. JC
+ if (gMenuObject->getVisible())
+ {
+ return;
+ }
+
+ LLVector3d selectionCenter = getSelectionCenterGlobal();
+ if (gSavedSettings.getBOOL("LimitSelectDistance")
+ && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar())
+ && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject())
+ && !mSelectedObjects->isAttachment()
+ && !selectionCenter.isExactlyZero())
+ {
+ F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance");
+ F32 deselect_dist_sq = deselect_dist * deselect_dist;
+
+ LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter;
+ F32 select_dist_sq = (F32) select_delta.magVecSquared();
+
+ if (select_dist_sq > deselect_dist_sq)
+ {
+ if (mDebugSelectMgr)
+ {
+ LL_INFOS() << "Selection manager: auto-deselecting, select_dist = " << (F32) sqrt(select_dist_sq) << LL_ENDL;
+ LL_INFOS() << "agent pos global = " << gAgent.getPositionGlobal() << LL_ENDL;
+ LL_INFOS() << "selection pos global = " << selectionCenter << LL_ENDL;
+ }
+
+ deselectAll();
+ }
+ }
}
void LLSelectMgr::selectionSetObjectName(const std::string& name)
{
- std::string name_copy(name);
+ std::string name_copy(name);
- // we only work correctly if 1 object is selected.
- if(mSelectedObjects->getRootObjectCount() == 1)
- {
- sendListToRegions("ObjectName",
- packAgentAndSessionID,
- packObjectName,
+ // we only work correctly if 1 object is selected.
+ if(mSelectedObjects->getRootObjectCount() == 1)
+ {
+ sendListToRegions("ObjectName",
+ packAgentAndSessionID,
+ packObjectName,
logNoOp,
- (void*)(&name_copy),
- SEND_ONLY_ROOTS);
- }
- else if(mSelectedObjects->getObjectCount() == 1)
- {
- sendListToRegions("ObjectName",
- packAgentAndSessionID,
- packObjectName,
+ (void*)(&name_copy),
+ SEND_ONLY_ROOTS);
+ }
+ else if(mSelectedObjects->getObjectCount() == 1)
+ {
+ sendListToRegions("ObjectName",
+ packAgentAndSessionID,
+ packObjectName,
logNoOp,
- (void*)(&name_copy),
- SEND_INDIVIDUALS);
- }
+ (void*)(&name_copy),
+ SEND_INDIVIDUALS);
+ }
}
void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
{
- std::string desc_copy(desc);
+ std::string desc_copy(desc);
- // we only work correctly if 1 object is selected.
- if(mSelectedObjects->getRootObjectCount() == 1)
- {
- sendListToRegions("ObjectDescription",
- packAgentAndSessionID,
- packObjectDescription,
+ // we only work correctly if 1 object is selected.
+ if(mSelectedObjects->getRootObjectCount() == 1)
+ {
+ sendListToRegions("ObjectDescription",
+ packAgentAndSessionID,
+ packObjectDescription,
logNoOp,
- (void*)(&desc_copy),
- SEND_ONLY_ROOTS);
- }
- else if(mSelectedObjects->getObjectCount() == 1)
- {
- sendListToRegions("ObjectDescription",
- packAgentAndSessionID,
- packObjectDescription,
+ (void*)(&desc_copy),
+ SEND_ONLY_ROOTS);
+ }
+ else if(mSelectedObjects->getObjectCount() == 1)
+ {
+ sendListToRegions("ObjectDescription",
+ packAgentAndSessionID,
+ packObjectDescription,
logNoOp,
- (void*)(&desc_copy),
- SEND_INDIVIDUALS);
- }
+ (void*)(&desc_copy),
+ SEND_INDIVIDUALS);
+ }
}
void LLSelectMgr::selectionSetObjectCategory(const LLCategory& category)
{
- // for now, we only want to be able to set one root category at
- // a time.
- if(mSelectedObjects->getRootObjectCount() != 1) return;
- sendListToRegions("ObjectCategory",
- packAgentAndSessionID,
- packObjectCategory,
+ // for now, we only want to be able to set one root category at
+ // a time.
+ if(mSelectedObjects->getRootObjectCount() != 1) return;
+ sendListToRegions("ObjectCategory",
+ packAgentAndSessionID,
+ packObjectCategory,
logNoOp,
- (void*)(&category),
- SEND_ONLY_ROOTS);
+ (void*)(&category),
+ SEND_ONLY_ROOTS);
}
void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info)
{
- sendListToRegions("ObjectSaleInfo",
- packAgentAndSessionID,
- packObjectSaleInfo,
+ sendListToRegions("ObjectSaleInfo",
+ packAgentAndSessionID,
+ packObjectSaleInfo,
logNoOp,
- (void*)(&sale_info),
- SEND_ONLY_ROOTS);
+ (void*)(&sale_info),
+ SEND_ONLY_ROOTS);
}
//----------------------------------------------------------------------
@@ -4932,80 +4939,80 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
void LLSelectMgr::sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace)
{
- if (selection_handle.isNull())
- {
- return;
- }
-
- LLViewerObject* attach_object = selection_handle->getFirstRootObject();
-
- if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD)
- {
- return;
- }
-
- BOOL build_mode = LLToolMgr::getInstance()->inEdit();
- // Special case: Attach to default location for this object.
- if (0 == attachment_point ||
- get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL))
- {
- if (!replace || attachment_point != 0)
- {
- // If we know the attachment point then we got here by clicking an
- // "Attach to..." context menu item, so we should add, not replace.
- attachment_point |= ATTACHMENT_ADD;
- }
-
- sendListToRegions(
- selection_handle,
- "ObjectAttach",
- packAgentIDAndSessionAndAttachment,
- packObjectIDAndRotation,
+ if (selection_handle.isNull())
+ {
+ return;
+ }
+
+ LLViewerObject* attach_object = selection_handle->getFirstRootObject();
+
+ if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD)
+ {
+ return;
+ }
+
+ BOOL build_mode = LLToolMgr::getInstance()->inEdit();
+ // Special case: Attach to default location for this object.
+ if (0 == attachment_point ||
+ get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL))
+ {
+ if (!replace || attachment_point != 0)
+ {
+ // If we know the attachment point then we got here by clicking an
+ // "Attach to..." context menu item, so we should add, not replace.
+ attachment_point |= ATTACHMENT_ADD;
+ }
+
+ sendListToRegions(
+ selection_handle,
+ "ObjectAttach",
+ packAgentIDAndSessionAndAttachment,
+ packObjectIDAndRotation,
logAttachmentRequest,
- &attachment_point,
- SEND_ONLY_ROOTS );
- if (!build_mode)
- {
- // After "ObjectAttach" server will unsubscribe us from properties updates
- // so either deselect objects or resend selection after attach packet reaches server
- // In case of build_mode LLPanelObjectInventory::refresh() will deal with selection
- // Still unsubscribe even in case selection_handle is not current selection
- deselectAll();
- }
- }
+ &attachment_point,
+ SEND_ONLY_ROOTS );
+ if (!build_mode)
+ {
+ // After "ObjectAttach" server will unsubscribe us from properties updates
+ // so either deselect objects or resend selection after attach packet reaches server
+ // In case of build_mode LLPanelObjectInventory::refresh() will deal with selection
+ // Still unsubscribe even in case selection_handle is not current selection
+ deselectAll();
+ }
+ }
}
void LLSelectMgr::sendDetach()
{
- if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
- {
- return;
- }
+ if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
+ {
+ return;
+ }
- sendListToRegions(
- "ObjectDetach",
- packAgentAndSessionID,
- packObjectLocalID,
+ sendListToRegions(
+ "ObjectDetach",
+ packAgentAndSessionID,
+ packObjectLocalID,
logDetachRequest,
- NULL,
- SEND_ONLY_ROOTS );
+ NULL,
+ SEND_ONLY_ROOTS );
}
void LLSelectMgr::sendDropAttachment()
{
- if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
- {
- return;
- }
+ if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
+ {
+ return;
+ }
- sendListToRegions(
- "ObjectDrop",
- packAgentAndSessionID,
- packObjectLocalID,
+ sendListToRegions(
+ "ObjectDrop",
+ packAgentAndSessionID,
+ packObjectLocalID,
logDetachRequest,
- NULL,
- SEND_ONLY_ROOTS);
+ NULL,
+ SEND_ONLY_ROOTS);
}
//----------------------------------------------------------------------
@@ -5014,56 +5021,56 @@ void LLSelectMgr::sendDropAttachment()
void LLSelectMgr::sendLink()
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
- sendListToRegions(
- "ObjectLink",
- packAgentAndSessionID,
- packObjectLocalID,
+ sendListToRegions(
+ "ObjectLink",
+ packAgentAndSessionID,
+ packObjectLocalID,
logNoOp,
- NULL,
- SEND_ONLY_ROOTS);
+ NULL,
+ SEND_ONLY_ROOTS);
}
void LLSelectMgr::sendDelink()
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
-
- struct f : public LLSelectedObjectFunctor
- { //on delink, any modifyable object should
- f() {}
-
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- if (object->getPhysicsShapeType() == LLViewerObject::PHYSICS_SHAPE_NONE)
- {
- object->setPhysicsShapeType(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
- object->updateFlags();
- }
- }
- return true;
- }
- } sendfunc;
- getSelection()->applyToObjects(&sendfunc);
-
-
- // Delink needs to send individuals so you can unlink a single object from
- // a linked set.
- sendListToRegions(
- "ObjectDelink",
- packAgentAndSessionID,
- packObjectLocalID,
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
+
+ struct f : public LLSelectedObjectFunctor
+ { //on delink, any modifyable object should
+ f() {}
+
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ if (object->getPhysicsShapeType() == LLViewerObject::PHYSICS_SHAPE_NONE)
+ {
+ object->setPhysicsShapeType(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ object->updateFlags();
+ }
+ }
+ return true;
+ }
+ } sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
+
+
+ // Delink needs to send individuals so you can unlink a single object from
+ // a linked set.
+ sendListToRegions(
+ "ObjectDelink",
+ packAgentAndSessionID,
+ packObjectLocalID,
logNoOp,
- NULL,
- SEND_INDIVIDUALS);
+ NULL,
+ SEND_INDIVIDUALS);
}
@@ -5074,118 +5081,118 @@ void LLSelectMgr::sendDelink()
/*
void LLSelectMgr::sendHinge(U8 type)
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
- sendListToRegions(
- "ObjectHinge",
- packHingeHead,
- packObjectLocalID,
- &type,
- SEND_ONLY_ROOTS);
+ sendListToRegions(
+ "ObjectHinge",
+ packHingeHead,
+ packObjectLocalID,
+ &type,
+ SEND_ONLY_ROOTS);
}
void LLSelectMgr::sendDehinge()
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
-
- sendListToRegions(
- "ObjectDehinge",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_ONLY_ROOTS);
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
+
+ sendListToRegions(
+ "ObjectDehinge",
+ packAgentAndSessionID,
+ packObjectLocalID,
+ NULL,
+ SEND_ONLY_ROOTS);
}*/
void LLSelectMgr::sendSelect()
{
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
+ if (!mSelectedObjects->getNumNodes())
+ {
+ return;
+ }
- sendListToRegions(
- "ObjectSelect",
- packAgentAndSessionID,
- packObjectLocalID,
+ sendListToRegions(
+ "ObjectSelect",
+ packAgentAndSessionID,
+ packObjectLocalID,
logNoOp,
- NULL,
- SEND_INDIVIDUALS);
+ NULL,
+ SEND_INDIVIDUALS);
}
// static
void LLSelectMgr::packHingeHead(void *user_data)
{
- U8 *type = (U8 *)user_data;
+ U8 *type = (U8 *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- gMessageSystem->nextBlockFast(_PREHASH_JointType);
- gMessageSystem->addU8Fast(_PREHASH_Type, *type );
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
+ gMessageSystem->nextBlockFast(_PREHASH_JointType);
+ gMessageSystem->addU8Fast(_PREHASH_Type, *type );
}
void LLSelectMgr::selectionDump()
{
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- object->dump();
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ object->dump();
+ return true;
+ }
+ } func;
+ getSelection()->applyToObjects(&func);
}
void LLSelectMgr::saveSelectedObjectColors()
{
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->saveColors();
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
+ struct f : public LLSelectedNodeFunctor
+ {
+ virtual bool apply(LLSelectNode* node)
+ {
+ node->saveColors();
+ return true;
+ }
+ } func;
+ getSelection()->applyToNodes(&func);
}
void LLSelectMgr::saveSelectedShinyColors()
{
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->saveShinyColors();
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
+ struct f : public LLSelectedNodeFunctor
+ {
+ virtual bool apply(LLSelectNode* node)
+ {
+ node->saveShinyColors();
+ return true;
+ }
+ } func;
+ getSelection()->applyToNodes(&func);
}
void LLSelectMgr::saveSelectedObjectTextures()
{
- // invalidate current selection so we update saved textures
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->mValid = FALSE;
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
+ // invalidate current selection so we update saved textures
+ struct f : public LLSelectedNodeFunctor
+ {
+ virtual bool apply(LLSelectNode* node)
+ {
+ node->mValid = FALSE;
+ return true;
+ }
+ } func;
+ getSelection()->applyToNodes(&func);
- // request object properties message to get updated permissions data
- sendSelect();
+ // request object properties message to get updated permissions data
+ sendSelect();
}
@@ -5193,293 +5200,304 @@ void LLSelectMgr::saveSelectedObjectTextures()
// also need to know to which simulator to send update message
void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
{
- if (mSelectedObjects->isEmpty())
- {
- // nothing selected, so nothing to save
- return;
- }
-
- struct f : public LLSelectedNodeFunctor
- {
- EActionType mActionType;
- LLSelectMgr* mManager;
- f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}
- virtual bool apply(LLSelectNode* selectNode)
- {
- LLViewerObject* object = selectNode->getObject();
- if (!object)
- {
- return true; // skip
+ if (mSelectedObjects->isEmpty())
+ {
+ // nothing selected, so nothing to save
+ return;
+ }
+
+ struct f : public LLSelectedNodeFunctor
+ {
+ EActionType mActionType;
+ LLSelectMgr* mManager;
+ f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (!object)
+ {
+ return true; // skip
+ }
+
+ if (selectNode->mSelectedGLTFNode != -1)
+ {
+ // save GLTF node state
+ object->getGLTFNodeTransformAgent(selectNode->mSelectedGLTFNode, &selectNode->mSavedPositionLocal, &selectNode->mSavedRotation, &selectNode->mSavedScale);
+ selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent(selectNode->mSavedPositionLocal);
+ selectNode->mLastMoveLocal.setZero();
}
- selectNode->mSavedPositionLocal = object->getPosition();
- if (object->isAttachment())
+ else
{
- if (object->isRootEdit())
+ selectNode->mSavedPositionLocal = object->getPosition();
+ if (object->isAttachment())
{
- LLXform* parent_xform = object->mDrawable->getXform()->getParent();
- if (parent_xform)
+ if (object->isRootEdit())
{
- selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition());
+ LLXform* parent_xform = object->mDrawable->getXform()->getParent();
+ if (parent_xform)
+ {
+ selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition());
+ }
+ else
+ {
+ selectNode->mSavedPositionGlobal = object->getPositionGlobal();
+ }
}
else
{
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
+ LLViewerObject* attachment_root = (LLViewerObject*)object->getParent();
+ LLXform* parent_xform = attachment_root ? attachment_root->mDrawable->getXform()->getParent() : NULL;
+ if (parent_xform)
+ {
+ LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
+ LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
+ selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
+ }
+ else
+ {
+ selectNode->mSavedPositionGlobal = object->getPositionGlobal();
+ }
}
+ selectNode->mSavedRotation = object->getRenderRotation();
}
else
{
- LLViewerObject* attachment_root = (LLViewerObject*)object->getParent();
- LLXform* parent_xform = attachment_root ? attachment_root->mDrawable->getXform()->getParent() : NULL;
- if (parent_xform)
- {
- LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
- LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
- selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
- }
- else
- {
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
- }
+ selectNode->mSavedPositionGlobal = object->getPositionGlobal();
+ selectNode->mSavedRotation = object->getRotationRegion();
}
- selectNode->mSavedRotation = object->getRenderRotation();
- }
- else
- {
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
- selectNode->mSavedRotation = object->getRotationRegion();
- }
-
- selectNode->mSavedScale = object->getScale();
- selectNode->saveTextureScaleRatios(mManager->mTextureChannel);
- return true;
- }
- } func(action_type, this);
- getSelection()->applyToNodes(&func);
- mSavedSelectionBBox = getBBoxOfSelection();
+ selectNode->mSavedScale = object->getScale();
+ selectNode->saveTextureScaleRatios(mManager->mTextureChannel);
+ }
+ return true;
+ }
+ } func(action_type, this);
+ getSelection()->applyToNodes(&func);
+
+ mSavedSelectionBBox = getBBoxOfSelection();
}
struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor
{
- LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {}
- U32 mFlags;
- BOOL mState;
- virtual bool apply(LLViewerObject* object)
- {
- if ( object->permModify())
- {
- if (object->isRoot()) // don't send for child objects
- {
- object->setFlags( mFlags, mState);
- }
- else if (FLAGS_WORLD & mFlags && ((LLViewerObject*)object->getRoot())->isSelected())
- {
- // FLAGS_WORLD are shared by all items in linkset
- object->setFlagsWithoutUpdate(FLAGS_WORLD & mFlags, mState);
- }
- };
- return true;
- }
+ LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {}
+ U32 mFlags;
+ BOOL mState;
+ virtual bool apply(LLViewerObject* object)
+ {
+ if ( object->permModify())
+ {
+ if (object->isRoot()) // don't send for child objects
+ {
+ object->setFlags( mFlags, mState);
+ }
+ else if (FLAGS_WORLD & mFlags && ((LLViewerObject*)object->getRoot())->isSelected())
+ {
+ // FLAGS_WORLD are shared by all items in linkset
+ object->setFlagsWithoutUpdate(FLAGS_WORLD & mFlags, mState);
+ }
+ };
+ return true;
+ }
};
void LLSelectMgr::selectionUpdatePhysics(BOOL physics)
{
- LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics);
- getSelection()->applyToObjects(&func);
+ LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics);
+ getSelection()->applyToObjects(&func);
}
void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary)
{
- LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary);
- getSelection()->applyToObjects(&func);
+ LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary);
+ getSelection()->applyToObjects(&func);
}
void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom)
{
- LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom);
- getSelection()->applyToObjects(&func);
+ LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom);
+ getSelection()->applyToObjects(&func);
}
//----------------------------------------------------------------------
// Helpful packing functions for sendObjectMessage()
//----------------------------------------------------------------------
-// static
+// static
void LLSelectMgr::packAgentIDAndSessionAndAttachment( void *user_data)
{
- U8 *attachment_point = (U8*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point);
+ U8 *attachment_point = (U8*)user_data;
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point);
}
// static
-void LLSelectMgr::packAgentID( void *user_data)
+void LLSelectMgr::packAgentID( void *user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
}
// static
void LLSelectMgr::packAgentAndSessionID(void* user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
// static
void LLSelectMgr::packAgentAndGroupID(void* user_data)
{
- LLOwnerData *data = (LLOwnerData *)user_data;
+ LLOwnerData *data = (LLOwnerData *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id );
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id );
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id );
+ gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id );
}
// static
void LLSelectMgr::packAgentAndSessionAndGroupID(void* user_data)
{
- LLUUID* group_idp = (LLUUID*) user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp);
+ LLUUID* group_idp = (LLUUID*) user_data;
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp);
}
// static
void LLSelectMgr::packDuplicateHeader(void* data)
{
- LLUUID group_id(gAgent.getGroupID());
- packAgentAndSessionAndGroupID(&group_id);
+ LLUUID group_id(gAgent.getGroupID());
+ packAgentAndSessionAndGroupID(&group_id);
- LLDuplicateData* dup_data = (LLDuplicateData*) data;
+ LLDuplicateData* dup_data = (LLDuplicateData*) data;
- gMessageSystem->nextBlockFast(_PREHASH_SharedData);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset);
- gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags);
+ gMessageSystem->nextBlockFast(_PREHASH_SharedData);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset);
+ gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags);
}
// static
void LLSelectMgr::packDeleteHeader(void* userdata)
{
- BOOL force = (BOOL)(intptr_t)userdata;
+ BOOL force = (BOOL)(intptr_t)userdata;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addBOOLFast(_PREHASH_Force, force);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addBOOLFast(_PREHASH_Force, force);
}
// static
void LLSelectMgr::packAgentGroupAndCatID(void* user_data)
{
- LLBuyData* buy = (LLBuyData*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID);
+ LLBuyData* buy = (LLBuyData*)user_data;
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+ gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID);
}
//static
void LLSelectMgr::packDeRezHeader(void* user_data)
{
- LLDeRezInfo* info = (LLDeRezInfo*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination);
- gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID);
- LLUUID tid;
- tid.generate();
- gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid);
- const U8 PACKET = 1;
- gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET);
- gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET);
-}
-
-// static
+ LLDeRezInfo* info = (LLDeRezInfo*)user_data;
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
+ gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+ gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination);
+ gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID);
+ LLUUID tid;
+ tid.generate();
+ gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid);
+ const U8 PACKET = 1;
+ gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET);
+ gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET);
+}
+
+// static
void LLSelectMgr::packObjectID(LLSelectNode* node, void *user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID );
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID );
}
void LLSelectMgr::packObjectIDAndRotation(LLSelectNode* node, void *user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
+ gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation());
}
void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
+ gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction());
}
void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data)
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
+ gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch());
}
// static
void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *)
{
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
}
// static
void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data)
{
- const std::string* name = (const std::string*)user_data;
- if(!name->empty())
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- gMessageSystem->addStringFast(_PREHASH_Name, *name);
- }
+ const std::string* name = (const std::string*)user_data;
+ if(!name->empty())
+ {
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
+ gMessageSystem->addStringFast(_PREHASH_Name, *name);
+ }
}
// static
void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data)
{
- const std::string* desc = (const std::string*)user_data;
- if(desc)
- { // Empty (non-null, but zero length) descriptions are OK
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- gMessageSystem->addStringFast(_PREHASH_Description, *desc);
- }
+ const std::string* desc = (const std::string*)user_data;
+ if(desc)
+ { // Empty (non-null, but zero length) descriptions are OK
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
+ gMessageSystem->addStringFast(_PREHASH_Description, *desc);
+ }
}
// static
void LLSelectMgr::packObjectCategory(LLSelectNode* node, void* user_data)
{
- LLCategory* category = (LLCategory*)user_data;
- if(!category) return;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- category->packMessage(gMessageSystem);
+ LLCategory* category = (LLCategory*)user_data;
+ if(!category) return;
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
+ category->packMessage(gMessageSystem);
}
// static
void LLSelectMgr::packObjectSaleInfo(LLSelectNode* node, void* user_data)
{
- LLSaleInfo* sale_info = (LLSaleInfo*)user_data;
- if(!sale_info) return;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- sale_info->packMessage(gMessageSystem);
+ LLSaleInfo* sale_info = (LLSaleInfo*)user_data;
+ if(!sale_info) return;
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
+ sale_info->packMessage(gMessageSystem);
}
// static
@@ -5492,46 +5510,46 @@ void LLSelectMgr::packShape(LLSelectNode* node, void *user_data)
{
}
-// static
+// static
void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data)
{
- LLPermData *data = (LLPermData *)user_data;
+ LLPermData *data = (LLPermData *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
- gMessageSystem->addU8Fast(_PREHASH_Field, data->mField);
- gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet);
- gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask);
+ gMessageSystem->addU8Fast(_PREHASH_Field, data->mField);
+ gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet);
+ gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask);
}
// Utility function to send some information to every region containing
// an object on the selection list. We want to do this to reduce the total
// number of packets sent by the viewer.
void LLSelectMgr::sendListToRegions(const std::string& message_name,
- void (*pack_header)(void *user_data),
- void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
- void *user_data,
- ESendType send_type)
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type)
{
sendListToRegions(mSelectedObjects, message_name, pack_header, pack_body, log_func, user_data, send_type);
}
void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
- const std::string& message_name,
- void (*pack_header)(void *user_data),
- void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
- void *user_data,
- ESendType send_type)
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type)
{
- LLSelectNode* node;
- LLSelectNode* linkset_root = NULL;
- LLViewerRegion* last_region;
- LLViewerRegion* current_region;
- S32 objects_in_this_packet = 0;
+ LLSelectNode* node;
+ LLSelectNode* linkset_root = NULL;
+ LLViewerRegion* last_region;
+ LLViewerRegion* current_region;
+ S32 objects_in_this_packet = 0;
- bool link_operation = message_name == "ObjectLink";
+ bool link_operation = message_name == "ObjectLink";
if (mAllowSelectAvatar)
{
@@ -5555,164 +5573,164 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
resetObjectOverrides(selected_handle);
}
- std::queue<LLSelectNode*> nodes_to_send;
-
- struct push_all : public LLSelectedNodeFunctor
- {
- std::queue<LLSelectNode*>& nodes_to_send;
- push_all(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
- virtual bool apply(LLSelectNode* node)
- {
- if (node->getObject())
- {
- nodes_to_send.push(node);
- }
- return true;
- }
- };
- struct push_some : public LLSelectedNodeFunctor
- {
- std::queue<LLSelectNode*>& nodes_to_send;
- bool mRoots;
- push_some(std::queue<LLSelectNode*>& n, bool roots) : nodes_to_send(n), mRoots(roots) {}
- virtual bool apply(LLSelectNode* node)
- {
- if (node->getObject())
- {
- BOOL is_root = node->getObject()->isRootEdit();
- if ((mRoots && is_root) || (!mRoots && !is_root))
- {
- nodes_to_send.push(node);
- }
- }
- return true;
- }
- };
- struct push_all pushall(nodes_to_send);
- struct push_some pushroots(nodes_to_send, TRUE);
- struct push_some pushnonroots(nodes_to_send, FALSE);
-
- switch(send_type)
- {
- case SEND_ONLY_ROOTS:
- if(message_name == "ObjectBuy")
- selected_handle->applyToRootNodes(&pushroots);
- else
- selected_handle->applyToRootNodes(&pushall);
-
- break;
- case SEND_INDIVIDUALS:
- selected_handle->applyToNodes(&pushall);
- break;
- case SEND_ROOTS_FIRST:
- // first roots...
- selected_handle->applyToNodes(&pushroots);
- // then children...
- selected_handle->applyToNodes(&pushnonroots);
- break;
- case SEND_CHILDREN_FIRST:
- // first children...
- selected_handle->applyToNodes(&pushnonroots);
- // then roots...
- selected_handle->applyToNodes(&pushroots);
- break;
-
- default:
- LL_ERRS() << "Bad send type " << send_type << " passed to SendListToRegions()" << LL_ENDL;
- }
-
- // bail if nothing selected
- if (nodes_to_send.empty())
- {
- return;
- }
-
- node = nodes_to_send.front();
- nodes_to_send.pop();
-
- // cache last region information
- current_region = node->getObject()->getRegion();
-
- // Start duplicate message
- // CRO: this isn't
- gMessageSystem->newMessage(message_name.c_str());
- (*pack_header)(user_data);
-
- // For each object
- while (node != NULL)
- {
- // remember the last region, look up the current one
- last_region = current_region;
- current_region = node->getObject()->getRegion();
-
- // if to same simulator and message not too big
- if ((current_region == last_region)
- && (! gMessageSystem->isSendFull(NULL))
- && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
- {
- if (link_operation && linkset_root == NULL)
- {
- // linksets over 254 will be split into multiple messages,
- // but we need to provide same root for all messages or we will get separate linksets
- linkset_root = node;
- }
- // add another instance of the body of the data
- (*pack_body)(node, user_data);
+ std::queue<LLSelectNode*> nodes_to_send;
+
+ struct push_all : public LLSelectedNodeFunctor
+ {
+ std::queue<LLSelectNode*>& nodes_to_send;
+ push_all(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ if (node->getObject())
+ {
+ nodes_to_send.push(node);
+ }
+ return true;
+ }
+ };
+ struct push_some : public LLSelectedNodeFunctor
+ {
+ std::queue<LLSelectNode*>& nodes_to_send;
+ bool mRoots;
+ push_some(std::queue<LLSelectNode*>& n, bool roots) : nodes_to_send(n), mRoots(roots) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ if (node->getObject())
+ {
+ BOOL is_root = node->getObject()->isRootEdit();
+ if ((mRoots && is_root) || (!mRoots && !is_root))
+ {
+ nodes_to_send.push(node);
+ }
+ }
+ return true;
+ }
+ };
+ struct push_all pushall(nodes_to_send);
+ struct push_some pushroots(nodes_to_send, TRUE);
+ struct push_some pushnonroots(nodes_to_send, FALSE);
+
+ switch(send_type)
+ {
+ case SEND_ONLY_ROOTS:
+ if(message_name == "ObjectBuy")
+ selected_handle->applyToRootNodes(&pushroots);
+ else
+ selected_handle->applyToRootNodes(&pushall);
+
+ break;
+ case SEND_INDIVIDUALS:
+ selected_handle->applyToNodes(&pushall);
+ break;
+ case SEND_ROOTS_FIRST:
+ // first roots...
+ selected_handle->applyToNodes(&pushroots);
+ // then children...
+ selected_handle->applyToNodes(&pushnonroots);
+ break;
+ case SEND_CHILDREN_FIRST:
+ // first children...
+ selected_handle->applyToNodes(&pushnonroots);
+ // then roots...
+ selected_handle->applyToNodes(&pushroots);
+ break;
+
+ default:
+ LL_ERRS() << "Bad send type " << send_type << " passed to SendListToRegions()" << LL_ENDL;
+ }
+
+ // bail if nothing selected
+ if (nodes_to_send.empty())
+ {
+ return;
+ }
+
+ node = nodes_to_send.front();
+ nodes_to_send.pop();
+
+ // cache last region information
+ current_region = node->getObject()->getRegion();
+
+ // Start duplicate message
+ // CRO: this isn't
+ gMessageSystem->newMessage(message_name.c_str());
+ (*pack_header)(user_data);
+
+ // For each object
+ while (node != NULL)
+ {
+ // remember the last region, look up the current one
+ last_region = current_region;
+ current_region = node->getObject()->getRegion();
+
+ // if to same simulator and message not too big
+ if ((current_region == last_region)
+ && (! gMessageSystem->isSendFull(NULL))
+ && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
+ {
+ if (link_operation && linkset_root == NULL)
+ {
+ // linksets over 254 will be split into multiple messages,
+ // but we need to provide same root for all messages or we will get separate linksets
+ linkset_root = node;
+ }
+ // add another instance of the body of the data
+ (*pack_body)(node, user_data);
// do any related logging
(*log_func)(node, user_data);
- ++objects_in_this_packet;
-
- // and on to the next object
- if(nodes_to_send.empty())
- {
- node = NULL;
- }
- else
- {
- node = nodes_to_send.front();
- nodes_to_send.pop();
- }
- }
- else
- {
- // otherwise send current message and start new one
- gMessageSystem->sendReliable( last_region->getHost());
- objects_in_this_packet = 0;
-
- gMessageSystem->newMessage(message_name.c_str());
- (*pack_header)(user_data);
-
- if (linkset_root != NULL)
- {
- if (current_region != last_region)
- {
- // root should be in one region with the child, reset it
- linkset_root = NULL;
- }
- else
- {
- // add root instance into new message
- (*pack_body)(linkset_root, user_data);
- ++objects_in_this_packet;
- }
- }
-
- // don't move to the next object, we still need to add the
- // body data.
- }
- }
-
- // flush messages
- if (gMessageSystem->getCurrentSendTotal() > 0)
- {
- gMessageSystem->sendReliable( current_region->getHost());
- }
- else
- {
- gMessageSystem->clearMessage();
- }
-
- // LL_INFOS() << "sendListToRegions " << message_name << " obj " << objects_sent << " pkt " << packets_sent << LL_ENDL;
+ ++objects_in_this_packet;
+
+ // and on to the next object
+ if(nodes_to_send.empty())
+ {
+ node = NULL;
+ }
+ else
+ {
+ node = nodes_to_send.front();
+ nodes_to_send.pop();
+ }
+ }
+ else
+ {
+ // otherwise send current message and start new one
+ gMessageSystem->sendReliable( last_region->getHost());
+ objects_in_this_packet = 0;
+
+ gMessageSystem->newMessage(message_name.c_str());
+ (*pack_header)(user_data);
+
+ if (linkset_root != NULL)
+ {
+ if (current_region != last_region)
+ {
+ // root should be in one region with the child, reset it
+ linkset_root = NULL;
+ }
+ else
+ {
+ // add root instance into new message
+ (*pack_body)(linkset_root, user_data);
+ ++objects_in_this_packet;
+ }
+ }
+
+ // don't move to the next object, we still need to add the
+ // body data.
+ }
+ }
+
+ // flush messages
+ if (gMessageSystem->getCurrentSendTotal() > 0)
+ {
+ gMessageSystem->sendReliable( current_region->getHost());
+ }
+ else
+ {
+ gMessageSystem->clearMessage();
+ }
+
+ // LL_INFOS() << "sendListToRegions " << message_name << " obj " << objects_sent << " pkt " << packets_sent << LL_ENDL;
}
@@ -5722,166 +5740,166 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
void LLSelectMgr::requestObjectPropertiesFamily(LLViewerObject* object)
{
- LLMessageSystem* msg = gMessageSystem;
+ LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
- msg->addUUIDFast(_PREHASH_ObjectID, object->mID );
+ msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
+ msg->addUUIDFast(_PREHASH_ObjectID, object->mID );
- LLViewerRegion* regionp = object->getRegion();
- msg->sendReliable( regionp->getHost() );
+ LLViewerRegion* regionp = object->getRegion();
+ msg->sendReliable( regionp->getHost() );
}
// static
void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data)
{
- S32 i;
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
- for (i = 0; i < count; i++)
- {
- LLUUID id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i);
-
- LLUUID creator_id;
- LLUUID owner_id;
- LLUUID group_id;
- LLUUID last_owner_id;
- U64 creation_date;
- LLUUID extra_id;
- U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
- LLSaleInfo sale_info;
- LLCategory category;
- LLAggregatePermissions ag_perms;
- LLAggregatePermissions ag_texture_perms;
- LLAggregatePermissions ag_texture_perms_owner;
-
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i);
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i);
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i);
- msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i);
- sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
-
- ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i);
- ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i);
- ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i);
- category.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
-
- S16 inv_serial = 0;
- msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i);
-
- LLUUID item_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i);
- LLUUID folder_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i);
- LLUUID from_task_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i);
-
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i);
-
- std::string name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name, i);
- std::string desc;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc, i);
-
- std::string touch_name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, touch_name, i);
- std::string sit_name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i);
-
- //unpack TE IDs
- uuid_vec_t texture_ids;
- S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID);
- if (size > 0)
- {
- S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES];
- msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES);
-
- for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES)
- {
- LLUUID tid;
- memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */
- texture_ids.push_back(tid);
- }
- }
-
-
- // Iterate through nodes at end, since it can be on both the regular AND hover list
- struct f : public LLSelectedNodeFunctor
- {
- LLUUID mID;
- f(const LLUUID& id) : mID(id) {}
- virtual bool apply(LLSelectNode* node)
- {
- return (node->getObject() && node->getObject()->mID == mID);
- }
- } func(id);
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
-
- if (!node)
- {
- LL_WARNS() << "Couldn't find object " << id << " selected." << LL_ENDL;
- }
- else
- {
+ S32 i;
+ S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
+ for (i = 0; i < count; i++)
+ {
+ LLUUID id;
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i);
+
+ LLUUID creator_id;
+ LLUUID owner_id;
+ LLUUID group_id;
+ LLUUID last_owner_id;
+ U64 creation_date;
+ LLUUID extra_id;
+ U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
+ LLSaleInfo sale_info;
+ LLCategory category;
+ LLAggregatePermissions ag_perms;
+ LLAggregatePermissions ag_texture_perms;
+ LLAggregatePermissions ag_texture_perms_owner;
+
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i);
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i);
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i);
+ msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i);
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i);
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i);
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i);
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i);
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i);
+ sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
+
+ ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i);
+ ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i);
+ ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i);
+ category.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
+
+ S16 inv_serial = 0;
+ msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i);
+
+ LLUUID item_id;
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i);
+ LLUUID folder_id;
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i);
+ LLUUID from_task_id;
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i);
+
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i);
+
+ std::string name;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name, i);
+ std::string desc;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc, i);
+
+ std::string touch_name;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, touch_name, i);
+ std::string sit_name;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i);
+
+ //unpack TE IDs
+ uuid_vec_t texture_ids;
+ S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID);
+ if (size > 0)
+ {
+ S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES];
+ msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES);
+
+ for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES)
+ {
+ LLUUID tid;
+ memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */
+ texture_ids.push_back(tid);
+ }
+ }
+
+
+ // Iterate through nodes at end, since it can be on both the regular AND hover list
+ struct f : public LLSelectedNodeFunctor
+ {
+ LLUUID mID;
+ f(const LLUUID& id) : mID(id) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ return (node->getObject() && node->getObject()->mID == mID);
+ }
+ } func(id);
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
+
+ if (!node)
+ {
+ LL_WARNS() << "Couldn't find object " << id << " selected." << LL_ENDL;
+ }
+ else
+ {
// save texture data as soon as we get texture perms first time
bool save_textures = !node->mValid;
- if (node->mInventorySerial != inv_serial && node->getObject())
- {
- node->getObject()->dirtyInventory();
+ if (node->mInventorySerial != inv_serial && node->getObject())
+ {
+ node->getObject()->dirtyInventory();
// Even if this isn't object's first udpate, inventory changed
// and some of the applied textures might have been in inventory
// so update texture list.
save_textures = true;
- }
-
- if (save_textures)
- {
- BOOL can_copy = FALSE;
- BOOL can_transfer = FALSE;
-
- LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE;
- if(node->getObject()->permYouOwner())
- {
- value = ag_texture_perms_owner.getValue(PERM_COPY);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_copy = TRUE;
- }
- value = ag_texture_perms_owner.getValue(PERM_TRANSFER);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_transfer = TRUE;
- }
- }
- else
- {
- value = ag_texture_perms.getValue(PERM_COPY);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_copy = TRUE;
- }
- value = ag_texture_perms.getValue(PERM_TRANSFER);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_transfer = TRUE;
- }
- }
-
- if (can_copy && can_transfer)
- {
- node->saveTextures(texture_ids);
- }
+ }
+
+ if (save_textures)
+ {
+ BOOL can_copy = FALSE;
+ BOOL can_transfer = FALSE;
+
+ LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE;
+ if(node->getObject()->permYouOwner())
+ {
+ value = ag_texture_perms_owner.getValue(PERM_COPY);
+ if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
+ {
+ can_copy = TRUE;
+ }
+ value = ag_texture_perms_owner.getValue(PERM_TRANSFER);
+ if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
+ {
+ can_transfer = TRUE;
+ }
+ }
+ else
+ {
+ value = ag_texture_perms.getValue(PERM_COPY);
+ if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
+ {
+ can_copy = TRUE;
+ }
+ value = ag_texture_perms.getValue(PERM_TRANSFER);
+ if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
+ {
+ can_transfer = TRUE;
+ }
+ }
+
+ if (can_copy && can_transfer)
+ {
+ node->saveTextures(texture_ids);
+ }
if (can_copy && can_transfer && node->getObject()->getVolume())
{
@@ -5912,572 +5930,572 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
// might need to be moved to LLGLTFMaterialOverrideDispatchHandler
node->saveGLTFMaterials(material_ids, override_materials);
}
- }
-
- node->mValid = TRUE;
- node->mPermissions->init(creator_id, owner_id,
- last_owner_id, group_id);
- node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
- node->mCreationDate = creation_date;
- node->mItemID = item_id;
- node->mFolderID = folder_id;
- node->mFromTaskID = from_task_id;
- node->mName.assign(name);
- node->mDescription.assign(desc);
- node->mSaleInfo = sale_info;
- node->mAggregatePerm = ag_perms;
- node->mAggregateTexturePerm = ag_texture_perms;
- node->mAggregateTexturePermOwner = ag_texture_perms_owner;
- node->mCategory = category;
- node->mInventorySerial = inv_serial;
- node->mSitName.assign(sit_name);
- node->mTouchName.assign(touch_name);
- }
- }
-
- dialog_refresh_all();
-
- // hack for left-click buy object
- LLToolPie::selectionPropertiesReceived();
+ }
+
+ node->mValid = TRUE;
+ node->mPermissions->init(creator_id, owner_id,
+ last_owner_id, group_id);
+ node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
+ node->mCreationDate = creation_date;
+ node->mItemID = item_id;
+ node->mFolderID = folder_id;
+ node->mFromTaskID = from_task_id;
+ node->mName.assign(name);
+ node->mDescription.assign(desc);
+ node->mSaleInfo = sale_info;
+ node->mAggregatePerm = ag_perms;
+ node->mAggregateTexturePerm = ag_texture_perms;
+ node->mAggregateTexturePermOwner = ag_texture_perms_owner;
+ node->mCategory = category;
+ node->mInventorySerial = inv_serial;
+ node->mSitName.assign(sit_name);
+ node->mTouchName.assign(touch_name);
+ }
+ }
+
+ dialog_refresh_all();
+
+ // hack for left-click buy object
+ LLToolPie::selectionPropertiesReceived();
}
// static
void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
{
- LLUUID id;
-
- U32 request_flags;
- LLUUID creator_id;
- LLUUID owner_id;
- LLUUID group_id;
- LLUUID extra_id;
- U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
- LLSaleInfo sale_info;
- LLCategory category;
-
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask );
- msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask);
- sale_info.unpackMessage(msg, _PREHASH_ObjectData);
- category.unpackMessage(msg, _PREHASH_ObjectData);
-
- LLUUID last_owner_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id );
-
- // unpack name & desc
- std::string name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name);
-
- std::string desc;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc);
-
- // the reporter widget askes the server for info about picked objects
- if (request_flags & COMPLAINT_REPORT_REQUEST )
- {
- LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
- if (reporterp)
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(owner_id, &av_name);
- reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id);
- }
- }
- else if (request_flags & OBJECT_PAY_REQUEST)
- {
- // check if the owner of the paid object is muted
- LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY);
- }
-
- // Now look through all of the hovered nodes
- struct f : public LLSelectedNodeFunctor
- {
- LLUUID mID;
- f(const LLUUID& id) : mID(id) {}
- virtual bool apply(LLSelectNode* node)
- {
- return (node->getObject() && node->getObject()->mID == mID);
- }
- } func(id);
- LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func);
-
- if (node)
- {
- node->mValid = TRUE;
- node->mPermissions->init(LLUUID::null, owner_id,
- last_owner_id, group_id);
- node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
- node->mSaleInfo = sale_info;
- node->mCategory = category;
- node->mName.assign(name);
- node->mDescription.assign(desc);
- }
-
- dialog_refresh_all();
+ LLUUID id;
+
+ U32 request_flags;
+ LLUUID creator_id;
+ LLUUID owner_id;
+ LLUUID group_id;
+ LLUUID extra_id;
+ U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
+ LLSaleInfo sale_info;
+ LLCategory category;
+
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags );
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id );
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id );
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id );
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask );
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask );
+ msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask );
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask );
+ msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask);
+ sale_info.unpackMessage(msg, _PREHASH_ObjectData);
+ category.unpackMessage(msg, _PREHASH_ObjectData);
+
+ LLUUID last_owner_id;
+ msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id );
+
+ // unpack name & desc
+ std::string name;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name);
+
+ std::string desc;
+ msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc);
+
+ // the reporter widget askes the server for info about picked objects
+ if (request_flags & COMPLAINT_REPORT_REQUEST )
+ {
+ LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ if (reporterp)
+ {
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(owner_id, &av_name);
+ reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id);
+ }
+ }
+ else if (request_flags & OBJECT_PAY_REQUEST)
+ {
+ // check if the owner of the paid object is muted
+ LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY);
+ }
+
+ // Now look through all of the hovered nodes
+ struct f : public LLSelectedNodeFunctor
+ {
+ LLUUID mID;
+ f(const LLUUID& id) : mID(id) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ return (node->getObject() && node->getObject()->mID == mID);
+ }
+ } func(id);
+ LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func);
+
+ if (node)
+ {
+ node->mValid = TRUE;
+ node->mPermissions->init(LLUUID::null, owner_id,
+ last_owner_id, group_id);
+ node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
+ node->mSaleInfo = sale_info;
+ node->mCategory = category;
+ node->mName.assign(name);
+ node->mDescription.assign(desc);
+ }
+
+ dialog_refresh_all();
}
// static
void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
{
- BOOL reset_list;
- msg->getBOOL("Header", "ResetList", reset_list);
+ BOOL reset_list;
+ msg->getBOOL("Header", "ResetList", reset_list);
- if (reset_list)
- {
- LLSelectMgr::getInstance()->deselectAll();
- }
+ if (reset_list)
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ }
- LLUUID full_id;
- S32 local_id;
- LLViewerObject* object;
- std::vector<LLViewerObject*> objects;
- S32 i;
- S32 block_count = msg->getNumberOfBlocks("Data");
+ LLUUID full_id;
+ S32 local_id;
+ LLViewerObject* object;
+ std::vector<LLViewerObject*> objects;
+ S32 i;
+ S32 block_count = msg->getNumberOfBlocks("Data");
- for (i = 0; i < block_count; i++)
- {
- msg->getS32("Data", "LocalID", local_id, i);
-
- gObjectList.getUUIDFromLocal(full_id,
- local_id,
- msg->getSenderIP(),
- msg->getSenderPort());
- object = gObjectList.findObject(full_id);
- if (object)
- {
- objects.push_back(object);
- }
- }
+ for (i = 0; i < block_count; i++)
+ {
+ msg->getS32("Data", "LocalID", local_id, i);
+
+ gObjectList.getUUIDFromLocal(full_id,
+ local_id,
+ msg->getSenderIP(),
+ msg->getSenderPort());
+ object = gObjectList.findObject(full_id);
+ if (object)
+ {
+ objects.push_back(object);
+ }
+ }
- // Don't select, just highlight
- LLSelectMgr::getInstance()->highlightObjectAndFamily(objects);
+ // Don't select, just highlight
+ LLSelectMgr::getInstance()->highlightObjectAndFamily(objects);
}
-extern F32 gGLModelView[16];
+extern F32 gGLModelView[16];
void LLSelectMgr::updateSilhouettes()
{
- S32 num_sils_genned = 0;
-
- LLVector3d cameraPos = gAgentCamera.getCameraPositionGlobal();
- F32 currentCameraZoom = gAgentCamera.getCurrentCameraBuildOffset();
-
- if (!mSilhouetteImagep)
- {
- mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);
- }
-
- mHighlightedObjects->cleanupNodes();
-
- if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- object->setChanged(LLXform::SILHOUETTE);
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
-
- mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
- }
-
- std::vector<LLViewerObject*> changed_objects;
-
- updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects);
- if (mRectSelectedObjects.size() > 0)
- {
- //gGLSPipelineSelection.set();
-
- //mSilhouetteImagep->bindTexture();
- //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
-
- std::set<LLViewerObject*> roots;
-
- // sync mHighlightedObjects with mRectSelectedObjects since the latter is rebuilt every frame and former
- // persists from frame to frame to avoid regenerating object silhouettes
- // mHighlightedObjects includes all siblings of rect selected objects
-
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
-
- // generate list of roots from current object selection
- for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
- iter != mRectSelectedObjects.end(); iter++)
- {
- LLViewerObject *objectp = *iter;
- if (select_linked_set)
- {
- LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot();
- roots.insert(rootp);
- }
- else
- {
- roots.insert(objectp);
- }
- }
-
- // remove highlight nodes not in roots list
- std::vector<LLSelectNode*> remove_these_nodes;
- std::vector<LLViewerObject*> remove_these_roots;
-
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- if (objectp->isRoot() || !select_linked_set)
- {
- if (roots.count(objectp) == 0)
- {
- remove_these_nodes.push_back(node);
- }
- else
- {
- remove_these_roots.push_back(objectp);
- }
- }
- else
- {
- LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot();
-
- if (roots.count(rootp) == 0)
- {
- remove_these_nodes.push_back(node);
- }
- }
- }
-
- // remove all highlight nodes no longer in rectangle selection
- for (std::vector<LLSelectNode*>::iterator iter = remove_these_nodes.begin();
- iter != remove_these_nodes.end(); ++iter)
- {
- LLSelectNode* nodep = *iter;
- mHighlightedObjects->removeNode(nodep);
- }
-
- // remove all root objects already being highlighted
- for (std::vector<LLViewerObject*>::iterator iter = remove_these_roots.begin();
- iter != remove_these_roots.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- roots.erase(objectp);
- }
-
- // add all new objects in rectangle selection
- for (std::set<LLViewerObject*>::iterator iter = roots.begin();
- iter != roots.end(); iter++)
- {
- LLViewerObject* objectp = *iter;
- if (!canSelectObject(objectp))
- {
- continue;
- }
-
- LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
- rect_select_root_node->selectAllTEs(TRUE);
-
- if (!select_linked_set)
- {
- rect_select_root_node->mIndividualSelection = TRUE;
- }
- else
- {
- LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child_objectp = *iter;
-
- if (!canSelectObject(child_objectp))
- {
- continue;
- }
-
- LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE);
- rect_select_node->selectAllTEs(TRUE);
- mHighlightedObjects->addNodeAtEnd(rect_select_node);
- }
- }
-
- // Add the root last, to preserve order for link operations.
- mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
- }
-
- num_sils_genned = 0;
-
- // render silhouettes for highlighted objects
- //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
-
- // do roots first, then children so that root flags are cleared ASAP
- BOOL roots_only = (pass == 0);
- BOOL is_root = objectp->isRootEdit();
- if (roots_only != is_root)
- {
- continue;
- }
-
- if (!node->mSilhouetteExists
- || objectp->isChanged(LLXform::SILHOUETTE)
- || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
- {
- if (num_sils_genned++ < MAX_SILS_PER_FRAME)
- {
- generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
- changed_objects.push_back(objectp);
- }
- else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull())
- {
- //RN: hack for orthogonal projection of HUD attachments
- LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
- if (attachment_pt && attachment_pt->getIsHUDAttachment())
- {
- LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
- generateSilhouette(node, camera_pos);
- }
- }
- }
- //LLColor4 highlight_color;
- //
- //if (subtracting_from_selection)
- //{
- // node->renderOneSilhouette(LLColor4::red);
- //}
- //else if (!objectp->isSelected())
- //{
- // highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
- // node->renderOneSilhouette(highlight_color);
- //}
- }
- }
- //mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
- }
- else
- {
- mHighlightedObjects->deleteAllNodes();
- }
-
- for (std::vector<LLViewerObject*>::iterator iter = changed_objects.begin();
- iter != changed_objects.end(); ++iter)
- {
- // clear flags after traversing node list (as child objects need to refer to parent flags, etc)
- LLViewerObject* objectp = *iter;
- objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
- }
+ S32 num_sils_genned = 0;
+
+ LLVector3d cameraPos = gAgentCamera.getCameraPositionGlobal();
+ F32 currentCameraZoom = gAgentCamera.getCurrentCameraBuildOffset();
+
+ if (!mSilhouetteImagep)
+ {
+ mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);
+ }
+
+ mHighlightedObjects->cleanupNodes();
+
+ if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom)
+ {
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ object->setChanged(LLXform::SILHOUETTE);
+ return true;
+ }
+ } func;
+ getSelection()->applyToObjects(&func);
+
+ mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
+ }
+
+ std::vector<LLViewerObject*> changed_objects;
+
+ updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects);
+ if (mRectSelectedObjects.size() > 0)
+ {
+ //gGLSPipelineSelection.set();
+
+ //mSilhouetteImagep->bindTexture();
+ //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
+
+ std::set<LLViewerObject*> roots;
+
+ // sync mHighlightedObjects with mRectSelectedObjects since the latter is rebuilt every frame and former
+ // persists from frame to frame to avoid regenerating object silhouettes
+ // mHighlightedObjects includes all siblings of rect selected objects
+
+ BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
+
+ // generate list of roots from current object selection
+ for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
+ iter != mRectSelectedObjects.end(); iter++)
+ {
+ LLViewerObject *objectp = *iter;
+ if (select_linked_set)
+ {
+ LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot();
+ roots.insert(rootp);
+ }
+ else
+ {
+ roots.insert(objectp);
+ }
+ }
+
+ // remove highlight nodes not in roots list
+ std::vector<LLSelectNode*> remove_these_nodes;
+ std::vector<LLViewerObject*> remove_these_roots;
+
+ for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
+ iter != mHighlightedObjects->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+ if (objectp->isRoot() || !select_linked_set)
+ {
+ if (roots.count(objectp) == 0)
+ {
+ remove_these_nodes.push_back(node);
+ }
+ else
+ {
+ remove_these_roots.push_back(objectp);
+ }
+ }
+ else
+ {
+ LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot();
+
+ if (roots.count(rootp) == 0)
+ {
+ remove_these_nodes.push_back(node);
+ }
+ }
+ }
+
+ // remove all highlight nodes no longer in rectangle selection
+ for (std::vector<LLSelectNode*>::iterator iter = remove_these_nodes.begin();
+ iter != remove_these_nodes.end(); ++iter)
+ {
+ LLSelectNode* nodep = *iter;
+ mHighlightedObjects->removeNode(nodep);
+ }
+
+ // remove all root objects already being highlighted
+ for (std::vector<LLViewerObject*>::iterator iter = remove_these_roots.begin();
+ iter != remove_these_roots.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ roots.erase(objectp);
+ }
+
+ // add all new objects in rectangle selection
+ for (std::set<LLViewerObject*>::iterator iter = roots.begin();
+ iter != roots.end(); iter++)
+ {
+ LLViewerObject* objectp = *iter;
+ if (!canSelectObject(objectp))
+ {
+ continue;
+ }
+
+ LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
+ rect_select_root_node->selectAllTEs(TRUE);
+
+ if (!select_linked_set)
+ {
+ rect_select_root_node->mIndividualSelection = TRUE;
+ }
+ else
+ {
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child_objectp = *iter;
+
+ if (!canSelectObject(child_objectp))
+ {
+ continue;
+ }
+
+ LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE);
+ rect_select_node->selectAllTEs(TRUE);
+ mHighlightedObjects->addNodeAtEnd(rect_select_node);
+ }
+ }
+
+ // Add the root last, to preserve order for link operations.
+ mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
+ }
+
+ num_sils_genned = 0;
+
+ // render silhouettes for highlighted objects
+ //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
+ iter != mHighlightedObjects->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+
+ // do roots first, then children so that root flags are cleared ASAP
+ BOOL roots_only = (pass == 0);
+ BOOL is_root = objectp->isRootEdit();
+ if (roots_only != is_root)
+ {
+ continue;
+ }
+
+ if (!node->mSilhouetteExists
+ || objectp->isChanged(LLXform::SILHOUETTE)
+ || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
+ {
+ if (num_sils_genned++ < MAX_SILS_PER_FRAME)
+ {
+ generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
+ changed_objects.push_back(objectp);
+ }
+ else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull())
+ {
+ //RN: hack for orthogonal projection of HUD attachments
+ LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
+ if (attachment_pt && attachment_pt->getIsHUDAttachment())
+ {
+ LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
+ generateSilhouette(node, camera_pos);
+ }
+ }
+ }
+ //LLColor4 highlight_color;
+ //
+ //if (subtracting_from_selection)
+ //{
+ // node->renderOneSilhouette(LLColor4::red);
+ //}
+ //else if (!objectp->isSelected())
+ //{
+ // highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
+ // node->renderOneSilhouette(highlight_color);
+ //}
+ }
+ }
+ //mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
+ }
+ else
+ {
+ mHighlightedObjects->deleteAllNodes();
+ }
+
+ for (std::vector<LLViewerObject*>::iterator iter = changed_objects.begin();
+ iter != changed_objects.end(); ++iter)
+ {
+ // clear flags after traversing node list (as child objects need to refer to parent flags, etc)
+ LLViewerObject* objectp = *iter;
+ objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
+ }
}
void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects)
{
- if (object_handle->getNumNodes())
- {
- //gGLSPipelineSelection.set();
-
- //mSilhouetteImagep->bindTexture();
- //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
-
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = object_handle->begin();
- iter != object_handle->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- // do roots first, then children so that root flags are cleared ASAP
- BOOL roots_only = (pass == 0);
- BOOL is_root = (objectp->isRootEdit());
- if (roots_only != is_root || objectp->mDrawable.isNull())
- {
- continue;
- }
-
- if (!node->mSilhouetteExists
- || objectp->isChanged(LLXform::SILHOUETTE)
- || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
- {
- if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
- {
- generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
- changed_objects.push_back(objectp);
- }
- else if (objectp->isAttachment())
- {
- //RN: hack for orthogonal projection of HUD attachments
- LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
- if (attachment_pt && attachment_pt->getIsHUDAttachment())
- {
- LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
- generateSilhouette(node, camera_pos);
- }
- }
- }
- }
- }
- }
+ if (object_handle->getNumNodes())
+ {
+ //gGLSPipelineSelection.set();
+
+ //mSilhouetteImagep->bindTexture();
+ //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
+
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ for (LLObjectSelection::iterator iter = object_handle->begin();
+ iter != object_handle->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+ // do roots first, then children so that root flags are cleared ASAP
+ BOOL roots_only = (pass == 0);
+ BOOL is_root = (objectp->isRootEdit());
+ if (roots_only != is_root || objectp->mDrawable.isNull())
+ {
+ continue;
+ }
+
+ if (!node->mSilhouetteExists
+ || objectp->isChanged(LLXform::SILHOUETTE)
+ || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
+ {
+ if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
+ {
+ generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
+ changed_objects.push_back(objectp);
+ }
+ else if (objectp->isAttachment())
+ {
+ //RN: hack for orthogonal projection of HUD attachments
+ LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
+ if (attachment_pt && attachment_pt->getIsHUDAttachment())
+ {
+ LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
+ generateSilhouette(node, camera_pos);
+ }
+ }
+ }
+ }
+ }
+ }
}
void LLSelectMgr::renderSilhouettes(BOOL for_hud)
{
- if (!mRenderSilhouettes || !mRenderHighlightSelections)
- {
- return;
- }
-
- gGL.getTexUnit(0)->bind(mSilhouetteImagep);
- LLGLSPipelineSelection gls_select;
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- if (isAgentAvatarValid() && for_hud)
- {
- LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
-
- F32 cur_zoom = gAgentCamera.mHUDCurZoom;
-
- // set up transform to encompass bounding box of HUD
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
- gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.pushUIMatrix();
- gGL.loadUIIdentity();
- gGL.loadIdentity();
- gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
- gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
- gGL.scalef(cur_zoom, cur_zoom, cur_zoom);
- }
-
- bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections;
- F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
-
- static LLColor4 sParentColor = LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha);
- static LLColor4 sChildColor = LLColor4(sSilhouetteChildColor[VRED], sSilhouetteChildColor[VGREEN], sSilhouetteChildColor[VBLUE], LLSelectMgr::sHighlightAlpha);
-
- auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor)
- {
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
- if (shader)
- {
- gDebugProgram.bind();
- }
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- BOOL is_hud_object = objectp->isHUDAttachment();
-
- if (!is_hud_object)
- {
- gGL.loadIdentity();
- gGL.multMatrix(gGLModelView);
- }
-
- if (objectp->mDrawable->isActive())
- {
- gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
- }
- else if (!is_hud_object)
- {
- LLVector3 trans = objectp->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- }
-
- bool bRenderHidenSelection = node->isTransient() ? false : LLSelectMgr::sRenderHiddenSelections;
-
-
- LLVOVolume* vobj = objectp->mDrawable->getVOVolume();
- if (vobj)
- {
- LLVertexBuffer::unbind();
- gGL.pushMatrix();
- gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix);
-
- if (objectp->mDrawable->isState(LLDrawable::RIGGED))
- {
- vobj->updateRiggedVolume(true);
- }
- }
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
- for (S32 te = 0; te < num_tes; ++te)
- {
- if (node->isTESelected(te))
- {
- objectp->mDrawable->getFace(te)->renderOneWireframe(hlColor, fogCfx, wireframe_selection, bRenderHidenSelection, nullptr != shader);
- }
- }
-
- gGL.popMatrix();
- gGL.popMatrix();
-
- glLineWidth(1.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
- if (shader)
- {
- shader->bind();
- }
- };
-
- if (mSelectedObjects->getNumNodes())
- {
- LLUUID inspect_item_id= LLUUID::null;
- LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
- if(inspect_instance && inspect_instance->getVisible())
- {
- inspect_item_id = inspect_instance->getSelectedUUID();
- }
- else
- {
- LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
- if (panel_task_info)
- {
- inspect_item_id = panel_task_info->getSelectedUUID();
- }
- }
-
- LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID();
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
-
+ if (!mRenderSilhouettes || !mRenderHighlightSelections)
+ {
+ return;
+ }
+
+ gGL.getTexUnit(0)->bind(mSilhouetteImagep);
+ LLGLSPipelineSelection gls_select;
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+
+ if (isAgentAvatarValid() && for_hud)
+ {
+ LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
+
+ F32 cur_zoom = gAgentCamera.mHUDCurZoom;
+
+ // set up transform to encompass bounding box of HUD
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
+ gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.pushUIMatrix();
+ gGL.loadUIIdentity();
+ gGL.loadIdentity();
+ gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
+ gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
+ gGL.scalef(cur_zoom, cur_zoom, cur_zoom);
+ }
+
+ bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections;
+ F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
+
+ static LLColor4 sParentColor = LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha);
+ static LLColor4 sChildColor = LLColor4(sSilhouetteChildColor[VRED], sSilhouetteChildColor[VGREEN], sSilhouetteChildColor[VBLUE], LLSelectMgr::sHighlightAlpha);
+
+ auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor)
+ {
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ if (shader)
+ {
+ gDebugProgram.bind();
+ }
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+
+ BOOL is_hud_object = objectp->isHUDAttachment();
+
+ if (!is_hud_object)
+ {
+ gGL.loadIdentity();
+ gGL.multMatrix(gGLModelView);
+ }
+
+ if (objectp->mDrawable->isActive())
+ {
+ gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
+ }
+ else if (!is_hud_object)
+ {
+ LLVector3 trans = objectp->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ }
+
+ bool bRenderHidenSelection = node->isTransient() ? false : LLSelectMgr::sRenderHiddenSelections;
+
+
+ LLVOVolume* vobj = objectp->mDrawable->getVOVolume();
+ if (vobj)
+ {
+ LLVertexBuffer::unbind();
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix);
+
+ if (objectp->mDrawable->isState(LLDrawable::RIGGED))
+ {
+ vobj->updateRiggedVolume(true);
+ }
+ }
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ objectp->mDrawable->getFace(te)->renderOneWireframe(hlColor, fogCfx, wireframe_selection, bRenderHidenSelection, nullptr != shader);
+ }
+ }
+
+ gGL.popMatrix();
+ gGL.popMatrix();
+
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ if (shader)
+ {
+ shader->bind();
+ }
+ };
+
+ if (mSelectedObjects->getNumNodes())
+ {
+ LLUUID inspect_item_id= LLUUID::null;
+ LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
+ if(inspect_instance && inspect_instance->getVisible())
+ {
+ inspect_item_id = inspect_instance->getSelectedUUID();
+ }
+ else
+ {
+ LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
+ if (panel_task_info)
+ {
+ inspect_item_id = panel_task_info->getSelectedUUID();
+ }
+ }
+
+ LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID();
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ iter != mSelectedObjects->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
if (getTEMode() && !node->hasSelectedTE())
continue;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
- if (objectp->mDrawable
- && objectp->mDrawable->getVOVolume()
+ if (objectp->mDrawable
+ && objectp->mDrawable->getVOVolume()
&& objectp->mDrawable->getVOVolume()->isMesh())
{
LLColor4 hlColor = objectp->isRootEdit() ? sParentColor : sChildColor;
@@ -6521,145 +6539,145 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
node->renderOneSilhouette(sSilhouetteChildColor);
}
}
- } //for all selected node's
- } //for pass
- }
-
- if (mHighlightedObjects->getNumNodes())
- {
- // render silhouettes for highlighted objects
- BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- if (objectp->isHUDAttachment() != for_hud)
- {
- continue;
- }
-
- LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
- if (objectp->mDrawable
- && objectp->mDrawable->getVOVolume()
- && objectp->mDrawable->getVOVolume()->isMesh())
- {
- renderMeshSelection_f(node, objectp, subtracting_from_selection ? LLColor4::red : highlight_color);
- }
- else if (subtracting_from_selection)
- {
- node->renderOneSilhouette(LLColor4::red);
- }
- else if (!objectp->isSelected())
- {
- node->renderOneSilhouette(highlight_color);
- }
- }
- }
- }
-
- if (isAgentAvatarValid() && for_hud)
- {
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- gGL.popUIMatrix();
- stop_glerror();
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ } //for all selected node's
+ } //for pass
+ }
+
+ if (mHighlightedObjects->getNumNodes())
+ {
+ // render silhouettes for highlighted objects
+ BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
+ iter != mHighlightedObjects->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+ if (objectp->isHUDAttachment() != for_hud)
+ {
+ continue;
+ }
+
+ LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
+ if (objectp->mDrawable
+ && objectp->mDrawable->getVOVolume()
+ && objectp->mDrawable->getVOVolume()->isMesh())
+ {
+ renderMeshSelection_f(node, objectp, subtracting_from_selection ? LLColor4::red : highlight_color);
+ }
+ else if (subtracting_from_selection)
+ {
+ node->renderOneSilhouette(LLColor4::red);
+ }
+ else if (!objectp->isSelected())
+ {
+ node->renderOneSilhouette(highlight_color);
+ }
+ }
+ }
+ }
+
+ if (isAgentAvatarValid() && for_hud)
+ {
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ gGL.popUIMatrix();
+ stop_glerror();
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
{
- LLViewerObject* objectp = nodep->getObject();
+ LLViewerObject* objectp = nodep->getObject();
- if (objectp && objectp->getPCode() == LL_PCODE_VOLUME)
- {
- ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point);
- }
+ if (objectp && objectp->getPCode() == LL_PCODE_VOLUME)
+ {
+ ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point);
+ }
}
//
// Utility classes
//
LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
-: mObject(object),
- mIndividualSelection(FALSE),
- mTransient(FALSE),
- mValid(FALSE),
- mPermissions(new LLPermissions()),
- mInventorySerial(0),
- mSilhouetteExists(FALSE),
- mDuplicated(FALSE),
- mTESelectMask(0),
- mLastTESelected(0),
- mName(LLStringUtil::null),
- mDescription(LLStringUtil::null),
- mTouchName(LLStringUtil::null),
- mSitName(LLStringUtil::null),
- mCreationDate(0)
-{
- saveColors();
- saveShinyColors();
+: mObject(object),
+ mIndividualSelection(FALSE),
+ mTransient(FALSE),
+ mValid(FALSE),
+ mPermissions(new LLPermissions()),
+ mInventorySerial(0),
+ mSilhouetteExists(FALSE),
+ mDuplicated(FALSE),
+ mTESelectMask(0),
+ mLastTESelected(0),
+ mName(LLStringUtil::null),
+ mDescription(LLStringUtil::null),
+ mTouchName(LLStringUtil::null),
+ mSitName(LLStringUtil::null),
+ mCreationDate(0)
+{
+ saveColors();
+ saveShinyColors();
}
LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
{
- mTESelectMask = nodep.mTESelectMask;
- mLastTESelected = nodep.mLastTESelected;
-
- mIndividualSelection = nodep.mIndividualSelection;
-
- mValid = nodep.mValid;
- mTransient = nodep.mTransient;
- mPermissions = new LLPermissions(*nodep.mPermissions);
- mSaleInfo = nodep.mSaleInfo;;
- mAggregatePerm = nodep.mAggregatePerm;
- mAggregateTexturePerm = nodep.mAggregateTexturePerm;
- mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner;
- mName = nodep.mName;
- mDescription = nodep.mDescription;
- mCategory = nodep.mCategory;
- mInventorySerial = 0;
- mSavedPositionLocal = nodep.mSavedPositionLocal;
- mSavedPositionGlobal = nodep.mSavedPositionGlobal;
- mSavedScale = nodep.mSavedScale;
- mSavedRotation = nodep.mSavedRotation;
- mDuplicated = nodep.mDuplicated;
- mDuplicatePos = nodep.mDuplicatePos;
- mDuplicateRot = nodep.mDuplicateRot;
- mItemID = nodep.mItemID;
- mFolderID = nodep.mFolderID;
- mFromTaskID = nodep.mFromTaskID;
- mTouchName = nodep.mTouchName;
- mSitName = nodep.mSitName;
- mCreationDate = nodep.mCreationDate;
-
- mSilhouetteVertices = nodep.mSilhouetteVertices;
- mSilhouetteNormals = nodep.mSilhouetteNormals;
- mSilhouetteExists = nodep.mSilhouetteExists;
- mObject = nodep.mObject;
-
- std::vector<LLColor4>::const_iterator color_iter;
- mSavedColors.clear();
- for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter)
- {
- mSavedColors.push_back(*color_iter);
- }
- mSavedShinyColors.clear();
- for (color_iter = nodep.mSavedShinyColors.begin(); color_iter != nodep.mSavedShinyColors.end(); ++color_iter)
- {
- mSavedShinyColors.push_back(*color_iter);
- }
-
- saveTextures(nodep.mSavedTextures);
+ mTESelectMask = nodep.mTESelectMask;
+ mLastTESelected = nodep.mLastTESelected;
+
+ mIndividualSelection = nodep.mIndividualSelection;
+
+ mValid = nodep.mValid;
+ mTransient = nodep.mTransient;
+ mPermissions = new LLPermissions(*nodep.mPermissions);
+ mSaleInfo = nodep.mSaleInfo;;
+ mAggregatePerm = nodep.mAggregatePerm;
+ mAggregateTexturePerm = nodep.mAggregateTexturePerm;
+ mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner;
+ mName = nodep.mName;
+ mDescription = nodep.mDescription;
+ mCategory = nodep.mCategory;
+ mInventorySerial = 0;
+ mSavedPositionLocal = nodep.mSavedPositionLocal;
+ mSavedPositionGlobal = nodep.mSavedPositionGlobal;
+ mSavedScale = nodep.mSavedScale;
+ mSavedRotation = nodep.mSavedRotation;
+ mDuplicated = nodep.mDuplicated;
+ mDuplicatePos = nodep.mDuplicatePos;
+ mDuplicateRot = nodep.mDuplicateRot;
+ mItemID = nodep.mItemID;
+ mFolderID = nodep.mFolderID;
+ mFromTaskID = nodep.mFromTaskID;
+ mTouchName = nodep.mTouchName;
+ mSitName = nodep.mSitName;
+ mCreationDate = nodep.mCreationDate;
+
+ mSilhouetteVertices = nodep.mSilhouetteVertices;
+ mSilhouetteNormals = nodep.mSilhouetteNormals;
+ mSilhouetteExists = nodep.mSilhouetteExists;
+ mObject = nodep.mObject;
+
+ std::vector<LLColor4>::const_iterator color_iter;
+ mSavedColors.clear();
+ for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter)
+ {
+ mSavedColors.push_back(*color_iter);
+ }
+ mSavedShinyColors.clear();
+ for (color_iter = nodep.mSavedShinyColors.begin(); color_iter != nodep.mSavedShinyColors.end(); ++color_iter)
+ {
+ mSavedShinyColors.push_back(*color_iter);
+ }
+
+ saveTextures(nodep.mSavedTextures);
saveGLTFMaterials(nodep.mSavedGLTFMaterialIds, nodep.mSavedGLTFOverrideMaterials);
}
@@ -6682,116 +6700,126 @@ LLSelectNode::~LLSelectNode()
}
}
-
delete mPermissions;
- mPermissions = NULL;
+ mPermissions = NULL;
}
void LLSelectNode::selectAllTEs(BOOL b)
{
- mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0;
- mLastTESelected = 0;
+ mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0;
+ mLastTESelected = 0;
}
void LLSelectNode::selectTE(S32 te_index, BOOL selected)
{
- if (te_index < 0 || te_index >= SELECT_MAX_TES)
+ if (te_index < 0 || te_index >= SELECT_MAX_TES)
+ {
+ return;
+ }
+ S32 mask = 0x1 << te_index;
+ if(selected)
+ {
+ mTESelectMask |= mask;
+ }
+ else
+ {
+ mTESelectMask &= ~mask;
+ }
+ mLastTESelected = te_index;
+}
+
+void LLSelectNode::selectGLTFNode(S32 node_index, S32 primitive_index, bool selected)
+{
+ if (node_index < 0)
{
return;
}
- S32 mask = 0x1 << te_index;
- if(selected)
- {
- mTESelectMask |= mask;
- }
- else
- {
- mTESelectMask &= ~mask;
- }
- mLastTESelected = te_index;
+
+ mSelectedGLTFNode = node_index;
+ mSelectedGLTFPrimitive = primitive_index;
}
BOOL LLSelectNode::isTESelected(S32 te_index) const
{
- if (te_index < 0 || te_index >= mObject->getNumTEs())
- {
- return FALSE;
- }
- return (mTESelectMask & (0x1 << te_index)) != 0;
+ if (te_index < 0 || te_index >= mObject->getNumTEs())
+ {
+ return FALSE;
+ }
+ return (mTESelectMask & (0x1 << te_index)) != 0;
}
S32 LLSelectNode::getLastSelectedTE() const
{
- if (!isTESelected(mLastTESelected))
- {
- return -1;
- }
- return mLastTESelected;
+ if (!isTESelected(mLastTESelected))
+ {
+ return -1;
+ }
+ return mLastTESelected;
}
LLViewerObject* LLSelectNode::getObject()
{
- if (!mObject)
- {
- return NULL;
- }
- else if (mObject->isDead())
- {
- mObject = NULL;
- }
- return mObject;
+ if (!mObject)
+ {
+ return NULL;
+ }
+ else if (mObject->isDead())
+ {
+ mObject = NULL;
+ }
+ return mObject;
}
void LLSelectNode::setObject(LLViewerObject* object)
{
- mObject = object;
+ mObject = object;
}
void LLSelectNode::saveColors()
{
- if (mObject.notNull())
- {
- mSavedColors.clear();
- for (S32 i = 0; i < mObject->getNumTEs(); i++)
- {
- const LLTextureEntry* tep = mObject->getTE(i);
- mSavedColors.push_back(tep->getColor());
- }
- }
+ if (mObject.notNull())
+ {
+ mSavedColors.clear();
+ for (S32 i = 0; i < mObject->getNumTEs(); i++)
+ {
+ const LLTextureEntry* tep = mObject->getTE(i);
+ mSavedColors.push_back(tep->getColor());
+ }
+ }
}
void LLSelectNode::saveShinyColors()
{
- if (mObject.notNull())
- {
- mSavedShinyColors.clear();
- for (S32 i = 0; i < mObject->getNumTEs(); i++)
- {
- const LLMaterialPtr mat = mObject->getTE(i)->getMaterialParams();
- if (!mat.isNull())
- {
- mSavedShinyColors.push_back(mat->getSpecularLightColor());
- }
- else
- {
- mSavedShinyColors.push_back(LLColor4::white);
- }
- }
- }
+ if (mObject.notNull())
+ {
+ mSavedShinyColors.clear();
+ for (S32 i = 0; i < mObject->getNumTEs(); i++)
+ {
+ const LLMaterialPtr mat = mObject->getTE(i)->getMaterialParams();
+ if (!mat.isNull())
+ {
+ mSavedShinyColors.push_back(mat->getSpecularLightColor());
+ }
+ else
+ {
+ mSavedShinyColors.push_back(LLColor4::white);
+ }
+ }
+ }
}
void LLSelectNode::saveTextures(const uuid_vec_t& textures)
{
- if (mObject.notNull())
- {
- mSavedTextures.clear();
+ if (mObject.notNull())
+ {
+ mSavedTextures.clear();
- for (uuid_vec_t::const_iterator texture_it = textures.begin();
- texture_it != textures.end(); ++texture_it)
- {
- mSavedTextures.push_back(*texture_it);
- }
- }
+ for (uuid_vec_t::const_iterator texture_it = textures.begin();
+ texture_it != textures.end(); ++texture_it)
+ {
+ mSavedTextures.push_back(*texture_it);
+ }
+ }
}
void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials)
@@ -6817,136 +6845,136 @@ void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_mat
void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
- mTextureScaleRatios.clear();
-
- if (mObject.notNull())
- {
-
- LLVector3 scale = mObject->getScale();
-
- for (U8 i = 0; i < mObject->getNumTEs(); i++)
- {
- F32 diffuse_s = 1.0f;
- F32 diffuse_t = 1.0f;
-
- LLVector3 v;
- const LLTextureEntry* tep = mObject->getTE(i);
- if (!tep)
- continue;
-
- U32 s_axis = VX;
- U32 t_axis = VY;
- LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
-
- tep->getScale(&diffuse_s,&diffuse_t);
-
- if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
- {
- v.mV[s_axis] = diffuse_s*scale.mV[s_axis];
- v.mV[t_axis] = diffuse_t*scale.mV[t_axis];
- mTextureScaleRatios.push_back(v);
- }
- else
- {
- v.mV[s_axis] = diffuse_s/scale.mV[s_axis];
- v.mV[t_axis] = diffuse_t/scale.mV[t_axis];
- mTextureScaleRatios.push_back(v);
- }
- }
- }
+ mTextureScaleRatios.clear();
+
+ if (mObject.notNull())
+ {
+
+ LLVector3 scale = mObject->getScale();
+
+ for (U8 i = 0; i < mObject->getNumTEs(); i++)
+ {
+ F32 diffuse_s = 1.0f;
+ F32 diffuse_t = 1.0f;
+
+ LLVector3 v;
+ const LLTextureEntry* tep = mObject->getTE(i);
+ if (!tep)
+ continue;
+
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
+
+ tep->getScale(&diffuse_s,&diffuse_t);
+
+ if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ v.mV[s_axis] = diffuse_s*scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t*scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
+ }
+ else
+ {
+ v.mV[s_axis] = diffuse_s/scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t/scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
+ }
+ }
+ }
}
// This implementation should be similar to LLTask::allowOperationOnTask
BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const
{
- // Extract ownership.
- BOOL object_is_group_owned = FALSE;
- LLUUID object_owner_id;
- mPermissions->getOwnership(object_owner_id, object_is_group_owned);
-
- // Operations on invalid or public objects is not allowed.
- if (!mObject || (mObject->isDead()) || !mPermissions->isOwned())
- {
- return FALSE;
- }
-
- // The transfer permissions can never be given through proxy.
- if (PERM_TRANSFER == op)
- {
- // The owner of an agent-owned object can transfer to themselves.
- if ( !object_is_group_owned
- && (gAgent.getID() == object_owner_id) )
- {
- return TRUE;
- }
- else
- {
- // Otherwise check aggregate permissions.
- return mObject->permTransfer();
- }
- }
-
- if (PERM_MOVE == op
- || PERM_MODIFY == op)
- {
- // only owners can move or modify their attachments
- // no proxy allowed.
- if (mObject->isAttachment() && object_owner_id != gAgent.getID())
- {
- return FALSE;
- }
- }
-
- // Calculate proxy_agent_id and group_id to use for permissions checks.
- // proxy_agent_id may be set to the object owner through group powers.
- // group_id can only be set to the object's group, if the agent is in that group.
- LLUUID group_id = LLUUID::null;
- LLUUID proxy_agent_id = gAgent.getID();
-
- // Gods can always operate.
- if (gAgent.isGodlike())
- {
- return TRUE;
- }
-
- // Check if the agent is in the same group as the object.
- LLUUID object_group_id = mPermissions->getGroup();
- if (object_group_id.notNull() &&
- gAgent.isInGroup(object_group_id))
- {
- // Assume the object's group during this operation.
- group_id = object_group_id;
- }
-
- // Only allow proxy powers for PERM_COPY if the actual agent can
- // receive the item (ie has PERM_TRANSFER permissions).
- // NOTE: op == PERM_TRANSFER has already been handled, but if
- // that ever changes we need to BLOCK proxy powers for PERM_TRANSFER. DK 03/28/06
- if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID()))
- {
- // Check if the agent can assume ownership through group proxy or agent-granted proxy.
- if ( ( object_is_group_owned
- && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power))
- // Only allow proxy for move, modify, and copy.
- || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op)
- && (!object_is_group_owned
- && gAgent.isGrantedProxy(*mPermissions))))
- {
- // This agent is able to assume the ownership role for this operation.
- proxy_agent_id = object_owner_id;
- }
- }
-
- // We now have max ownership information.
- if (PERM_OWNER == op)
- {
- // This this was just a check for ownership, we can now return the answer.
- return (proxy_agent_id == object_owner_id ? TRUE : FALSE);
- }
-
- // check permissions to see if the agent can operate
- return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
+ // Extract ownership.
+ BOOL object_is_group_owned = FALSE;
+ LLUUID object_owner_id;
+ mPermissions->getOwnership(object_owner_id, object_is_group_owned);
+
+ // Operations on invalid or public objects is not allowed.
+ if (!mObject || (mObject->isDead()) || !mPermissions->isOwned())
+ {
+ return FALSE;
+ }
+
+ // The transfer permissions can never be given through proxy.
+ if (PERM_TRANSFER == op)
+ {
+ // The owner of an agent-owned object can transfer to themselves.
+ if ( !object_is_group_owned
+ && (gAgent.getID() == object_owner_id) )
+ {
+ return TRUE;
+ }
+ else
+ {
+ // Otherwise check aggregate permissions.
+ return mObject->permTransfer();
+ }
+ }
+
+ if (PERM_MOVE == op
+ || PERM_MODIFY == op)
+ {
+ // only owners can move or modify their attachments
+ // no proxy allowed.
+ if (mObject->isAttachment() && object_owner_id != gAgent.getID())
+ {
+ return FALSE;
+ }
+ }
+
+ // Calculate proxy_agent_id and group_id to use for permissions checks.
+ // proxy_agent_id may be set to the object owner through group powers.
+ // group_id can only be set to the object's group, if the agent is in that group.
+ LLUUID group_id = LLUUID::null;
+ LLUUID proxy_agent_id = gAgent.getID();
+
+ // Gods can always operate.
+ if (gAgent.isGodlike())
+ {
+ return TRUE;
+ }
+
+ // Check if the agent is in the same group as the object.
+ LLUUID object_group_id = mPermissions->getGroup();
+ if (object_group_id.notNull() &&
+ gAgent.isInGroup(object_group_id))
+ {
+ // Assume the object's group during this operation.
+ group_id = object_group_id;
+ }
+
+ // Only allow proxy powers for PERM_COPY if the actual agent can
+ // receive the item (ie has PERM_TRANSFER permissions).
+ // NOTE: op == PERM_TRANSFER has already been handled, but if
+ // that ever changes we need to BLOCK proxy powers for PERM_TRANSFER. DK 03/28/06
+ if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID()))
+ {
+ // Check if the agent can assume ownership through group proxy or agent-granted proxy.
+ if ( ( object_is_group_owned
+ && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power))
+ // Only allow proxy for move, modify, and copy.
+ || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op)
+ && (!object_is_group_owned
+ && gAgent.isGrantedProxy(*mPermissions))))
+ {
+ // This agent is able to assume the ownership role for this operation.
+ proxy_agent_id = object_owner_id;
+ }
+ }
+
+ // We now have max ownership information.
+ if (PERM_OWNER == op)
+ {
+ // This this was just a check for ownership, we can now return the answer.
+ return (proxy_agent_id == object_owner_id ? TRUE : FALSE);
+ }
+
+ // check permissions to see if the agent can operate
+ return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
}
//-----------------------------------------------------------------------------
@@ -6954,167 +6982,167 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)
//-----------------------------------------------------------------------------
void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
{
- LLViewerObject* objectp = getObject();
- if (!objectp)
- {
- return;
- }
-
- LLDrawable* drawable = objectp->mDrawable;
- if(!drawable)
- {
- return;
- }
-
- LLVOVolume* vobj = drawable->getVOVolume();
- if (vobj && vobj->isMesh())
- {
- //This check (if(...)) with assert here just for ensure that this situation will not happens, and can be removed later. For example on the next release.
- llassert(!"renderOneWireframe() was removed SL-10194");
- return;
- }
-
- if (!mSilhouetteExists)
- {
- return;
- }
-
- BOOL is_hud_object = objectp->isHUDAttachment();
-
- if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size())
- {
- return;
- }
-
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
- if (shader)
- { //use UI program for selection highlights (texture color modulated by vertex color)
- gUIProgram.bind();
- }
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.pushUIMatrix();
- gGL.loadUIIdentity();
-
- if (!is_hud_object)
- {
- gGL.loadIdentity();
- gGL.multMatrix(gGLModelView);
- }
-
-
- if (drawable->isActive())
- {
- gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
- }
-
- LLVolume *volume = objectp->getVolume();
- if (volume)
- {
- F32 silhouette_thickness;
- if (isAgentAvatarValid() && is_hud_object)
- {
- silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom;
- }
- else
- {
- LLVector3 view_vector = LLViewerCamera::getInstance()->getOrigin() - objectp->getRenderPosition();
- silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV());
- }
- F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds();
-
- F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
- F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f);
- F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1));
-
- if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
- {
- gGL.flush();
- gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
-
+ LLViewerObject* objectp = getObject();
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLDrawable* drawable = objectp->mDrawable;
+ if(!drawable)
+ {
+ return;
+ }
+
+ LLVOVolume* vobj = drawable->getVOVolume();
+ if (vobj && vobj->isMesh())
+ {
+ //This check (if(...)) with assert here just for ensure that this situation will not happens, and can be removed later. For example on the next release.
+ llassert(!"renderOneWireframe() was removed SL-10194");
+ return;
+ }
+
+ if (!mSilhouetteExists)
+ {
+ return;
+ }
+
+ BOOL is_hud_object = objectp->isHUDAttachment();
+
+ if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size())
+ {
+ return;
+ }
+
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ if (shader)
+ { //use UI program for selection highlights (texture color modulated by vertex color)
+ gUIProgram.bind();
+ }
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.pushUIMatrix();
+ gGL.loadUIIdentity();
+
+ if (!is_hud_object)
+ {
+ gGL.loadIdentity();
+ gGL.multMatrix(gGLModelView);
+ }
+
+
+ if (drawable->isActive())
+ {
+ gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
+ }
+
+ LLVolume *volume = objectp->getVolume();
+ if (volume)
+ {
+ F32 silhouette_thickness;
+ if (isAgentAvatarValid() && is_hud_object)
+ {
+ silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom;
+ }
+ else
+ {
+ LLVector3 view_vector = LLViewerCamera::getInstance()->getOrigin() - objectp->getRenderPosition();
+ silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV());
+ }
+ F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds();
+
+ F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
+ F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f);
+ F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1));
+
+ if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
+ {
+ gGL.flush();
+ gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
gGL.flush();
- gGL.begin(LLRender::LINES);
- {
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
-
- for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2)
- {
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.texCoord2f( u_coord, v_coord );
- gGL.vertex3fv( mSilhouetteVertices[i].mV);
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.texCoord2f( u_coord, v_coord );
- gGL.vertex3fv(mSilhouetteVertices[i+1].mV);
- }
- }
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+
+ for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2)
+ {
+ u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
+ gGL.texCoord2f( u_coord, v_coord );
+ gGL.vertex3fv( mSilhouetteVertices[i].mV);
+ u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
+ gGL.texCoord2f( u_coord, v_coord );
+ gGL.vertex3fv(mSilhouetteVertices[i+1].mV);
+ }
+ }
gGL.end();
- u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
- }
-
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.begin(LLRender::TRIANGLES);
- {
- for(S32 i = 0; i < mSilhouetteVertices.size(); i+=2)
- {
- if (!mSilhouetteNormals[i].isFinite() ||
- !mSilhouetteNormals[i+1].isFinite())
- { //skip skewed segments
- continue;
- }
-
- LLVector3 v[4];
- LLVector2 tc[4];
- v[0] = mSilhouetteVertices[i] + (mSilhouetteNormals[i] * silhouette_thickness);
- tc[0].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale);
-
- v[1] = mSilhouetteVertices[i];
- tc[1].set(u_coord, v_coord);
-
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
-
- v[2] = mSilhouetteVertices[i+1] + (mSilhouetteNormals[i+1] * silhouette_thickness);
- tc[2].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale);
-
- v[3] = mSilhouetteVertices[i+1];
- tc[3].set(u_coord,v_coord);
-
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2fv(tc[0].mV);
- gGL.vertex3fv( v[0].mV );
-
- gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2fv( tc[1].mV );
- gGL.vertex3fv( v[1].mV );
-
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2fv( tc[2].mV );
- gGL.vertex3fv( v[2].mV );
-
- gGL.vertex3fv( v[2].mV );
-
- gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2fv( tc[1].mV );
- gGL.vertex3fv( v[1].mV );
-
- gGL.texCoord2fv( tc[3].mV );
- gGL.vertex3fv( v[3].mV );
- }
- }
- gGL.end();
- gGL.flush();
- }
- gGL.popMatrix();
- gGL.popUIMatrix();
-
- if (shader)
- {
- shader->bind();
- }
+ u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
+ }
+
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ for(S32 i = 0; i < mSilhouetteVertices.size(); i+=2)
+ {
+ if (!mSilhouetteNormals[i].isFinite() ||
+ !mSilhouetteNormals[i+1].isFinite())
+ { //skip skewed segments
+ continue;
+ }
+
+ LLVector3 v[4];
+ LLVector2 tc[4];
+ v[0] = mSilhouetteVertices[i] + (mSilhouetteNormals[i] * silhouette_thickness);
+ tc[0].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale);
+
+ v[1] = mSilhouetteVertices[i];
+ tc[1].set(u_coord, v_coord);
+
+ u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
+
+ v[2] = mSilhouetteVertices[i+1] + (mSilhouetteNormals[i+1] * silhouette_thickness);
+ tc[2].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale);
+
+ v[3] = mSilhouetteVertices[i+1];
+ tc[3].set(u_coord,v_coord);
+
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
+ gGL.texCoord2fv(tc[0].mV);
+ gGL.vertex3fv( v[0].mV );
+
+ gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha);
+ gGL.texCoord2fv( tc[1].mV );
+ gGL.vertex3fv( v[1].mV );
+
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
+ gGL.texCoord2fv( tc[2].mV );
+ gGL.vertex3fv( v[2].mV );
+
+ gGL.vertex3fv( v[2].mV );
+
+ gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha);
+ gGL.texCoord2fv( tc[1].mV );
+ gGL.vertex3fv( v[1].mV );
+
+ gGL.texCoord2fv( tc[3].mV );
+ gGL.vertex3fv( v[3].mV );
+ }
+ }
+ gGL.end();
+ gGL.flush();
+ }
+ gGL.popMatrix();
+ gGL.popUIMatrix();
+
+ if (shader)
+ {
+ shader->bind();
+ }
}
//
@@ -7124,71 +7152,71 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
// *DEPRECATED: See header comment.
void dialog_refresh_all()
{
- // This is the easiest place to fire the update signal, as it will
- // make cleaning up the functions below easier. Also, sometimes entities
- // outside the selection manager change properties of selected objects
- // and call into this function. Yuck.
- LLSelectMgr::getInstance()->mUpdateSignal();
+ // This is the easiest place to fire the update signal, as it will
+ // make cleaning up the functions below easier. Also, sometimes entities
+ // outside the selection manager change properties of selected objects
+ // and call into this function. Yuck.
+ LLSelectMgr::getInstance()->mUpdateSignal();
- // *TODO: Eliminate all calls into outside classes below, make those
- // objects register with the update signal.
+ // *TODO: Eliminate all calls into outside classes below, make those
+ // objects register with the update signal.
- gFloaterTools->dirty();
+ gFloaterTools->dirty();
- gMenuObject->needsArrange();
+ gMenuObject->needsArrange();
- if( gMenuAttachmentSelf->getVisible() )
- {
- gMenuAttachmentSelf->arrange();
- }
- if( gMenuAttachmentOther->getVisible() )
- {
- gMenuAttachmentOther->arrange();
- }
+ if( gMenuAttachmentSelf->getVisible() )
+ {
+ gMenuAttachmentSelf->arrange();
+ }
+ if( gMenuAttachmentOther->getVisible() )
+ {
+ gMenuAttachmentOther->arrange();
+ }
- LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
- if(inspect_instance)
- {
- inspect_instance->dirty();
- }
+ LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
+ if(inspect_instance)
+ {
+ inspect_instance->dirty();
+ }
- LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
- if (panel_task_info)
- {
- panel_task_info->dirty();
- }
+ LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
+ if (panel_task_info)
+ {
+ panel_task_info->dirty();
+ }
}
S32 get_family_count(LLViewerObject *parent)
{
- if (!parent)
- {
- LL_WARNS() << "Trying to get_family_count on null parent!" << LL_ENDL;
- }
- S32 count = 1; // for this object
- LLViewerObject::const_child_list_t& child_list = parent->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
-
- if (!child)
- {
- LL_WARNS() << "Family object has NULL child! Show Doug." << LL_ENDL;
- }
- else if (child->isDead())
- {
- LL_WARNS() << "Family object has dead child object. Show Doug." << LL_ENDL;
- }
- else
- {
- if (LLSelectMgr::getInstance()->canSelectObject(child))
- {
- count += get_family_count( child );
- }
- }
- }
- return count;
+ if (!parent)
+ {
+ LL_WARNS() << "Trying to get_family_count on null parent!" << LL_ENDL;
+ }
+ S32 count = 1; // for this object
+ LLViewerObject::const_child_list_t& child_list = parent->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+
+ if (!child)
+ {
+ LL_WARNS() << "Family object has NULL child! Show Doug." << LL_ENDL;
+ }
+ else if (child->isDead())
+ {
+ LL_WARNS() << "Family object has dead child object. Show Doug." << LL_ENDL;
+ }
+ else
+ {
+ if (LLSelectMgr::getInstance()->canSelectObject(child))
+ {
+ count += get_family_count( child );
+ }
+ }
+ }
+ return count;
}
//-----------------------------------------------------------------------------
@@ -7199,106 +7227,106 @@ S32 get_family_count(LLViewerObject *parent)
// -----------------------------------------------------------------------------
void LLSelectMgr::updateSelectionCenter()
{
- const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
- // center (tractor beam)
+ const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
+ // center (tractor beam)
// override any avatar updates received
// Works only if avatar was repositioned
// and edit floater is visible
overrideAvatarUpdates();
- //override any object updates received
- //for selected objects
- overrideObjectUpdates();
-
- LLViewerObject* object = mSelectedObjects->getFirstObject();
- if (!object)
- {
- // nothing selected, probably grabbing
- // Ignore by setting to avatar origin.
- mSelectionCenterGlobal.clearVec();
- mShowSelection = FALSE;
- mSelectionBBox = LLBBox();
- resetAgentHUDZoom();
- }
- else
- {
- mSelectedObjects->mSelectType = getSelectTypeForObject(object);
-
- if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid())
- {
- // reset hud ZOOM
- resetAgentHUDZoom();
- }
-
- mShowSelection = FALSE;
- LLBBox bbox;
-
- // have stuff selected
- LLVector3d select_center;
- // keep a list of jointed objects for showing the joint HUDEffects
-
- // Initialize the bounding box to the root prim, so the BBox orientation
- // matches the root prim's (affecting the orientation of the manipulators).
- bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() );
-
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object)
- continue;
-
- LLViewerObject *root = object->getRootEdit();
- if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment
- !root->isChild(gAgentAvatarp) && // not the object you're sitting on
- !object->isAvatar()) // not another avatar
- {
- mShowSelection = TRUE;
- }
-
- bbox.addBBoxAgent( object->getBoundingBoxAgent() );
- }
-
- LLVector3 bbox_center_agent = bbox.getCenterAgent();
- mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
- mSelectionBBox = bbox;
-
- }
-
- if ( !(gAgentID == LLUUID::null))
- {
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
- if (mShowSelection)
- {
- LLVector3d select_center_global;
-
- if( tool->isEditing() )
- {
- select_center_global = tool->getEditingPointGlobal();
- }
- else
- {
- select_center_global = mSelectionCenterGlobal;
- }
-
- // Send selection center if moved beyond threshold (used to animate tractor beam)
- LLVector3d diff;
- diff = select_center_global - mLastSentSelectionCenterGlobal;
-
- if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD )
- {
- // Transmit updated selection center
- mLastSentSelectionCenterGlobal = select_center_global;
- }
- }
- }
-
- // give up edit menu if no objects selected
- if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0)
- {
- gEditMenuHandler = NULL;
- }
+ //override any object updates received
+ //for selected objects
+ overrideObjectUpdates();
+
+ LLViewerObject* object = mSelectedObjects->getFirstObject();
+ if (!object)
+ {
+ // nothing selected, probably grabbing
+ // Ignore by setting to avatar origin.
+ mSelectionCenterGlobal.clearVec();
+ mShowSelection = FALSE;
+ mSelectionBBox = LLBBox();
+ resetAgentHUDZoom();
+ }
+ else
+ {
+ mSelectedObjects->mSelectType = getSelectTypeForObject(object);
+
+ if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid())
+ {
+ // reset hud ZOOM
+ resetAgentHUDZoom();
+ }
+
+ mShowSelection = FALSE;
+ LLBBox bbox;
+
+ // have stuff selected
+ LLVector3d select_center;
+ // keep a list of jointed objects for showing the joint HUDEffects
+
+ // Initialize the bounding box to the root prim, so the BBox orientation
+ // matches the root prim's (affecting the orientation of the manipulators).
+ bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() );
+
+ for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ iter != mSelectedObjects->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if (!object)
+ continue;
+
+ LLViewerObject *root = object->getRootEdit();
+ if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment
+ !root->isChild(gAgentAvatarp) && // not the object you're sitting on
+ !object->isAvatar()) // not another avatar
+ {
+ mShowSelection = TRUE;
+ }
+
+ bbox.addBBoxAgent( object->getBoundingBoxAgent() );
+ }
+
+ LLVector3 bbox_center_agent = bbox.getCenterAgent();
+ mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
+ mSelectionBBox = bbox;
+
+ }
+
+ if ( !(gAgentID == LLUUID::null))
+ {
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (mShowSelection)
+ {
+ LLVector3d select_center_global;
+
+ if( tool->isEditing() )
+ {
+ select_center_global = tool->getEditingPointGlobal();
+ }
+ else
+ {
+ select_center_global = mSelectionCenterGlobal;
+ }
+
+ // Send selection center if moved beyond threshold (used to animate tractor beam)
+ LLVector3d diff;
+ diff = select_center_global - mLastSentSelectionCenterGlobal;
+
+ if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD )
+ {
+ // Transmit updated selection center
+ mLastSentSelectionCenterGlobal = select_center_global;
+ }
+ }
+ }
+
+ // give up edit menu if no objects selected
+ if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0)
+ {
+ gEditMenuHandler = NULL;
+ }
pauseAssociatedAvatars();
}
@@ -7321,7 +7349,7 @@ void LLSelectMgr::pauseAssociatedAvatars()
LLViewerObject* object = node->getObject();
if (!object)
continue;
-
+
mSelectedObjects->mSelectType = getSelectTypeForObject(object);
LLVOAvatar* parent_av = NULL;
@@ -7349,40 +7377,40 @@ void LLSelectMgr::pauseAssociatedAvatars()
void LLSelectMgr::updatePointAt()
{
- if (mShowSelection)
- {
- if (mSelectedObjects->getObjectCount())
- {
- LLVector3 select_offset;
- const LLPickInfo& pick = gViewerWindow->getLastPick();
- LLViewerObject *click_object = pick.getObject();
- if (click_object && click_object->isSelected())
- {
- // clicked on another object in our selection group, use that as target
- select_offset.setVec(pick.mObjectOffset);
- select_offset.rotVec(~click_object->getRenderRotation());
-
- gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
- gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
- }
- else
- {
- // didn't click on an object this time, revert to pointing at center of first object
- gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
- gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
- }
- }
- else
- {
- gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
- gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
- }
- }
- else
- {
- gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
- gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
- }
+ if (mShowSelection)
+ {
+ if (mSelectedObjects->getObjectCount())
+ {
+ LLVector3 select_offset;
+ const LLPickInfo& pick = gViewerWindow->getLastPick();
+ LLViewerObject *click_object = pick.getObject();
+ if (click_object && click_object->isSelected())
+ {
+ // clicked on another object in our selection group, use that as target
+ select_offset.setVec(pick.mObjectOffset);
+ select_offset.rotVec(~click_object->getRenderRotation());
+
+ gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
+ gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
+ }
+ else
+ {
+ // didn't click on an object this time, revert to pointing at center of first object
+ gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
+ gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
+ }
+ }
+ else
+ {
+ gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+ gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
+ }
+ }
+ else
+ {
+ gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+ gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
+ }
}
//-----------------------------------------------------------------------------
@@ -7390,7 +7418,7 @@ void LLSelectMgr::updatePointAt()
//-----------------------------------------------------------------------------
LLBBox LLSelectMgr::getBBoxOfSelection() const
{
- return mSelectionBBox;
+ return mSelectionBBox;
}
@@ -7399,8 +7427,8 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::canUndo() const
{
- // Can edit or can move
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstUndoEnabledObject() != NULL; // HACK: casting away constness - MG;
+ // Can edit or can move
+ return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstUndoEnabledObject() != NULL; // HACK: casting away constness - MG;
}
//-----------------------------------------------------------------------------
@@ -7408,9 +7436,9 @@ BOOL LLSelectMgr::canUndo() const
//-----------------------------------------------------------------------------
void LLSelectMgr::undo()
{
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- LLUUID group_id(gAgent.getGroupID());
- sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
+ BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
+ LLUUID group_id(gAgent.getGroupID());
+ sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
}
//-----------------------------------------------------------------------------
@@ -7418,7 +7446,7 @@ void LLSelectMgr::undo()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::canRedo() const
{
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG
+ return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG
}
//-----------------------------------------------------------------------------
@@ -7426,9 +7454,9 @@ BOOL LLSelectMgr::canRedo() const
//-----------------------------------------------------------------------------
void LLSelectMgr::redo()
{
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- LLUUID group_id(gAgent.getGroupID());
- sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
+ BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
+ LLUUID group_id(gAgent.getGroupID());
+ sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, logNoOp, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
}
//-----------------------------------------------------------------------------
@@ -7436,22 +7464,22 @@ void LLSelectMgr::redo()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::canDoDelete() const
{
- bool can_delete = false;
- // This function is "logically const" - it does not change state in
- // a way visible outside the selection manager.
- LLSelectMgr* self = const_cast<LLSelectMgr*>(this);
- LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject();
- // Note: Can only delete root objects (see getFirstDeleteableObject() for more info)
- if (obj!= NULL)
- {
- // all the faces needs to be selected
- if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES ))
- {
- can_delete = true;
- }
- }
-
- return can_delete;
+ bool can_delete = false;
+ // This function is "logically const" - it does not change state in
+ // a way visible outside the selection manager.
+ LLSelectMgr* self = const_cast<LLSelectMgr*>(this);
+ LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject();
+ // Note: Can only delete root objects (see getFirstDeleteableObject() for more info)
+ if (obj!= NULL)
+ {
+ // all the faces needs to be selected
+ if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES ))
+ {
+ can_delete = true;
+ }
+ }
+
+ return can_delete;
}
//-----------------------------------------------------------------------------
@@ -7459,7 +7487,7 @@ BOOL LLSelectMgr::canDoDelete() const
//-----------------------------------------------------------------------------
void LLSelectMgr::doDelete()
{
- selectDelete();
+ selectDelete();
}
//-----------------------------------------------------------------------------
@@ -7467,7 +7495,7 @@ void LLSelectMgr::doDelete()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::canDeselect() const
{
- return !mSelectedObjects->isEmpty();
+ return !mSelectedObjects->isEmpty();
}
//-----------------------------------------------------------------------------
@@ -7475,123 +7503,123 @@ BOOL LLSelectMgr::canDeselect() const
//-----------------------------------------------------------------------------
void LLSelectMgr::deselect()
{
- deselectAll();
+ deselectAll();
}
//-----------------------------------------------------------------------------
// canDuplicate()
//-----------------------------------------------------------------------------
BOOL LLSelectMgr::canDuplicate() const
{
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG
+ return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG
}
//-----------------------------------------------------------------------------
// duplicate()
//-----------------------------------------------------------------------------
void LLSelectMgr::duplicate()
{
- LLVector3 offset(0.5f, 0.5f, 0.f);
- selectDuplicate(offset, TRUE);
+ LLVector3 offset(0.5f, 0.5f, 0.f);
+ selectDuplicate(offset, TRUE);
}
ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object)
{
- if (!object)
- {
- return SELECT_TYPE_WORLD;
- }
- if (object->isHUDAttachment())
- {
- return SELECT_TYPE_HUD;
- }
- else if (object->isAttachment())
- {
- return SELECT_TYPE_ATTACHMENT;
- }
- else
- {
- return SELECT_TYPE_WORLD;
- }
+ if (!object)
+ {
+ return SELECT_TYPE_WORLD;
+ }
+ if (object->isHUDAttachment())
+ {
+ return SELECT_TYPE_HUD;
+ }
+ else if (object->isAttachment())
+ {
+ return SELECT_TYPE_ATTACHMENT;
+ }
+ else
+ {
+ return SELECT_TYPE_WORLD;
+ }
}
void LLSelectMgr::validateSelection()
{
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (!LLSelectMgr::getInstance()->canSelectObject(object))
- {
- LLSelectMgr::getInstance()->deselectObjectOnly(object);
- }
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (!LLSelectMgr::getInstance()->canSelectObject(object))
+ {
+ LLSelectMgr::getInstance()->deselectObjectOnly(object);
+ }
+ return true;
+ }
+ } func;
+ getSelection()->applyToObjects(&func);
}
BOOL LLSelectMgr::canSelectObject(LLViewerObject* object, BOOL ignore_select_owned)
{
- // Never select dead objects
- if (!object || object->isDead())
- {
- return FALSE;
- }
+ // Never select dead objects
+ if (!object || object->isDead())
+ {
+ return FALSE;
+ }
- if (mForceSelection)
- {
- return TRUE;
- }
+ if (mForceSelection)
+ {
+ return TRUE;
+ }
- if(!ignore_select_owned)
- {
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
- (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced())))
- {
- // only select my own objects
- return FALSE;
- }
- }
+ if(!ignore_select_owned)
+ {
+ if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
+ (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced())))
+ {
+ // only select my own objects
+ return FALSE;
+ }
+ }
- // Can't select orphans
- if (object->isOrphaned()) return FALSE;
+ // Can't select orphans
+ if (object->isOrphaned()) return FALSE;
- // Can't select avatars
- if (object->isAvatar()) return FALSE;
+ // Can't select avatars
+ if (object->isAvatar()) return FALSE;
- // Can't select land
- if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE;
+ // Can't select land
+ if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE;
- ESelectType selection_type = getSelectTypeForObject(object);
- if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE;
+ ESelectType selection_type = getSelectTypeForObject(object);
+ if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE;
- return TRUE;
+ return TRUE;
}
-BOOL LLSelectMgr::setForceSelection(BOOL force)
-{
- std::swap(mForceSelection,force);
- return force;
+BOOL LLSelectMgr::setForceSelection(BOOL force)
+{
+ std::swap(mForceSelection,force);
+ return force;
}
void LLSelectMgr::resetAgentHUDZoom()
{
- if (gAgentCamera.mHUDTargetZoom != 1)
- {
- gAgentCamera.mHUDTargetZoom = 1.f;
- gAgentCamera.mHUDCurZoom = 1.f;
- }
+ if (gAgentCamera.mHUDTargetZoom != 1)
+ {
+ gAgentCamera.mHUDTargetZoom = 1.f;
+ gAgentCamera.mHUDCurZoom = 1.f;
+ }
}
void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const
{
- target_zoom = gAgentCamera.mHUDTargetZoom;
- current_zoom = gAgentCamera.mHUDCurZoom;
+ target_zoom = gAgentCamera.mHUDTargetZoom;
+ current_zoom = gAgentCamera.mHUDCurZoom;
}
void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
{
- gAgentCamera.mHUDTargetZoom = target_zoom;
- gAgentCamera.mHUDCurZoom = current_zoom;
+ gAgentCamera.mHUDTargetZoom = target_zoom;
+ gAgentCamera.mHUDCurZoom = current_zoom;
}
/////////////////////////////////////////////////////////////////////////////
@@ -7599,45 +7627,45 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
/////////////////////////////////////////////////////////////////////////////
bool LLObjectSelection::is_root::operator()(LLSelectNode *node)
{
- LLViewerObject* object = node->getObject();
- return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit());
+ LLViewerObject* object = node->getObject();
+ return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit());
}
bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node)
{
- LLViewerObject* object = node->getObject();
- return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit());
+ LLViewerObject* object = node->getObject();
+ return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit());
}
bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node)
{
- LLViewerObject* object = node->getObject();
- return (object != NULL) && (object->isRootEdit());
+ LLViewerObject* object = node->getObject();
+ return (object != NULL) && (object->isRootEdit());
}
-LLObjectSelection::LLObjectSelection() :
- LLRefCount(),
- mSelectType(SELECT_TYPE_WORLD)
+LLObjectSelection::LLObjectSelection() :
+ LLRefCount(),
+ mSelectType(SELECT_TYPE_WORLD)
{
}
LLObjectSelection::~LLObjectSelection()
{
- deleteAllNodes();
+ deleteAllNodes();
}
void LLObjectSelection::cleanupNodes()
{
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); )
- {
- list_t::iterator curiter = iter++;
- LLSelectNode* node = *curiter;
- if (node->getObject() == NULL || node->getObject()->isDead())
- {
- mList.erase(curiter);
- delete node;
- }
- }
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); )
+ {
+ list_t::iterator curiter = iter++;
+ LLSelectNode* node = *curiter;
+ if (node->getObject() == NULL || node->getObject()->isDead())
+ {
+ mList.erase(curiter);
+ delete node;
+ }
+ }
}
void LLObjectSelection::updateEffects()
@@ -7646,56 +7674,56 @@ void LLObjectSelection::updateEffects()
S32 LLObjectSelection::getNumNodes()
{
- return mList.size();
+ return mList.size();
}
void LLObjectSelection::addNode(LLSelectNode *nodep)
{
- llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
- mList.push_front(nodep);
- mSelectNodeMap[nodep->getObject()] = nodep;
+ llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
+ mList.push_front(nodep);
+ mSelectNodeMap[nodep->getObject()] = nodep;
}
void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep)
{
- llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
- mList.push_back(nodep);
- mSelectNodeMap[nodep->getObject()] = nodep;
+ llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
+ mList.push_back(nodep);
+ mSelectNodeMap[nodep->getObject()] = nodep;
}
void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep)
{
- mList.remove(nodep);
- mList.push_front(nodep);
+ mList.remove(nodep);
+ mList.push_front(nodep);
}
void LLObjectSelection::removeNode(LLSelectNode *nodep)
{
- mSelectNodeMap.erase(nodep->getObject());
- if (nodep->getObject() == mPrimaryObject)
- {
- mPrimaryObject = NULL;
- }
- nodep->setObject(NULL); // Will get erased in cleanupNodes()
- mList.remove(nodep);
+ mSelectNodeMap.erase(nodep->getObject());
+ if (nodep->getObject() == mPrimaryObject)
+ {
+ mPrimaryObject = NULL;
+ }
+ nodep->setObject(NULL); // Will get erased in cleanupNodes()
+ mList.remove(nodep);
}
void LLObjectSelection::deleteAllNodes()
{
- std::for_each(mList.begin(), mList.end(), DeletePointer());
- mList.clear();
- mSelectNodeMap.clear();
- mPrimaryObject = NULL;
+ std::for_each(mList.begin(), mList.end(), DeletePointer());
+ mList.clear();
+ mSelectNodeMap.clear();
+ mPrimaryObject = NULL;
}
LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
{
- std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp);
- if (found_it != mSelectNodeMap.end())
- {
- return found_it->second;
- }
- return NULL;
+ std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp);
+ if (found_it != mSelectNodeMap.end())
+ {
+ return found_it->second;
+ }
+ return NULL;
}
//-----------------------------------------------------------------------------
@@ -7703,7 +7731,7 @@ LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
//-----------------------------------------------------------------------------
BOOL LLObjectSelection::isEmpty() const
{
- return (mList.size() == 0);
+ return (mList.size() == 0);
}
@@ -7712,119 +7740,119 @@ BOOL LLObjectSelection::isEmpty() const
//-----------------------------------------------------------------------------
S32 LLObjectSelection::getObjectCount()
{
- cleanupNodes();
- S32 count = mList.size();
+ cleanupNodes();
+ S32 count = mList.size();
- return count;
+ return count;
}
F32 LLObjectSelection::getSelectedObjectCost()
{
- cleanupNodes();
- F32 cost = 0.f;
-
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
+ cleanupNodes();
+ F32 cost = 0.f;
- if (object)
- {
- cost += object->getObjectCost();
- }
- }
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object)
+ {
+ cost += object->getObjectCost();
+ }
+ }
- return cost;
+ return cost;
}
F32 LLObjectSelection::getSelectedLinksetCost()
{
- cleanupNodes();
- F32 cost = 0.f;
-
- std::set<LLViewerObject*> me_roots;
-
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
-
- if (object && !object->isAttachment())
- {
- LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
- if (root)
- {
- if (me_roots.find(root) == me_roots.end())
- {
- me_roots.insert(root);
- cost += root->getLinksetCost();
- }
- }
- }
- }
-
- return cost;
+ cleanupNodes();
+ F32 cost = 0.f;
+
+ std::set<LLViewerObject*> me_roots;
+
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object && !object->isAttachment())
+ {
+ LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
+ if (root)
+ {
+ if (me_roots.find(root) == me_roots.end())
+ {
+ me_roots.insert(root);
+ cost += root->getLinksetCost();
+ }
+ }
+ }
+ }
+
+ return cost;
}
F32 LLObjectSelection::getSelectedPhysicsCost()
{
- cleanupNodes();
- F32 cost = 0.f;
-
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
+ cleanupNodes();
+ F32 cost = 0.f;
- if (object)
- {
- cost += object->getPhysicsCost();
- }
- }
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object)
+ {
+ cost += object->getPhysicsCost();
+ }
+ }
- return cost;
+ return cost;
}
F32 LLObjectSelection::getSelectedLinksetPhysicsCost()
{
- cleanupNodes();
- F32 cost = 0.f;
-
- std::set<LLViewerObject*> me_roots;
-
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
-
- if (object)
- {
- LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
- if (root)
- {
- if (me_roots.find(root) == me_roots.end())
- {
- me_roots.insert(root);
- cost += root->getLinksetPhysicsCost();
- }
- }
- }
- }
-
- return cost;
+ cleanupNodes();
+ F32 cost = 0.f;
+
+ std::set<LLViewerObject*> me_roots;
+
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object)
+ {
+ LLViewerObject* root = static_cast<LLViewerObject*>(object->getRoot());
+ if (root)
+ {
+ if (me_roots.find(root) == me_roots.end())
+ {
+ me_roots.insert(root);
+ cost += root->getLinksetPhysicsCost();
+ }
+ }
+ }
+ }
+
+ return cost;
}
F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* visible_bytes)
{
- F32 cost = 0.f;
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
-
- if (object)
- {
- cost += object->getStreamingCost();
+ F32 cost = 0.f;
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object)
+ {
+ cost += object->getStreamingCost();
S32 bytes = 0;
S32 visible = 0;
@@ -7834,38 +7862,38 @@ F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* vis
bytes = costs.getSizeTotal();
visible = costs.getSizeByLOD(object->getLOD());
}
- if (total_bytes)
- {
- *total_bytes += bytes;
- }
+ if (total_bytes)
+ {
+ *total_bytes += bytes;
+ }
- if (visible_bytes)
- {
- *visible_bytes += visible;
- }
- }
- }
+ if (visible_bytes)
+ {
+ *visible_bytes += visible;
+ }
+ }
+ }
- return cost;
+ return cost;
}
U32 LLObjectSelection::getSelectedObjectTriangleCount(S32* vcount)
{
- U32 count = 0;
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
+ U32 count = 0;
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+
+ if (object)
+ {
+ S32 vt = 0;
+ count += object->getTriangleCount(&vt);
+ *vcount += vt;
+ }
+ }
- if (object)
- {
- S32 vt = 0;
- count += object->getTriangleCount(&vt);
- *vcount += vt;
- }
- }
-
- return count;
+ return count;
}
S32 LLObjectSelection::getSelectedObjectRenderCost()
@@ -7875,65 +7903,65 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
typedef std::set<LLUUID> uuid_list_t;
uuid_list_t computed_objects;
- typedef std::list<LLPointer<LLViewerObject> > child_list_t;
- typedef const child_list_t const_child_list_t;
+ typedef std::list<LLPointer<LLViewerObject> > child_list_t;
+ typedef const child_list_t const_child_list_t;
- // add render cost of complete linksets first, to get accurate texture counts
+ // add render cost of complete linksets first, to get accurate texture counts
for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
{
LLSelectNode* node = *iter;
-
+
LLVOVolume* object = (LLVOVolume*)node->getObject();
if (object && object->isRootEdit())
{
- cost += object->getRenderCost(textures);
- computed_objects.insert(object->getID());
-
- const_child_list_t children = object->getChildren();
- for (const_child_list_t::const_iterator child_iter = children.begin();
- child_iter != children.end();
- ++child_iter)
- {
- LLViewerObject* child_obj = *child_iter;
- LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
- if (child)
- {
- cost += child->getRenderCost(textures);
- computed_objects.insert(child->getID());
- }
- }
-
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += LLVOVolume::getTextureCost(*iter);
- }
-
- textures.clear();
+ cost += object->getRenderCost(textures);
+ computed_objects.insert(object->getID());
+
+ const_child_list_t children = object->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
+ {
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
+ if (child)
+ {
+ cost += child->getRenderCost(textures);
+ computed_objects.insert(child->getID());
+ }
+ }
+
+ for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
+ {
+ // add the cost of each individual texture in the linkset
+ cost += LLVOVolume::getTextureCost(*iter);
+ }
+
+ textures.clear();
}
}
-
- // add any partial linkset objects, texture cost may be slightly misleading
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = (LLVOVolume*)node->getObject();
-
- if (object && computed_objects.find(object->getID()) == computed_objects.end() )
- {
- cost += object->getRenderCost(textures);
- computed_objects.insert(object->getID());
- }
-
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += LLVOVolume::getTextureCost(*iter);
- }
-
- textures.clear();
- }
+
+ // add any partial linkset objects, texture cost may be slightly misleading
+ for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = (LLVOVolume*)node->getObject();
+
+ if (object && computed_objects.find(object->getID()) == computed_objects.end() )
+ {
+ cost += object->getRenderCost(textures);
+ computed_objects.insert(object->getID());
+ }
+
+ for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
+ {
+ // add the cost of each individual texture in the linkset
+ cost += LLVOVolume::getTextureCost(*iter);
+ }
+
+ textures.clear();
+ }
return cost;
}
@@ -7943,23 +7971,23 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
//-----------------------------------------------------------------------------
S32 LLObjectSelection::getTECount()
{
- S32 count = 0;
- for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object)
- continue;
- S32 num_tes = object->getNumTEs();
- for (S32 te = 0; te < num_tes; te++)
- {
- if (node->isTESelected(te))
- {
- ++count;
- }
- }
- }
- return count;
+ S32 count = 0;
+ for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if (!object)
+ continue;
+ S32 num_tes = object->getNumTEs();
+ for (S32 te = 0; te < num_tes; te++)
+ {
+ if (node->isTESelected(te))
+ {
+ ++count;
+ }
+ }
+ }
+ return count;
}
//-----------------------------------------------------------------------------
@@ -7967,27 +7995,27 @@ S32 LLObjectSelection::getTECount()
//-----------------------------------------------------------------------------
S32 LLObjectSelection::getRootObjectCount()
{
- S32 count = 0;
- for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++)
- {
- ++count;
- }
- return count;
+ S32 count = 0;
+ for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++)
+ {
+ ++count;
+ }
+ return count;
}
bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func)
{
- bool result = true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- bool r = func->apply(object);
- result = result && r;
- }
- return result;
+ bool result = true;
+ for (iterator iter = begin(); iter != end(); )
+ {
+ iterator nextiter = iter++;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ bool r = func->apply(object);
+ result = result && r;
+ }
+ return result;
}
bool LLObjectSelection::checkAnimatedObjectEstTris()
@@ -7995,19 +8023,19 @@ bool LLObjectSelection::checkAnimatedObjectEstTris()
F32 est_tris = 0;
F32 max_tris = 0;
S32 anim_count = 0;
- for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
- {
- LLViewerObject* object = (*iter)->getObject();
- if (!object)
- continue;
+ for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
+ {
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ continue;
if (object->isAnimatedObject())
{
anim_count++;
}
est_tris += object->recursiveGetEstTrianglesMax();
max_tris = llmax((F32)max_tris,(F32)object->getAnimatedObjectMaxTris());
- }
- return anim_count==0 || est_tris <= max_tris;
+ }
+ return anim_count==0 || est_tris <= max_tris;
}
bool LLObjectSelection::checkAnimatedObjectLinkable()
@@ -8017,101 +8045,101 @@ bool LLObjectSelection::checkAnimatedObjectLinkable()
bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly)
{
- bool result = firstonly ? false : true;
- for (root_iterator iter = root_begin(); iter != root_end(); )
- {
- root_iterator nextiter = iter++;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- bool r = func->apply(object);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
+ bool result = firstonly ? false : true;
+ for (root_iterator iter = root_begin(); iter != root_end(); )
+ {
+ root_iterator nextiter = iter++;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ bool r = func->apply(object);
+ if (firstonly && r)
+ return true;
+ else
+ result = result && r;
+ }
+ return result;
}
bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly)
{
- bool result = firstonly ? false : true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces
- for (S32 te = 0; te < num_tes; ++te)
- {
- if (node->isTESelected(te))
- {
- bool r = func->apply(object, te);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- }
- }
- return result;
+ bool result = firstonly ? false : true;
+ for (iterator iter = begin(); iter != end(); )
+ {
+ iterator nextiter = iter++;
+ LLSelectNode* node = *nextiter;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ bool r = func->apply(object, te);
+ if (firstonly && r)
+ return true;
+ else
+ result = result && r;
+ }
+ }
+ }
+ return result;
}
bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly)
{
- bool result = firstonly ? false : true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- bool r = func->apply(node);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
+ bool result = firstonly ? false : true;
+ for (iterator iter = begin(); iter != end(); )
+ {
+ iterator nextiter = iter++;
+ LLSelectNode* node = *nextiter;
+ bool r = func->apply(node);
+ if (firstonly && r)
+ return true;
+ else
+ result = result && r;
+ }
+ return result;
}
bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly)
{
- bool result = firstonly ? false : true;
- for (root_iterator iter = root_begin(); iter != root_end(); )
- {
- root_iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- bool r = func->apply(node);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
+ bool result = firstonly ? false : true;
+ for (root_iterator iter = root_begin(); iter != root_end(); )
+ {
+ root_iterator nextiter = iter++;
+ LLSelectNode* node = *nextiter;
+ bool r = func->apply(node);
+ if (firstonly && r)
+ return true;
+ else
+ result = result && r;
+ }
+ return result;
}
BOOL LLObjectSelection::isMultipleTESelected()
{
- BOOL te_selected = FALSE;
- // ...all faces
- for (LLObjectSelection::iterator iter = begin();
- iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- for (S32 i = 0; i < SELECT_MAX_TES; i++)
- {
- if(nodep->isTESelected(i))
- {
- if(te_selected)
- {
- return TRUE;
- }
- te_selected = TRUE;
- }
- }
- }
- return FALSE;
+ BOOL te_selected = FALSE;
+ // ...all faces
+ for (LLObjectSelection::iterator iter = begin();
+ iter != end(); iter++)
+ {
+ LLSelectNode* nodep = *iter;
+ for (S32 i = 0; i < SELECT_MAX_TES; i++)
+ {
+ if(nodep->isTESelected(i))
+ {
+ if(te_selected)
+ {
+ return TRUE;
+ }
+ te_selected = TRUE;
+ }
+ }
+ }
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -8119,7 +8147,7 @@ BOOL LLObjectSelection::isMultipleTESelected()
//-----------------------------------------------------------------------------
BOOL LLObjectSelection::contains(LLViewerObject* object)
{
- return findNode(object) != NULL;
+ return findNode(object) != NULL;
}
@@ -8128,50 +8156,50 @@ BOOL LLObjectSelection::contains(LLViewerObject* object)
//-----------------------------------------------------------------------------
BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
{
- if (te == SELECT_ALL_TES)
- {
- // ...all faces
- for (LLObjectSelection::iterator iter = begin();
- iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object)
- {
- // Optimization
- if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL)
- {
- return TRUE;
- }
-
- BOOL all_selected = TRUE;
- for (S32 i = 0; i < object->getNumTEs(); i++)
- {
- all_selected = all_selected && nodep->isTESelected(i);
- }
- return all_selected;
- }
- }
- return FALSE;
- }
- else
- {
- // ...one face
- for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object && nodep->isTESelected(te))
- {
- return TRUE;
- }
- }
- return FALSE;
- }
+ if (te == SELECT_ALL_TES)
+ {
+ // ...all faces
+ for (LLObjectSelection::iterator iter = begin();
+ iter != end(); iter++)
+ {
+ LLSelectNode* nodep = *iter;
+ if (nodep->getObject() == object)
+ {
+ // Optimization
+ if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL)
+ {
+ return TRUE;
+ }
+
+ BOOL all_selected = TRUE;
+ for (S32 i = 0; i < object->getNumTEs(); i++)
+ {
+ all_selected = all_selected && nodep->isTESelected(i);
+ }
+ return all_selected;
+ }
+ }
+ return FALSE;
+ }
+ else
+ {
+ // ...one face
+ for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
+ {
+ LLSelectNode* nodep = *iter;
+ if (nodep->getObject() == object && nodep->isTESelected(te))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
}
// returns TRUE is any node is currenly worn as an attachment
BOOL LLObjectSelection::isAttachment()
{
- return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD);
+ return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD);
}
//-----------------------------------------------------------------------------
@@ -8179,19 +8207,19 @@ BOOL LLObjectSelection::isAttachment()
//-----------------------------------------------------------------------------
LLViewerObject* getSelectedParentObject(LLViewerObject *object)
{
- LLViewerObject *parent;
- while (object && (parent = (LLViewerObject*)object->getParent()))
- {
- if (parent->isSelected())
- {
- object = parent;
- }
- else
- {
- break;
- }
- }
- return object;
+ LLViewerObject *parent;
+ while (object && (parent = (LLViewerObject*)object->getParent()))
+ {
+ if (parent->isSelected())
+ {
+ object = parent;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return object;
}
//-----------------------------------------------------------------------------
@@ -8199,33 +8227,33 @@ LLViewerObject* getSelectedParentObject(LLViewerObject *object)
//-----------------------------------------------------------------------------
LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func)
{
- for (iterator iter = begin(); iter != end(); ++iter)
- {
- LLSelectNode* node = *iter;
- if (func == NULL || func->apply(node))
- {
- return node;
- }
- }
- return NULL;
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ if (func == NULL || func->apply(node))
+ {
+ return node;
+ }
+ }
+ return NULL;
}
LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok)
{
- for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
- {
- LLSelectNode* node = *iter;
- if (func == NULL || func->apply(node))
- {
- return node;
- }
- }
- if (non_root_ok)
- {
- // Get non root
- return getFirstNode(func);
- }
- return NULL;
+ for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ if (func == NULL || func->apply(node))
+ {
+ return node;
+ }
+ }
+ if (non_root_ok)
+ {
+ // Get non root
+ return getFirstNode(func);
+ }
+ return NULL;
}
@@ -8234,16 +8262,16 @@ LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, B
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent)
{
- LLSelectNode* res = getFirstNode(func);
- if (res && get_parent)
- {
- return getSelectedParentObject(res->getObject());
- }
- else if (res)
- {
- return res->getObject();
- }
- return NULL;
+ LLSelectNode* res = getFirstNode(func);
+ if (res && get_parent)
+ {
+ return getSelectedParentObject(res->getObject());
+ }
+ else if (res)
+ {
+ return res->getObject();
+ }
+ return NULL;
}
//-----------------------------------------------------------------------------
@@ -8251,8 +8279,8 @@ LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor*
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstObject()
{
- LLSelectNode* res = getFirstNode(NULL);
- return res ? res->getObject() : NULL;
+ LLSelectNode* res = getFirstNode(NULL);
+ return res ? res->getObject() : NULL;
}
//-----------------------------------------------------------------------------
@@ -8260,8 +8288,8 @@ LLViewerObject* LLObjectSelection::getFirstObject()
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok)
{
- LLSelectNode* res = getFirstRootNode(NULL, non_root_ok);
- return res ? res->getObject() : NULL;
+ LLSelectNode* res = getFirstRootNode(NULL, non_root_ok);
+ return res ? res->getObject() : NULL;
}
//-----------------------------------------------------------------------------
@@ -8269,16 +8297,16 @@ LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok)
//-----------------------------------------------------------------------------
LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
{
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permMove() && !obj->isPermanentEnforced();
- }
- } func;
- LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
- return res;
+ struct f : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ return obj && obj->permMove() && !obj->isPermanentEnforced();
+ }
+ } func;
+ LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
+ return res;
}
//-----------------------------------------------------------------------------
@@ -8286,15 +8314,15 @@ LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent)
{
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permCopy() && !obj->isAttachment();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
+ struct f : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ return obj && obj->permCopy() && !obj->isAttachment();
+ }
+ } func;
+ return getFirstSelectedObject(&func, get_parent);
}
//-----------------------------------------------------------------------------
@@ -8302,31 +8330,31 @@ LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent)
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
{
- //RN: don't currently support deletion of child objects, as that requires separating them first
- // then derezzing to trash
-
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- // you can delete an object if you are the owner
- // or you have permission to modify it.
- if( obj && !obj->isPermanentEnforced() &&
- ( (obj->permModify()) ||
- (obj->permYouOwner()) ||
- (!obj->permAnyOwner()) )) // public
- {
- if( !obj->isAttachment() )
- {
- return true;
- }
- }
- return false;
- }
- } func;
- LLSelectNode* node = getFirstNode(&func);
- return node ? node->getObject() : NULL;
+ //RN: don't currently support deletion of child objects, as that requires separating them first
+ // then derezzing to trash
+
+ struct f : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ // you can delete an object if you are the owner
+ // or you have permission to modify it.
+ if( obj && !obj->isPermanentEnforced() &&
+ ( (obj->permModify()) ||
+ (obj->permYouOwner()) ||
+ (!obj->permAnyOwner()) )) // public
+ {
+ if( !obj->isAttachment() )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ } func;
+ LLSelectNode* node = getFirstNode(&func);
+ return node ? node->getObject() : NULL;
}
//-----------------------------------------------------------------------------
@@ -8334,15 +8362,15 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent)
{
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permModify();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
+ struct f : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ return obj && obj->permModify();
+ }
+ } func;
+ return getFirstSelectedObject(&func, get_parent);
}
//-----------------------------------------------------------------------------
@@ -8350,15 +8378,15 @@ LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent)
//-----------------------------------------------------------------------------
LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)
{
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permMove() && !obj->isPermanentEnforced();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
+ struct f : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ return obj && obj->permMove() && !obj->isPermanentEnforced();
+ }
+ } func;
+ return getFirstSelectedObject(&func, get_parent);
}
//-----------------------------------------------------------------------------
@@ -8383,196 +8411,196 @@ LLViewerObject* LLObjectSelection::getFirstUndoEnabledObject(BOOL get_parent)
bool LLSelectMgr::selectionMove(const LLVector3& displ,
F32 roll, F32 pitch, F32 yaw, U32 update_type)
{
- if (update_type == UPD_NONE)
- {
- return false;
- }
-
- LLVector3 displ_global;
- bool update_success = true;
- bool update_position = update_type & UPD_POSITION;
- bool update_rotation = update_type & UPD_ROTATION;
- const bool noedit_linked_parts = !gSavedSettings.getBOOL("EditLinkedParts");
-
- if (update_position)
- {
- // calculate the distance of the object closest to the camera origin
- F32 min_dist_squared = F32_MAX; // value will be overridden in the loop
-
- LLVector3 obj_pos;
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it)
- {
- obj_pos = (*it)->getObject()->getPositionEdit();
-
- F32 obj_dist_squared = dist_vec_squared(obj_pos, LLViewerCamera::getInstance()->getOrigin());
- if (obj_dist_squared < min_dist_squared)
- {
- min_dist_squared = obj_dist_squared;
- }
- }
-
- // factor the distance into the displacement vector. This will get us
- // equally visible movements for both close and far away selections.
- F32 min_dist = sqrt((F32) sqrtf(min_dist_squared)) / 2;
- displ_global.setVec(displ.mV[0] * min_dist,
- displ.mV[1] * min_dist,
- displ.mV[2] * min_dist);
-
- // equates to: Displ_global = Displ * M_cam_axes_in_global_frame
- displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global);
- }
-
- LLQuaternion new_rot;
- if (update_rotation)
- {
- // let's calculate the rotation around each camera axes
- LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis());
- LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis());
- LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis());
- new_rot.setQuat(qx * qy * qz);
- }
-
- LLViewerObject *obj;
- S32 obj_count = getSelection()->getObjectCount();
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it )
- {
- obj = (*it)->getObject();
- bool enable_pos = false, enable_rot = false;
- bool perm_move = obj->permMove() && !obj->isPermanentEnforced();
- bool perm_mod = obj->permModify();
-
- LLVector3d sel_center(getSelectionCenterGlobal());
-
- if (update_rotation)
- {
- enable_rot = perm_move
- && ((perm_mod && !obj->isAttachment()) || noedit_linked_parts);
-
- if (enable_rot)
- {
- int children_count = obj->getChildren().size();
- if (obj_count > 1 && children_count > 0)
- {
- // for linked sets, rotate around the group center
- const LLVector3 t(obj->getPositionGlobal() - sel_center);
-
- // Ra = T x R x T^-1
- LLMatrix4 mt; mt.setTranslation(t);
- const LLMatrix4 mnew_rot(new_rot);
- LLMatrix4 mt_1; mt_1.setTranslation(-t);
- mt *= mnew_rot;
- mt *= mt_1;
-
- // Rfin = Rcur * Ra
- obj->setRotation(obj->getRotationEdit() * mt.quaternion());
- displ_global += mt.getTranslation();
- }
- else
- {
- obj->setRotation(obj->getRotationEdit() * new_rot);
- }
- }
- else
- {
- update_success = false;
- }
- }
-
- if (update_position)
- {
- // establish if object can be moved or not
- enable_pos = perm_move && !obj->isAttachment()
- && (perm_mod || noedit_linked_parts);
-
- if (enable_pos)
- {
- obj->setPosition(obj->getPositionEdit() + displ_global);
- }
- else
- {
- update_success = false;
- }
- }
-
- if (enable_pos && enable_rot && obj->mDrawable.notNull())
- {
- gPipeline.markMoved(obj->mDrawable, TRUE);
- }
- }
-
- if (update_position && update_success && obj_count > 1)
- {
- updateSelectionCenter();
- }
-
- return update_success;
+ if (update_type == UPD_NONE)
+ {
+ return false;
+ }
+
+ LLVector3 displ_global;
+ bool update_success = true;
+ bool update_position = update_type & UPD_POSITION;
+ bool update_rotation = update_type & UPD_ROTATION;
+ const bool noedit_linked_parts = !gSavedSettings.getBOOL("EditLinkedParts");
+
+ if (update_position)
+ {
+ // calculate the distance of the object closest to the camera origin
+ F32 min_dist_squared = F32_MAX; // value will be overridden in the loop
+
+ LLVector3 obj_pos;
+ for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
+ it != getSelection()->root_end(); ++it)
+ {
+ obj_pos = (*it)->getObject()->getPositionEdit();
+
+ F32 obj_dist_squared = dist_vec_squared(obj_pos, LLViewerCamera::getInstance()->getOrigin());
+ if (obj_dist_squared < min_dist_squared)
+ {
+ min_dist_squared = obj_dist_squared;
+ }
+ }
+
+ // factor the distance into the displacement vector. This will get us
+ // equally visible movements for both close and far away selections.
+ F32 min_dist = sqrt((F32) sqrtf(min_dist_squared)) / 2;
+ displ_global.setVec(displ.mV[0] * min_dist,
+ displ.mV[1] * min_dist,
+ displ.mV[2] * min_dist);
+
+ // equates to: Displ_global = Displ * M_cam_axes_in_global_frame
+ displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global);
+ }
+
+ LLQuaternion new_rot;
+ if (update_rotation)
+ {
+ // let's calculate the rotation around each camera axes
+ LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis());
+ LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis());
+ LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis());
+ new_rot.setQuat(qx * qy * qz);
+ }
+
+ LLViewerObject *obj;
+ S32 obj_count = getSelection()->getObjectCount();
+ for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
+ it != getSelection()->root_end(); ++it )
+ {
+ obj = (*it)->getObject();
+ bool enable_pos = false, enable_rot = false;
+ bool perm_move = obj->permMove() && !obj->isPermanentEnforced();
+ bool perm_mod = obj->permModify();
+
+ LLVector3d sel_center(getSelectionCenterGlobal());
+
+ if (update_rotation)
+ {
+ enable_rot = perm_move
+ && ((perm_mod && !obj->isAttachment()) || noedit_linked_parts);
+
+ if (enable_rot)
+ {
+ int children_count = obj->getChildren().size();
+ if (obj_count > 1 && children_count > 0)
+ {
+ // for linked sets, rotate around the group center
+ const LLVector3 t(obj->getPositionGlobal() - sel_center);
+
+ // Ra = T x R x T^-1
+ LLMatrix4 mt; mt.setTranslation(t);
+ const LLMatrix4 mnew_rot(new_rot);
+ LLMatrix4 mt_1; mt_1.setTranslation(-t);
+ mt *= mnew_rot;
+ mt *= mt_1;
+
+ // Rfin = Rcur * Ra
+ obj->setRotation(obj->getRotationEdit() * mt.quaternion());
+ displ_global += mt.getTranslation();
+ }
+ else
+ {
+ obj->setRotation(obj->getRotationEdit() * new_rot);
+ }
+ }
+ else
+ {
+ update_success = false;
+ }
+ }
+
+ if (update_position)
+ {
+ // establish if object can be moved or not
+ enable_pos = perm_move && !obj->isAttachment()
+ && (perm_mod || noedit_linked_parts);
+
+ if (enable_pos)
+ {
+ obj->setPosition(obj->getPositionEdit() + displ_global);
+ }
+ else
+ {
+ update_success = false;
+ }
+ }
+
+ if (enable_pos && enable_rot && obj->mDrawable.notNull())
+ {
+ gPipeline.markMoved(obj->mDrawable, TRUE);
+ }
+ }
+
+ if (update_position && update_success && obj_count > 1)
+ {
+ updateSelectionCenter();
+ }
+
+ return update_success;
}
void LLSelectMgr::sendSelectionMove()
{
- LLSelectNode *node = mSelectedObjects->getFirstRootNode();
- if (node == NULL)
- {
- return;
- }
-
- //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
-
- U32 update_type = UPD_POSITION | UPD_ROTATION;
- LLViewerRegion *last_region, *curr_region = node->getObject()->getRegion();
- S32 objects_in_this_packet = 0;
-
- // apply to linked objects if unable to select their individual parts
- if (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode())
- {
- // tell simulator to apply to whole linked sets
- update_type |= UPD_LINKED_SETS;
- }
-
- // prepare first bulk message
- gMessageSystem->newMessage("MultipleObjectUpdate");
- packAgentAndSessionID(&update_type);
-
- LLViewerObject *obj = NULL;
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it)
- {
- obj = (*it)->getObject();
-
- // note: following code adapted from sendListToRegions() (@3924)
- last_region = curr_region;
- curr_region = obj->getRegion();
-
- // if not simulator or message too big
- if (curr_region != last_region
- || gMessageSystem->isSendFull(NULL)
- || objects_in_this_packet >= MAX_OBJECTS_PER_PACKET)
- {
- // send sim the current message and start new one
- gMessageSystem->sendReliable(last_region->getHost());
- objects_in_this_packet = 0;
- gMessageSystem->newMessage("MultipleObjectUpdate");
- packAgentAndSessionID(&update_type);
- }
-
- // add another instance of the body of data
- packMultipleUpdate(*it, &update_type);
- ++objects_in_this_packet;
- }
-
- // flush remaining messages
- if (gMessageSystem->getCurrentSendTotal() > 0)
- {
- gMessageSystem->sendReliable(curr_region->getHost());
- }
- else
- {
- gMessageSystem->clearMessage();
- }
-
- //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+ LLSelectNode *node = mSelectedObjects->getFirstRootNode();
+ if (node == NULL)
+ {
+ return;
+ }
+
+ //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
+
+ U32 update_type = UPD_POSITION | UPD_ROTATION;
+ LLViewerRegion *last_region, *curr_region = node->getObject()->getRegion();
+ S32 objects_in_this_packet = 0;
+
+ // apply to linked objects if unable to select their individual parts
+ if (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode())
+ {
+ // tell simulator to apply to whole linked sets
+ update_type |= UPD_LINKED_SETS;
+ }
+
+ // prepare first bulk message
+ gMessageSystem->newMessage("MultipleObjectUpdate");
+ packAgentAndSessionID(&update_type);
+
+ LLViewerObject *obj = NULL;
+ for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
+ it != getSelection()->root_end(); ++it)
+ {
+ obj = (*it)->getObject();
+
+ // note: following code adapted from sendListToRegions() (@3924)
+ last_region = curr_region;
+ curr_region = obj->getRegion();
+
+ // if not simulator or message too big
+ if (curr_region != last_region
+ || gMessageSystem->isSendFull(NULL)
+ || objects_in_this_packet >= MAX_OBJECTS_PER_PACKET)
+ {
+ // send sim the current message and start new one
+ gMessageSystem->sendReliable(last_region->getHost());
+ objects_in_this_packet = 0;
+ gMessageSystem->newMessage("MultipleObjectUpdate");
+ packAgentAndSessionID(&update_type);
+ }
+
+ // add another instance of the body of data
+ packMultipleUpdate(*it, &update_type);
+ ++objects_in_this_packet;
+ }
+
+ // flush remaining messages
+ if (gMessageSystem->getCurrentSendTotal() > 0)
+ {
+ gMessageSystem->sendReliable(curr_region->getHost());
+ }
+ else
+ {
+ gMessageSystem->clearMessage();
+ }
+
+ //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
}
template<>
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 1ce53fe149..66c794af4c 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llselectmgr.h
* @brief A manager for selected objects and TEs.
*
* $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$
*/
@@ -42,13 +42,13 @@
#include "llbbox.h"
#include "llpermissions.h"
#include "llcontrol.h"
-#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template
+#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template
#include "llmaterial.h"
#include <deque>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/signals2.hpp>
-#include <boost/make_shared.hpp> // boost::make_shared
+#include <boost/make_shared.hpp> // boost::make_shared
class LLMessageSystem;
class LLViewerTexture;
@@ -56,30 +56,30 @@ class LLColor4;
class LLVector3;
class LLSelectNode;
-const U8 UPD_NONE = 0x00;
-const U8 UPD_POSITION = 0x01;
-const U8 UPD_ROTATION = 0x02;
-const U8 UPD_SCALE = 0x04;
-const U8 UPD_LINKED_SETS = 0x08;
-const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE
+const U8 UPD_NONE = 0x00;
+const U8 UPD_POSITION = 0x01;
+const U8 UPD_ROTATION = 0x02;
+const U8 UPD_SCALE = 0x04;
+const U8 UPD_LINKED_SETS = 0x08;
+const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE
// This is used by the DeRezObject message to determine where to put
// derezed tasks.
enum EDeRezDestination
{
- DRD_SAVE_INTO_AGENT_INVENTORY = 0,
- DRD_ACQUIRE_TO_AGENT_INVENTORY = 1, // try to leave copy in world
- DRD_SAVE_INTO_TASK_INVENTORY = 2,
- DRD_ATTACHMENT = 3,
- DRD_TAKE_INTO_AGENT_INVENTORY = 4, // delete from world
- DRD_FORCE_TO_GOD_INVENTORY = 5, // force take copy
- DRD_TRASH = 6,
- DRD_ATTACHMENT_TO_INV = 7,
- DRD_ATTACHMENT_EXISTS = 8,
- DRD_RETURN_TO_OWNER = 9, // back to owner's inventory
- DRD_RETURN_TO_LAST_OWNER = 10, // deeded object back to last owner's inventory
-
- DRD_COUNT = 11
+ DRD_SAVE_INTO_AGENT_INVENTORY = 0,
+ DRD_ACQUIRE_TO_AGENT_INVENTORY = 1, // try to leave copy in world
+ DRD_SAVE_INTO_TASK_INVENTORY = 2,
+ DRD_ATTACHMENT = 3,
+ DRD_TAKE_INTO_AGENT_INVENTORY = 4, // delete from world
+ DRD_FORCE_TO_GOD_INVENTORY = 5, // force take copy
+ DRD_TRASH = 6,
+ DRD_ATTACHMENT_TO_INV = 7,
+ DRD_ATTACHMENT_EXISTS = 8,
+ DRD_RETURN_TO_OWNER = 9, // back to owner's inventory
+ DRD_RETURN_TO_LAST_OWNER = 10, // deeded object back to last owner's inventory
+
+ DRD_COUNT = 11
};
@@ -92,8 +92,8 @@ const S32 SELECT_MAX_TES = 32;
// the operation was successful.
struct LLSelectedObjectFunctor
{
- virtual ~LLSelectedObjectFunctor() {};
- virtual bool apply(LLViewerObject* object) = 0;
+ virtual ~LLSelectedObjectFunctor() {};
+ virtual bool apply(LLViewerObject* object) = 0;
};
// Do something to all select nodes in the selection manager.
@@ -102,63 +102,63 @@ struct LLSelectedObjectFunctor
// the operation was successful.
struct LLSelectedNodeFunctor
{
- virtual ~LLSelectedNodeFunctor() {};
- virtual bool apply(LLSelectNode* node) = 0;
+ virtual ~LLSelectedNodeFunctor() {};
+ virtual bool apply(LLSelectNode* node) = 0;
};
struct LLSelectedTEFunctor
{
- virtual ~LLSelectedTEFunctor() {};
- virtual bool apply(LLViewerObject* object, S32 face) = 0;
+ virtual ~LLSelectedTEFunctor() {};
+ virtual bool apply(LLViewerObject* object, S32 face) = 0;
};
struct LLSelectedTEMaterialFunctor
{
- virtual ~LLSelectedTEMaterialFunctor() {};
- virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0;
+ virtual ~LLSelectedTEMaterialFunctor() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0;
};
template <typename T> struct LLSelectedTEGetFunctor
{
- virtual ~LLSelectedTEGetFunctor() {};
- virtual T get(LLViewerObject* object, S32 te) = 0;
+ virtual ~LLSelectedTEGetFunctor() {};
+ virtual T get(LLViewerObject* object, S32 te) = 0;
};
template <typename T> struct LLCheckIdenticalFunctor
{
- static bool same(const T& a, const T& b, const T& tolerance);
+ static bool same(const T& a, const T& b, const T& tolerance);
};
typedef enum e_send_type
{
- SEND_ONLY_ROOTS,
- SEND_INDIVIDUALS,
- SEND_ROOTS_FIRST, // useful for serial undos on linked sets
- SEND_CHILDREN_FIRST // useful for serial transforms of linked sets
+ SEND_ONLY_ROOTS,
+ SEND_INDIVIDUALS,
+ SEND_ROOTS_FIRST, // useful for serial undos on linked sets
+ SEND_CHILDREN_FIRST // useful for serial transforms of linked sets
} ESendType;
typedef enum e_grid_mode
{
- GRID_MODE_WORLD,
- GRID_MODE_LOCAL,
- GRID_MODE_REF_OBJECT
+ GRID_MODE_WORLD,
+ GRID_MODE_LOCAL,
+ GRID_MODE_REF_OBJECT
} EGridMode;
typedef enum e_action_type
{
- SELECT_ACTION_TYPE_BEGIN,
- SELECT_ACTION_TYPE_PICK,
- SELECT_ACTION_TYPE_MOVE,
- SELECT_ACTION_TYPE_ROTATE,
- SELECT_ACTION_TYPE_SCALE,
- NUM_ACTION_TYPES
+ SELECT_ACTION_TYPE_BEGIN,
+ SELECT_ACTION_TYPE_PICK,
+ SELECT_ACTION_TYPE_MOVE,
+ SELECT_ACTION_TYPE_ROTATE,
+ SELECT_ACTION_TYPE_SCALE,
+ NUM_ACTION_TYPES
}EActionType;
typedef enum e_selection_type
{
- SELECT_TYPE_WORLD,
- SELECT_TYPE_ATTACHMENT,
- SELECT_TYPE_HUD
+ SELECT_TYPE_WORLD,
+ SELECT_TYPE_ATTACHMENT,
+ SELECT_TYPE_HUD
}ESelectType;
typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t;
@@ -169,28 +169,29 @@ const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
class LLSelectNode
{
public:
- LLSelectNode(LLViewerObject* object, BOOL do_glow);
- LLSelectNode(const LLSelectNode& nodep);
- ~LLSelectNode();
-
- void selectAllTEs(BOOL b);
- void selectTE(S32 te_index, BOOL selected);
- BOOL isTESelected(S32 te_index) const;
- bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; }
- S32 getLastSelectedTE() const;
- S32 getLastOperatedTE() const { return mLastTESelected; }
- S32 getTESelectMask() { return mTESelectMask; }
- void renderOneSilhouette(const LLColor4 &color);
- void setTransient(BOOL transient) { mTransient = transient; }
- BOOL isTransient() const { return mTransient; }
- LLViewerObject* getObject();
- void setObject(LLViewerObject* object);
- // *NOTE: invalidate stored textures and colors when # faces change
+ LLSelectNode(LLViewerObject* object, BOOL do_glow);
+ LLSelectNode(const LLSelectNode& nodep);
+ ~LLSelectNode();
+
+ void selectAllTEs(BOOL b);
+ void selectTE(S32 te_index, BOOL selected);
+ void selectGLTFNode(S32 node_index, S32 primitive_index, bool selected);
+ BOOL isTESelected(S32 te_index) const;
+ bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; }
+ S32 getLastSelectedTE() const;
+ S32 getLastOperatedTE() const { return mLastTESelected; }
+ S32 getTESelectMask() { return mTESelectMask; }
+ void renderOneSilhouette(const LLColor4 &color);
+ void setTransient(BOOL transient) { mTransient = transient; }
+ BOOL isTransient() const { return mTransient; }
+ LLViewerObject* getObject();
+ void setObject(LLViewerObject* object);
+ // *NOTE: invalidate stored textures and colors when # faces change
// Used by tools floater's color/texture pickers to restore changes
- void saveColors();
- void saveShinyColors();
- void saveTextures(const uuid_vec_t& textures);
- void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
+ void saveColors();
+ void saveShinyColors();
+ void saveTextures(const uuid_vec_t& textures);
+ void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
// GLTF materials are applied to objects by ids,
// overrides get applied on top of materials resulting in
@@ -199,185 +200,189 @@ public:
// overrides get applied in live material editor
void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials);
- BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
+ BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
public:
- BOOL mIndividualSelection; // For root objects and objects individually selected
-
- BOOL mTransient;
- BOOL mValid; // is extra information valid?
- LLPermissions* mPermissions;
- LLSaleInfo mSaleInfo;
- LLAggregatePermissions mAggregatePerm;
- LLAggregatePermissions mAggregateTexturePerm;
- LLAggregatePermissions mAggregateTexturePermOwner;
- std::string mName;
- std::string mDescription;
- LLCategory mCategory;
- S16 mInventorySerial;
- LLVector3 mSavedPositionLocal; // for interactively modifying object position
- LLVector3 mLastPositionLocal;
- LLVector3d mSavedPositionGlobal; // for interactively modifying object position
- LLVector3 mSavedScale; // for interactively modifying object scale
- LLVector3 mLastScale;
- LLQuaternion mSavedRotation; // for interactively modifying object rotation
- LLQuaternion mLastRotation;
- BOOL mDuplicated;
- LLVector3d mDuplicatePos;
- LLQuaternion mDuplicateRot;
- LLUUID mItemID;
- LLUUID mFolderID;
- LLUUID mFromTaskID;
- std::string mTouchName;
- std::string mSitName;
- U64 mCreationDate;
- std::vector<LLColor4> mSavedColors;
- std::vector<LLColor4> mSavedShinyColors;
- uuid_vec_t mSavedTextures;
- uuid_vec_t mSavedGLTFMaterialIds;
+ BOOL mIndividualSelection; // For root objects and objects individually selected
+
+ BOOL mTransient;
+ BOOL mValid; // is extra information valid?
+ LLPermissions* mPermissions;
+ LLSaleInfo mSaleInfo;
+ LLAggregatePermissions mAggregatePerm;
+ LLAggregatePermissions mAggregateTexturePerm;
+ LLAggregatePermissions mAggregateTexturePermOwner;
+ std::string mName;
+ std::string mDescription;
+ LLCategory mCategory;
+ S16 mInventorySerial;
+ LLVector3 mSavedPositionLocal; // for interactively modifying object position
+ LLVector3 mLastPositionLocal;
+ LLVector3 mLastMoveLocal;
+ LLVector3d mSavedPositionGlobal; // for interactively modifying object position
+ LLVector3 mSavedScale; // for interactively modifying object scale
+ LLVector3 mLastScale;
+ LLQuaternion mSavedRotation; // for interactively modifying object rotation
+ LLQuaternion mLastRotation;
+ BOOL mDuplicated;
+ LLVector3d mDuplicatePos;
+ LLQuaternion mDuplicateRot;
+ LLUUID mItemID;
+ LLUUID mFolderID;
+ LLUUID mFromTaskID;
+ std::string mTouchName;
+ std::string mSitName;
+ U64 mCreationDate;
+ std::vector<LLColor4> mSavedColors;
+ std::vector<LLColor4> mSavedShinyColors;
+ uuid_vec_t mSavedTextures;
+ uuid_vec_t mSavedGLTFMaterialIds;
gltf_materials_vec_t mSavedGLTFOverrideMaterials;
- std::vector<LLVector3> mTextureScaleRatios;
- std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object
- std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
- BOOL mSilhouetteExists; // need to generate silhouette?
+ std::vector<LLVector3> mTextureScaleRatios;
+ std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object
+ std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
+ BOOL mSilhouetteExists; // need to generate silhouette?
+ S32 mSelectedGLTFNode = -1;
+ S32 mSelectedGLTFPrimitive = -1;
protected:
- LLPointer<LLViewerObject> mObject;
- S32 mTESelectMask;
- S32 mLastTESelected;
+ LLPointer<LLViewerObject> mObject;
+ S32 mTESelectMask;
+ S32 mLastTESelected;
+
};
class LLObjectSelection : public LLRefCount
{
- friend class LLSelectMgr;
- friend class LLSafeHandle<LLObjectSelection>;
- friend class LLSelectionCallbackData;
+ friend class LLSelectMgr;
+ friend class LLSafeHandle<LLObjectSelection>;
+ friend class LLSelectionCallbackData;
protected:
- ~LLObjectSelection();
+ ~LLObjectSelection();
public:
- typedef std::list<LLSelectNode*> list_t;
-
- // Iterators
- struct is_non_null
- {
- bool operator()(LLSelectNode* node)
- {
- return (node->getObject() != NULL);
- }
- };
- typedef boost::filter_iterator<is_non_null, list_t::iterator > iterator;
- iterator begin() { return iterator(mList.begin(), mList.end()); }
- iterator end() { return iterator(mList.end(), mList.end()); }
-
- struct is_valid
- {
- bool operator()(LLSelectNode* node)
- {
- return (node->getObject() != NULL) && node->mValid;
- }
- };
- typedef boost::filter_iterator<is_valid, list_t::iterator > valid_iterator;
- valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); }
- valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); }
-
- struct is_root
- {
- bool operator()(LLSelectNode* node);
- };
- typedef boost::filter_iterator<is_root, list_t::iterator > root_iterator;
- root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); }
- root_iterator root_end() { return root_iterator(mList.end(), mList.end()); }
-
- struct is_valid_root
- {
- bool operator()(LLSelectNode* node);
- };
- typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;
- valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }
- valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); }
-
- struct is_root_object
- {
- bool operator()(LLSelectNode* node);
- };
- typedef boost::filter_iterator<is_root_object, list_t::iterator > root_object_iterator;
- root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); }
- root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); }
-
+ typedef std::list<LLSelectNode*> list_t;
+
+ // Iterators
+ struct is_non_null
+ {
+ bool operator()(LLSelectNode* node)
+ {
+ return (node->getObject() != NULL);
+ }
+ };
+ typedef boost::filter_iterator<is_non_null, list_t::iterator > iterator;
+ iterator begin() { return iterator(mList.begin(), mList.end()); }
+ iterator end() { return iterator(mList.end(), mList.end()); }
+
+ struct is_valid
+ {
+ bool operator()(LLSelectNode* node)
+ {
+ return (node->getObject() != NULL) && node->mValid;
+ }
+ };
+ typedef boost::filter_iterator<is_valid, list_t::iterator > valid_iterator;
+ valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); }
+ valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); }
+
+ struct is_root
+ {
+ bool operator()(LLSelectNode* node);
+ };
+ typedef boost::filter_iterator<is_root, list_t::iterator > root_iterator;
+ root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); }
+ root_iterator root_end() { return root_iterator(mList.end(), mList.end()); }
+
+ struct is_valid_root
+ {
+ bool operator()(LLSelectNode* node);
+ };
+ typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;
+ valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }
+ valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); }
+
+ struct is_root_object
+ {
+ bool operator()(LLSelectNode* node);
+ };
+ typedef boost::filter_iterator<is_root_object, list_t::iterator > root_object_iterator;
+ root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); }
+ root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); }
+
public:
- LLObjectSelection();
-
- void updateEffects();
-
- BOOL isEmpty() const;
-
- LLSelectNode* getFirstNode(LLSelectedNodeFunctor* func = NULL);
- LLSelectNode* getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE);
- LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE);
- LLViewerObject* getFirstObject();
- LLViewerObject* getFirstRootObject(BOOL non_root_ok = FALSE);
-
- LLSelectNode* getFirstMoveableNode(BOOL get_root_first = FALSE);
-
- LLViewerObject* getFirstEditableObject(BOOL get_parent = FALSE);
- LLViewerObject* getFirstCopyableObject(BOOL get_parent = FALSE);
- LLViewerObject* getFirstDeleteableObject();
- LLViewerObject* getFirstMoveableObject(BOOL get_parent = FALSE);
- LLViewerObject* getFirstUndoEnabledObject(BOOL get_parent = FALSE);
-
- /// Return the object that lead to this selection, possible a child
- LLViewerObject* getPrimaryObject() { return mPrimaryObject; }
-
- // iterate through texture entries
- template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T());
- template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);
-
- S32 getNumNodes();
- LLSelectNode* findNode(LLViewerObject* objectp);
-
- // count members
- S32 getObjectCount();
- F32 getSelectedObjectCost();
- F32 getSelectedLinksetCost();
- F32 getSelectedPhysicsCost();
- F32 getSelectedLinksetPhysicsCost();
- S32 getSelectedObjectRenderCost();
-
- F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL);
- U32 getSelectedObjectTriangleCount(S32* vcount = NULL);
-
- S32 getTECount();
- S32 getRootObjectCount();
-
- BOOL isMultipleTESelected();
- BOOL contains(LLViewerObject* object);
- BOOL contains(LLViewerObject* object, S32 te);
-
- // returns TRUE is any node is currenly worn as an attachment
- BOOL isAttachment();
+ LLObjectSelection();
+
+ void updateEffects();
+
+ BOOL isEmpty() const;
+
+ LLSelectNode* getFirstNode(LLSelectedNodeFunctor* func = NULL);
+ LLSelectNode* getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE);
+ LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE);
+ LLViewerObject* getFirstObject();
+ LLViewerObject* getFirstRootObject(BOOL non_root_ok = FALSE);
+
+ LLSelectNode* getFirstMoveableNode(BOOL get_root_first = FALSE);
+
+ LLViewerObject* getFirstEditableObject(BOOL get_parent = FALSE);
+ LLViewerObject* getFirstCopyableObject(BOOL get_parent = FALSE);
+ LLViewerObject* getFirstDeleteableObject();
+ LLViewerObject* getFirstMoveableObject(BOOL get_parent = FALSE);
+ LLViewerObject* getFirstUndoEnabledObject(BOOL get_parent = FALSE);
+
+ /// Return the object that lead to this selection, possible a child
+ LLViewerObject* getPrimaryObject() { return mPrimaryObject; }
+
+ // iterate through texture entries
+ template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T());
+ template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);
+
+ S32 getNumNodes();
+ LLSelectNode* findNode(LLViewerObject* objectp);
+
+ // count members
+ S32 getObjectCount();
+ F32 getSelectedObjectCost();
+ F32 getSelectedLinksetCost();
+ F32 getSelectedPhysicsCost();
+ F32 getSelectedLinksetPhysicsCost();
+ S32 getSelectedObjectRenderCost();
+
+ F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL);
+ U32 getSelectedObjectTriangleCount(S32* vcount = NULL);
+
+ S32 getTECount();
+ S32 getRootObjectCount();
+
+ BOOL isMultipleTESelected();
+ BOOL contains(LLViewerObject* object);
+ BOOL contains(LLViewerObject* object, S32 te);
+
+ // returns TRUE is any node is currenly worn as an attachment
+ BOOL isAttachment();
bool checkAnimatedObjectEstTris();
bool checkAnimatedObjectLinkable();
-
- // Apply functors to various subsets of the selected objects
- // If firstonly is FALSE, returns the AND of all apply() calls.
- // Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit)
- bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false);
- bool applyToObjects(LLSelectedObjectFunctor* func);
- bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false);
- bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
- bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
-
- /*
- * Used to apply (no-copy) textures to the selected object or
- * selected face/faces of the object.
- * This method moves (no-copy) texture to the object's inventory
- * and doesn't make copy of the texture for each face.
- * Then this only texture is used for all selected faces.
- */
- void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+
+ // Apply functors to various subsets of the selected objects
+ // If firstonly is FALSE, returns the AND of all apply() calls.
+ // Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit)
+ bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false);
+ bool applyToObjects(LLSelectedObjectFunctor* func);
+ bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false);
+ bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
+ bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
+
+ /*
+ * Used to apply (no-copy) textures to the selected object or
+ * selected face/faces of the object.
+ * This method moves (no-copy) texture to the object's inventory
+ * and doesn't make copy of the texture for each face.
+ * Then this only texture is used for all selected faces.
+ */
+ void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
/*
* Multi-purpose function for applying PBR materials to the
* selected object or faces, any combination of copy/mod/transfer
@@ -390,24 +395,24 @@ public:
*/
bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item);
- ESelectType getSelectType() const { return mSelectType; }
+ ESelectType getSelectType() const { return mSelectType; }
private:
- void addNode(LLSelectNode *nodep);
- void addNodeAtEnd(LLSelectNode *nodep);
- void moveNodeToFront(LLSelectNode *nodep);
- void removeNode(LLSelectNode *nodep);
- void deleteAllNodes();
- void cleanupNodes();
+ void addNode(LLSelectNode *nodep);
+ void addNodeAtEnd(LLSelectNode *nodep);
+ void moveNodeToFront(LLSelectNode *nodep);
+ void removeNode(LLSelectNode *nodep);
+ void deleteAllNodes();
+ void cleanupNodes();
private:
- list_t mList;
- const LLObjectSelection &operator=(const LLObjectSelection &);
+ list_t mList;
+ const LLObjectSelection &operator=(const LLObjectSelection &);
- LLPointer<LLViewerObject> mPrimaryObject;
- std::map<LLPointer<LLViewerObject>, LLSelectNode*> mSelectNodeMap;
- ESelectType mSelectType;
+ LLPointer<LLViewerObject> mPrimaryObject;
+ std::map<LLPointer<LLViewerObject>, LLSelectNode*> mSelectNodeMap;
+ ESelectType mSelectType;
};
typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
@@ -425,70 +430,70 @@ class LLSelectionCallbackData
{
public:
LLSelectionCallbackData();
- LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
+ LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
private:
- LLObjectSelectionHandle mSelectedObjects;
+ LLObjectSelectionHandle mSelectedObjects;
};
class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr>
{
public:
- static BOOL sRectSelectInclusive; // do we need to surround an object to pick it?
- static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded?
- static BOOL sRenderLightRadius; // do we show the radius of selected lights?
-
- static F32 sHighlightThickness;
- static F32 sHighlightUScale;
- static F32 sHighlightVScale;
- static F32 sHighlightAlpha;
- static F32 sHighlightAlphaTest;
- static F32 sHighlightUAnim;
- static F32 sHighlightVAnim;
- static LLColor4 sSilhouetteParentColor;
- static LLColor4 sSilhouetteChildColor;
- static LLColor4 sHighlightParentColor;
- static LLColor4 sHighlightChildColor;
- static LLColor4 sHighlightInspectColor;
- static LLColor4 sContextSilhouetteColor;
-
- LLCachedControl<bool> mHideSelectedObjects;
- LLCachedControl<bool> mRenderHighlightSelections;
- LLCachedControl<bool> mAllowSelectAvatar;
- LLCachedControl<bool> mDebugSelectMgr;
+ static BOOL sRectSelectInclusive; // do we need to surround an object to pick it?
+ static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded?
+ static BOOL sRenderLightRadius; // do we show the radius of selected lights?
+
+ static F32 sHighlightThickness;
+ static F32 sHighlightUScale;
+ static F32 sHighlightVScale;
+ static F32 sHighlightAlpha;
+ static F32 sHighlightAlphaTest;
+ static F32 sHighlightUAnim;
+ static F32 sHighlightVAnim;
+ static LLColor4 sSilhouetteParentColor;
+ static LLColor4 sSilhouetteChildColor;
+ static LLColor4 sHighlightParentColor;
+ static LLColor4 sHighlightChildColor;
+ static LLColor4 sHighlightInspectColor;
+ static LLColor4 sContextSilhouetteColor;
+
+ LLCachedControl<bool> mHideSelectedObjects;
+ LLCachedControl<bool> mRenderHighlightSelections;
+ LLCachedControl<bool> mAllowSelectAvatar;
+ LLCachedControl<bool> mDebugSelectMgr;
public:
LLSelectMgr();
~LLSelectMgr();
- static void cleanupGlobals();
+ static void cleanupGlobals();
- // LLEditMenuHandler interface
- virtual BOOL canUndo() const;
- virtual void undo();
+ // LLEditMenuHandler interface
+ virtual BOOL canUndo() const;
+ virtual void undo();
- virtual BOOL canRedo() const;
- virtual void redo();
+ virtual BOOL canRedo() const;
+ virtual void redo();
- virtual BOOL canDoDelete() const;
- virtual void doDelete();
+ virtual BOOL canDoDelete() const;
+ virtual void doDelete();
- virtual void deselect();
- virtual BOOL canDeselect() const;
+ virtual void deselect();
+ virtual BOOL canDeselect() const;
- virtual void duplicate();
- virtual BOOL canDuplicate() const;
+ virtual void duplicate();
+ virtual BOOL canDuplicate() const;
- void clearSelections();
- void update();
- void updateEffects(); // Update HUD effects
+ void clearSelections();
+ void update();
+ void updateEffects(); // Update HUD effects
- // When we edit object's position/rotation/scale we set local
- // overrides and ignore any updates (override received valeus).
- // When we send data to server, we send local values and reset
- // overrides
- void resetObjectOverrides();
- void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
- void overrideObjectUpdates();
+ // When we edit object's position/rotation/scale we set local
+ // overrides and ignore any updates (override received valeus).
+ // When we send data to server, we send local values and reset
+ // overrides
+ void resetObjectOverrides();
+ void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
+ void overrideObjectUpdates();
void resetAvatarOverrides();
void overrideAvatarUpdates();
@@ -514,430 +519,430 @@ public:
public:
- // Returns the previous value of mForceSelection
- BOOL setForceSelection(BOOL force);
-
- ////////////////////////////////////////////////////////////////
- // Selection methods
- ////////////////////////////////////////////////////////////////
+ // Returns the previous value of mForceSelection
+ BOOL setForceSelection(BOOL force);
- ////////////////////////////////////////////////////////////////
- // Add
- ////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////
+ // Selection methods
+ ////////////////////////////////////////////////////////////////
- // This method is meant to select an object, and then select all
- // of the ancestors and descendants. This should be the normal behavior.
- //
- // *NOTE: You must hold on to the object selection handle, otherwise
- // the objects will be automatically deselected in 1 frame.
- LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE, BOOL ignore_select_owned = FALSE);
+ ////////////////////////////////////////////////////////////////
+ // Add
+ ////////////////////////////////////////////////////////////////
- // For when you want just a child object.
- LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES);
+ // This method is meant to select an object, and then select all
+ // of the ancestors and descendants. This should be the normal behavior.
+ //
+ // *NOTE: You must hold on to the object selection handle, otherwise
+ // the objects will be automatically deselected in 1 frame.
+ LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE, BOOL ignore_select_owned = FALSE);
- // Same as above, but takes a list of objects. Used by rectangle select.
- LLObjectSelectionHandle selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, BOOL send_to_sim = TRUE);
+ // For when you want just a child object.
+ LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES, S32 gltf_node = -1, S32 gltf_primitive = -1);
- // converts all objects currently highlighted to a selection, and returns it
- LLObjectSelectionHandle selectHighlightedObjects();
+ // Same as above, but takes a list of objects. Used by rectangle select.
+ LLObjectSelectionHandle selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, BOOL send_to_sim = TRUE);
- LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1);
- LLSelectNode *getHoverNode();
- LLSelectNode *getPrimaryHoverNode();
+ // converts all objects currently highlighted to a selection, and returns it
+ LLObjectSelectionHandle selectHighlightedObjects();
- void highlightObjectOnly(LLViewerObject *objectp);
- void highlightObjectAndFamily(LLViewerObject *objectp);
- void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list);
+ LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1);
+ LLSelectNode *getHoverNode();
+ LLSelectNode *getPrimaryHoverNode();
- ////////////////////////////////////////////////////////////////
- // Remove
- ////////////////////////////////////////////////////////////////
+ void highlightObjectOnly(LLViewerObject *objectp);
+ void highlightObjectAndFamily(LLViewerObject *objectp);
+ void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list);
- void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE);
- void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE);
+ ////////////////////////////////////////////////////////////////
+ // Remove
+ ////////////////////////////////////////////////////////////////
- // Send deselect messages to simulator, then clear the list
- void deselectAll();
- void deselectAllForStandingUp();
+ void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE);
+ void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE);
- // deselect only if nothing else currently referencing the selection
- void deselectUnused();
+ // Send deselect messages to simulator, then clear the list
+ void deselectAll();
+ void deselectAllForStandingUp();
- // Deselect if the selection center is too far away from the agent.
- void deselectAllIfTooFar();
+ // deselect only if nothing else currently referencing the selection
+ void deselectUnused();
- // Removes all highlighted objects from current selection
- void deselectHighlightedObjects();
+ // Deselect if the selection center is too far away from the agent.
+ void deselectAllIfTooFar();
- void unhighlightObjectOnly(LLViewerObject *objectp);
- void unhighlightObjectAndFamily(LLViewerObject *objectp);
- void unhighlightAll();
+ // Removes all highlighted objects from current selection
+ void deselectHighlightedObjects();
- BOOL removeObjectFromSelections(const LLUUID &id);
+ void unhighlightObjectOnly(LLViewerObject *objectp);
+ void unhighlightObjectAndFamily(LLViewerObject *objectp);
+ void unhighlightAll();
- ////////////////////////////////////////////////////////////////
- // Selection editing
- ////////////////////////////////////////////////////////////////
- bool linkObjects();
+ BOOL removeObjectFromSelections(const LLUUID &id);
- bool unlinkObjects();
+ ////////////////////////////////////////////////////////////////
+ // Selection editing
+ ////////////////////////////////////////////////////////////////
+ bool linkObjects();
- void confirmUnlinkObjects(const LLSD& notification, const LLSD& response);
+ bool unlinkObjects();
- bool enableLinkObjects();
+ void confirmUnlinkObjects(const LLSD& notification, const LLSD& response);
- bool enableUnlinkObjects();
+ bool enableLinkObjects();
- ////////////////////////////////////////////////////////////////
- // Selection accessors
- ////////////////////////////////////////////////////////////////
- LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
- // right now this just renders the selection with root/child colors instead of a single color
- LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; }
- LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; }
+ bool enableUnlinkObjects();
- ////////////////////////////////////////////////////////////////
- // Grid manipulation
- ////////////////////////////////////////////////////////////////
- void addGridObject(LLViewerObject* objectp);
- void clearGridObjects();
- void setGridMode(EGridMode mode);
- EGridMode getGridMode() { return mGridMode; }
- void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false);
+ ////////////////////////////////////////////////////////////////
+ // Selection accessors
+ ////////////////////////////////////////////////////////////////
+ LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
+ // right now this just renders the selection with root/child colors instead of a single color
+ LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; }
+ LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; }
- BOOL getTEMode() const { return mTEMode; }
- void setTEMode(BOOL b) { mTEMode = b; }
+ ////////////////////////////////////////////////////////////////
+ // Grid manipulation
+ ////////////////////////////////////////////////////////////////
+ void addGridObject(LLViewerObject* objectp);
+ void clearGridObjects();
+ void setGridMode(EGridMode mode);
+ EGridMode getGridMode() { return mGridMode; }
+ void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false);
- BOOL shouldShowSelection() const { return mShowSelection; }
+ BOOL getTEMode() const { return mTEMode; }
+ void setTEMode(BOOL b) { mTEMode = b; }
- LLBBox getBBoxOfSelection() const;
- LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; }
+ BOOL shouldShowSelection() const { return mShowSelection; }
- void dump();
- void cleanup();
+ LLBBox getBBoxOfSelection() const;
+ LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; }
- void updateSilhouettes();
- void renderSilhouettes(BOOL for_hud);
- void enableSilhouette(BOOL enable) { mRenderSilhouettes = enable; }
-
- ////////////////////////////////////////////////////////////////
- // Utility functions that operate on the current selection
- ////////////////////////////////////////////////////////////////
- void saveSelectedObjectTransform(EActionType action_type);
- void saveSelectedObjectColors();
- void saveSelectedShinyColors();
- void saveSelectedObjectTextures();
-
- void selectionUpdatePhysics(BOOL use_physics);
- void selectionUpdateTemporary(BOOL is_temporary);
- void selectionUpdatePhantom(BOOL is_ghost);
- void selectionDump();
-
- BOOL selectionAllPCode(LLPCode code); // all objects have this PCode
- BOOL selectionGetClickAction(U8 *out_action);
- bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same
- BOOL selectionGetGlow(F32 *glow);
-
- void selectionSetPhysicsType(U8 type);
- void selectionSetGravity(F32 gravity);
- void selectionSetFriction(F32 friction);
- void selectionSetDensity(F32 density);
- void selectionSetRestitution(F32 restitution);
- void selectionSetMaterial(U8 material);
- bool selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ void dump();
+ void cleanup();
+
+ void updateSilhouettes();
+ void renderSilhouettes(BOOL for_hud);
+ void enableSilhouette(BOOL enable) { mRenderSilhouettes = enable; }
+
+ ////////////////////////////////////////////////////////////////
+ // Utility functions that operate on the current selection
+ ////////////////////////////////////////////////////////////////
+ void saveSelectedObjectTransform(EActionType action_type);
+ void saveSelectedObjectColors();
+ void saveSelectedShinyColors();
+ void saveSelectedObjectTextures();
+
+ void selectionUpdatePhysics(BOOL use_physics);
+ void selectionUpdateTemporary(BOOL is_temporary);
+ void selectionUpdatePhantom(BOOL is_ghost);
+ void selectionDump();
+
+ BOOL selectionAllPCode(LLPCode code); // all objects have this PCode
+ BOOL selectionGetClickAction(U8 *out_action);
+ bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same
+ BOOL selectionGetGlow(F32 *glow);
+
+ void selectionSetPhysicsType(U8 type);
+ void selectionSetGravity(F32 gravity);
+ void selectionSetFriction(F32 friction);
+ void selectionSetDensity(F32 density);
+ void selectionSetRestitution(F32 restitution);
+ void selectionSetMaterial(U8 material);
+ bool selectionSetImage(const LLUUID& imageid); // could be item or asset id
bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only
- void selectionSetColor(const LLColor4 &color);
- void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
- void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
- void selectionRevertColors();
- void selectionRevertShinyColors();
- BOOL selectionRevertTextures();
+ void selectionSetColor(const LLColor4 &color);
+ void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
+ void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
+ void selectionRevertColors();
+ void selectionRevertShinyColors();
+ BOOL selectionRevertTextures();
void selectionRevertGLTFMaterials();
- void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
- void selectionSetTexGen( U8 texgen );
- void selectionSetShiny( U8 shiny, const LLUUID &image_id );
- void selectionSetFullbright( U8 fullbright );
- void selectionSetMedia( U8 media_type, const LLSD &media_data );
- void selectionSetClickAction(U8 action);
- void selectionSetIncludeInSearch(bool include_in_search);
- void selectionSetGlow(const F32 glow);
- void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1);
- void selectionRemoveMaterial();
-
- void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
- void selectionSetObjectName(const std::string& name);
- void selectionSetObjectDescription(const std::string& desc);
- void selectionSetObjectCategory(const LLCategory& category);
- void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info);
-
- void selectionTexScaleAutofit(F32 repeats_per_meter);
- void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch);
-
- bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz,
- U32 update_type);
- void sendSelectionMove();
-
- void sendGodlikeRequest(const std::string& request, const std::string& parameter);
-
-
- // will make sure all selected object meet current criteria, or deselect them otherwise
- void validateSelection();
-
- // returns TRUE if it is possible to select this object
- BOOL canSelectObject(LLViewerObject* object, BOOL ignore_select_owned = FALSE);
-
- // Returns TRUE if the viewer has information on all selected objects
- BOOL selectGetAllRootsValid();
- BOOL selectGetAllValid();
- BOOL selectGetAllValidAndObjectsFound();
-
- // returns TRUE if you can modify all selected objects.
- BOOL selectGetRootsModify();
- BOOL selectGetModify();
-
- // returns TRUE if all objects are in same region
- BOOL selectGetSameRegion();
-
- // returns TRUE if is all objects are non-permanent-enforced
- BOOL selectGetRootsNonPermanentEnforced();
- BOOL selectGetNonPermanentEnforced();
-
- // returns TRUE if is all objects are permanent
- BOOL selectGetRootsPermanent();
- BOOL selectGetPermanent();
-
- // returns TRUE if is all objects are character
- BOOL selectGetRootsCharacter();
- BOOL selectGetCharacter();
-
- // returns TRUE if is all objects are not permanent
- BOOL selectGetRootsNonPathfinding();
- BOOL selectGetNonPathfinding();
-
- // returns TRUE if is all objects are not permanent
- BOOL selectGetRootsNonPermanent();
- BOOL selectGetNonPermanent();
-
- // returns TRUE if is all objects are not character
- BOOL selectGetRootsNonCharacter();
- BOOL selectGetNonCharacter();
-
- BOOL selectGetEditableLinksets();
- BOOL selectGetViewableCharacters();
-
- // returns TRUE if selected objects can be transferred.
- BOOL selectGetRootsTransfer();
-
- // returns TRUE if selected objects can be copied.
- BOOL selectGetRootsCopy();
-
- BOOL selectGetCreator(LLUUID& id, std::string& name); // TRUE if all have same creator, returns id
- BOOL selectGetOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id
- BOOL selectGetLastOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id
-
- // returns TRUE if all are the same. id is stuffed with
- // the value found if available.
- BOOL selectGetGroup(LLUUID& id);
- BOOL selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off); // TRUE if all have data, returns two masks, each indicating which bits are all on and all off
-
- BOOL selectIsGroupOwned(); // TRUE if all root objects have valid data and are group owned.
-
- // returns TRUE if all the nodes are valid. Accumulates
- // permissions in the parameter.
- BOOL selectGetPermissions(LLPermissions& perm);
-
- // returns TRUE if all the nodes are valid. Depends onto "edit linked" state
- // Children in linksets are a bit special - they require not only move permission
- // but also modify if "edit linked" is set, since you move them relative to parent
- BOOL selectGetEditMoveLinksetPermissions(bool &move, bool &modify);
-
- // Get a bunch of useful sale information for the object(s) selected.
- // "_mixed" is true if not all objects have the same setting.
- void selectGetAggregateSaleInfo(U32 &num_for_sale,
- BOOL &is_for_sale_mixed,
- BOOL &is_sale_price_mixed,
- S32 &total_sale_price,
- S32 &individual_sale_price);
-
- // returns TRUE if all nodes are valid.
- BOOL selectGetCategory(LLCategory& category);
-
- // returns TRUE if all nodes are valid. method also stores an
- // accumulated sale info.
- BOOL selectGetSaleInfo(LLSaleInfo& sale_info);
-
- // returns TRUE if all nodes are valid. fills passed in object
- // with the aggregate permissions of the selection.
- BOOL selectGetAggregatePermissions(LLAggregatePermissions& ag_perm);
-
- // returns TRUE if all nodes are valid. fills passed in object
- // with the aggregate permissions for texture inventory items of the selection.
- BOOL selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm);
-
- LLPermissions* findObjectPermissions(const LLViewerObject* object);
-
- BOOL isMovableAvatarSelected();
-
- void selectDelete(); // Delete on simulator
- void selectForceDelete(); // just delete, no into trash
- void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator
- void repeatDuplicate();
- void selectDuplicateOnRay(const LLVector3 &ray_start_region,
- const LLVector3 &ray_end_region,
- BOOL bypass_raycast,
- BOOL ray_end_is_intersection,
- const LLUUID &ray_target_id,
- BOOL copy_centers,
- BOOL copy_rotates,
- BOOL select_copy);
-
- void sendMultipleUpdate(U32 type); // Position, rotation, scale all in one
- void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, BOOL override = FALSE);
- void sendGroup(const LLUUID& group_id);
-
- // Category ID is the UUID of the folder you want to contain the purchase.
- // *NOTE: sale_info check doesn't work for multiple object buy,
- // which UI does not currently support sale info is used for
- // verification only, if it doesn't match region info then sale is
- // canceled
- void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
- void sendAttach(U8 attachment_point, bool replace);
- void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace);
- void sendDetach();
- void sendDropAttachment();
- void sendLink();
- void sendDelink();
- //void sendHinge(U8 type);
- //void sendDehinge();
- void sendSelect();
-
- void requestObjectPropertiesFamily(LLViewerObject* object); // asks sim for creator, permissions, resources, etc.
- static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data);
- static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data);
- static void processForceObjectSelect(LLMessageSystem* msg, void**);
-
- void requestGodInfo();
-
- LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; }
- void updateSelectionCenter();
+ void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
+ void selectionSetTexGen( U8 texgen );
+ void selectionSetShiny( U8 shiny, const LLUUID &image_id );
+ void selectionSetFullbright( U8 fullbright );
+ void selectionSetMedia( U8 media_type, const LLSD &media_data );
+ void selectionSetClickAction(U8 action);
+ void selectionSetIncludeInSearch(bool include_in_search);
+ void selectionSetGlow(const F32 glow);
+ void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1);
+ void selectionRemoveMaterial();
+
+ void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
+ void selectionSetObjectName(const std::string& name);
+ void selectionSetObjectDescription(const std::string& desc);
+ void selectionSetObjectCategory(const LLCategory& category);
+ void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info);
+
+ void selectionTexScaleAutofit(F32 repeats_per_meter);
+ void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch);
+
+ bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz,
+ U32 update_type);
+ void sendSelectionMove();
+
+ void sendGodlikeRequest(const std::string& request, const std::string& parameter);
+
+
+ // will make sure all selected object meet current criteria, or deselect them otherwise
+ void validateSelection();
+
+ // returns TRUE if it is possible to select this object
+ BOOL canSelectObject(LLViewerObject* object, BOOL ignore_select_owned = FALSE);
+
+ // Returns TRUE if the viewer has information on all selected objects
+ BOOL selectGetAllRootsValid();
+ BOOL selectGetAllValid();
+ BOOL selectGetAllValidAndObjectsFound();
+
+ // returns TRUE if you can modify all selected objects.
+ BOOL selectGetRootsModify();
+ BOOL selectGetModify();
+
+ // returns TRUE if all objects are in same region
+ BOOL selectGetSameRegion();
+
+ // returns TRUE if is all objects are non-permanent-enforced
+ BOOL selectGetRootsNonPermanentEnforced();
+ BOOL selectGetNonPermanentEnforced();
+
+ // returns TRUE if is all objects are permanent
+ BOOL selectGetRootsPermanent();
+ BOOL selectGetPermanent();
+
+ // returns TRUE if is all objects are character
+ BOOL selectGetRootsCharacter();
+ BOOL selectGetCharacter();
+
+ // returns TRUE if is all objects are not permanent
+ BOOL selectGetRootsNonPathfinding();
+ BOOL selectGetNonPathfinding();
+
+ // returns TRUE if is all objects are not permanent
+ BOOL selectGetRootsNonPermanent();
+ BOOL selectGetNonPermanent();
+
+ // returns TRUE if is all objects are not character
+ BOOL selectGetRootsNonCharacter();
+ BOOL selectGetNonCharacter();
+
+ BOOL selectGetEditableLinksets();
+ BOOL selectGetViewableCharacters();
+
+ // returns TRUE if selected objects can be transferred.
+ BOOL selectGetRootsTransfer();
+
+ // returns TRUE if selected objects can be copied.
+ BOOL selectGetRootsCopy();
+
+ BOOL selectGetCreator(LLUUID& id, std::string& name); // TRUE if all have same creator, returns id
+ BOOL selectGetOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id
+ BOOL selectGetLastOwner(LLUUID& id, std::string& name); // TRUE if all objects have same owner, returns id
+
+ // returns TRUE if all are the same. id is stuffed with
+ // the value found if available.
+ BOOL selectGetGroup(LLUUID& id);
+ BOOL selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off); // TRUE if all have data, returns two masks, each indicating which bits are all on and all off
+
+ BOOL selectIsGroupOwned(); // TRUE if all root objects have valid data and are group owned.
+
+ // returns TRUE if all the nodes are valid. Accumulates
+ // permissions in the parameter.
+ BOOL selectGetPermissions(LLPermissions& perm);
+
+ // returns TRUE if all the nodes are valid. Depends onto "edit linked" state
+ // Children in linksets are a bit special - they require not only move permission
+ // but also modify if "edit linked" is set, since you move them relative to parent
+ BOOL selectGetEditMoveLinksetPermissions(bool &move, bool &modify);
+
+ // Get a bunch of useful sale information for the object(s) selected.
+ // "_mixed" is true if not all objects have the same setting.
+ void selectGetAggregateSaleInfo(U32 &num_for_sale,
+ BOOL &is_for_sale_mixed,
+ BOOL &is_sale_price_mixed,
+ S32 &total_sale_price,
+ S32 &individual_sale_price);
+
+ // returns TRUE if all nodes are valid.
+ BOOL selectGetCategory(LLCategory& category);
+
+ // returns TRUE if all nodes are valid. method also stores an
+ // accumulated sale info.
+ BOOL selectGetSaleInfo(LLSaleInfo& sale_info);
+
+ // returns TRUE if all nodes are valid. fills passed in object
+ // with the aggregate permissions of the selection.
+ BOOL selectGetAggregatePermissions(LLAggregatePermissions& ag_perm);
+
+ // returns TRUE if all nodes are valid. fills passed in object
+ // with the aggregate permissions for texture inventory items of the selection.
+ BOOL selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm);
+
+ LLPermissions* findObjectPermissions(const LLViewerObject* object);
+
+ BOOL isMovableAvatarSelected();
+
+ void selectDelete(); // Delete on simulator
+ void selectForceDelete(); // just delete, no into trash
+ void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator
+ void repeatDuplicate();
+ void selectDuplicateOnRay(const LLVector3 &ray_start_region,
+ const LLVector3 &ray_end_region,
+ BOOL bypass_raycast,
+ BOOL ray_end_is_intersection,
+ const LLUUID &ray_target_id,
+ BOOL copy_centers,
+ BOOL copy_rotates,
+ BOOL select_copy);
+
+ void sendMultipleUpdate(U32 type); // Position, rotation, scale all in one
+ void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, BOOL override = FALSE);
+ void sendGroup(const LLUUID& group_id);
+
+ // Category ID is the UUID of the folder you want to contain the purchase.
+ // *NOTE: sale_info check doesn't work for multiple object buy,
+ // which UI does not currently support sale info is used for
+ // verification only, if it doesn't match region info then sale is
+ // canceled
+ void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
+ void sendAttach(U8 attachment_point, bool replace);
+ void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace);
+ void sendDetach();
+ void sendDropAttachment();
+ void sendLink();
+ void sendDelink();
+ //void sendHinge(U8 type);
+ //void sendDehinge();
+ void sendSelect();
+
+ void requestObjectPropertiesFamily(LLViewerObject* object); // asks sim for creator, permissions, resources, etc.
+ static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data);
+ static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data);
+ static void processForceObjectSelect(LLMessageSystem* msg, void**);
+
+ void requestGodInfo();
+
+ LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; }
+ void updateSelectionCenter();
void pauseAssociatedAvatars();
- void resetAgentHUDZoom();
- void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
- void getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const;
+ void resetAgentHUDZoom();
+ void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
+ void getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const;
- void updatePointAt();
+ void updatePointAt();
- // Internal list maintenance functions. TODO: Make these private!
- void remove(std::vector<LLViewerObject*>& objects);
- void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE);
- void removeAll();
- void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE);
- void promoteSelectionToRoot();
- void demoteSelectionToIndividuals();
+ // Internal list maintenance functions. TODO: Make these private!
+ void remove(std::vector<LLViewerObject*>& objects);
+ void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE);
+ void removeAll();
+ void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE, S32 gltf_node = -1, S32 gltf_primitive = -1);
+ void promoteSelectionToRoot();
+ void demoteSelectionToIndividuals();
private:
- void convertTransient(); // converts temporarily selected objects to full-fledged selections
- ESelectType getSelectTypeForObject(LLViewerObject* object);
- void addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end = FALSE);
- void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
- void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects);
- // Send one message to each region containing an object on selection list.
- void sendListToRegions( const std::string& message_name,
- void (*pack_header)(void *user_data),
- void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
- void *user_data,
- ESendType send_type);
- void sendListToRegions( LLObjectSelectionHandle selected_handle,
- const std::string& message_name,
- void (*pack_header)(void *user_data),
- void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
- void *user_data,
- ESendType send_type);
-
-
- static void packAgentID( void *);
- static void packAgentAndSessionID(void* user_data);
- static void packAgentAndGroupID(void* user_data);
- static void packAgentAndSessionAndGroupID(void* user_data);
- static void packAgentIDAndSessionAndAttachment(void*);
- static void packAgentGroupAndCatID(void*);
- static void packDeleteHeader(void* userdata);
- static void packDeRezHeader(void* user_data);
- static void packObjectID( LLSelectNode* node, void *);
- static void packObjectIDAsParam(LLSelectNode* node, void *);
- static void packObjectIDAndRotation(LLSelectNode* node, void *);
- static void packObjectLocalID(LLSelectNode* node, void *);
- static void packObjectClickAction(LLSelectNode* node, void* data);
- static void packObjectIncludeInSearch(LLSelectNode* node, void* data);
- static void packObjectName(LLSelectNode* node, void* user_data);
- static void packObjectDescription(LLSelectNode* node, void* user_data);
- static void packObjectCategory(LLSelectNode* node, void* user_data);
- static void packObjectSaleInfo(LLSelectNode* node, void* user_data);
- static void packBuyObjectIDs(LLSelectNode* node, void* user_data);
- static void packDuplicate( LLSelectNode* node, void *duplicate_data);
- static void packDuplicateHeader(void*);
- static void packDuplicateOnRayHead(void *user_data);
- static void packPermissions(LLSelectNode* node, void *user_data);
- static void packDeselect( LLSelectNode* node, void *user_data);
- static void packMultipleUpdate(LLSelectNode* node, void *user_data);
- static void packPhysics(LLSelectNode* node, void *user_data);
- static void packShape(LLSelectNode* node, void *user_data);
- static void packOwnerHead(void *user_data);
- static void packHingeHead(void *user_data);
- static void packPermissionsHead(void* user_data);
- static void packGodlikeHead(void* user_data);
+ void convertTransient(); // converts temporarily selected objects to full-fledged selections
+ ESelectType getSelectTypeForObject(LLViewerObject* object);
+ void addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end = FALSE);
+ void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
+ void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects);
+ // Send one message to each region containing an object on selection list.
+ void sendListToRegions( const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type);
+ void sendListToRegions( LLObjectSelectionHandle selected_handle,
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type);
+
+
+ static void packAgentID( void *);
+ static void packAgentAndSessionID(void* user_data);
+ static void packAgentAndGroupID(void* user_data);
+ static void packAgentAndSessionAndGroupID(void* user_data);
+ static void packAgentIDAndSessionAndAttachment(void*);
+ static void packAgentGroupAndCatID(void*);
+ static void packDeleteHeader(void* userdata);
+ static void packDeRezHeader(void* user_data);
+ static void packObjectID( LLSelectNode* node, void *);
+ static void packObjectIDAsParam(LLSelectNode* node, void *);
+ static void packObjectIDAndRotation(LLSelectNode* node, void *);
+ static void packObjectLocalID(LLSelectNode* node, void *);
+ static void packObjectClickAction(LLSelectNode* node, void* data);
+ static void packObjectIncludeInSearch(LLSelectNode* node, void* data);
+ static void packObjectName(LLSelectNode* node, void* user_data);
+ static void packObjectDescription(LLSelectNode* node, void* user_data);
+ static void packObjectCategory(LLSelectNode* node, void* user_data);
+ static void packObjectSaleInfo(LLSelectNode* node, void* user_data);
+ static void packBuyObjectIDs(LLSelectNode* node, void* user_data);
+ static void packDuplicate( LLSelectNode* node, void *duplicate_data);
+ static void packDuplicateHeader(void*);
+ static void packDuplicateOnRayHead(void *user_data);
+ static void packPermissions(LLSelectNode* node, void *user_data);
+ static void packDeselect( LLSelectNode* node, void *user_data);
+ static void packMultipleUpdate(LLSelectNode* node, void *user_data);
+ static void packPhysics(LLSelectNode* node, void *user_data);
+ static void packShape(LLSelectNode* node, void *user_data);
+ static void packOwnerHead(void *user_data);
+ static void packHingeHead(void *user_data);
+ static void packPermissionsHead(void* user_data);
+ static void packGodlikeHead(void* user_data);
static void logNoOp(LLSelectNode* node, void *user_data);
static void logAttachmentRequest(LLSelectNode* node, void *user_data);
static void logDetachRequest(LLSelectNode* node, void *user_data);
- static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
+ static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
- // Get the first ID that matches test and whether or not all ids are identical in selected objects.
- void getFirst(LLSelectGetFirstTest* test);
+ // Get the first ID that matches test and whether or not all ids are identical in selected objects.
+ void getFirst(LLSelectGetFirstTest* test);
public:
- // Observer/callback support for when object selection changes or
- // properties are received/updated
- typedef boost::signals2::signal< void ()> update_signal_t;
- update_signal_t mUpdateSignal;
+ // Observer/callback support for when object selection changes or
+ // properties are received/updated
+ typedef boost::signals2::signal< void ()> update_signal_t;
+ update_signal_t mUpdateSignal;
private:
- LLPointer<LLViewerTexture> mSilhouetteImagep;
- LLObjectSelectionHandle mSelectedObjects;
- LLObjectSelectionHandle mHoverObjects;
- LLObjectSelectionHandle mHighlightedObjects;
- std::set<LLPointer<LLViewerObject> > mRectSelectedObjects;
-
- LLObjectSelection mGridObjects;
- LLQuaternion mGridRotation;
- LLVector3 mGridOrigin;
- LLVector3 mGridScale;
- EGridMode mGridMode;
-
- BOOL mTEMode; // render te
- LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode
- LLVector3d mSelectionCenterGlobal;
- LLBBox mSelectionBBox;
-
- LLVector3d mLastSentSelectionCenterGlobal;
- BOOL mShowSelection; // do we send the selection center name value and do we animate this selection?
- LLVector3d mLastCameraPos; // camera position from last generation of selection silhouette
- BOOL mRenderSilhouettes; // do we render the silhouette
- LLBBox mSavedSelectionBBox;
-
- LLFrameTimer mEffectsTimer;
- BOOL mForceSelection;
-
- std::vector<LLAnimPauseRequest> mPauseRequests;
+ LLPointer<LLViewerTexture> mSilhouetteImagep;
+ LLObjectSelectionHandle mSelectedObjects;
+ LLObjectSelectionHandle mHoverObjects;
+ LLObjectSelectionHandle mHighlightedObjects;
+ std::set<LLPointer<LLViewerObject> > mRectSelectedObjects;
+
+ LLObjectSelection mGridObjects;
+ LLQuaternion mGridRotation;
+ LLVector3 mGridOrigin;
+ LLVector3 mGridScale;
+ EGridMode mGridMode;
+
+ BOOL mTEMode; // render te
+ LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode
+ LLVector3d mSelectionCenterGlobal;
+ LLBBox mSelectionBBox;
+
+ LLVector3d mLastSentSelectionCenterGlobal;
+ BOOL mShowSelection; // do we send the selection center name value and do we animate this selection?
+ LLVector3d mLastCameraPos; // camera position from last generation of selection silhouette
+ BOOL mRenderSilhouettes; // do we render the silhouette
+ LLBBox mSavedSelectionBBox;
+
+ LLFrameTimer mEffectsTimer;
+ BOOL mForceSelection;
+
+ std::vector<LLAnimPauseRequest> mPauseRequests;
};
// *DEPRECATED: For callbacks or observers, use
// LLSelectMgr::getInstance()->mUpdateSignal.connect( callback )
// Update subscribers to the selection list
-void dialog_refresh_all();
+void dialog_refresh_all();
// Templates
//-----------------------------------------------------------------------------
@@ -945,113 +950,113 @@ void dialog_refresh_all();
//-----------------------------------------------------------------------------
template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance, T tolerance)
{
- bool have_first = false;
- bool have_selected = false;
- T selected_value = T();
-
- // Now iterate through all TEs to test for sameness
- bool identical = TRUE;
- for (iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- S32 selected_te = -1;
- if (object == getPrimaryObject())
- {
- selected_te = node->getLastSelectedTE();
- }
- for (S32 te = 0; te < object->getNumTEs(); ++te)
- {
- if (!node->isTESelected(te))
- {
- continue;
- }
- T value = func->get(object, te);
- if (!have_first)
- {
- have_first = true;
- if (!have_selected)
- {
- selected_value = value;
- }
- }
- else
- {
- if ( value != selected_value )
- {
+ bool have_first = false;
+ bool have_selected = false;
+ T selected_value = T();
+
+ // Now iterate through all TEs to test for sameness
+ bool identical = TRUE;
+ for (iterator iter = begin(); iter != end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ S32 selected_te = -1;
+ if (object == getPrimaryObject())
+ {
+ selected_te = node->getLastSelectedTE();
+ }
+ for (S32 te = 0; te < object->getNumTEs(); ++te)
+ {
+ if (!node->isTESelected(te))
+ {
+ continue;
+ }
+ T value = func->get(object, te);
+ if (!have_first)
+ {
+ have_first = true;
+ if (!have_selected)
+ {
+ selected_value = value;
+ }
+ }
+ else
+ {
+ if ( value != selected_value )
+ {
if (!has_tolerance)
{
- identical = false;
+ identical = false;
}
else if (!LLCheckIdenticalFunctor<T>::same(value, selected_value, tolerance))
{
identical = false;
}
- }
- if (te == selected_te)
- {
- selected_value = value;
- have_selected = true;
- }
- }
- }
- if (!identical && have_selected)
- {
- break;
- }
- }
- if (have_first || have_selected)
- {
- res = selected_value;
- }
- return identical;
+ }
+ if (te == selected_te)
+ {
+ selected_value = value;
+ have_selected = true;
+ }
+ }
+ }
+ if (!identical && have_selected)
+ {
+ break;
+ }
+ }
+ if (have_first || have_selected)
+ {
+ res = selected_value;
+ }
+ return identical;
}
// Templates
//-----------------------------------------------------------------------------
-// isMultipleTEValue iterate through all TEs and test for uniqueness
-// with certain return value ignored when performing the test.
+// isMultipleTEValue iterate through all TEs and test for uniqueness
+// with certain return value ignored when performing the test.
// e.g. when testing if the selection has a unique non-empty homeurl :
-// you can set ignore_value = "" and it will only compare among the non-empty
+// you can set ignore_value = "" and it will only compare among the non-empty
// homeUrls and ignore the empty ones.
//-----------------------------------------------------------------------------
template <typename T> bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value)
{
- bool have_first = false;
- T selected_value = T();
-
- // Now iterate through all TEs to test for sameness
- bool unique = TRUE;
- for (iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- for (S32 te = 0; te < object->getNumTEs(); ++te)
- {
- if (!node->isTESelected(te))
- {
- continue;
- }
- T value = func->get(object, te);
- if(value == ignore_value)
- {
- continue;
- }
- if (!have_first)
- {
- have_first = true;
- }
- else
- {
- if (value !=selected_value )
- {
- unique = false;
- return !unique;
- }
- }
- }
- }
- return !unique;
+ bool have_first = false;
+ T selected_value = T();
+
+ // Now iterate through all TEs to test for sameness
+ bool unique = TRUE;
+ for (iterator iter = begin(); iter != end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ for (S32 te = 0; te < object->getNumTEs(); ++te)
+ {
+ if (!node->isTESelected(te))
+ {
+ continue;
+ }
+ T value = func->get(object, te);
+ if(value == ignore_value)
+ {
+ continue;
+ }
+ if (!have_first)
+ {
+ have_first = true;
+ }
+ else
+ {
+ if (value !=selected_value )
+ {
+ unique = false;
+ return !unique;
+ }
+ }
+ }
+ }
+ return !unique;
}
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index ca5e148952..ff9332aeee 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -72,7 +72,7 @@
extern BOOL gCubeSnapshot;
//=========================================================================
-namespace
+namespace
{
LLSD ensure_array_4(LLSD in, F32 fill);
LLSD read_legacy_preset_data(const std::string &name, const std::string& path, LLSD &messages);
@@ -185,7 +185,7 @@ void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSetti
}
}
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,
+ { // The item was created as new with no settings passed in. Simulator should have given it the default for the type... check ID,
// no need to upload asset.
LLUUID asset_id;
if (pitem)
@@ -246,11 +246,11 @@ void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings
}
}
- std::stringstream buffer;
+ 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(),
+ 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);
@@ -313,7 +313,7 @@ void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, L
void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback)
{
gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS,
- [callback](const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status)
+ [callback](const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status)
{ onAssetDownloadComplete(asset_id, status, ext_status, callback); },
nullptr, true);
@@ -503,7 +503,7 @@ LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &n
if (!llsd_equals(oldsettings, oldsettings))
{
- LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n"
+ LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n"
<< "Old: " << oldsettings
<< "new: " << oldsettings << LL_ENDL;
}
@@ -601,7 +601,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
{
LLSD legacy(LLSD::emptyMap());
LLSD settings = psky->getSettings();
-
+
convertAtmosphericsToLegacy(legacy, settings);
legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0);
@@ -610,15 +610,15 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
legacy[SETTING_CLOUD_SCALE] = llsd::array(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] = llsd::array(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] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f);
+ LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
+ legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f);
legacy[SETTING_GAMMA] = llsd::array(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] = llsd::array(settings[SETTING_MAX_Y], 0.0f, 0.0f, 1.0f);
legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes
legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
-
+
LLVector3 dir = psky->getLightDirection();
F32 phi = asin(dir.mV[2]);
@@ -633,17 +633,17 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
{
theta += F_PI * 2;
}
-
+
if (theta > 4 * F_PI)
{
theta = fmod(theta, 2 * F_PI);
}
-
+
while (phi < -F_PI)
{
phi += 2 * F_PI;
}
-
+
if (phi > 3 * F_PI)
{
phi = F_PI + fmod(phi - F_PI, 2 * F_PI);
@@ -651,8 +651,8 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
legacy[SETTING_LEGACY_EAST_ANGLE] = theta;
legacy[SETTING_LEGACY_SUN_ANGLE] = phi;
-
- return legacy;
+
+ return legacy;
}
//-------------------------------------------------------------------------
@@ -669,10 +669,10 @@ void LLSettingsVOSky::updateSettings()
// Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
// between sunlight and point lights in windlight to normalize point lights.
//
- // After some A/B comparison of relesae vs EEP, tweak to allow strength to fall below 2
+ // After some A/B comparison of relesae vs EEP, tweak to allow strength to fall below 2
// at night, for better match. (mSceneLightStrength is a divisor, so lower value means brighter
// local lights)
- F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
+ F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
mSceneLightStrength = 2.0f * (0.75f + sun_dynamic_range * dp);
gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
@@ -693,11 +693,11 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
bool irradiance_pass = gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass();
LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];
- {
+ {
shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());
- }
-
+ }
+
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];
shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
@@ -718,11 +718,11 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
// TODO -- make these getters return vec3s
- LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV);
- LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV);
+ LLVector3 sun_light_color = LLVector3(psky->getSunlightColor().mV);
+ LLVector3 moon_light_color = LLVector3(psky->getMoonlightColor().mV);
- shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
- shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color);
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moon_light_color);
shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV));
@@ -745,8 +745,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, sunlight_scale);
shader->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, ambient_scale);
- static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
- F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale);
+ F32 probe_ambiance = getReflectionProbeAmbiance();
if (irradiance_pass)
{ // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue)
@@ -760,14 +759,14 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails
}
else if (psky->canAutoAdjust() && should_auto_adjust)
- { // auto-adjust legacy sky to take advantage of probe ambiance
+ { // auto-adjust legacy sky to take advantage of probe ambiance
shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV);
shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale);
LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale;
LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale;
- LLColor3 sun_diffuse = getSunDiffuse() * auto_adjust_sun_color_scale;
-
- shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_diffuse.mV);
+ sun_light_color = sun_light_color * auto_adjust_sun_color_scale;
+
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color.mV);
shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV);
shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV);
@@ -786,7 +785,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier());
shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier());
-
+
shader->uniform1f(LLShaderMgr::GAMMA, g);
}
@@ -810,7 +809,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
// Following values are always present, so we can just zero these ones, but used values from defaults()
LLSD sky_defaults = LLSettingsSky::defaults();
-
+
param_map[SETTING_CLOUD_POS_DENSITY2] = DefaultParam(LLShaderMgr::CLOUD_POS_DENSITY2, sky_defaults[SETTING_CLOUD_POS_DENSITY2]);
param_map[SETTING_CLOUD_SCALE] = DefaultParam(LLShaderMgr::CLOUD_SCALE, sky_defaults[SETTING_CLOUD_SCALE]);
param_map[SETTING_CLOUD_SHADOW] = DefaultParam(LLShaderMgr::CLOUD_SHADOW, sky_defaults[SETTING_CLOUD_SHADOW]);
@@ -873,7 +872,7 @@ LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::strin
return LLSettingsWater::ptr_t();
}
- newsettings[SETTING_NAME] = name;
+ newsettings[SETTING_NAME] = name;
LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
LLSD results = LLSettingsWater::settingValidation(newsettings, validations);
if (!results["success"].asBoolean())
@@ -971,7 +970,7 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)
legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW];
legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR];
legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR];
-
+
return legacy;
}
//-------------------------------------------------------------------------
@@ -984,8 +983,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
auto group = LLGLSLShader::SG_ANY;
LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group];
-
- {
+
+ {
F32 water_height = env.getWaterHeight();
if (LLViewerCamera::instance().cameraUnderWater())
@@ -1009,6 +1008,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
glh::matrix4f mat(modelView);
glh::matrix4f invtrans = mat.inverse().transpose();
+ invtrans.m[3] = invtrans.m[7] = invtrans.m[11] = 0.f;
glh::vec3f enorm;
glh::vec3f ep;
invtrans.mult_matrix_vec(norm, enorm);
@@ -1017,12 +1017,29 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+ norm = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
+ p = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
+ invtrans.mult_matrix_vec(norm, enorm);
+ enorm.normalize();
+ mat.mult_matrix_vec(p, ep);
+
+ LLVector4 mirrorPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+
LLDrawPoolAlpha::sWaterPlane = waterPlane;
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
-
+ shader->uniform4fv(LLShaderMgr::CLIP_PLANE, mirrorPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
+ if (gPipeline.mHeroProbeManager.isMirrorPass())
+ {
+ shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 1);
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0);
+ }
+
F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);
@@ -1102,7 +1119,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
std::set<std::string> notfound;
// expected and correct folder sctructure is to have
- // three folders in widnlight's root: days, water, skies
+ // three folders in widnlight's root: days, water, skies
std::string base_path(gDirUtilp->getDirName(path));
std::string water_path(base_path);
std::string sky_path(base_path);
@@ -1193,7 +1210,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
if (!llsd_equals(oldsettings, testsettings))
{
- LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n"
+ LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n"
<< "Old: " << oldsettings
<< "new: " << testsettings << LL_ENDL;
}
@@ -1228,7 +1245,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
{
std::string newname = "sky:" + (*itm).first;
LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second);
-
+
newsettings[SETTING_NAME] = newname;
frames[newname] = newsettings;
@@ -1267,7 +1284,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
}
LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings);
-
+
if (dayp)
{
// true for validation - either validate here, or when cloning for floater.
@@ -1417,34 +1434,34 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
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( llsd::array(LLSD::Real(frame), name.str()) );
}
LLSD llsdskylist(LLSD::emptyMap());
-
+
for (std::map<std::string, LLSettingsSky::ptr_t>::iterator its = skys.begin(); its != skys.end(); ++its)
{
LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false);
llsdsky[SETTING_NAME] = (*its).first;
-
+
llsdskylist[(*its).first] = llsdsky;
}
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index fe5b6f71a3..f3b5bb0565 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llspatialpartition.cpp
* @brief LLSpatialGroup class implementation and supporting functions
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -47,6 +47,7 @@
#include "pipeline.h"
#include "llmeshrepository.h"
#include "llrender.h"
+#include "lldrawpool.h"
#include "lloctree.h"
#include "llphysicsshapebuilderutil.h"
#include "llvoavatar.h"
@@ -72,131 +73,131 @@ static F32 sCurMaxTexPriority = 1.f;
void sg_assert(BOOL expr)
{
#if LL_OCTREE_PARANOIA_CHECK
- if (!expr)
- {
- LL_ERRS() << "Octree invalid!" << LL_ENDL;
- }
+ if (!expr)
+ {
+ LL_ERRS() << "Octree invalid!" << LL_ENDL;
+ }
#endif
}
//returns:
-// 0 if sphere and AABB are not intersecting
-// 1 if they are
-// 2 if AABB is entirely inside sphere
+// 0 if sphere and AABB are not intersecting
+// 1 if they are
+// 2 if AABB is entirely inside sphere
S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3& pos, const F32 &rad)
{
- S32 ret = 2;
-
- LLVector3 min = center - size;
- LLVector3 max = center + size;
- for (U32 i = 0; i < 3; i++)
- {
- if (min.mV[i] > pos.mV[i] + rad ||
- max.mV[i] < pos.mV[i] - rad)
- { //totally outside
- return 0;
- }
-
- if (min.mV[i] < pos.mV[i] - rad ||
- max.mV[i] > pos.mV[i] + rad)
- { //intersecting
- ret = 1;
- }
- }
-
- return ret;
+ S32 ret = 2;
+
+ LLVector3 min = center - size;
+ LLVector3 max = center + size;
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (min.mV[i] > pos.mV[i] + rad ||
+ max.mV[i] < pos.mV[i] - rad)
+ { //totally outside
+ return 0;
+ }
+
+ if (min.mV[i] < pos.mV[i] - rad ||
+ max.mV[i] > pos.mV[i] + rad)
+ { //intersecting
+ ret = 1;
+ }
+ }
+
+ return ret;
}
LLSpatialGroup::~LLSpatialGroup()
{
- /*if (sNoDelete)
- {
- LL_ERRS() << "Illegal deletion of LLSpatialGroup!" << LL_ENDL;
- }*/
+ /*if (sNoDelete)
+ {
+ LL_ERRS() << "Illegal deletion of LLSpatialGroup!" << LL_ENDL;
+ }*/
- if (gDebugGL)
- {
- gPipeline.checkReferences(this);
- }
-
- if (hasState(DEAD))
- {
- sZombieGroups--;
- }
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
- sNodeCount--;
+ if (hasState(DEAD))
+ {
+ sZombieGroups--;
+ }
+
+ sNodeCount--;
- clearDrawMap();
+ clearDrawMap();
}
void LLSpatialGroup::clearDrawMap()
{
- mDrawMap.clear();
+ mDrawMap.clear();
}
-BOOL LLSpatialGroup::isHUDGroup()
+BOOL LLSpatialGroup::isHUDGroup()
{
- return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
+ return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
}
void LLSpatialGroup::validate()
{
- ll_assert_aligned(this,64);
+ ll_assert_aligned(this,64);
#if LL_OCTREE_PARANOIA_CHECK
- sg_assert(!isState(DIRTY));
- sg_assert(!isDead());
-
- LLVector4a myMin;
- myMin.setSub(mBounds[0], mBounds[1]);
- LLVector4a myMax;
- myMax.setAdd(mBounds[0], mBounds[1]);
-
- validateDrawMap();
-
- for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
- {
- LLDrawable* drawable = *i;
- sg_assert(drawable->getSpatialGroup() == this);
- if (drawable->getSpatialBridge())
- {
- sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge());
- }
-
- /*if (drawable->isSpatialBridge())
- {
- LLSpatialPartition* part = drawable->asPartition();
- if (!part)
- {
- LL_ERRS() << "Drawable reports it is a spatial bridge but not a partition." << LL_ENDL;
- }
- LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
- group->validate();
- }*/
- }
-
- for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
-
- group->validate();
-
- //ensure all children are enclosed in this node
- LLVector4a center = group->mBounds[0];
- LLVector4a size = group->mBounds[1];
-
- LLVector4a min;
- min.setSub(center, size);
- LLVector4a max;
- max.setAdd(center, size);
-
- for (U32 j = 0; j < 3; j++)
- {
- sg_assert(min[j] >= myMin[j]-0.02f);
- sg_assert(max[j] <= myMax[j]+0.02f);
- }
- }
+ sg_assert(!isState(DIRTY));
+ sg_assert(!isDead());
+
+ LLVector4a myMin;
+ myMin.setSub(mBounds[0], mBounds[1]);
+ LLVector4a myMax;
+ myMax.setAdd(mBounds[0], mBounds[1]);
+
+ validateDrawMap();
+
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = *i;
+ sg_assert(drawable->getSpatialGroup() == this);
+ if (drawable->getSpatialBridge())
+ {
+ sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge());
+ }
+
+ /*if (drawable->isSpatialBridge())
+ {
+ LLSpatialPartition* part = drawable->asPartition();
+ if (!part)
+ {
+ LL_ERRS() << "Drawable reports it is a spatial bridge but not a partition." << LL_ENDL;
+ }
+ LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
+ group->validate();
+ }*/
+ }
+
+ for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
+
+ group->validate();
+
+ //ensure all children are enclosed in this node
+ LLVector4a center = group->mBounds[0];
+ LLVector4a size = group->mBounds[1];
+
+ LLVector4a min;
+ min.setSub(center, size);
+ LLVector4a max;
+ max.setAdd(center, size);
+
+ for (U32 j = 0; j < 3; j++)
+ {
+ sg_assert(min[j] >= myMin[j]-0.02f);
+ sg_assert(max[j] <= myMax[j]+0.02f);
+ }
+ }
#endif
}
@@ -204,195 +205,195 @@ void LLSpatialGroup::validate()
void LLSpatialGroup::validateDrawMap()
{
#if LL_OCTREE_PARANOIA_CHECK
- for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i)
- {
- LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
- for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
- {
- LLDrawInfo& params = **j;
-
- params.validate();
- }
- }
+ for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i)
+ {
+ LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
+ for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
+ {
+ LLDrawInfo& params = **j;
+
+ params.validate();
+ }
+ }
#endif
}
BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
{
LL_PROFILE_ZONE_SCOPED;
- drawablep->updateSpatialExtents();
-
- OctreeNode* parent = mOctreeNode->getOctParent();
-
- if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
- (mOctreeNode->contains(drawablep->getEntry()) ||
- (drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&
- parent && parent->getElementCount() >= gOctreeMaxCapacity)))
- {
- unbound();
- setState(OBJECT_DIRTY);
- //setState(GEOM_DIRTY);
- return TRUE;
- }
-
- return FALSE;
+ drawablep->updateSpatialExtents();
+
+ OctreeNode* parent = mOctreeNode->getOctParent();
+
+ if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
+ (mOctreeNode->contains(drawablep->getEntry()) ||
+ (drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&
+ parent && parent->getElementCount() >= gOctreeMaxCapacity)))
+ {
+ unbound();
+ setState(OBJECT_DIRTY);
+ //setState(GEOM_DIRTY);
+ return TRUE;
+ }
+
+ return FALSE;
}
void LLSpatialGroup::expandExtents(const LLVector4a* addingExtents, const LLXformMatrix& currentTransform)
{
- // Get coordinates of the adding extents
- const LLVector4a& min = addingExtents[0];
- const LLVector4a& max = addingExtents[1];
-
- // Get coordinates of all corners of the bounding box
- LLVector3 corners[] =
- {
- LLVector3(min[0], min[1], min[2]),
- LLVector3(min[0], min[1], max[2]),
- LLVector3(min[0], max[1], min[2]),
- LLVector3(min[0], max[1], max[2]),
- LLVector3(max[0], min[1], min[2]),
- LLVector3(max[0], min[1], max[2]),
- LLVector3(max[0], max[1], min[2]),
- LLVector3(max[0], max[1], max[2])
- };
-
- // New extents (to be expanded)
- LLVector3 extents[] =
- {
- LLVector3(mExtents[0].getF32ptr()),
- LLVector3(mExtents[1].getF32ptr())
- };
-
- LLQuaternion backwardRotation = ~currentTransform.getWorldRotation();
- for (LLVector3& corner : corners)
- {
- // Make coordinates relative to the current position
- corner -= currentTransform.getWorldPosition();
- // Rotate coordinates backward to the current rotation
- corner.rotVec(backwardRotation);
- // Expand root extents on the current corner
- for (int j = 0; j < 3; ++j)
- {
- if (corner[j] < extents[0][j])
- extents[0][j] = corner[j];
- if (corner[j] > extents[1][j])
- extents[1][j] = corner[j];
- }
- }
-
- // Set new expanded extents
- mExtents[0].load3(extents[0].mV);
- mExtents[1].load3(extents[1].mV);
-
- // Calculate new center and size
- mBounds[0].setAdd(mExtents[0], mExtents[1]);
- mBounds[0].mul(0.5f);
- mBounds[1].setSub(mExtents[0], mExtents[1]);
- mBounds[1].mul(0.5f);
+ // Get coordinates of the adding extents
+ const LLVector4a& min = addingExtents[0];
+ const LLVector4a& max = addingExtents[1];
+
+ // Get coordinates of all corners of the bounding box
+ LLVector3 corners[] =
+ {
+ LLVector3(min[0], min[1], min[2]),
+ LLVector3(min[0], min[1], max[2]),
+ LLVector3(min[0], max[1], min[2]),
+ LLVector3(min[0], max[1], max[2]),
+ LLVector3(max[0], min[1], min[2]),
+ LLVector3(max[0], min[1], max[2]),
+ LLVector3(max[0], max[1], min[2]),
+ LLVector3(max[0], max[1], max[2])
+ };
+
+ // New extents (to be expanded)
+ LLVector3 extents[] =
+ {
+ LLVector3(mExtents[0].getF32ptr()),
+ LLVector3(mExtents[1].getF32ptr())
+ };
+
+ LLQuaternion backwardRotation = ~currentTransform.getWorldRotation();
+ for (LLVector3& corner : corners)
+ {
+ // Make coordinates relative to the current position
+ corner -= currentTransform.getWorldPosition();
+ // Rotate coordinates backward to the current rotation
+ corner.rotVec(backwardRotation);
+ // Expand root extents on the current corner
+ for (int j = 0; j < 3; ++j)
+ {
+ if (corner[j] < extents[0][j])
+ extents[0][j] = corner[j];
+ if (corner[j] > extents[1][j])
+ extents[1][j] = corner[j];
+ }
+ }
+
+ // Set new expanded extents
+ mExtents[0].load3(extents[0].mV);
+ mExtents[1].load3(extents[1].mV);
+
+ // Calculate new center and size
+ mBounds[0].setAdd(mExtents[0], mExtents[1]);
+ mBounds[0].mul(0.5f);
+ mBounds[1].setSub(mExtents[0], mExtents[1]);
+ mBounds[1].mul(0.5f);
}
BOOL LLSpatialGroup::addObject(LLDrawable *drawablep)
{
- if(!drawablep)
- {
- return FALSE;
- }
- {
- drawablep->setGroup(this);
- setState(OBJECT_DIRTY | GEOM_DIRTY);
- setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
- gPipeline.markRebuild(this);
- if (drawablep->isSpatialBridge())
- {
- mBridgeList.push_back((LLSpatialBridge*) drawablep);
- }
- if (drawablep->getRadius() > 1.f)
- {
- setState(IMAGE_DIRTY);
- }
- }
-
- return TRUE;
+ if(!drawablep)
+ {
+ return FALSE;
+ }
+ {
+ drawablep->setGroup(this);
+ setState(OBJECT_DIRTY | GEOM_DIRTY);
+ setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
+ gPipeline.markRebuild(this);
+ if (drawablep->isSpatialBridge())
+ {
+ mBridgeList.push_back((LLSpatialBridge*) drawablep);
+ }
+ if (drawablep->getRadius() > 1.f)
+ {
+ setState(IMAGE_DIRTY);
+ }
+ }
+
+ return TRUE;
}
void LLSpatialGroup::rebuildGeom()
{
- if (!isDead())
- {
- getSpatialPartition()->rebuildGeom(this);
+ if (!isDead())
+ {
+ getSpatialPartition()->rebuildGeom(this);
- if (hasState(LLSpatialGroup::MESH_DIRTY))
- {
- gPipeline.markMeshDirty(this);
- }
- }
+ if (hasState(LLSpatialGroup::MESH_DIRTY))
+ {
+ gPipeline.markMeshDirty(this);
+ }
+ }
}
void LLSpatialGroup::rebuildMesh()
{
- if (!isDead())
- {
- getSpatialPartition()->rebuildMesh(this);
- }
+ if (!isDead())
+ {
+ getSpatialPartition()->rebuildMesh(this);
+ }
}
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
- if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
- {
- return;
- }
-
- if (group->changeLOD())
- {
- group->mLastUpdateDistance = group->mDistance;
- group->mLastUpdateViewAngle = group->mViewAngle;
- }
-
+ if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ return;
+ }
+
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ group->mLastUpdateViewAngle = group->mViewAngle;
+ }
+
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
- group->clearDrawMap();
-
- //get geometry count
- U32 index_count = 0;
- U32 vertex_count = 0;
+ group->clearDrawMap();
+
+ //get geometry count
+ U32 index_count = 0;
+ U32 vertex_count = 0;
addGeometryCount(group, vertex_count, index_count);
-
- if (vertex_count > 0 && index_count > 0)
- { //create vertex buffer containing volume geometry for this node
- {
- group->mBuilt = 1.f;
- if (group->mVertexBuffer.isNull() ||
+
+ if (vertex_count > 0 && index_count > 0)
+ { //create vertex buffer containing volume geometry for this node
+ {
+ group->mBuilt = 1.f;
+ if (group->mVertexBuffer.isNull() ||
group->mVertexBuffer->getNumVerts() != vertex_count ||
group->mVertexBuffer->getNumVerts() != index_count)
- {
- group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask);
- if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count))
- {
- LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to "
- << vertex_count << " vertices and "
- << index_count << " indices" << LL_ENDL;
- group->mVertexBuffer = NULL;
- group->mBufferMap.clear();
- }
- }
- }
-
- if (group->mVertexBuffer)
- {
- getGeometry(group);
- }
- }
- else
- {
- group->mVertexBuffer = NULL;
- group->mBufferMap.clear();
- }
-
- group->mLastUpdateTime = gFrameTimeSeconds;
- group->clearState(LLSpatialGroup::GEOM_DIRTY);
+ {
+ group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask);
+ if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count))
+ {
+ LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to "
+ << vertex_count << " vertices and "
+ << index_count << " indices" << LL_ENDL;
+ group->mVertexBuffer = NULL;
+ group->mBufferMap.clear();
+ }
+ }
+ }
+
+ if (group->mVertexBuffer)
+ {
+ getGeometry(group);
+ }
+ }
+ else
+ {
+ group->mVertexBuffer = NULL;
+ group->mBufferMap.clear();
+ }
+
+ group->mLastUpdateTime = gFrameTimeSeconds;
+ group->clearState(LLSpatialGroup::GEOM_DIRTY);
}
@@ -403,198 +404,198 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)
LLSpatialGroup* LLSpatialGroup::getParent()
{
- return (LLSpatialGroup*)LLViewerOctreeGroup::getParent();
- }
+ return (LLSpatialGroup*)LLViewerOctreeGroup::getParent();
+ }
BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
-
- if(!drawablep)
- {
- return FALSE;
- }
-
- unbound();
- if (mOctreeNode && !from_octree)
- {
- drawablep->setGroup(NULL);
- }
- else
- {
- drawablep->setGroup(NULL);
- setState(GEOM_DIRTY);
- gPipeline.markRebuild(this);
-
- if (drawablep->isSpatialBridge())
- {
- for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i)
- {
- if (*i == drawablep)
- {
- mBridgeList.erase(i);
- break;
- }
- }
- }
-
- if (getElementCount() == 0)
- { //delete draw map on last element removal since a rebuild might never happen
- clearDrawMap();
- }
- }
- return TRUE;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+
+ if(!drawablep)
+ {
+ return FALSE;
+ }
+
+ unbound();
+ if (mOctreeNode && !from_octree)
+ {
+ drawablep->setGroup(NULL);
+ }
+ else
+ {
+ drawablep->setGroup(NULL);
+ setState(GEOM_DIRTY);
+ gPipeline.markRebuild(this);
+
+ if (drawablep->isSpatialBridge())
+ {
+ for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i)
+ {
+ if (*i == drawablep)
+ {
+ mBridgeList.erase(i);
+ break;
+ }
+ }
+ }
+
+ if (getElementCount() == 0)
+ { //delete draw map on last element removal since a rebuild might never happen
+ clearDrawMap();
+ }
+ }
+ return TRUE;
}
void LLSpatialGroup::shift(const LLVector4a &offset)
{
- LLVector4a t = mOctreeNode->getCenter();
- t.add(offset);
- mOctreeNode->setCenter(t);
- mOctreeNode->updateMinMax();
- mBounds[0].add(offset);
- mExtents[0].add(offset);
- mExtents[1].add(offset);
- mObjectBounds[0].add(offset);
- mObjectExtents[0].add(offset);
- mObjectExtents[1].add(offset);
-
- if (!getSpatialPartition()->mRenderByGroup &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)
- {
- setState(GEOM_DIRTY);
- gPipeline.markRebuild(this);
- }
+ LLVector4a t = mOctreeNode->getCenter();
+ t.add(offset);
+ mOctreeNode->setCenter(t);
+ mOctreeNode->updateMinMax();
+ mBounds[0].add(offset);
+ mExtents[0].add(offset);
+ mExtents[1].add(offset);
+ mObjectBounds[0].add(offset);
+ mObjectExtents[0].add(offset);
+ mObjectExtents[1].add(offset);
+
+ if (!getSpatialPartition()->mRenderByGroup &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)
+ {
+ setState(GEOM_DIRTY);
+ gPipeline.markRebuild(this);
+ }
}
class LLSpatialSetState : public OctreeTraveler
{
public:
- U32 mState;
- LLSpatialSetState(U32 state) : mState(state) { }
- virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }
+ U32 mState;
+ LLSpatialSetState(U32 state) : mState(state) { }
+ virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }
};
class LLSpatialSetStateDiff : public LLSpatialSetState
{
public:
- LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { }
-
- virtual void traverse(const OctreeNode* n)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (!group->hasState(mState))
- {
- OctreeTraveler::traverse(n);
- }
- }
+ LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { }
+
+ virtual void traverse(const OctreeNode* n)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
+
+ if (!group->hasState(mState))
+ {
+ OctreeTraveler::traverse(n);
+ }
+ }
};
-void LLSpatialGroup::setState(U32 state, S32 mode)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
-
- llassert(state <= LLSpatialGroup::STATE_MASK);
-
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialSetStateDiff setter(state);
- setter.traverse(mOctreeNode);
- }
- else
- {
- LLSpatialSetState setter(state);
- setter.traverse(mOctreeNode);
- }
- }
- else
- {
- mState |= state;
- }
+void LLSpatialGroup::setState(U32 state, S32 mode)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+
+ llassert(state <= LLSpatialGroup::STATE_MASK);
+
+ if (mode > STATE_MODE_SINGLE)
+ {
+ if (mode == STATE_MODE_DIFF)
+ {
+ LLSpatialSetStateDiff setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ else
+ {
+ LLSpatialSetState setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ }
+ else
+ {
+ mState |= state;
+ }
}
class LLSpatialClearState : public OctreeTraveler
{
public:
- U32 mState;
- LLSpatialClearState(U32 state) : mState(state) { }
- virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); }
+ U32 mState;
+ LLSpatialClearState(U32 state) : mState(state) { }
+ virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); }
};
class LLSpatialClearStateDiff : public LLSpatialClearState
{
public:
- LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { }
-
- virtual void traverse(const OctreeNode* n)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (group->hasState(mState))
- {
- OctreeTraveler::traverse(n);
- }
- }
+ LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { }
+
+ virtual void traverse(const OctreeNode* n)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
+
+ if (group->hasState(mState))
+ {
+ OctreeTraveler::traverse(n);
+ }
+ }
};
void LLSpatialGroup::clearState(U32 state, S32 mode)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
-
- llassert(state <= LLSpatialGroup::STATE_MASK);
-
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialClearStateDiff clearer(state);
- clearer.traverse(mOctreeNode);
- }
- else
- {
- LLSpatialClearState clearer(state);
- clearer.traverse(mOctreeNode);
- }
- }
- else
- {
- mState &= ~state;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+
+ llassert(state <= LLSpatialGroup::STATE_MASK);
+
+ if (mode > STATE_MODE_SINGLE)
+ {
+ if (mode == STATE_MODE_DIFF)
+ {
+ LLSpatialClearStateDiff clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ else
+ {
+ LLSpatialClearState clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ }
+ else
+ {
+ mState &= ~state;
+ }
}
//======================================
-// Octree Listener Implementation
+// Octree Listener Implementation
//======================================
LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part),
- mObjectBoxSize(1.f),
- mGeometryBytes(0),
- mSurfaceArea(0.f),
- mBuilt(0.f),
- mVertexBuffer(NULL),
- mDistance(0.f),
- mDepth(0.f),
- mLastUpdateDistance(-1.f),
- mLastUpdateTime(gFrameTimeSeconds)
-{
- ll_assert_aligned(this,16);
-
- sNodeCount++;
-
- mViewAngle.splat(0.f);
- mLastUpdateViewAngle.splat(-1.f);
-
- sg_assert(mOctreeNode->getListenerCount() == 0);
- setState(SG_INITIAL_STATE_MASK);
- gPipeline.markRebuild(this);
-
+ mObjectBoxSize(1.f),
+ mGeometryBytes(0),
+ mSurfaceArea(0.f),
+ mBuilt(0.f),
+ mVertexBuffer(NULL),
+ mDistance(0.f),
+ mDepth(0.f),
+ mLastUpdateDistance(-1.f),
+ mLastUpdateTime(gFrameTimeSeconds)
+{
+ ll_assert_aligned(this,16);
+
+ sNodeCount++;
+
+ mViewAngle.splat(0.f);
+ mLastUpdateViewAngle.splat(-1.f);
+
+ sg_assert(mOctreeNode->getListenerCount() == 0);
+ setState(SG_INITIAL_STATE_MASK);
+ gPipeline.markRebuild(this);
+
// let the reflection map manager know about this spatial group
mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this);
@@ -604,141 +605,141 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
void LLSpatialGroup::updateDistance(LLCamera &camera)
{
- if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
- {
- LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL;
+ if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
+ {
+ LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL;
llassert(false);
- return;
- }
+ return;
+ }
- if (gShiftFrame)
- {
- return;
- }
+ if (gShiftFrame)
+ {
+ return;
+ }
#if !LL_RELEASE_FOR_DOWNLOAD
- if (hasState(LLSpatialGroup::OBJECT_DIRTY))
- {
- LL_ERRS() << "Spatial group dirty on distance update." << LL_ENDL;
- }
+ if (hasState(LLSpatialGroup::OBJECT_DIRTY))
+ {
+ LL_ERRS() << "Spatial group dirty on distance update." << LL_ENDL;
+ }
#endif
- if (!isEmpty())
- {
- mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
- (F32) mOctreeNode->getSize().getLength3().getF32();
- mDistance = getSpatialPartition()->calcDistance(this, camera);
- mPixelArea = getSpatialPartition()->calcPixelArea(this, camera);
- }
+ if (!isEmpty())
+ {
+ mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
+ (F32) mOctreeNode->getSize().getLength3().getF32();
+ mDistance = getSpatialPartition()->calcDistance(this, camera);
+ mPixelArea = getSpatialPartition()->calcPixelArea(this, camera);
+ }
}
F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
-
- LLVector4a eye;
- LLVector4a origin;
- origin.load3(camera.getOrigin().mV);
-
- eye.setSub(group->mObjectBounds[0], origin);
-
- F32 dist = 0.f;
-
- if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end())
- {
- LLVector4a v = eye;
-
- dist = eye.getLength3().getF32();
- eye.normalize3fast();
-
- if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY))
- {
- if (!group->getSpatialPartition()->isBridge())
- {
- LLVector4a view_angle = eye;
-
- LLVector4a diff;
- diff.setSub(view_angle, group->mLastUpdateViewAngle);
-
- if (diff.getLength3().getF32() > 0.64f)
- {
- group->mViewAngle = view_angle;
- group->mLastUpdateViewAngle = view_angle;
- //for occasional alpha sorting within the group
- //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order,
- //not setting this node to dirty would be a very good thing
- group->setState(LLSpatialGroup::ALPHA_DIRTY);
- gPipeline.markRebuild(group);
- }
- }
- }
-
- //calculate depth of node for alpha sorting
-
- LLVector3 at = camera.getAtAxis();
-
- LLVector4a ata;
- ata.load3(at.mV);
-
- LLVector4a t = ata;
- //front of bounding box
- t.mul(0.25f);
- t.mul(group->mObjectBounds[1]);
- v.sub(t);
-
- group->mDepth = v.dot3(ata).getF32();
- }
- else
- {
- dist = eye.getLength3().getF32();
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+
+ LLVector4a eye;
+ LLVector4a origin;
+ origin.load3(camera.getOrigin().mV);
+
+ eye.setSub(group->mObjectBounds[0], origin);
+
+ F32 dist = 0.f;
+
+ if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end())
+ {
+ LLVector4a v = eye;
+
+ dist = eye.getLength3().getF32();
+ eye.normalize3fast();
+
+ if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY))
+ {
+ if (!group->getSpatialPartition()->isBridge())
+ {
+ LLVector4a view_angle = eye;
+
+ LLVector4a diff;
+ diff.setSub(view_angle, group->mLastUpdateViewAngle);
+
+ if (diff.getLength3().getF32() > 0.64f)
+ {
+ group->mViewAngle = view_angle;
+ group->mLastUpdateViewAngle = view_angle;
+ //for occasional alpha sorting within the group
+ //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order,
+ //not setting this node to dirty would be a very good thing
+ group->setState(LLSpatialGroup::ALPHA_DIRTY);
+ gPipeline.markRebuild(group);
+ }
+ }
+ }
+
+ //calculate depth of node for alpha sorting
+
+ LLVector3 at = camera.getAtAxis();
+
+ LLVector4a ata;
+ ata.load3(at.mV);
+
+ LLVector4a t = ata;
+ //front of bounding box
+ t.mul(0.25f);
+ t.mul(group->mObjectBounds[1]);
+ v.sub(t);
+
+ group->mDepth = v.dot3(ata).getF32();
+ }
+ else
+ {
+ dist = eye.getLength3().getF32();
+ }
#if !LL_RELEASE
- LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds "
- << group->mObjectBounds[0] << ", " << group->mObjectBounds[1]
+ LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds "
+ << group->mObjectBounds[0] << ", " << group->mObjectBounds[1]
<< " dist " << dist << " radius " << group->mRadius << LL_ENDL;
#endif
- if (dist < 16.f)
- {
- dist /= 16.f;
- dist *= dist;
- dist *= 16.f;
- }
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
- return dist;
+ return dist;
}
F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
{
- return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera);
+ return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera);
}
F32 LLSpatialGroup::getUpdateUrgency() const
{
- if (!isVisible())
- {
- return 0.f;
- }
- else
- {
- F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f;
- return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance;
- }
+ if (!isVisible())
+ {
+ return 0.f;
+ }
+ else
+ {
+ F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f;
+ return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance;
+ }
}
BOOL LLSpatialGroup::changeLOD()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
- if (hasState(ALPHA_DIRTY | OBJECT_DIRTY))
- {
- //a rebuild is going to happen, update distance and LoD
- return TRUE;
- }
+ if (hasState(ALPHA_DIRTY | OBJECT_DIRTY))
+ {
+ //a rebuild is going to happen, update distance and LoD
+ return TRUE;
+ }
- if (getSpatialPartition()->mSlopRatio > 0.f)
- {
- F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius));
+ if (getSpatialPartition()->mSlopRatio > 0.f)
+ {
+ F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius));
// MAINT-8264 - this check is not robust if it needs to work
// for bounding boxes much larger than the actual enclosed
@@ -752,85 +753,85 @@ BOOL LLSpatialGroup::changeLOD()
// was large only due to another error, so this logic did not
// need to be changed.
- if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio)
- {
+ if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio)
+ {
LL_DEBUGS("RiggedBox") << "changeLOD true because of ratio compare "
<< fabsf(ratio) << " " << getSpatialPartition()->mSlopRatio << LL_ENDL;
LL_DEBUGS("RiggedBox") << "sg " << this << "\nmDistance " << mDistance
<< " mLastUpdateDistance " << mLastUpdateDistance
<< " mRadius " << mRadius
- << " fab ratio " << fabsf(ratio)
+ << " fab ratio " << fabsf(ratio)
<< " slop " << getSpatialPartition()->mSlopRatio << LL_ENDL;
-
- return TRUE;
- }
- }
-
- if (needsUpdate())
- {
- return TRUE;
- }
-
- return FALSE;
+
+ return TRUE;
+ }
+ }
+
+ if (needsUpdate())
+ {
+ return TRUE;
+ }
+
+ return FALSE;
}
void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- addObject((LLDrawable*)entry->getDrawable());
- unbound();
- setState(OBJECT_DIRTY);
+ addObject((LLDrawable*)entry->getDrawable());
+ unbound();
+ setState(OBJECT_DIRTY);
}
void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- removeObject((LLDrawable*)entry->getDrawable(), TRUE);
- LLViewerOctreeGroup::handleRemoval(node, entry);
+ removeObject((LLDrawable*)entry->getDrawable(), TRUE);
+ LLViewerOctreeGroup::handleRemoval(node, entry);
}
void LLSpatialGroup::handleDestruction(const TreeNode* node)
{
- if(isDead())
- {
- return;
- }
- setState(DEAD);
-
- for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
- {
- LLViewerOctreeEntry* entry = *i;
-
- if (entry->getGroup() == this)
- {
- if(entry->hasDrawable())
- {
- ((LLDrawable*)entry->getDrawable())->setGroup(NULL);
- }
- }
- }
-
- clearDrawMap();
- mVertexBuffer = NULL;
- mBufferMap.clear();
- sZombieGroups++;
- mOctreeNode = NULL;
+ if(isDead())
+ {
+ return;
+ }
+ setState(DEAD);
+
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
+ {
+ LLViewerOctreeEntry* entry = *i;
+
+ if (entry->getGroup() == this)
+ {
+ if(entry->hasDrawable())
+ {
+ ((LLDrawable*)entry->getDrawable())->setGroup(NULL);
+ }
+ }
+ }
+
+ clearDrawMap();
+ mVertexBuffer = NULL;
+ mBufferMap.clear();
+ sZombieGroups++;
+ mOctreeNode = NULL;
}
-void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
+void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
- if (child->getListenerCount() == 0)
- {
- new LLSpatialGroup(child, getSpatialPartition());
- }
- else
- {
- OCT_ERRS << "LLSpatialGroup redundancy detected." << LL_ENDL;
- }
+ if (child->getListenerCount() == 0)
+ {
+ new LLSpatialGroup(child, getSpatialPartition());
+ }
+ else
+ {
+ OCT_ERRS << "LLSpatialGroup redundancy detected." << LL_ENDL;
+ }
- unbound();
+ unbound();
- assert_states_valid(this);
+ assert_states_valid(this);
}
//virtual
@@ -871,41 +872,41 @@ void LLSpatialGroup::rebound()
void LLSpatialGroup::destroyGLState(bool keep_occlusion)
{
- setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
-
- if (!keep_occlusion)
- { //going to need a rebuild
- gPipeline.markRebuild(this);
- }
-
- mLastUpdateTime = gFrameTimeSeconds;
- mVertexBuffer = NULL;
- mBufferMap.clear();
-
- clearDrawMap();
-
- if (!keep_occlusion)
- {
- releaseOcclusionQueryObjectNames();
- }
-
-
- for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
- for (S32 j = 0; j < drawable->getNumFaces(); j++)
- {
- LLFace* facep = drawable->getFace(j);
- if (facep)
- {
- facep->clearVertexBuffer();
- }
- }
- }
+ setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
+
+ if (!keep_occlusion)
+ { //going to need a rebuild
+ gPipeline.markRebuild(this);
+ }
+
+ mLastUpdateTime = gFrameTimeSeconds;
+ mVertexBuffer = NULL;
+ mBufferMap.clear();
+
+ clearDrawMap();
+
+ if (!keep_occlusion)
+ {
+ releaseOcclusionQueryObjectNames();
+ }
+
+
+ for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+ for (S32 j = 0; j < drawable->getNumFaces(); j++)
+ {
+ LLFace* facep = drawable->getFace(j);
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+ }
}
//==============================================
@@ -913,14 +914,14 @@ void LLSpatialGroup::destroyGLState(bool keep_occlusion)
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp)
: mRenderByGroup(render_by_group), mBridge(NULL)
{
- mRegionp = regionp;
- mPartitionType = LLViewerRegion::PARTITION_NONE;
- mVertexDataMask = data_mask;
- mDepthMask = FALSE;
- mSlopRatio = 0.25f;
- mInfiniteFarClip = FALSE;
+ mRegionp = regionp;
+ mPartitionType = LLViewerRegion::PARTITION_NONE;
+ mVertexDataMask = data_mask;
+ mDepthMask = FALSE;
+ mSlopRatio = 0.25f;
+ mInfiniteFarClip = FALSE;
- new LLSpatialGroup(mOctree, this);
+ new LLSpatialGroup(mOctree, this);
}
@@ -932,391 +933,391 @@ LLSpatialPartition::~LLSpatialPartition()
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
{
LL_PROFILE_ZONE_SCOPED;
- drawablep->updateSpatialExtents();
-
- //keep drawable from being garbage collected
- LLPointer<LLDrawable> ptr = drawablep;
-
- if(!drawablep->getGroup())
- {
- assert_octree_valid(mOctree);
- mOctree->insert(drawablep->getEntry());
- assert_octree_valid(mOctree);
- }
-
- LLSpatialGroup* group = drawablep->getSpatialGroup();
- //llassert(group != NULL);
-
- if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
- {
- group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
- }
-
- return group;
+ drawablep->updateSpatialExtents();
+
+ //keep drawable from being garbage collected
+ LLPointer<LLDrawable> ptr = drawablep;
+
+ if(!drawablep->getGroup())
+ {
+ assert_octree_valid(mOctree);
+ mOctree->insert(drawablep->getEntry());
+ assert_octree_valid(mOctree);
+ }
+
+ LLSpatialGroup* group = drawablep->getSpatialGroup();
+ //llassert(group != NULL);
+
+ if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
+ {
+ group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
+ }
+
+ return group;
}
BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
{
LL_PROFILE_ZONE_SCOPED;
- if (!curp->removeObject(drawablep))
- {
- OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL;
- }
- else
- {
- drawablep->setGroup(NULL);
- }
-
- assert_octree_valid(mOctree);
-
- return TRUE;
+ if (!curp->removeObject(drawablep))
+ {
+ OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL;
+ }
+ else
+ {
+ drawablep->setGroup(NULL);
+ }
+
+ assert_octree_valid(mOctree);
+
+ return TRUE;
}
void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate)
{
LL_PROFILE_ZONE_SCOPED;
- // sanity check submitted by open source user bushing Spatula
- // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
- if (!drawablep)
- {
- OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << LL_ENDL;
- return;
- }
-
- BOOL was_visible = curp ? curp->isVisible() : FALSE;
-
- if (curp && curp->getSpatialPartition() != this)
- {
- //keep drawable from being garbage collected
- LLPointer<LLDrawable> ptr = drawablep;
- if (curp->getSpatialPartition()->remove(drawablep, curp))
- {
- put(drawablep, was_visible);
- return;
- }
- else
- {
- OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << LL_ENDL;
- }
- }
-
- if (curp && curp->updateInGroup(drawablep, immediate))
- {
- // Already updated, don't need to do anything
- assert_octree_valid(mOctree);
- return;
- }
-
- //keep drawable from being garbage collected
- LLPointer<LLDrawable> ptr = drawablep;
- if (curp && !remove(drawablep, curp))
- {
- OCT_ERRS << "Move couldn't find existing spatial group!" << LL_ENDL;
- }
-
- put(drawablep, was_visible);
+ // sanity check submitted by open source user bushing Spatula
+ // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
+ if (!drawablep)
+ {
+ OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << LL_ENDL;
+ return;
+ }
+
+ BOOL was_visible = curp ? curp->isVisible() : FALSE;
+
+ if (curp && curp->getSpatialPartition() != this)
+ {
+ //keep drawable from being garbage collected
+ LLPointer<LLDrawable> ptr = drawablep;
+ if (curp->getSpatialPartition()->remove(drawablep, curp))
+ {
+ put(drawablep, was_visible);
+ return;
+ }
+ else
+ {
+ OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << LL_ENDL;
+ }
+ }
+
+ if (curp && curp->updateInGroup(drawablep, immediate))
+ {
+ // Already updated, don't need to do anything
+ assert_octree_valid(mOctree);
+ return;
+ }
+
+ //keep drawable from being garbage collected
+ LLPointer<LLDrawable> ptr = drawablep;
+ if (curp && !remove(drawablep, curp))
+ {
+ OCT_ERRS << "Move couldn't find existing spatial group!" << LL_ENDL;
+ }
+
+ put(drawablep, was_visible);
}
class LLSpatialShift : public OctreeTraveler
{
public:
- const LLVector4a& mOffset;
+ const LLVector4a& mOffset;
- LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { }
- virtual void visit(const OctreeNode* branch)
- {
- ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);
- }
+ LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { }
+ virtual void visit(const OctreeNode* branch)
+ {
+ ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);
+ }
};
void LLSpatialPartition::shift(const LLVector4a &offset)
{ //shift octree node bounding boxes by offset
- LLSpatialShift shifter(offset);
- shifter.traverse(mOctree);
+ LLSpatialShift shifter(offset);
+ shifter.traverse(mOctree);
}
class LLOctreeCull : public LLViewerOctreeCull
{
public:
- LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {}
+ LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {}
- virtual bool earlyFail(LLViewerOctreeGroup* base_group)
- {
+ virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+ {
if (LLPipeline::sReflectionRender)
{
return false;
}
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- group->checkOcclusion();
-
- if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
- LLPipeline::sUseOcclusion && //ignore occlusion if disabled
- group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- gPipeline.markOccluder(group);
- return true;
- }
-
- return false;
- }
-
- virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
- {
- S32 res = AABBInFrustumNoFarClipGroupBounds(group);
- if (res != 0)
- {
- res = llmin(res, AABBSphereIntersectGroupExtents(group));
- }
- return res;
- }
-
- virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
- {
- S32 res = AABBInFrustumNoFarClipObjectBounds(group);
- if (res != 0)
- {
- res = llmin(res, AABBSphereIntersectObjectExtents(group));
- }
- return res;
- }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- /*if (group->needsUpdate() ||
- group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
- {
- group->doOcclusion(mCamera);
- }*/
- gPipeline.markNotCulled(group, *mCamera);
- }
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+ group->checkOcclusion();
+
+ if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
+ LLPipeline::sUseOcclusion && //ignore occlusion if disabled
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ gPipeline.markOccluder(group);
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
+ {
+ S32 res = AABBInFrustumNoFarClipGroupBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBSphereIntersectGroupExtents(group));
+ }
+ return res;
+ }
+
+ virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
+ {
+ S32 res = AABBInFrustumNoFarClipObjectBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBSphereIntersectObjectExtents(group));
+ }
+ return res;
+ }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+ /*if (group->needsUpdate() ||
+ group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+ {
+ group->doOcclusion(mCamera);
+ }*/
+ gPipeline.markNotCulled(group, *mCamera);
+ }
};
class LLOctreeCullNoFarClip : public LLOctreeCull
{
-public:
- LLOctreeCullNoFarClip(LLCamera* camera)
- : LLOctreeCull(camera) { }
+public:
+ LLOctreeCullNoFarClip(LLCamera* camera)
+ : LLOctreeCull(camera) { }
- virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
- {
- return AABBInFrustumNoFarClipGroupBounds(group);
- }
+ virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
+ {
+ return AABBInFrustumNoFarClipGroupBounds(group);
+ }
- virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
- {
- S32 res = AABBInFrustumNoFarClipObjectBounds(group);
- return res;
- }
+ virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
+ {
+ S32 res = AABBInFrustumNoFarClipObjectBounds(group);
+ return res;
+ }
};
class LLOctreeCullShadow : public LLOctreeCull
{
public:
- LLOctreeCullShadow(LLCamera* camera)
- : LLOctreeCull(camera) { }
-
- virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
- {
- return AABBInFrustumGroupBounds(group);
- }
-
- virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
- {
- return AABBInFrustumObjectBounds(group);
- }
+ LLOctreeCullShadow(LLCamera* camera)
+ : LLOctreeCull(camera) { }
+
+ virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
+ {
+ return AABBInFrustumGroupBounds(group);
+ }
+
+ virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
+ {
+ return AABBInFrustumObjectBounds(group);
+ }
};
class LLOctreeCullVisExtents: public LLOctreeCullShadow
{
public:
- LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)
- : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { }
-
- virtual bool earlyFail(LLViewerOctreeGroup* base_group)
- {
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
-
- if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
- LLPipeline::sUseOcclusion && //ignore occlusion if disabled
- group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- return true;
- }
-
- return false;
- }
-
- virtual void traverse(const OctreeNode* n)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (earlyFail(group))
- {
- return;
- }
-
- if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||
- mRes == 2)
- { //don't need to do frustum check
- OctreeTraveler::traverse(n);
- }
- else
- {
- mRes = frustumCheck(group);
-
- if (mRes)
- { //at least partially in, run on down
- OctreeTraveler::traverse(n);
- }
-
- mRes = 0;
- }
- }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
-
- llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty());
-
- if (mRes < 2)
- {
- if (AABBInFrustumObjectBounds(group) > 0)
- {
- mEmpty = FALSE;
- const LLVector4a* exts = group->getObjectExtents();
- update_min_max(mMin, mMax, exts[0]);
- update_min_max(mMin, mMax, exts[1]);
- }
- }
- else
- {
- mEmpty = FALSE;
- const LLVector4a* exts = group->getExtents();
- update_min_max(mMin, mMax, exts[0]);
- update_min_max(mMin, mMax, exts[1]);
- }
- }
-
- BOOL mEmpty;
- LLVector4a& mMin;
- LLVector4a& mMax;
+ LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)
+ : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { }
+
+ virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
+ if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
+ LLPipeline::sUseOcclusion && //ignore occlusion if disabled
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void traverse(const OctreeNode* n)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
+
+ if (earlyFail(group))
+ {
+ return;
+ }
+
+ if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||
+ mRes == 2)
+ { //don't need to do frustum check
+ OctreeTraveler::traverse(n);
+ }
+ else
+ {
+ mRes = frustumCheck(group);
+
+ if (mRes)
+ { //at least partially in, run on down
+ OctreeTraveler::traverse(n);
+ }
+
+ mRes = 0;
+ }
+ }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
+ llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty());
+
+ if (mRes < 2)
+ {
+ if (AABBInFrustumObjectBounds(group) > 0)
+ {
+ mEmpty = FALSE;
+ const LLVector4a* exts = group->getObjectExtents();
+ update_min_max(mMin, mMax, exts[0]);
+ update_min_max(mMin, mMax, exts[1]);
+ }
+ }
+ else
+ {
+ mEmpty = FALSE;
+ const LLVector4a* exts = group->getExtents();
+ update_min_max(mMin, mMax, exts[0]);
+ update_min_max(mMin, mMax, exts[1]);
+ }
+ }
+
+ BOOL mEmpty;
+ LLVector4a& mMin;
+ LLVector4a& mMax;
};
class LLOctreeCullDetectVisible: public LLOctreeCullShadow
{
public:
- LLOctreeCullDetectVisible(LLCamera* camera)
- : LLOctreeCullShadow(camera), mResult(FALSE) { }
-
- virtual bool earlyFail(LLViewerOctreeGroup* base_group)
- {
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
-
- if (mResult || //already found a node, don't check any more
- (group->getOctreeNode()->getParent() && //never occlusion cull the root node
- LLPipeline::sUseOcclusion && //ignore occlusion if disabled
- group->isOcclusionState(LLSpatialGroup::OCCLUDED)))
- {
- return true;
- }
-
- return false;
- }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- if (base_group->isVisible())
- {
- mResult = TRUE;
- }
- }
-
- BOOL mResult;
+ LLOctreeCullDetectVisible(LLCamera* camera)
+ : LLOctreeCullShadow(camera), mResult(FALSE) { }
+
+ virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
+ if (mResult || //already found a node, don't check any more
+ (group->getOctreeNode()->getParent() && //never occlusion cull the root node
+ LLPipeline::sUseOcclusion && //ignore occlusion if disabled
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ if (base_group->isVisible())
+ {
+ mResult = TRUE;
+ }
+ }
+
+ BOOL mResult;
};
class LLOctreeSelect : public LLOctreeCull
{
public:
- LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results)
- : LLOctreeCull(camera), mResults(results) { }
-
- virtual bool earlyFail(LLViewerOctreeGroup* group) { return false; }
- virtual void preprocess(LLViewerOctreeGroup* group) { }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- OctreeNode* branch = group->getOctreeNode();
-
- for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
- if (!drawable->isDead())
- {
- if (drawable->isSpatialBridge())
- {
- drawable->setVisible(*mCamera, mResults, TRUE);
- }
- else
- {
- mResults->push_back(drawable);
- }
- }
- }
- }
-
- std::vector<LLDrawable*>* mResults;
+ LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results)
+ : LLOctreeCull(camera), mResults(results) { }
+
+ virtual bool earlyFail(LLViewerOctreeGroup* group) { return false; }
+ virtual void preprocess(LLViewerOctreeGroup* group) { }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+ OctreeNode* branch = group->getOctreeNode();
+
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+ if (!drawable->isDead())
+ {
+ if (drawable->isSpatialBridge())
+ {
+ drawable->setVisible(*mCamera, mResults, TRUE);
+ }
+ else
+ {
+ mResults->push_back(drawable);
+ }
+ }
+ }
+ }
+
+ std::vector<LLDrawable*>* mResults;
};
void drawBox(const LLVector3& c, const LLVector3& r)
{
- LLVertexBuffer::unbind();
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- //left front
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
- //right front
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV);
- //right back
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV);
- //left back
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV);
- //left front
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
- gGL.end();
-
- //bottom
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV);
- gGL.end();
-
- //top
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV);
- gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV);
- gGL.end();
+ LLVertexBuffer::unbind();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ //left front
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
+ //right front
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV);
+ //right back
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV);
+ //left back
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV);
+ //left front
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
+ gGL.end();
+
+ //bottom
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV);
+ gGL.end();
+
+ //top
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV);
+ gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV);
+ gGL.end();
}
void drawBox(const LLVector4a& c, const LLVector4a& r)
{
- drawBox(reinterpret_cast<const LLVector3&>(c), reinterpret_cast<const LLVector3&>(r));
+ drawBox(reinterpret_cast<const LLVector3&>(c), reinterpret_cast<const LLVector3&>(r));
}
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
@@ -1324,53 +1325,53 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
if (!pos.isFinite() || !size.isFinite())
return;
- LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
- LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
- LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
- LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
-
- gGL.begin(LLRender::LINES);
-
- //top
- gGL.vertex3fv((pos+v1).mV);
- gGL.vertex3fv((pos+v2).mV);
- gGL.vertex3fv((pos+v2).mV);
- gGL.vertex3fv((pos+v3).mV);
- gGL.vertex3fv((pos+v3).mV);
- gGL.vertex3fv((pos+v4).mV);
- gGL.vertex3fv((pos+v4).mV);
- gGL.vertex3fv((pos+v1).mV);
-
- //bottom
- gGL.vertex3fv((pos-v1).mV);
- gGL.vertex3fv((pos-v2).mV);
- gGL.vertex3fv((pos-v2).mV);
- gGL.vertex3fv((pos-v3).mV);
- gGL.vertex3fv((pos-v3).mV);
- gGL.vertex3fv((pos-v4).mV);
- gGL.vertex3fv((pos-v4).mV);
- gGL.vertex3fv((pos-v1).mV);
-
- //right
- gGL.vertex3fv((pos+v1).mV);
- gGL.vertex3fv((pos-v3).mV);
-
- gGL.vertex3fv((pos+v4).mV);
- gGL.vertex3fv((pos-v2).mV);
-
- //left
- gGL.vertex3fv((pos+v2).mV);
- gGL.vertex3fv((pos-v4).mV);
-
- gGL.vertex3fv((pos+v3).mV);
- gGL.vertex3fv((pos-v1).mV);
-
- gGL.end();
+ LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
+ LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
+ LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
+ LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
+
+ gGL.begin(LLRender::LINES);
+
+ //top
+ gGL.vertex3fv((pos+v1).mV);
+ gGL.vertex3fv((pos+v2).mV);
+ gGL.vertex3fv((pos+v2).mV);
+ gGL.vertex3fv((pos+v3).mV);
+ gGL.vertex3fv((pos+v3).mV);
+ gGL.vertex3fv((pos+v4).mV);
+ gGL.vertex3fv((pos+v4).mV);
+ gGL.vertex3fv((pos+v1).mV);
+
+ //bottom
+ gGL.vertex3fv((pos-v1).mV);
+ gGL.vertex3fv((pos-v2).mV);
+ gGL.vertex3fv((pos-v2).mV);
+ gGL.vertex3fv((pos-v3).mV);
+ gGL.vertex3fv((pos-v3).mV);
+ gGL.vertex3fv((pos-v4).mV);
+ gGL.vertex3fv((pos-v4).mV);
+ gGL.vertex3fv((pos-v1).mV);
+
+ //right
+ gGL.vertex3fv((pos+v1).mV);
+ gGL.vertex3fv((pos-v3).mV);
+
+ gGL.vertex3fv((pos+v4).mV);
+ gGL.vertex3fv((pos-v2).mV);
+
+ //left
+ gGL.vertex3fv((pos+v2).mV);
+ gGL.vertex3fv((pos-v4).mV);
+
+ gGL.vertex3fv((pos+v3).mV);
+ gGL.vertex3fv((pos-v1).mV);
+
+ gGL.end();
}
void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
{
- drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
+ drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
}
@@ -1381,49 +1382,49 @@ void LLSpatialPartition::restoreGL()
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
- LLVector4a visMina, visMaxa;
- visMina.load3(visMin.mV);
- visMaxa.load3(visMax.mV);
+ LLVector4a visMina, visMaxa;
+ visMina.load3(visMin.mV);
+ visMaxa.load3(visMax.mV);
- {
- LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
- group->rebound();
- }
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
+ }
- LLOctreeCullVisExtents vis(&camera, visMina, visMaxa);
- vis.traverse(mOctree);
+ LLOctreeCullVisExtents vis(&camera, visMina, visMaxa);
+ vis.traverse(mOctree);
- visMin.set(visMina.getF32ptr());
- visMax.set(visMaxa.getF32ptr());
- return vis.mEmpty;
+ visMin.set(visMina.getF32ptr());
+ visMax.set(visMaxa.getF32ptr());
+ return vis.mEmpty;
}
BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera)
{
- LLOctreeCullDetectVisible vis(&camera);
- vis.traverse(mOctree);
- return vis.mResult;
+ LLOctreeCullDetectVisible vis(&camera);
+ vis.traverse(mOctree);
+ return vis.mResult;
}
S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
#if LL_OCTREE_PARANOIA_CHECK
- ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
+ ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
#endif
- {
- LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
- group->rebound();
- }
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
+ }
#if LL_OCTREE_PARANOIA_CHECK
- ((LLSpatialGroup*)mOctree->getListener(0))->validate();
+ ((LLSpatialGroup*)mOctree->getListener(0))->validate();
#endif
- LLOctreeSelect selecter(&camera, results);
- selecter.traverse(mOctree);
-
- return 0;
+ LLOctreeSelect selecter(&camera, results);
+ selecter.traverse(mOctree);
+
+ return 0;
}
extern BOOL gCubeSnapshot;
@@ -1432,13 +1433,13 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
#if LL_OCTREE_PARANOIA_CHECK
- ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
+ ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
#endif
- LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
- group->rebound();
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
#if LL_OCTREE_PARANOIA_CHECK
- ((LLSpatialGroup*)mOctree->getListener(0))->validate();
+ ((LLSpatialGroup*)mOctree->getListener(0))->validate();
#endif
if (LLPipeline::sShadowRender)
@@ -1456,132 +1457,132 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
LLOctreeCull culler(&camera);
culler.traverse(mOctree);
}
-
- return 0;
+
+ return 0;
}
void pushVerts(LLDrawInfo* params)
{
- LLRenderPass::applyModelMatrix(*params);
- params->mVertexBuffer->setBuffer();
- params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
- params->mStart, params->mEnd, params->mCount, params->mOffset);
+ LLRenderPass::applyModelMatrix(*params);
+ params->mVertexBuffer->setBuffer();
+ params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
+ params->mStart, params->mEnd, params->mCount, params->mOffset);
}
void pushVerts(LLSpatialGroup* group)
{
- LLDrawInfo* params = NULL;
+ LLDrawInfo* params = NULL;
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
- {
- params = *j;
- pushVerts(params);
- }
- }
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ params = *j;
+ pushVerts(params);
+ }
+ }
}
void pushVerts(LLFace* face)
{
- if (face)
- {
- llassert(face->verify());
+ if (face)
+ {
+ llassert(face->verify());
face->renderIndexed();
- }
+ }
}
void pushVerts(LLDrawable* drawable)
{
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- pushVerts(drawable->getFace(i));
- }
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ pushVerts(drawable->getFace(i));
+ }
}
void pushVerts(LLVolume* volume)
{
- LLVertexBuffer::unbind();
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
- }
+ LLVertexBuffer::unbind();
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
+ }
}
void pushBufferVerts(LLVertexBuffer* buffer)
{
- if (buffer)
- {
- buffer->setBuffer();
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- }
+ if (buffer)
+ {
+ buffer->setBuffer();
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ }
}
void pushBufferVerts(LLSpatialGroup* group, bool push_alpha = true)
{
- if (group->getSpatialPartition()->mRenderByGroup)
- {
- if (!group->mDrawMap.empty())
- {
- LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
- LLRenderPass::applyModelMatrix(*params);
-
- if (push_alpha)
- {
- pushBufferVerts(group->mVertexBuffer);
- }
-
- for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
- {
- for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
- {
- for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k)
- {
- pushBufferVerts(*k);
- }
- }
- }
- }
- }
- /*else
- {
- //const LLVector4a* bounds = group->getBounds();
- //drawBox(bounds[0], bounds[1]);
- }*/
+ if (group->getSpatialPartition()->mRenderByGroup)
+ {
+ if (!group->mDrawMap.empty())
+ {
+ LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
+ LLRenderPass::applyModelMatrix(*params);
+
+ if (push_alpha)
+ {
+ pushBufferVerts(group->mVertexBuffer);
+ }
+
+ for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
+ {
+ for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k)
+ {
+ pushBufferVerts(*k);
+ }
+ }
+ }
+ }
+ }
+ /*else
+ {
+ //const LLVector4a* bounds = group->getBounds();
+ //drawBox(bounds[0], bounds[1]);
+ }*/
}
void pushVertsColorCoded(LLSpatialGroup* group)
{
- LLDrawInfo* params = NULL;
-
- static const LLColor4 colors[] = {
- LLColor4::green,
- LLColor4::green1,
- LLColor4::green2,
- LLColor4::green3,
- LLColor4::green4,
- LLColor4::green5,
- LLColor4::green6
- };
-
- static const U32 col_count = LL_ARRAY_SIZE(colors);
-
- U32 col = 0;
-
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
- {
- params = *j;
- LLRenderPass::applyModelMatrix(*params);
- gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
- params->mVertexBuffer->setBuffer();
- params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
- params->mStart, params->mEnd, params->mCount, params->mOffset);
- col = (col+1)%col_count;
- }
- }
+ LLDrawInfo* params = NULL;
+
+ static const LLColor4 colors[] = {
+ LLColor4::green,
+ LLColor4::green1,
+ LLColor4::green2,
+ LLColor4::green3,
+ LLColor4::green4,
+ LLColor4::green5,
+ LLColor4::green6
+ };
+
+ static const U32 col_count = LL_ARRAY_SIZE(colors);
+
+ U32 col = 0;
+
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ params = *j;
+ LLRenderPass::applyModelMatrix(*params);
+ gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
+ params->mVertexBuffer->setBuffer();
+ params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
+ params->mStart, params->mEnd, params->mCount, params->mOffset);
+ col = (col+1)%col_count;
+ }
+ }
}
// return false if drawable is rigged and:
@@ -1629,7 +1630,7 @@ bool check_rigged_group(LLDrawable* drawable)
last_draw_index = face->getDrawOrderIndex();
}
}
-
+
if (child->mDrawable->getSpatialGroup() != group)
{
llassert(false);
@@ -1643,49 +1644,49 @@ bool check_rigged_group(LLDrawable* drawable)
void renderOctree(LLSpatialGroup* group)
{
- //render solid object bounding box, color
- //coded by buffer usage and activity
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- LLVector4 col;
- if (group->mBuilt > 0.f)
- {
- group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
- col.setVec(0.1f,0.1f,1,0.1f);
-
- {
- LLGLDepthTest gl_depth(FALSE, FALSE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- gGL.diffuseColor4f(1,0,0,group->mBuilt);
- gGL.flush();
- glLineWidth(5.f);
-
- const LLVector4a* bounds = group->getObjectBounds();
- drawBoxOutline(bounds[0], bounds[1]);
- gGL.flush();
- glLineWidth(1.f);
- gGL.flush();
+ //render solid object bounding box, color
+ //coded by buffer usage and activity
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ LLVector4 col;
+ if (group->mBuilt > 0.f)
+ {
+ group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
+ col.setVec(0.1f,0.1f,1,0.1f);
+
+ {
+ LLGLDepthTest gl_depth(FALSE, FALSE);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ gGL.diffuseColor4f(1,0,0,group->mBuilt);
+ gGL.flush();
+ glLineWidth(5.f);
+
+ const LLVector4a* bounds = group->getObjectBounds();
+ drawBoxOutline(bounds[0], bounds[1]);
+ gGL.flush();
+ glLineWidth(1.f);
+ gGL.flush();
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable || drawable->getNumFaces() == 0)
- {
- continue;
- }
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable || drawable->getNumFaces() == 0)
+ {
+ continue;
+ }
llassert(check_rigged_group(drawable));
- if (!group->getSpatialPartition()->isBridge())
- {
- gGL.pushMatrix();
- LLVector3 trans = drawable->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- }
-
+ if (!group->getSpatialPartition()->isBridge())
+ {
+ gGL.pushMatrix();
+ LLVector3 trans = drawable->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ }
+
LLFace* face = drawable->getFace(0);
bool rigged = face->isState(LLFace::RIGGED);
gDebugProgram.bind(rigged);
@@ -1707,11 +1708,11 @@ void renderOctree(LLSpatialGroup* group)
lastMeshId = face->mSkinInfo->mHash;
}
}
- for (S32 j = 0; j < drawable->getNumFaces(); j++)
- {
- LLFace* face = drawable->getFace(j);
- if (face && face->getVertexBuffer())
- {
+ for (S32 j = 0; j < drawable->getNumFaces(); j++)
+ {
+ LLFace* face = drawable->getFace(j);
+ if (face && face->getVertexBuffer())
+ {
LLVOVolume* vol = drawable->getVOVolume();
if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
@@ -1741,40 +1742,40 @@ void renderOctree(LLSpatialGroup* group)
continue;
}
- face->getVertexBuffer()->setBuffer();
- face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
- }
- }
+ face->getVertexBuffer()->setBuffer();
+ face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
+ }
+ }
if (rigged)
{
gGL.popMatrix();
}
- if (!group->getSpatialPartition()->isBridge())
- {
- gGL.popMatrix();
- }
- }
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ if (!group->getSpatialPartition()->isBridge())
+ {
+ gGL.popMatrix();
+ }
+ }
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
gDebugProgram.bind(); // make sure non-rigged variant is bound
- gGL.diffuseColor4f(1,1,1,1);
- }
- }
+ gGL.diffuseColor4f(1,1,1,1);
+ }
+ }
- gGL.diffuseColor4fv(col.mV);
- LLVector4a fudge;
- fudge.splat(0.001f);
+ gGL.diffuseColor4fv(col.mV);
+ LLVector4a fudge;
+ fudge.splat(0.001f);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
- {
- //draw opaque outline
- gGL.diffuseColor4f(0,1,1,1);
+ {
+ //draw opaque outline
+ gGL.diffuseColor4f(0,1,1,1);
- const LLVector4a* bounds = group->getBounds();
- drawBoxOutline(bounds[0], bounds[1]);
- }
+ const LLVector4a* bounds = group->getBounds();
+ drawBoxOutline(bounds[0], bounds[1]);
+ }
}
std::set<LLSpatialGroup*> visible_selected_groups;
@@ -1783,214 +1784,218 @@ std::set<LLSpatialGroup*> visible_selected_groups;
void renderXRay(LLSpatialGroup* group, LLCamera* camera)
{
- BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
- !group->isEmpty();
-
- if (render_objects)
- {
- pushBufferVerts(group, false);
-
- bool selected = false;
-
- for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
- {
- LLDrawable* drawable = (LLDrawable*)(*iter)->getDrawable();
- if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
- {
- selected = true;
- break;
- }
- }
-
- if (selected)
- { //store for rendering occlusion volume as overlay
-
- if (!group->getSpatialPartition()->isBridge())
- {
- visible_selected_groups.insert(group);
- }
- else
- {
- visible_selected_groups.insert(group->getSpatialPartition()->asBridge()->getSpatialGroup());
- }
- }
- }
+ BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
+ !group->isEmpty();
+
+ if (render_objects)
+ {
+ pushBufferVerts(group, false);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*iter)->getDrawable();
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+
+ if (!group->getSpatialPartition()->isBridge())
+ {
+ visible_selected_groups.insert(group);
+ }
+ else
+ {
+ visible_selected_groups.insert(group->getSpatialPartition()->asBridge()->getSpatialGroup());
+ }
+ }
+ }
}
void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
{
- gGL.color4fv(color.mV);
- gGL.begin(LLRender::LINES);
- {
- gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
- gGL.vertex3fv((position + LLVector3(size, 0.f, 0.f)).mV);
- gGL.vertex3fv((position - LLVector3(0.f, size, 0.f)).mV);
- gGL.vertex3fv((position + LLVector3(0.f, size, 0.f)).mV);
- gGL.vertex3fv((position - LLVector3(0.f, 0.f, size)).mV);
- gGL.vertex3fv((position + LLVector3(0.f, 0.f, size)).mV);
- }
- gGL.end();
+ gGL.color4fv(color.mV);
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
+ gGL.vertex3fv((position + LLVector3(size, 0.f, 0.f)).mV);
+ gGL.vertex3fv((position - LLVector3(0.f, size, 0.f)).mV);
+ gGL.vertex3fv((position + LLVector3(0.f, size, 0.f)).mV);
+ gGL.vertex3fv((position - LLVector3(0.f, 0.f, size)).mV);
+ gGL.vertex3fv((position + LLVector3(0.f, 0.f, size)).mV);
+ }
+ gGL.end();
}
void renderUpdateType(LLDrawable* drawablep)
{
- LLViewerObject* vobj = drawablep->getVObj();
- if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType())
- {
- return;
- }
- LLGLEnable blend(GL_BLEND);
- switch (vobj->getLastUpdateType())
- {
- case OUT_FULL:
- gGL.diffuseColor4f(0,1,0,0.5f);
- break;
- case OUT_TERSE_IMPROVED:
- gGL.diffuseColor4f(0,1,1,0.5f);
- break;
- case OUT_FULL_COMPRESSED:
- if (vobj->getLastUpdateCached())
- {
- gGL.diffuseColor4f(1,0,0,0.5f);
- }
- else
- {
- gGL.diffuseColor4f(1,1,0,0.5f);
- }
- break;
- case OUT_FULL_CACHED:
- gGL.diffuseColor4f(0,0,1,0.5f);
- break;
- default:
- LL_WARNS() << "Unknown update_type " << vobj->getLastUpdateType() << LL_ENDL;
- break;
- };
- S32 num_faces = drawablep->getNumFaces();
- if (num_faces)
- {
- for (S32 i = 0; i < num_faces; ++i)
- {
- pushVerts(drawablep->getFace(i));
- }
- }
+ LLViewerObject* vobj = drawablep->getVObj();
+ if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType())
+ {
+ return;
+ }
+ LLGLEnable blend(GL_BLEND);
+ switch (vobj->getLastUpdateType())
+ {
+ case OUT_FULL:
+ gGL.diffuseColor4f(0,1,0,0.5f);
+ break;
+ case OUT_TERSE_IMPROVED:
+ gGL.diffuseColor4f(0,1,1,0.5f);
+ break;
+ case OUT_FULL_COMPRESSED:
+ if (vobj->getLastUpdateCached())
+ {
+ gGL.diffuseColor4f(1,0,0,0.5f);
+ }
+ else
+ {
+ gGL.diffuseColor4f(1,1,0,0.5f);
+ }
+ break;
+ case OUT_FULL_CACHED:
+ gGL.diffuseColor4f(0,0,1,0.5f);
+ break;
+ default:
+ LL_WARNS() << "Unknown update_type " << vobj->getLastUpdateType() << LL_ENDL;
+ break;
+ };
+ S32 num_faces = drawablep->getNumFaces();
+ if (num_faces)
+ {
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ pushVerts(drawablep->getFace(i));
+ }
+ }
}
void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
- if (set_color)
- {
- if (drawable->isSpatialBridge())
- {
- gGL.diffuseColor4f(1,0.5f,0,1); // orange
- }
- else if (drawable->getVOVolume())
- {
+ if (set_color)
+ {
+ if (drawable->isSpatialBridge())
+ {
+ gGL.diffuseColor4f(1,0.5f,0,1); // orange
+ }
+ else if (drawable->getVOVolume())
+ {
if (drawable->isRoot())
- {
- gGL.diffuseColor4f(1,1,0,1); // yellow
- }
- else
- {
- gGL.diffuseColor4f(0,1,0,1); // green
- }
- }
- else if (drawable->getVObj())
- {
- switch (drawable->getVObj()->getPCode())
- {
- case LLViewerObject::LL_VO_SURFACE_PATCH:
- gGL.diffuseColor4f(0,1,1,1); // cyan
- break;
- case LLViewerObject::LL_VO_CLOUDS:
- // no longer used
- break;
- case LLViewerObject::LL_VO_PART_GROUP:
- case LLViewerObject::LL_VO_HUD_PART_GROUP:
- gGL.diffuseColor4f(0,0,1,1); // blue
- break;
- case LLViewerObject::LL_VO_VOID_WATER:
- case LLViewerObject::LL_VO_WATER:
- gGL.diffuseColor4f(0,0.5f,1,1); // medium blue
- break;
- case LL_PCODE_LEGACY_TREE:
- gGL.diffuseColor4f(0,0.5f,0,1); // dark green
- break;
- default:
- LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(drawable->getVObj()->asAvatar());
- if (cav)
- {
- bool has_pos_constraint = (cav->mPositionConstraintFixup != LLVector3());
- bool has_scale_constraint = (cav->mScaleConstraintFixup != 1.0f);
- if (has_pos_constraint || has_scale_constraint)
- {
- gGL.diffuseColor4f(1,0,0,1);
- }
- else
- {
- gGL.diffuseColor4f(0,1,0.5,1);
- }
- }
- else
- {
- gGL.diffuseColor4f(1,0,1,1); // magenta
- }
- break;
- }
- }
- else
- {
- gGL.diffuseColor4f(1,0,0,1);
- }
- }
-
- const LLVector4a* ext;
- LLVector4a pos, size;
-
- if (drawable->getVOVolume())
- {
- //render face bounding boxes
- for (S32 i = 0; i < drawable->getNumFaces(); i++)
- {
- LLFace* facep = drawable->getFace(i);
- if (facep)
- {
- ext = facep->mExtents;
-
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
-
- drawBoxOutline(pos,size);
- }
- }
- }
-
- //render drawable bounding box
- ext = drawable->getSpatialExtents();
-
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
-
- LLViewerObject* vobj = drawable->getVObj();
- if (vobj && vobj->onActiveList())
- {
- gGL.flush();
- glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f));
- //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f));
- stop_glerror();
- drawBoxOutline(pos,size);
- gGL.flush();
- glLineWidth(1.f);
- }
- else
- {
- drawBoxOutline(pos,size);
- }
+ {
+ gGL.diffuseColor4f(1,1,0,1); // yellow
+ }
+ else
+ {
+ gGL.diffuseColor4f(0,1,0,1); // green
+ }
+ }
+ else if (drawable->getVObj())
+ {
+ switch (drawable->getVObj()->getPCode())
+ {
+ case LLViewerObject::LL_VO_SURFACE_PATCH:
+ gGL.diffuseColor4f(0,1,1,1); // cyan
+ break;
+ case LLViewerObject::LL_VO_CLOUDS:
+ // no longer used
+ break;
+ case LLViewerObject::LL_VO_PART_GROUP:
+ case LLViewerObject::LL_VO_HUD_PART_GROUP:
+ gGL.diffuseColor4f(0,0,1,1); // blue
+ break;
+ case LLViewerObject::LL_VO_VOID_WATER:
+ case LLViewerObject::LL_VO_WATER:
+ gGL.diffuseColor4f(0,0.5f,1,1); // medium blue
+ break;
+ case LL_PCODE_LEGACY_TREE:
+ gGL.diffuseColor4f(0,0.5f,0,1); // dark green
+ break;
+ default:
+ LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(drawable->getVObj()->asAvatar());
+ if (cav)
+ {
+ bool has_pos_constraint = (cav->mPositionConstraintFixup != LLVector3());
+ bool has_scale_constraint = (cav->mScaleConstraintFixup != 1.0f);
+ if (has_pos_constraint || has_scale_constraint)
+ {
+ gGL.diffuseColor4f(1,0,0,1);
+ }
+ else
+ {
+ gGL.diffuseColor4f(0,1,0.5,1);
+ }
+ }
+ else
+ {
+ gGL.diffuseColor4f(1,0,1,1); // magenta
+ }
+ break;
+ }
+ }
+ else
+ {
+ gGL.diffuseColor4f(1,0,0,1);
+ }
+ }
+
+ const LLVector4a* ext;
+ LLVector4a pos, size;
+
+ if (drawable->getVOVolume())
+ {
+ //render face bounding boxes
+ for (S32 i = 0; i < drawable->getNumFaces(); i++)
+ {
+ LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ ext = facep->mExtents;
+
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+
+ drawBoxOutline(pos,size);
+ }
+ }
+ }
+
+ //render drawable bounding box
+ ext = drawable->getSpatialExtents();
+
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+
+ LLViewerObject* vobj = drawable->getVObj();
+ if (vobj && vobj->onActiveList())
+ {
+ gGL.flush();
+ glLineWidth(llmax(4.f*sinf(gFrameTimeSeconds*2.f)+1.f, 1.f));
+ //glLineWidth(4.f*(sinf(gFrameTimeSeconds*2.f)*0.25f+0.75f));
+ stop_glerror();
+ drawBoxOutline(pos,size);
+ gGL.flush();
+ glLineWidth(1.f);
+ }
+ else
+ {
+ drawBoxOutline(pos,size);
+ }
}
-
+// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different
+// code path which uses a shader - it was tested to be faster than mapping a
+// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well
+// to simplify and speed up this debug code. Alternatively, a compute shader is
+// likely faster. -Cosmic,2023-09-28
void renderNormals(LLDrawable *drawablep)
{
if (!drawablep->isVisible())
@@ -1998,11 +2003,13 @@ void renderNormals(LLDrawable *drawablep)
LLVertexBuffer::unbind();
+ LLViewerObject* obj = drawablep->getVObj();
LLVOVolume *vol = drawablep->getVOVolume();
- if (vol)
+ if (obj)
{
- LLVolume *volume = vol->getVolume();
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE);
// Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
//
@@ -2011,68 +2018,136 @@ void renderNormals(LLDrawable *drawablep)
// transform. We get that effect here by pre-applying the inverse scale (twice, because
// one forward scale will be re-applied via the MVP in the vertex shader)
- LLVector3 scale_v3 = vol->getScale();
- float scale_len = scale_v3.length();
- LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
- obj_scale.normalize3();
+ LLVector4a inv_scale;
+ float scale_len;
+ if (vol)
+ {
+ LLVector3 scale_v3 = vol->getScale();
+ LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
+ obj_scale.normalize3();
- // Normals &tangent line segments get scaled along with the object. Divide by scale length
- // to keep the as-viewed lengths (relatively) constant with the debug setting length
- float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+ // Create inverse-scale vector for normals
+ inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0);
+ inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
- // Create inverse-scale vector for normals
- LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
- inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
- inv_scale.normalize3fast();
+ inv_scale.normalize3fast();
+ scale_len = scale_v3.length();
+ }
+ else
+ {
+ inv_scale.set(1.0, 1.0, 1.0, 0.0);
+ scale_len = 1.0;
+ }
gGL.pushMatrix();
- gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ if (vol)
{
- const LLVolumeFace &face = volume->getVolumeFace(i);
+ gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+ }
- gGL.flush();
- gGL.diffuseColor4f(1, 1, 0, 1);
- gGL.begin(LLRender::LINES);
- for (S32 j = 0; j < face.mNumVertices; ++j)
- {
- LLVector4a n, p;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- n.setMul(face.mNormals[j], 1.0);
- n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
- n.normalize3fast();
- n.mul(draw_length);
- p.setAdd(face.mPositions[j], n);
+ // Normals &tangent line segments get scaled along with the object. Divide by scale length
+ // to keep the as-viewed lengths (relatively) constant with the debug setting length
+ float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
+ std::vector<LLVolumeFace>* faces = nullptr;
+ std::vector<LLFace*>* drawable_faces = nullptr;
+ if (vol)
+ {
+ LLVolume* volume = vol->getVolume();
+ faces = &volume->getVolumeFaces();
+ }
+ else
+ {
+ drawable_faces = &drawablep->getFaces();
+ }
- // Tangents are simple vectors and do not require reorientation via pre-scaling
- if (face.mTangents)
+ if (faces)
+ {
+ for (auto it = faces->begin(); it != faces->end(); ++it)
+ {
+ const LLVolumeFace& face = *it;
+
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a n, p;
+
+ n.setMul(face.mNormals[j], 1.0);
+ n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
+ n.normalize3fast();
+ n.mul(draw_length);
+ p.setAdd(face.mPositions[j], n);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+
+ // Tangents are simple vectors and do not require reorientation via pre-scaling
+ if (face.mTangents)
+ {
+ gGL.flush();
+ gGL.diffuseColor4f(0, 1, 1, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a t, p;
+
+ t.setMul(face.mTangents[j], 1.0f);
+ t.normalize3fast();
+ t.mul(draw_length);
+ p.setAdd(face.mPositions[j], t);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+ }
+ }
+ }
+ else if (drawable_faces)
+ {
+ // *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present
+ llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram);
+ LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr;
+ for (auto it = drawable_faces->begin(); it != drawable_faces->end(); ++it)
{
- gGL.flush();
- gGL.diffuseColor4f(0, 1, 1, 1);
- gGL.begin(LLRender::LINES);
- for (S32 j = 0; j < face.mNumVertices; ++j)
+ LLFace* facep = *it;
+ LLFace& face = **it;
+ LLVertexBuffer* buf = face.getVertexBuffer();
+ if (!buf) { continue; }
+ U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL;
+ if ((buf->getTypeMask() & mask_vn) != mask_vn) { continue; }
+
+ LLGLSLShader* shader;
+ if ((buf->getTypeMask() & LLVertexBuffer::TYPE_TANGENT) != LLVertexBuffer::TYPE_TANGENT)
{
- LLVector4a t, p;
+ shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_DEFAULT];
+ }
+ else
+ {
+ shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_WITH_TANGENTS];
+ }
+ shader->bind();
- t.setMul(face.mTangents[j], 1.0f);
- t.normalize3fast();
- t.mul(draw_length);
- p.setAdd(face.mPositions[j], t);
+ shader->uniform1f(LLShaderMgr::DEBUG_NORMAL_DRAW_LENGTH, draw_length);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
+ LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix);
+
+ buf->setBuffer();
+ // *NOTE: The render type in the vertex shader is TRIANGLES, but gets converted to LINES in the geometry shader
+ // *NOTE: For terrain normal debug, this seems to also include vertices for water, which is technically not part of the terrain. Should fix that at some point.
+ buf->drawRange(LLRender::TRIANGLES, face.getGeomIndex(), face.getGeomIndex() + face.getGeomCount()-1, face.getIndicesCount(), face.getIndicesStart());
}
- }
+ if (prev_shader)
+ {
+ prev_shader->bind();
+ }
+ }
gGL.popMatrix();
}
@@ -2080,278 +2155,278 @@ void renderNormals(LLDrawable *drawablep)
S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale)
{
- const S32 DEFAULT_DETAIL = 1;
- const F32 LARGE_THRESHOLD = 5.f;
- const F32 MEGA_THRESHOLD = 25.f;
+ const S32 DEFAULT_DETAIL = 1;
+ const F32 LARGE_THRESHOLD = 5.f;
+ const F32 MEGA_THRESHOLD = 25.f;
- S32 detail = DEFAULT_DETAIL;
- F32 avg_scale = (scale[0]+scale[1]+scale[2])/3.f;
+ S32 detail = DEFAULT_DETAIL;
+ F32 avg_scale = (scale[0]+scale[1]+scale[2])/3.f;
- if (avg_scale > LARGE_THRESHOLD)
- {
- detail += 1;
- if (avg_scale > MEGA_THRESHOLD)
- {
- detail += 1;
- }
- }
+ if (avg_scale > LARGE_THRESHOLD)
+ {
+ detail += 1;
+ if (avg_scale > MEGA_THRESHOLD)
+ {
+ detail += 1;
+ }
+ }
- return detail;
+ return detail;
}
void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color)
{
- LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
- LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
+ LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
+ LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
- const LLVector3 center(0,0,0);
- const LLVector3 size(0.25f,0.25f,0.25f);
+ const LLVector3 center(0,0,0);
+ const LLVector3 size(0.25f,0.25f,0.25f);
- if (decomp)
- {
- if (!decomp->mBaseHullMesh.empty())
- {
+ if (decomp)
+ {
+ if (!decomp->mBaseHullMesh.empty())
+ {
gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
- }
- else
- {
- gMeshRepo.buildPhysicsMesh(*decomp);
- gGL.diffuseColor4f(0,1,1,1);
- drawBoxOutline(center, size);
- }
-
- }
- else
- {
- gGL.diffuseColor3f(1,0,1);
- drawBoxOutline(center, size);
- }
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
+ }
+ else
+ {
+ gMeshRepo.buildPhysicsMesh(*decomp);
+ gGL.diffuseColor4f(0,1,1,1);
+ drawBoxOutline(center, size);
+ }
+
+ }
+ else
+ {
+ gGL.diffuseColor3f(1,0,1);
+ drawBoxOutline(center, size);
+ }
}
void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color)
{
gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
}
void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe)
{
- U8 physics_type = volume->getPhysicsShapeType();
+ U8 physics_type = volume->getPhysicsShapeType();
- if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible())
- {
- return;
- }
+ if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible())
+ {
+ return;
+ }
- //not allowed to return at this point without rendering *something*
+ //not allowed to return at this point without rendering *something*
- F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold");
- F32 cost = volume->getObjectCost();
+ F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold");
+ F32 cost = volume->getObjectCost();
- LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor");
- LLColor4 mid = gSavedSettings.getColor4("ObjectCostMidColor");
- LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor");
+ LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor");
+ LLColor4 mid = gSavedSettings.getColor4("ObjectCostMidColor");
+ LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor");
- F32 normalizedCost = 1.f - exp( -(cost / threshold) );
+ F32 normalizedCost = 1.f - exp( -(cost / threshold) );
- LLColor4 color;
- if ( normalizedCost <= 0.5f )
- {
- color = lerp( low, mid, 2.f * normalizedCost );
- }
- else
- {
- color = lerp( mid, high, 2.f * ( normalizedCost - 0.5f ) );
- }
+ LLColor4 color;
+ if ( normalizedCost <= 0.5f )
+ {
+ color = lerp( low, mid, 2.f * normalizedCost );
+ }
+ else
+ {
+ color = lerp( mid, high, 2.f * ( normalizedCost - 0.5f ) );
+ }
if (wireframe)
{
color = color * 0.5f;
}
- U32 data_mask = LLVertexBuffer::MAP_VERTEX;
-
- LLVolumeParams volume_params = volume->getVolume()->getParams();
+ U32 data_mask = LLVertexBuffer::MAP_VERTEX;
- LLPhysicsVolumeParams physics_params(volume_params,
- physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ LLVolumeParams volume_params = volume->getVolume()->getParams();
- LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec;
- LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec);
+ LLPhysicsVolumeParams physics_params(volume_params,
+ physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
- U32 type = physics_spec.getType();
+ LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec;
+ LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec);
- LLVector3 center(0,0,0);
- LLVector3 size(0.25f,0.25f,0.25f);
+ U32 type = physics_spec.getType();
- gGL.pushMatrix();
- gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
+ LLVector3 center(0,0,0);
+ LLVector3 size(0.25f,0.25f,0.25f);
- if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH)
- {
- LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
- LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
+
+ if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH)
+ {
+ LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
+ LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
+
+ if (decomp)
+ { //render a physics based mesh
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (decomp)
- { //render a physics based mesh
+ if (!decomp->mHull.empty())
+ { //decomposition exists, use that
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (decomp->mMesh.empty())
+ {
+ gMeshRepo.buildPhysicsMesh(*decomp);
+ }
- if (!decomp->mHull.empty())
- { //decomposition exists, use that
-
- if (decomp->mMesh.empty())
- {
- gMeshRepo.buildPhysicsMesh(*decomp);
- }
-
- for (U32 i = 0; i < decomp->mMesh.size(); ++i)
- {
- render_hull(decomp->mMesh[i], color);
- }
- }
- else if (!decomp->mPhysicsShapeMesh.empty())
- {
- //decomp has physics mesh, render that mesh
+ for (U32 i = 0; i < decomp->mMesh.size(); ++i)
+ {
+ render_hull(decomp->mMesh[i], color);
+ }
+ }
+ else if (!decomp->mPhysicsShapeMesh.empty())
+ {
+ //decomp has physics mesh, render that mesh
gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions);
- }
- else
- { //no mesh or decomposition, render base hull
- renderMeshBaseHull(volume, data_mask, color);
-
- if (decomp->mPhysicsShapeMesh.empty())
- {
- //attempt to fetch physics shape mesh if available
- gMeshRepo.fetchPhysicsShape(mesh_id);
- }
- }
- }
- else
- {
- gGL.diffuseColor3f(1,1,0);
- drawBoxOutline(center, size);
- }
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_CONVEX ||
- type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX)
- {
- if (volume->isMesh())
- {
- renderMeshBaseHull(volume, data_mask, color);
- }
- else
- {
- LLVolumeParams volume_params = volume->getVolume()->getParams();
- S32 detail = get_physics_detail(volume_params, volume->getScale());
- LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
-
- if (!phys_volume->mHullPoints)
- { //build convex hull
- std::vector<LLVector3> pos;
- std::vector<U16> index;
-
- S32 index_offset = 0;
-
- for (S32 i = 0; i < phys_volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = phys_volume->getVolumeFace(i);
- if (index_offset + face.mNumVertices > 65535)
- {
- continue;
- }
-
- for (S32 j = 0; j < face.mNumVertices; ++j)
- {
- pos.push_back(LLVector3(face.mPositions[j].getF32ptr()));
- }
-
- for (S32 j = 0; j < face.mNumIndices; ++j)
- {
- index.push_back(face.mIndices[j]+index_offset);
- }
-
- index_offset += face.mNumVertices;
- }
-
- if (!pos.empty() && !index.empty())
- {
- LLCDMeshData mesh;
- mesh.mIndexBase = &index[0];
- mesh.mVertexBase = pos[0].mV;
- mesh.mNumVertices = pos.size();
- mesh.mVertexStrideBytes = 12;
- mesh.mIndexStrideBytes = 6;
- mesh.mIndexType = LLCDMeshData::INT_16;
-
- mesh.mNumTriangles = index.size()/3;
-
- LLCDMeshData res;
-
- LLConvexDecomposition::getInstance()->generateSingleHullMeshFromMesh( &mesh, &res );
-
- //copy res into phys_volume
- phys_volume->mHullPoints = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*res.mNumVertices);
- phys_volume->mNumHullPoints = res.mNumVertices;
-
- S32 idx_size = (res.mNumTriangles*3*2+0xF) & ~0xF;
- phys_volume->mHullIndices = (U16*) ll_aligned_malloc_16(idx_size);
- phys_volume->mNumHullIndices = res.mNumTriangles*3;
-
- const F32* v = res.mVertexBase;
-
- for (S32 i = 0; i < res.mNumVertices; ++i)
- {
- F32* p = (F32*) ((U8*)v+i*res.mVertexStrideBytes);
- phys_volume->mHullPoints[i].load3(p);
- }
-
- if (res.mIndexType == LLCDMeshData::INT_16)
- {
- for (S32 i = 0; i < res.mNumTriangles; ++i)
- {
- U16* idx = (U16*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes);
-
- phys_volume->mHullIndices[i*3+0] = idx[0];
- phys_volume->mHullIndices[i*3+1] = idx[1];
- phys_volume->mHullIndices[i*3+2] = idx[2];
- }
- }
- else
- {
- for (S32 i = 0; i < res.mNumTriangles; ++i)
- {
- U32* idx = (U32*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes);
-
- phys_volume->mHullIndices[i*3+0] = (U16) idx[0];
- phys_volume->mHullIndices[i*3+1] = (U16) idx[1];
- phys_volume->mHullIndices[i*3+2] = (U16) idx[2];
- }
- }
- }
- }
-
- if (phys_volume->mHullPoints)
- {
- //render hull
+ }
+ else
+ { //no mesh or decomposition, render base hull
+ renderMeshBaseHull(volume, data_mask, color);
+
+ if (decomp->mPhysicsShapeMesh.empty())
+ {
+ //attempt to fetch physics shape mesh if available
+ gMeshRepo.fetchPhysicsShape(mesh_id);
+ }
+ }
+ }
+ else
+ {
+ gGL.diffuseColor3f(1,1,0);
+ drawBoxOutline(center, size);
+ }
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_CONVEX ||
+ type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX)
+ {
+ if (volume->isMesh())
+ {
+ renderMeshBaseHull(volume, data_mask, color);
+ }
+ else
+ {
+ LLVolumeParams volume_params = volume->getVolume()->getParams();
+ S32 detail = get_physics_detail(volume_params, volume->getScale());
+ LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
+
+ if (!phys_volume->mHullPoints)
+ { //build convex hull
+ std::vector<LLVector3> pos;
+ std::vector<U16> index;
+
+ S32 index_offset = 0;
+
+ for (S32 i = 0; i < phys_volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = phys_volume->getVolumeFace(i);
+ if (index_offset + face.mNumVertices > 65535)
+ {
+ continue;
+ }
+
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ pos.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+ }
+
+ for (S32 j = 0; j < face.mNumIndices; ++j)
+ {
+ index.push_back(face.mIndices[j]+index_offset);
+ }
+
+ index_offset += face.mNumVertices;
+ }
+
+ if (!pos.empty() && !index.empty())
+ {
+ LLCDMeshData mesh;
+ mesh.mIndexBase = &index[0];
+ mesh.mVertexBase = pos[0].mV;
+ mesh.mNumVertices = pos.size();
+ mesh.mVertexStrideBytes = 12;
+ mesh.mIndexStrideBytes = 6;
+ mesh.mIndexType = LLCDMeshData::INT_16;
+
+ mesh.mNumTriangles = index.size()/3;
+
+ LLCDMeshData res;
+
+ LLConvexDecomposition::getInstance()->generateSingleHullMeshFromMesh( &mesh, &res );
+
+ //copy res into phys_volume
+ phys_volume->mHullPoints = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*res.mNumVertices);
+ phys_volume->mNumHullPoints = res.mNumVertices;
+
+ S32 idx_size = (res.mNumTriangles*3*2+0xF) & ~0xF;
+ phys_volume->mHullIndices = (U16*) ll_aligned_malloc_16(idx_size);
+ phys_volume->mNumHullIndices = res.mNumTriangles*3;
+
+ const F32* v = res.mVertexBase;
+
+ for (S32 i = 0; i < res.mNumVertices; ++i)
+ {
+ F32* p = (F32*) ((U8*)v+i*res.mVertexStrideBytes);
+ phys_volume->mHullPoints[i].load3(p);
+ }
+
+ if (res.mIndexType == LLCDMeshData::INT_16)
+ {
+ for (S32 i = 0; i < res.mNumTriangles; ++i)
+ {
+ U16* idx = (U16*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes);
+
+ phys_volume->mHullIndices[i*3+0] = idx[0];
+ phys_volume->mHullIndices[i*3+1] = idx[1];
+ phys_volume->mHullIndices[i*3+2] = idx[2];
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < res.mNumTriangles; ++i)
+ {
+ U32* idx = (U32*) (((U8*)res.mIndexBase)+i*res.mIndexStrideBytes);
+
+ phys_volume->mHullIndices[i*3+0] = (U16) idx[0];
+ phys_volume->mHullIndices[i*3+1] = (U16) idx[1];
+ phys_volume->mHullIndices[i*3+2] = (U16) idx[2];
+ }
+ }
+ }
+ }
+
+ if (phys_volume->mHullPoints)
+ {
+ //render hull
gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::unbind();
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
- }
- else
- {
- gGL.diffuseColor4f(1,0,1,1);
- drawBoxOutline(center, size);
- }
-
- LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
- }
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX)
- {
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
+ }
+ else
+ {
+ gGL.diffuseColor4f(1,0,1,1);
+ drawBoxOutline(center, size);
+ }
+
+ LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
+ }
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX)
+ {
if (!wireframe)
{
LLVector3 center = physics_spec.getCenter();
@@ -2362,9 +2437,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe
gGL.diffuseColor4fv(color.mV);
drawBox(center, scale);
}
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
- {
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
+ {
if (!wireframe)
{
LLVolumeParams volume_params;
@@ -2379,9 +2454,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe
pushVerts(sphere);
LLPrimitive::sVolumeManager->unrefVolume(sphere);
}
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
- {
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
+ {
if (!wireframe)
{
LLVolumeParams volume_params;
@@ -2396,244 +2471,244 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe
pushVerts(cylinder);
LLPrimitive::sVolumeManager->unrefVolume(cylinder);
}
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH)
- {
- LLVolumeParams volume_params = volume->getVolume()->getParams();
- S32 detail = get_physics_detail(volume_params, volume->getScale());
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH)
+ {
+ LLVolumeParams volume_params = volume->getVolume()->getParams();
+ S32 detail = get_physics_detail(volume_params, volume->getScale());
- LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
+ LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
gGL.diffuseColor4fv(color.mV);
- pushVerts(phys_volume);
+ pushVerts(phys_volume);
- LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX)
- {
- LLVolumeParams volume_params = volume->getVolume()->getParams();
- S32 detail = get_physics_detail(volume_params, volume->getScale());
+ LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX)
+ {
+ LLVolumeParams volume_params = volume->getVolume()->getParams();
+ S32 detail = get_physics_detail(volume_params, volume->getScale());
- LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
-
- if (phys_volume->mHullPoints && phys_volume->mHullIndices)
- {
+ LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
- llassert(LLGLSLShader::sCurBoundShader != 0);
- LLVertexBuffer::unbind();
- glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
+ if (phys_volume->mHullPoints && phys_volume->mHullIndices)
+ {
+
+ llassert(LLGLSLShader::sCurBoundShader != 0);
+ LLVertexBuffer::unbind();
+ glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
gGL.diffuseColor4fv(color.mV);
gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
- }
- else
- {
- gGL.diffuseColor3f(1,0,1);
- drawBoxOutline(center, size);
- gMeshRepo.buildHull(volume_params, detail);
- }
- LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
- }
- else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SCULPT)
- {
- //TODO: implement sculpted prim physics display
- }
- else
- {
- LL_ERRS() << "Unhandled type" << LL_ENDL;
- }
-
- gGL.popMatrix();
+ glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+ }
+ else
+ {
+ gGL.diffuseColor3f(1,0,1);
+ drawBoxOutline(center, size);
+ gMeshRepo.buildHull(volume_params, detail);
+ }
+ LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
+ }
+ else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SCULPT)
+ {
+ //TODO: implement sculpted prim physics display
+ }
+ else
+ {
+ LL_ERRS() << "Unhandled type" << LL_ENDL;
+ }
+
+ gGL.popMatrix();
}
void renderPhysicsShapes(LLSpatialGroup* group, bool wireframe)
{
- for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
-
- if (drawable->isSpatialBridge())
- {
- LLSpatialBridge* bridge = drawable->asPartition()->asBridge();
-
- if (bridge)
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- bridge->renderPhysicsShapes(wireframe);
- gGL.popMatrix();
- }
- }
- else
- {
- LLVOVolume* volume = drawable->getVOVolume();
- if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
- {
- if (!group->getSpatialPartition()->isBridge())
- {
- gGL.pushMatrix();
- LLVector3 trans = drawable->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- renderPhysicsShape(drawable, volume, wireframe);
- gGL.popMatrix();
- }
- else
- {
- renderPhysicsShape(drawable, volume, wireframe);
- }
- }
- else
- {
-#if 0
- LLViewerObject* object = drawable->getVObj();
- if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix);
- //push face vertices for terrain
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* face = drawable->getFace(i);
- if (face)
- {
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- buff->setBuffer();
- gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
-
- gGL.diffuseColor4f(0.2f, 1.f, 0.3f, 0.75f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
- }
- }
- }
- gGL.popMatrix();
- }
+ for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+
+ if (drawable->isSpatialBridge())
+ {
+ LLSpatialBridge* bridge = drawable->asPartition()->asBridge();
+
+ if (bridge)
+ {
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+ bridge->renderPhysicsShapes(wireframe);
+ gGL.popMatrix();
+ }
+ }
+ else
+ {
+ LLVOVolume* volume = drawable->getVOVolume();
+ if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
+ {
+ if (!group->getSpatialPartition()->isBridge())
+ {
+ gGL.pushMatrix();
+ LLVector3 trans = drawable->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ renderPhysicsShape(drawable, volume, wireframe);
+ gGL.popMatrix();
+ }
+ else
+ {
+ renderPhysicsShape(drawable, volume, wireframe);
+ }
+ }
+ else
+ {
+#if 0
+ LLViewerObject* object = drawable->getVObj();
+ if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+ {
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix);
+ //push face vertices for terrain
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ if (face)
+ {
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ buff->setBuffer();
+ gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+
+ gGL.diffuseColor4f(0.2f, 1.f, 0.3f, 0.75f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ }
+ }
+ }
+ gGL.popMatrix();
+ }
#endif
- }
- }
- }
+ }
+ }
+ }
}
void renderTexturePriority(LLDrawable* drawable)
{
- for (int face=0; face<drawable->getNumFaces(); ++face)
- {
- LLFace *facep = drawable->getFace(face);
-
- LLVector4 cold(0,0,0.25f);
- LLVector4 hot(1,0.25f,0.25f);
-
- LLVector4 boost_cold(0,0,0,0);
- LLVector4 boost_hot(0,1,0,1);
-
- LLGLDisable blend(GL_BLEND);
-
- //LLViewerTexture* imagep = facep->getTexture();
- //if (imagep)
- if (facep)
- {
-
- //F32 vsize = imagep->mMaxVirtualSize;
- F32 vsize = facep->getPixelArea();
-
- if (vsize > sCurMaxTexPriority)
- {
- sCurMaxTexPriority = vsize;
- }
-
- F32 t = vsize/sLastMaxTexPriority;
-
- LLVector4 col = lerp(cold, hot, t);
- gGL.diffuseColor4fv(col.mV);
- }
- //else
- //{
- // gGL.diffuseColor4f(1,0,1,1);
- //}
-
- LLVector4a center;
- center.setAdd(facep->mExtents[1],facep->mExtents[0]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(facep->mExtents[1],facep->mExtents[0]);
- size.mul(0.5f);
- size.add(LLVector4a(0.01f));
- drawBox(center, size);
-
- /*S32 boost = imagep->getBoostLevel();
- if (boost>LLGLTexture::BOOST_NONE)
- {
- F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
- LLVector4 col = lerp(boost_cold, boost_hot, t);
- LLGLEnable blend_on(GL_BLEND);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
- gGL.diffuseColor4fv(col.mV);
- drawBox(center, size);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }*/
- }
+ for (int face=0; face<drawable->getNumFaces(); ++face)
+ {
+ LLFace *facep = drawable->getFace(face);
+
+ LLVector4 cold(0,0,0.25f);
+ LLVector4 hot(1,0.25f,0.25f);
+
+ LLVector4 boost_cold(0,0,0,0);
+ LLVector4 boost_hot(0,1,0,1);
+
+ LLGLDisable blend(GL_BLEND);
+
+ //LLViewerTexture* imagep = facep->getTexture();
+ //if (imagep)
+ if (facep)
+ {
+
+ //F32 vsize = imagep->mMaxVirtualSize;
+ F32 vsize = facep->getPixelArea();
+
+ if (vsize > sCurMaxTexPriority)
+ {
+ sCurMaxTexPriority = vsize;
+ }
+
+ F32 t = vsize/sLastMaxTexPriority;
+
+ LLVector4 col = lerp(cold, hot, t);
+ gGL.diffuseColor4fv(col.mV);
+ }
+ //else
+ //{
+ // gGL.diffuseColor4f(1,0,1,1);
+ //}
+
+ LLVector4a center;
+ center.setAdd(facep->mExtents[1],facep->mExtents[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(facep->mExtents[1],facep->mExtents[0]);
+ size.mul(0.5f);
+ size.add(LLVector4a(0.01f));
+ drawBox(center, size);
+
+ /*S32 boost = imagep->getBoostLevel();
+ if (boost>LLGLTexture::BOOST_NONE)
+ {
+ F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
+ LLVector4 col = lerp(boost_cold, boost_hot, t);
+ LLGLEnable blend_on(GL_BLEND);
+ gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
+ gGL.diffuseColor4fv(col.mV);
+ drawBox(center, size);
+ gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }*/
+ }
}
void renderPoints(LLDrawable* drawablep)
{
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- if (drawablep->getNumFaces())
- {
- gGL.begin(LLRender::POINTS);
- gGL.diffuseColor3f(1,1,1);
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace * face = drawablep->getFace(i);
- if (face)
- {
- gGL.vertex3fv(face->mCenterLocal.mV);
- }
- }
- gGL.end();
- }
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ if (drawablep->getNumFaces())
+ {
+ gGL.begin(LLRender::POINTS);
+ gGL.diffuseColor3f(1,1,1);
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ gGL.vertex3fv(face->mCenterLocal.mV);
+ }
+ }
+ gGL.end();
+ }
}
void renderTextureAnim(LLDrawInfo* params)
{
- if (!params->mTextureMatrix)
- {
- return;
- }
-
- LLGLEnable blend(GL_BLEND);
- gGL.diffuseColor4f(1,1,0,0.5f);
- pushVerts(params);
+ if (!params->mTextureMatrix)
+ {
+ return;
+ }
+
+ LLGLEnable blend(GL_BLEND);
+ gGL.diffuseColor4f(1,1,0,0.5f);
+ pushVerts(params);
}
void renderBatchSize(LLDrawInfo* params)
{
- LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.f, 1.f);
+ LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.f, 1.f);
LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr;
bool bind = false;
if (params->mAvatar)
- {
+ {
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
bind = true;
old_shader->mRiggedVariant->bind();
LLRenderPass::uploadMatrixPalette(*params);
}
-
-
+
+
gGL.diffuseColor4ubv(params->getDebugColor().mV);
- pushVerts(params);
+ pushVerts(params);
if (bind)
{
@@ -2644,388 +2719,386 @@ void renderBatchSize(LLDrawInfo* params)
void renderTexelDensity(LLDrawable* drawable)
{
- if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
- || LLViewerTexture::sCheckerBoardImagep.isNull())
- {
- return;
- }
-
- LLGLEnable _(GL_BLEND);
-
- LLMatrix4 checkerboard_matrix;
- S32 discard_level = -1;
-
- for (S32 f = 0; f < drawable->getNumFaces(); f++)
- {
- LLFace* facep = drawable->getFace(f);
- LLVertexBuffer* buffer = facep->getVertexBuffer();
- LLViewerTexture* texturep = facep->getTexture();
-
- if (texturep == NULL) continue;
-
- switch(LLViewerTexture::sDebugTexelsMode)
- {
- case LLViewerTexture::DEBUG_TEXELS_CURRENT:
- discard_level = -1;
- break;
- case LLViewerTexture::DEBUG_TEXELS_DESIRED:
- {
- LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
- discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
- break;
- }
- default:
- case LLViewerTexture::DEBUG_TEXELS_FULL:
- discard_level = 0;
- break;
- }
-
- checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
-
- gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix);
-
- if (buffer && (facep->getGeomCount() >= 3))
- {
- buffer->setBuffer();
- U16 start = facep->getGeomStart();
- U16 end = start + facep->getGeomCount()-1;
- U32 count = facep->getIndicesCount();
- U16 offset = facep->getIndicesStart();
- buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- }
-
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
-
- //S32 num_textures = llmax(1, (S32)params->mTextureList.size());
-
- //for (S32 i = 0; i < num_textures; i++)
- //{
- // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get();
- // if (texturep == NULL) continue;
-
- // LLMatrix4 checkboard_matrix;
- // S32 discard_level = -1;
- // switch(LLViewerTexture::sDebugTexelsMode)
- // {
- // case LLViewerTexture::DEBUG_TEXELS_CURRENT:
- // discard_level = -1;
- // break;
- // case LLViewerTexture::DEBUG_TEXELS_DESIRED:
- // {
- // LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
- // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
- // break;
- // }
- // default:
- // case LLViewerTexture::DEBUG_TEXELS_FULL:
- // discard_level = 0;
- // break;
- // }
-
- // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
- // gGL.getTexUnit(i)->activate();
-
- // glMatrixMode(GL_TEXTURE);
- // glPushMatrix();
- // glLoadIdentity();
- // //gGL.matrixMode(LLRender::MM_TEXTURE);
- // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix);
-
- // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
-
- // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
-
- // glPopMatrix();
- // glMatrixMode(GL_MODELVIEW);
- // //gGL.matrixMode(LLRender::MM_MODELVIEW);
- //}
+ if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
+ || LLViewerTexture::sCheckerBoardImagep.isNull())
+ {
+ return;
+ }
+
+ LLGLEnable _(GL_BLEND);
+
+ LLMatrix4 checkerboard_matrix;
+ S32 discard_level = -1;
+
+ for (S32 f = 0; f < drawable->getNumFaces(); f++)
+ {
+ LLFace* facep = drawable->getFace(f);
+ LLVertexBuffer* buffer = facep->getVertexBuffer();
+ LLViewerTexture* texturep = facep->getTexture();
+
+ if (texturep == NULL) continue;
+
+ switch(LLViewerTexture::sDebugTexelsMode)
+ {
+ case LLViewerTexture::DEBUG_TEXELS_CURRENT:
+ discard_level = -1;
+ break;
+ case LLViewerTexture::DEBUG_TEXELS_DESIRED:
+ {
+ LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
+ discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
+ break;
+ }
+ default:
+ case LLViewerTexture::DEBUG_TEXELS_FULL:
+ discard_level = 0;
+ break;
+ }
+
+ checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
+
+ gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix);
+
+ if (buffer && (facep->getGeomCount() >= 3))
+ {
+ buffer->setBuffer();
+ U16 start = facep->getGeomStart();
+ U16 end = start + facep->getGeomCount()-1;
+ U32 count = facep->getIndicesCount();
+ U16 offset = facep->getIndicesStart();
+ buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ }
+
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+
+ //S32 num_textures = llmax(1, (S32)params->mTextureList.size());
+
+ //for (S32 i = 0; i < num_textures; i++)
+ //{
+ // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get();
+ // if (texturep == NULL) continue;
+
+ // LLMatrix4 checkboard_matrix;
+ // S32 discard_level = -1;
+ // switch(LLViewerTexture::sDebugTexelsMode)
+ // {
+ // case LLViewerTexture::DEBUG_TEXELS_CURRENT:
+ // discard_level = -1;
+ // break;
+ // case LLViewerTexture::DEBUG_TEXELS_DESIRED:
+ // {
+ // LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
+ // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
+ // break;
+ // }
+ // default:
+ // case LLViewerTexture::DEBUG_TEXELS_FULL:
+ // discard_level = 0;
+ // break;
+ // }
+
+ // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
+ // gGL.getTexUnit(i)->activate();
+
+ // glMatrixMode(GL_TEXTURE);
+ // glPushMatrix();
+ // glLoadIdentity();
+ // //gGL.matrixMode(LLRender::MM_TEXTURE);
+ // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix);
+
+ // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
+
+ // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
+
+ // glPopMatrix();
+ // glMatrixMode(GL_MODELVIEW);
+ // //gGL.matrixMode(LLRender::MM_MODELVIEW);
+ //}
}
void renderLights(LLDrawable* drawablep)
{
- if (!drawablep->isLight())
- {
- return;
- }
-
- if (drawablep->getNumFaces())
- {
- LLGLEnable blend(GL_BLEND);
- gGL.diffuseColor4f(0,1,1,0.5f);
-
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace * face = drawablep->getFace(i);
- if (face)
- {
- pushVerts(face);
- }
- }
-
- const LLVector4a* ext = drawablep->getSpatialExtents();
-
- LLVector4a pos;
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- LLVector4a size;
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
-
- {
- LLGLDepthTest depth(GL_FALSE, GL_TRUE);
- gGL.diffuseColor4f(1,1,1,1);
- drawBoxOutline(pos, size);
- }
-
- gGL.diffuseColor4f(1,1,0,1);
- F32 rad = drawablep->getVOVolume()->getLightRadius();
- drawBoxOutline(pos, LLVector4a(rad));
- }
+ if (!drawablep->isLight())
+ {
+ return;
+ }
+
+ if (drawablep->getNumFaces())
+ {
+ LLGLEnable blend(GL_BLEND);
+ gGL.diffuseColor4f(0,1,1,0.5f);
+
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ pushVerts(face);
+ }
+ }
+
+ const LLVector4a* ext = drawablep->getSpatialExtents();
+
+ LLVector4a pos;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_TRUE);
+ gGL.diffuseColor4f(1,1,1,1);
+ drawBoxOutline(pos, size);
+ }
+
+ gGL.diffuseColor4f(1,1,0,1);
+ F32 rad = drawablep->getVOVolume()->getLightRadius();
+ drawBoxOutline(pos, LLVector4a(rad));
+ }
}
class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect
{
public:
+ LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t)
+ : LLOctreeTriangleRayIntersect(start, dir, nullptr, closest_t, NULL, NULL, NULL, NULL)
+ {
-
- LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t)
- : LLOctreeTriangleRayIntersect(start, dir, NULL, closest_t, NULL, NULL, NULL, NULL)
- {
-
- }
+ }
void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
- {
- LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
-
- LLVector3 center, size;
-
- if (branch->isEmpty())
- {
- gGL.diffuseColor3f(1.f,0.2f,0.f);
- center.set(branch->getCenter().getF32ptr());
- size.set(branch->getSize().getF32ptr());
- }
- else
- {
- gGL.diffuseColor3f(0.75f, 1.f, 0.f);
- center.set(vl->mBounds[0].getF32ptr());
- size.set(vl->mBounds[1].getF32ptr());
- }
-
- drawBoxOutline(center, size);
-
- for (U32 i = 0; i < 2; i++)
- {
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, i == 1 ? GL_LEQUAL : GL_GREATER);
-
- if (i == 1)
- {
- gGL.diffuseColor4f(0,1,1,0.5f);
- }
- else
- {
- gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f);
- drawBoxOutline(center, size);
- }
-
- if (i == 1)
- {
- gGL.flush();
- glLineWidth(3.f);
- }
-
- gGL.begin(LLRender::TRIANGLES);
+ {
+ LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
+
+ LLVector3 center, size;
+
+ if (branch->isEmpty())
+ {
+ gGL.diffuseColor3f(1.f,0.2f,0.f);
+ center.set(branch->getCenter().getF32ptr());
+ size.set(branch->getSize().getF32ptr());
+ }
+ else
+ {
+ gGL.diffuseColor3f(0.75f, 1.f, 0.f);
+ center.set(vl->mBounds[0].getF32ptr());
+ size.set(vl->mBounds[1].getF32ptr());
+ }
+
+ drawBoxOutline(center, size);
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, i == 1 ? GL_LEQUAL : GL_GREATER);
+
+ if (i == 1)
+ {
+ gGL.diffuseColor4f(0,1,1,0.5f);
+ }
+ else
+ {
+ gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f);
+ drawBoxOutline(center, size);
+ }
+
+ if (i == 1)
+ {
+ gGL.flush();
+ glLineWidth(3.f);
+ }
+
+ gGL.begin(LLRender::TRIANGLES);
for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
- iter != branch->getDataEnd();
- ++iter)
- {
- const LLVolumeTriangle* tri = *iter;
-
- gGL.vertex3fv(tri->mV[0]->getF32ptr());
- gGL.vertex3fv(tri->mV[1]->getF32ptr());
- gGL.vertex3fv(tri->mV[2]->getF32ptr());
- }
- gGL.end();
-
- if (i == 1)
- {
- gGL.flush();
- glLineWidth(1.f);
- }
- }
- }
+ iter != branch->getDataEnd();
+ ++iter)
+ {
+ const LLVolumeTriangle* tri = *iter;
+
+ gGL.vertex3fv(tri->mV[0]->getF32ptr());
+ gGL.vertex3fv(tri->mV[1]->getF32ptr());
+ gGL.vertex3fv(tri->mV[2]->getF32ptr());
+ }
+ gGL.end();
+
+ if (i == 1)
+ {
+ gGL.flush();
+ glLineWidth(1.f);
+ }
+ }
+ }
};
-void renderRaycast(LLDrawable* drawablep)
+void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree)
{
- if (drawablep->getNumFaces())
- {
- LLGLEnable blend(GL_BLEND);
- gGL.diffuseColor4f(0,1,1,0.5f);
-
- LLVOVolume* vobj = drawablep->getVOVolume();
- if (vobj && !vobj->isDead())
- {
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- //pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
- LLVolume* volume = vobj->getVolume();
-
- bool transform = true;
- if (drawablep->isState(LLDrawable::RIGGED))
- {
- volume = vobj->getRiggedVolume();
- transform = false;
- }
-
- if (volume)
- {
- LLVector3 trans = drawablep->getRegion()->getOriginAgent();
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
-
- gGL.pushMatrix();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
-
- LLVector4a start, end;
- if (transform)
- {
- LLVector3 v_start(gDebugRaycastStart.getF32ptr());
- LLVector3 v_end(gDebugRaycastEnd.getF32ptr());
-
- v_start = vobj->agentPositionToVolume(v_start);
- v_end = vobj->agentPositionToVolume(v_end);
-
- start.load3(v_start.mV);
- end.load3(v_end.mV);
- }
- else
- {
- start = gDebugRaycastStart;
- end = gDebugRaycastEnd;
- }
-
- LLVector4a dir;
- dir.setSub(end, start);
-
- gGL.flush();
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- {
- //render face positions
- LLVertexBuffer::unbind();
- gGL.diffuseColor4f(0,1,1,0.5f);
- glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
- }
-
- if (!volume->isUnique())
- {
- F32 t = 1.f;
+ F32 t = 1.f;
+ LLRenderOctreeRaycast render(start, end, &t);
+ render.traverse(octree);
+}
+void renderRaycast(LLDrawable* drawablep)
+{
+ if (drawablep->getNumFaces())
+ {
+ LLGLEnable blend(GL_BLEND);
+ gGL.diffuseColor4f(0,1,1,0.5f);
+
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj && !vobj->isDead())
+ {
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ //pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ LLVolume* volume = vobj->getVolume();
+
+ bool transform = true;
+ if (drawablep->isState(LLDrawable::RIGGED))
+ {
+ volume = vobj->getRiggedVolume();
+ transform = false;
+ }
+
+ if (volume)
+ {
+ LLVector3 trans = drawablep->getRegion()->getOriginAgent();
+
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+
+ gGL.pushMatrix();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
+
+ LLVector4a start, end;
+ if (transform)
+ {
+ LLVector3 v_start(gDebugRaycastStart.getF32ptr());
+ LLVector3 v_end(gDebugRaycastEnd.getF32ptr());
+
+ v_start = vobj->agentPositionToVolume(v_start);
+ v_end = vobj->agentPositionToVolume(v_end);
+
+ start.load3(v_start.mV);
+ end.load3(v_end.mV);
+ }
+ else
+ {
+ start = gDebugRaycastStart;
+ end = gDebugRaycastEnd;
+ }
+
+ LLVector4a dir;
+ dir.setSub(end, start);
+
+ gGL.flush();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ {
+ //render face positions
+ //gGL.diffuseColor4f(0,1,1,0.5f);
+ //LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, nullptr, face.mNumIndices, face.mIndices);
+ }
+
+ if (!volume->isUnique())
+ {
if (!face.getOctree())
- {
- ((LLVolumeFace*) &face)->createOctree();
- }
-
- LLRenderOctreeRaycast render(start, dir, &t);
-
- render.traverse(face.getOctree());
- }
-
- gGL.popMatrix();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
- }
- }
- else if (drawablep->isAvatar())
- {
- if (drawablep->getVObj() == gDebugRaycastObject)
- {
- LLGLDepthTest depth(GL_FALSE);
- LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get();
- av->renderCollisionVolumes();
- }
- }
-
- if (drawablep->getVObj() == gDebugRaycastObject)
- {
- // draw intersection point
- gGL.pushMatrix();
- gGL.loadMatrix(gGLModelView);
- LLVector3 translate(gDebugRaycastIntersection.getF32ptr());
- gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
- LLCoordFrame orient;
- LLVector4a debug_binormal;
-
- debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent);
- debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]);
-
- LLVector3 normal(gDebugRaycastNormal.getF32ptr());
- LLVector3 binormal(debug_binormal.getF32ptr());
-
- orient.lookDir(normal, binormal);
- LLMatrix4 rotation;
- orient.getRotMatrixToParent(rotation);
- gGL.multMatrix((float*)rotation.mMatrix);
-
- gGL.diffuseColor4f(1,0,0,0.5f);
- drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f));
- gGL.diffuseColor4f(0,1,0,0.5f);
- drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f));
- gGL.diffuseColor4f(0,0,1,0.5f);
- drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
- gGL.popMatrix();
-
- // draw bounding box of prim
- const LLVector4a* ext = drawablep->getSpatialExtents();
-
- LLVector4a pos;
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- LLVector4a size;
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
-
- LLGLDepthTest depth(GL_FALSE, GL_TRUE);
- gGL.diffuseColor4f(0,0.5f,0.5f,1);
- drawBoxOutline(pos, size);
- }
- }
+ {
+ ((LLVolumeFace*) &face)->createOctree();
+ }
+
+ renderOctreeRaycast(start, end, face.getOctree());
+ }
+
+ gGL.popMatrix();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+ }
+ }
+ else if (drawablep->isAvatar())
+ {
+ if (drawablep->getVObj() == gDebugRaycastObject)
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get();
+ av->renderCollisionVolumes();
+ }
+ }
+
+ if (drawablep->getVObj() == gDebugRaycastObject)
+ {
+ // draw intersection point
+ gGL.pushMatrix();
+ gGL.loadMatrix(gGLModelView);
+ LLVector3 translate(gDebugRaycastIntersection.getF32ptr());
+ gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
+ LLCoordFrame orient;
+ LLVector4a debug_binormal;
+
+ debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent);
+ debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]);
+
+ LLVector3 normal(gDebugRaycastNormal.getF32ptr());
+ LLVector3 binormal(debug_binormal.getF32ptr());
+
+ orient.lookDir(normal, binormal);
+ LLMatrix4 rotation;
+ orient.getRotMatrixToParent(rotation);
+ gGL.multMatrix((float*)rotation.mMatrix);
+
+ gGL.diffuseColor4f(1,0,0,0.5f);
+ drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f));
+ gGL.diffuseColor4f(0,1,0,0.5f);
+ drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f));
+ gGL.diffuseColor4f(0,0,1,0.5f);
+ drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
+ gGL.popMatrix();
+
+ // draw bounding box of prim
+ const LLVector4a* ext = drawablep->getSpatialExtents();
+
+ LLVector4a pos;
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
+
+ LLGLDepthTest depth(GL_FALSE, GL_TRUE);
+ gGL.diffuseColor4f(0,0.5f,0.5f,1);
+ drawBoxOutline(pos, size);
+ }
+ }
}
void renderAvatarCollisionVolumes(LLVOAvatar* avatar)
{
- avatar->renderCollisionVolumes();
+ avatar->renderCollisionVolumes();
}
void renderAvatarBones(LLVOAvatar* avatar)
{
- avatar->renderBones();
+ avatar->renderBones();
}
void renderAgentTarget(LLVOAvatar* avatar)
{
- // render these for self only (why, i don't know)
- if (avatar->isSelf())
- {
- renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
- renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
- renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
- renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
- }
+ // render these for self only (why, i don't know)
+ if (avatar->isSelf())
+ {
+ renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
+ renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
+ renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
+ renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
+ }
}
static void setTextureAreaDebugText(LLDrawable* drawablep)
@@ -3085,668 +3158,668 @@ static void setTextureAreaDebugText(LLDrawable* drawablep)
class LLOctreeRenderNonOccluded : public OctreeTraveler
{
public:
- LLCamera* mCamera;
- LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {}
-
- virtual void traverse(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- const LLVector4a* bounds = group->getBounds();
- if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
- {
- node->accept(this);
- stop_glerror();
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- traverse(node->getChild(i));
- stop_glerror();
- }
-
- //draw tight fit bounding boxes for spatial group
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
- {
- group->rebuildGeom();
- group->rebuildMesh();
-
- renderOctree(group);
- stop_glerror();
- }
- }
- }
-
- virtual void visit(const OctreeNode* branch)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
- const LLVector4a* bounds = group->getBounds();
- if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
- {
- return;
- }
-
- group->rebuildGeom();
- group->rebuildMesh();
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
- {
- if (!group->isEmpty())
- {
- gGL.diffuseColor3f(0,0,1);
- const LLVector4a* obj_bounds = group->getObjectBounds();
- drawBoxOutline(obj_bounds[0], obj_bounds[1]);
- }
- }
-
- for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable || drawable->isDead())
- {
- continue;
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
- {
- renderBoundingBox(drawable);
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS))
- {
- renderNormals(drawable);
- }
-
+ LLCamera* mCamera;
+ LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {}
+
+ virtual void traverse(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
+ {
+ node->accept(this);
+ stop_glerror();
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ stop_glerror();
+ }
+
+ //draw tight fit bounding boxes for spatial group
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
+ {
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ renderOctree(group);
+ stop_glerror();
+ }
+ }
+ }
+
+ virtual void visit(const OctreeNode* branch)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
+ const LLVector4a* bounds = group->getBounds();
+ if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
+ {
+ return;
+ }
+
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
+ {
+ if (!group->isEmpty())
+ {
+ gGL.diffuseColor3f(0,0,1);
+ const LLVector4a* obj_bounds = group->getObjectBounds();
+ drawBoxOutline(obj_bounds[0], obj_bounds[1]);
+ }
+ }
+
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable || drawable->isDead())
+ {
+ continue;
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
+ {
+ renderBoundingBox(drawable);
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS))
+ {
+ renderNormals(drawable);
+ }
+
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
{
setTextureAreaDebugText(drawable);
}
- /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
- {
- renderTexturePriority(drawable);
- }*/
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
- {
- renderPoints(drawable);
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS))
- {
- renderLights(drawable);
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
- {
- renderRaycast(drawable);
- }
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE))
- {
- renderUpdateType(drawable);
- }
- if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
- {
- renderTexelDensity(drawable);
- }
-
- LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get());
-
- if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME))
- {
- renderAvatarCollisionVolumes(avatar);
- }
-
- if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS))
- {
- renderAvatarBones(avatar);
- }
-
- if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET))
- {
- renderAgentTarget(avatar);
- }
-
+ /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ {
+ renderTexturePriority(drawable);
+ }*/
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
+ {
+ renderPoints(drawable);
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS))
+ {
+ renderLights(drawable);
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
+ {
+ renderRaycast(drawable);
+ }
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_UPDATE_TYPE))
+ {
+ renderUpdateType(drawable);
+ }
+ if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ {
+ renderTexelDensity(drawable);
+ }
+
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get());
+
+ if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME))
+ {
+ renderAvatarCollisionVolumes(avatar);
+ }
+
+ if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_JOINTS))
+ {
+ renderAvatarBones(avatar);
+ }
+
+ if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET))
+ {
+ renderAgentTarget(avatar);
+ }
+
#if 0
- if (gDebugGL)
- {
- for (U32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* facep = drawable->getFace(i);
- if (facep)
- {
- U8 index = facep->getTextureIndex();
- if (facep->mDrawInfo)
- {
- if (index < FACE_DO_NOT_BATCH_TEXTURES)
- {
- if (facep->mDrawInfo->mTextureList.size() <= index)
- {
- LL_ERRS() << "Face texture index out of bounds." << LL_ENDL;
- }
- else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
- {
- LL_ERRS() << "Face texture index incorrect." << LL_ENDL;
- }
- }
- }
- }
- }
- }
+ if (gDebugGL)
+ {
+ for (U32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ U8 index = facep->getTextureIndex();
+ if (facep->mDrawInfo)
+ {
+ if (index < FACE_DO_NOT_BATCH_TEXTURES)
+ {
+ if (facep->mDrawInfo->mTextureList.size() <= index)
+ {
+ LL_ERRS() << "Face texture index out of bounds." << LL_ENDL;
+ }
+ else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+ {
+ LL_ERRS() << "Face texture index incorrect." << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ }
#endif
- }
-
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
- for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
- {
- LLDrawInfo* draw_info = *j;
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM))
- {
- renderTextureAnim(draw_info);
- }
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE))
- {
- renderBatchSize(draw_info);
- }
- }
- }
- }
+ }
+
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
+ {
+ LLDrawInfo* draw_info = *j;
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM))
+ {
+ renderTextureAnim(draw_info);
+ }
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE))
+ {
+ renderBatchSize(draw_info);
+ }
+ }
+ }
+ }
};
class LLOctreeRenderXRay : public OctreeTraveler
{
public:
- LLCamera* mCamera;
- LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {}
-
- virtual void traverse(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- const LLVector4a* bounds = group->getBounds();
- if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
- {
- node->accept(this);
- stop_glerror();
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- traverse(node->getChild(i));
- stop_glerror();
- }
-
- //render visibility wireframe
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
- {
- group->rebuildGeom();
- group->rebuildMesh();
-
- gGL.flush();
- gGL.pushMatrix();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- renderXRay(group, mCamera);
- stop_glerror();
- gGLLastMatrix = NULL;
- gGL.popMatrix();
- }
- }
- }
-
- virtual void visit(const OctreeNode* node) {}
+ LLCamera* mCamera;
+ LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {}
+
+ virtual void traverse(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
+ {
+ node->accept(this);
+ stop_glerror();
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ stop_glerror();
+ }
+
+ //render visibility wireframe
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ gGL.flush();
+ gGL.pushMatrix();
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ renderXRay(group, mCamera);
+ stop_glerror();
+ gGLLastMatrix = NULL;
+ gGL.popMatrix();
+ }
+ }
+ }
+
+ virtual void visit(const OctreeNode* node) {}
};
class LLOctreeRenderPhysicsShapes : public OctreeTraveler
{
public:
- LLCamera* mCamera;
+ LLCamera* mCamera;
bool mWireframe;
- LLOctreeRenderPhysicsShapes(LLCamera* camera, bool wireframe): mCamera(camera), mWireframe(wireframe) {}
-
- virtual void traverse(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- const LLVector4a* bounds = group->getBounds();
- if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
- {
- node->accept(this);
- stop_glerror();
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- traverse(node->getChild(i));
- stop_glerror();
- }
-
- group->rebuildGeom();
- group->rebuildMesh();
-
- renderPhysicsShapes(group, mWireframe);
- }
- }
-
- virtual void visit(const OctreeNode* branch)
- {
-
- }
+ LLOctreeRenderPhysicsShapes(LLCamera* camera, bool wireframe): mCamera(camera), mWireframe(wireframe) {}
+
+ virtual void traverse(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
+ {
+ node->accept(this);
+ stop_glerror();
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ stop_glerror();
+ }
+
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ renderPhysicsShapes(group, mWireframe);
+ }
+ }
+
+ virtual void visit(const OctreeNode* branch)
+ {
+
+ }
};
class LLOctreePushBBoxVerts : public OctreeTraveler
{
public:
- LLCamera* mCamera;
- LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {}
-
- virtual void traverse(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- const LLVector4a* bounds = group->getBounds();
- if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1]))
- {
- node->accept(this);
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- traverse(node->getChild(i));
- }
- }
- }
-
- virtual void visit(const OctreeNode* branch)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
-
- const LLVector4a* bounds = group->getBounds();
- if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
- {
- return;
- }
-
- for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
- renderBoundingBox(drawable, FALSE);
- }
- }
+ LLCamera* mCamera;
+ LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {}
+
+ virtual void traverse(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1]))
+ {
+ node->accept(this);
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ }
+ }
+ }
+
+ virtual void visit(const OctreeNode* branch)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
+
+ const LLVector4a* bounds = group->getBounds();
+ if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
+ {
+ return;
+ }
+
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+ renderBoundingBox(drawable, FALSE);
+ }
+ }
};
void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera)
{
- LLOctreePushBBoxVerts pusher(camera);
- pusher.traverse(mOctree);
+ LLOctreePushBBoxVerts pusher(camera);
+ pusher.traverse(mOctree);
}
class LLOctreeStateCheck : public OctreeTraveler
{
public:
- U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS];
-
- LLOctreeStateCheck()
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mInheritedMask[i] = 0;
- }
- }
-
- virtual void traverse(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- node->accept(this);
-
-
- U32 temp[LLViewerCamera::NUM_CAMERAS];
-
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- temp[i] = mInheritedMask[i];
- mInheritedMask[i] |= group->mOcclusionState[i] & LLSpatialGroup::OCCLUDED;
- }
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- traverse(node->getChild(i));
- }
-
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mInheritedMask[i] = temp[i];
- }
- }
-
-
- virtual void visit(const OctreeNode* state)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
-
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i]))
- {
- LL_ERRS() << "Spatial group failed inherited mask test." << LL_ENDL;
- }
- }
-
- if (group->hasState(LLSpatialGroup::DIRTY))
- {
- assert_parent_state(group, LLSpatialGroup::DIRTY);
- }
- }
-
- void assert_parent_state(LLSpatialGroup* group, U32 state)
- {
- LLSpatialGroup* parent = group->getParent();
- while (parent)
- {
- if (!parent->hasState(state))
- {
- LL_ERRS() << "Spatial group failed parent state check." << LL_ENDL;
- }
- parent = parent->getParent();
- }
- }
+ U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS];
+
+ LLOctreeStateCheck()
+ {
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mInheritedMask[i] = 0;
+ }
+ }
+
+ virtual void traverse(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ node->accept(this);
+
+
+ U32 temp[LLViewerCamera::NUM_CAMERAS];
+
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ temp[i] = mInheritedMask[i];
+ mInheritedMask[i] |= group->mOcclusionState[i] & LLSpatialGroup::OCCLUDED;
+ }
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ }
+
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mInheritedMask[i] = temp[i];
+ }
+ }
+
+
+ virtual void visit(const OctreeNode* state)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
+
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i]))
+ {
+ LL_ERRS() << "Spatial group failed inherited mask test." << LL_ENDL;
+ }
+ }
+
+ if (group->hasState(LLSpatialGroup::DIRTY))
+ {
+ assert_parent_state(group, LLSpatialGroup::DIRTY);
+ }
+ }
+
+ void assert_parent_state(LLSpatialGroup* group, U32 state)
+ {
+ LLSpatialGroup* parent = group->getParent();
+ while (parent)
+ {
+ if (!parent->hasState(state))
+ {
+ LL_ERRS() << "Spatial group failed parent state check." << LL_ENDL;
+ }
+ parent = parent->getParent();
+ }
+ }
};
void LLSpatialPartition::renderPhysicsShapes(bool wireframe)
{
- LLSpatialBridge* bridge = asBridge();
- LLCamera* camera = LLViewerCamera::getInstance();
-
- if (bridge)
- {
- camera = NULL;
- }
-
- gGL.flush();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLOctreeRenderPhysicsShapes render_physics(camera, wireframe);
- render_physics.traverse(mOctree);
- gGL.flush();
+ LLSpatialBridge* bridge = asBridge();
+ LLCamera* camera = LLViewerCamera::getInstance();
+
+ if (bridge)
+ {
+ camera = NULL;
+ }
+
+ gGL.flush();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLOctreeRenderPhysicsShapes render_physics(camera, wireframe);
+ render_physics.traverse(mOctree);
+ gGL.flush();
}
void LLSpatialPartition::renderDebug()
{
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE |
- LLPipeline::RENDER_DEBUG_OCCLUSION |
- LLPipeline::RENDER_DEBUG_LIGHTS |
- LLPipeline::RENDER_DEBUG_BATCH_SIZE |
- LLPipeline::RENDER_DEBUG_UPDATE_TYPE |
- LLPipeline::RENDER_DEBUG_BBOXES |
- LLPipeline::RENDER_DEBUG_NORMALS |
- LLPipeline::RENDER_DEBUG_POINTS |
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE |
+ LLPipeline::RENDER_DEBUG_OCCLUSION |
+ LLPipeline::RENDER_DEBUG_LIGHTS |
+ LLPipeline::RENDER_DEBUG_BATCH_SIZE |
+ LLPipeline::RENDER_DEBUG_UPDATE_TYPE |
+ LLPipeline::RENDER_DEBUG_BBOXES |
+ LLPipeline::RENDER_DEBUG_NORMALS |
+ LLPipeline::RENDER_DEBUG_POINTS |
LLPipeline::RENDER_DEBUG_TEXTURE_AREA |
- LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |
- LLPipeline::RENDER_DEBUG_RAYCAST |
- LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
- LLPipeline::RENDER_DEBUG_AVATAR_JOINTS |
- LLPipeline::RENDER_DEBUG_AGENT_TARGET |
- LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
- LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
- {
- return;
- }
-
- gDebugProgram.bind();
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
- {
- //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds);
- sLastMaxTexPriority = (F32) LLViewerCamera::getInstance()->getScreenPixelArea();
- sCurMaxTexPriority = 0.f;
- }
-
- LLGLDisable cullface(GL_CULL_FACE);
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gPipeline.disableLights();
-
- LLSpatialBridge* bridge = asBridge();
- LLCamera* camera = LLViewerCamera::getInstance();
-
- if (bridge)
- {
- camera = NULL;
- }
-
- LLOctreeStateCheck checker;
- checker.traverse(mOctree);
-
- LLOctreeRenderNonOccluded render_debug(camera);
- render_debug.traverse(mOctree);
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
- {
- {
- LLGLEnable cull(GL_CULL_FACE);
-
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f);
-
- LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(-1.f, -1.f);
-
- LLOctreeRenderXRay xray(camera);
- xray.traverse(mOctree);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
- }
- gDebugProgram.unbind();
+ LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |
+ LLPipeline::RENDER_DEBUG_RAYCAST |
+ LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
+ LLPipeline::RENDER_DEBUG_AVATAR_JOINTS |
+ LLPipeline::RENDER_DEBUG_AGENT_TARGET |
+ LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
+ LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ {
+ return;
+ }
+
+ gDebugProgram.bind();
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ {
+ //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds);
+ sLastMaxTexPriority = (F32) LLViewerCamera::getInstance()->getScreenPixelArea();
+ sCurMaxTexPriority = 0.f;
+ }
+
+ LLGLDisable cullface(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gPipeline.disableLights();
+
+ LLSpatialBridge* bridge = asBridge();
+ LLCamera* camera = LLViewerCamera::getInstance();
+
+ if (bridge)
+ {
+ camera = NULL;
+ }
+
+ LLOctreeStateCheck checker;
+ checker.traverse(mOctree);
+
+ LLOctreeRenderNonOccluded render_debug(camera);
+ render_debug.traverse(mOctree);
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ {
+ LLGLEnable cull(GL_CULL_FACE);
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f);
+
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(-1.f, -1.f);
+
+ LLOctreeRenderXRay xray(camera);
+ xray.traverse(mOctree);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+ }
+ gDebugProgram.unbind();
}
void LLSpatialGroup::drawObjectBox(LLColor4 col)
{
- gGL.diffuseColor4fv(col.mV);
- LLVector4a size;
- size = mObjectBounds[1];
- size.mul(1.01f);
- size.add(LLVector4a(0.001f));
- drawBox(mObjectBounds[0], size);
+ gGL.diffuseColor4fv(col.mV);
+ LLVector4a size;
+ size = mObjectBounds[1];
+ size.mul(1.01f);
+ size.add(LLVector4a(0.001f));
+ drawBox(mObjectBounds[0], size);
}
-bool LLSpatialPartition::isHUDPartition()
-{
- return mPartitionType == LLViewerRegion::PARTITION_HUD ;
-}
+bool LLSpatialPartition::isHUDPartition()
+{
+ return mPartitionType == LLViewerRegion::PARTITION_HUD ;
+}
BOOL LLSpatialPartition::isVisible(const LLVector3& v)
{
- if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f))
- {
- return FALSE;
- }
+ if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f))
+ {
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
LL_ALIGN_PREFIX(16)
class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
- LL_ALIGN_16(LLVector4a mStart);
- LL_ALIGN_16(LLVector4a mEnd);
-
- S32 *mFaceHit;
- LLVector4a *mIntersection;
- LLVector2 *mTexCoord;
- LLVector4a *mNormal;
- LLVector4a *mTangent;
- LLDrawable* mHit;
- BOOL mPickTransparent;
- BOOL mPickRigged;
+ LL_ALIGN_16(LLVector4a mStart);
+ LL_ALIGN_16(LLVector4a mEnd);
+
+ S32 *mFaceHit;
+ LLVector4a *mIntersection;
+ LLVector2 *mTexCoord;
+ LLVector4a *mNormal;
+ LLVector4a *mTangent;
+ LLDrawable* mHit;
+ BOOL mPickTransparent;
+ BOOL mPickRigged;
BOOL mPickUnselectable;
BOOL mPickReflectionProbe;
- LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe,
- S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
- : mStart(start),
- mEnd(end),
- mFaceHit(face_hit),
- mIntersection(intersection),
- mTexCoord(tex_coord),
- mNormal(normal),
- mTangent(tangent),
- mHit(NULL),
- mPickTransparent(pick_transparent),
- mPickRigged(pick_rigged),
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe,
+ S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
+ : mStart(start),
+ mEnd(end),
+ mFaceHit(face_hit),
+ mIntersection(intersection),
+ mTexCoord(tex_coord),
+ mNormal(normal),
+ mTangent(tangent),
+ mHit(NULL),
+ mPickTransparent(pick_transparent),
+ mPickRigged(pick_rigged),
mPickUnselectable(pick_unselectable),
mPickReflectionProbe(pick_reflection_probe)
- {
- }
-
- virtual void visit(const OctreeNode* branch)
- {
- for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
- {
- check(*i);
- }
- }
-
- virtual LLDrawable* check(const OctreeNode* node)
- {
- node->accept(this);
-
- for (U32 i = 0; i < node->getChildCount(); i++)
- {
- const OctreeNode* child = node->getChild(i);
- LLVector3 res;
-
- LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0);
-
- LLVector4a size;
- LLVector4a center;
-
- const LLVector4a* bounds = group->getBounds();
- size = bounds[1];
- center = bounds[0];
-
- LLVector4a local_start = mStart;
- LLVector4a local_end = mEnd;
-
- if (group->getSpatialPartition()->isBridge())
- {
- LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix();
- local_matrix.invert();
-
- LLMatrix4a local_matrix4a;
- local_matrix4a.loadu(local_matrix);
-
- local_matrix4a.affineTransform(mStart, local_start);
- local_matrix4a.affineTransform(mEnd, local_end);
- }
-
- if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
- {
- check(child);
- }
- }
-
- return mHit;
- }
-
- virtual bool check(LLViewerOctreeEntry* entry)
- {
- LLDrawable* drawable = (LLDrawable*)entry->getDrawable();
-
- if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
- {
- return false;
- }
-
- if (drawable->isSpatialBridge())
- {
- LLSpatialPartition *part = drawable->asPartition();
- LLSpatialBridge* bridge = part->asBridge();
- if (bridge && gPipeline.hasRenderType(bridge->mDrawableType))
- {
- check(part->mOctree);
- }
- }
- else
- {
- LLViewerObject* vobj = drawable->getVObj();
+ {
+ }
+
+ virtual void visit(const OctreeNode* branch)
+ {
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ {
+ check(*i);
+ }
+ }
+
+ virtual LLDrawable* check(const OctreeNode* node)
+ {
+ node->accept(this);
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ const OctreeNode* child = node->getChild(i);
+ LLVector3 res;
+
+ LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0);
+
+ LLVector4a size;
+ LLVector4a center;
+
+ const LLVector4a* bounds = group->getBounds();
+ size = bounds[1];
+ center = bounds[0];
+
+ LLVector4a local_start = mStart;
+ LLVector4a local_end = mEnd;
+
+ if (group->getSpatialPartition()->isBridge())
+ {
+ LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix();
+ local_matrix.invert();
+
+ LLMatrix4a local_matrix4a;
+ local_matrix4a.loadu(local_matrix);
+
+ local_matrix4a.affineTransform(mStart, local_start);
+ local_matrix4a.affineTransform(mEnd, local_end);
+ }
+
+ if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
+ {
+ check(child);
+ }
+ }
+
+ return mHit;
+ }
+
+ virtual bool check(LLViewerOctreeEntry* entry)
+ {
+ LLDrawable* drawable = (LLDrawable*)entry->getDrawable();
+
+ if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
+ {
+ return false;
+ }
+
+ if (drawable->isSpatialBridge())
+ {
+ LLSpatialPartition *part = drawable->asPartition();
+ LLSpatialBridge* bridge = part->asBridge();
+ if (bridge && gPipeline.hasRenderType(bridge->mDrawableType))
+ {
+ check(part->mOctree);
+ }
+ }
+ else
+ {
+ LLViewerObject* vobj = drawable->getVObj();
if (vobj &&
(!vobj->isReflectionProbe() || mPickReflectionProbe))
- {
- if (vobj->getClickAction() == CLICK_ACTION_IGNORE && !LLFloater::isVisible(gFloaterTools))
- {
- return false;
- }
-
- LLVector4a intersection;
- bool skip_check = false;
- if (vobj->isAvatar())
- {
- LLVOAvatar* avatar = (LLVOAvatar*) vobj;
- if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
- {
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
- if (hit)
- {
- mEnd = intersection;
- if (mIntersection)
- {
- *mIntersection = intersection;
- }
-
- mHit = hit->mDrawable;
- skip_check = true;
- }
-
- }
- }
-
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1,
+ {
+ if (vobj->getClickAction() == CLICK_ACTION_IGNORE && !LLFloater::isVisible(gFloaterTools))
+ {
+ return false;
+ }
+
+ LLVector4a intersection;
+ bool skip_check = false;
+ if (vobj->isAvatar())
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*) vobj;
+ if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
+ {
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
+ if (hit)
+ {
+ mEnd = intersection;
+ if (mIntersection)
+ {
+ *mIntersection = intersection;
+ }
+
+ mHit = hit->mDrawable;
+ skip_check = true;
+ }
+
+ }
+ }
+
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1,
(mPickReflectionProbe && vobj->isReflectionProbe()) ? TRUE : mPickTransparent, // always pick transparent when picking selection probe
mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
- {
- mEnd = intersection; // shorten ray so we only find CLOSER hits
- if (mIntersection)
- {
- *mIntersection = intersection;
- }
-
- mHit = vobj->mDrawable;
- }
- }
- }
-
- return false;
- }
+ {
+ mEnd = intersection; // shorten ray so we only find CLOSER hits
+ if (mIntersection)
+ {
+ *mIntersection = intersection;
+ }
+
+ mHit = vobj->mDrawable;
+ }
+ }
+ }
+
+ return false;
+ }
} LL_ALIGN_POSTFIX(16);
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- BOOL pick_transparent,
- BOOL pick_rigged,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable,
BOOL pick_reflection_probe,
- S32* face_hit, // return the face hit
- LLVector4a* intersection, // return the intersection point
- LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector4a* normal, // return the surface normal at the intersection point
- LLVector4a* tangent // return the surface tangent at the intersection point
- )
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+ )
{
- LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent);
- LLDrawable* drawable = intersect.check(mOctree);
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* drawable = intersect.check(mOctree);
- return drawable;
+ return drawable;
}
LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
@@ -3758,7 +3831,7 @@ LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
LLVector4a* normal, // return the surface normal at the intersection point
- LLVector4a* tangent // return the surface tangent at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
@@ -3768,32 +3841,32 @@ LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const
return drawable;
}
-LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
- LLViewerTexture* texture, LLVertexBuffer* buffer,
- bool fullbright, U8 bump)
-: mVertexBuffer(buffer),
- mTexture(texture),
- mStart(start),
- mEnd(end),
- mCount(count),
- mOffset(offset),
- mFullbright(fullbright),
- mBump(bump),
- mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
- mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
- mHasGlow(false),
- mEnvIntensity(0.0f),
- mAlphaMaskCutoff(0.5f)
-{
- mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
+LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
+ LLViewerTexture* texture, LLVertexBuffer* buffer,
+ bool fullbright, U8 bump)
+: mVertexBuffer(buffer),
+ mTexture(texture),
+ mStart(start),
+ mEnd(end),
+ mCount(count),
+ mOffset(offset),
+ mFullbright(fullbright),
+ mBump(bump),
+ mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
+ mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
+ mHasGlow(false),
+ mEnvIntensity(0.0f),
+ mAlphaMaskCutoff(0.5f)
+{
+ mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
}
-LLDrawInfo::~LLDrawInfo()
+LLDrawInfo::~LLDrawInfo()
{
- if (gDebugGL)
- {
- gPipeline.checkReferences(this);
- }
+ if (gDebugGL)
+ {
+ gPipeline.checkReferences(this);
+ }
}
LLColor4U LLDrawInfo::getDebugColor() const
@@ -3806,13 +3879,13 @@ LLColor4U LLDrawInfo::getDebugColor() const
*((U32*) color.mV) = hash.getCRC();
color.mV[3] = 200;
-
+
return color;
}
void LLDrawInfo::validate()
{
- mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
+ mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
}
U64 LLDrawInfo::getSkinHash()
@@ -3820,110 +3893,110 @@ U64 LLDrawInfo::getSkinHash()
return mSkinInfo ? mSkinInfo->mHash : 0;
}
-LLCullResult::LLCullResult()
+LLCullResult::LLCullResult()
{
- mVisibleGroupsAllocated = 0;
- mAlphaGroupsAllocated = 0;
+ mVisibleGroupsAllocated = 0;
+ mAlphaGroupsAllocated = 0;
mRiggedAlphaGroupsAllocated = 0;
- mOcclusionGroupsAllocated = 0;
- mDrawableGroupsAllocated = 0;
- mVisibleListAllocated = 0;
- mVisibleBridgeAllocated = 0;
-
- mVisibleGroups.clear();
- mVisibleGroups.push_back(NULL);
- mVisibleGroupsEnd = &mVisibleGroups[0];
- mAlphaGroups.clear();
- mAlphaGroups.push_back(NULL);
- mAlphaGroupsEnd = &mAlphaGroups[0];
+ mOcclusionGroupsAllocated = 0;
+ mDrawableGroupsAllocated = 0;
+ mVisibleListAllocated = 0;
+ mVisibleBridgeAllocated = 0;
+
+ mVisibleGroups.clear();
+ mVisibleGroups.push_back(NULL);
+ mVisibleGroupsEnd = &mVisibleGroups[0];
+ mAlphaGroups.clear();
+ mAlphaGroups.push_back(NULL);
+ mAlphaGroupsEnd = &mAlphaGroups[0];
mRiggedAlphaGroups.clear();
mRiggedAlphaGroups.push_back(NULL);
mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0];
- mOcclusionGroups.clear();
- mOcclusionGroups.push_back(NULL);
- mOcclusionGroupsEnd = &mOcclusionGroups[0];
- mDrawableGroups.clear();
- mDrawableGroups.push_back(NULL);
- mDrawableGroupsEnd = &mDrawableGroups[0];
- mVisibleList.clear();
- mVisibleList.push_back(NULL);
- mVisibleListEnd = &mVisibleList[0];
- mVisibleBridge.clear();
- mVisibleBridge.push_back(NULL);
- mVisibleBridgeEnd = &mVisibleBridge[0];
-
- for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
- {
- mRenderMap[i].clear();
- mRenderMap[i].push_back(NULL);
- mRenderMapEnd[i] = &mRenderMap[i][0];
- mRenderMapAllocated[i] = 0;
- }
-
- clear();
+ mOcclusionGroups.clear();
+ mOcclusionGroups.push_back(NULL);
+ mOcclusionGroupsEnd = &mOcclusionGroups[0];
+ mDrawableGroups.clear();
+ mDrawableGroups.push_back(NULL);
+ mDrawableGroupsEnd = &mDrawableGroups[0];
+ mVisibleList.clear();
+ mVisibleList.push_back(NULL);
+ mVisibleListEnd = &mVisibleList[0];
+ mVisibleBridge.clear();
+ mVisibleBridge.push_back(NULL);
+ mVisibleBridgeEnd = &mVisibleBridge[0];
+
+ for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
+ {
+ mRenderMap[i].clear();
+ mRenderMap[i].push_back(NULL);
+ mRenderMapEnd[i] = &mRenderMap[i][0];
+ mRenderMapAllocated[i] = 0;
+ }
+
+ clear();
}
-template <class T, class V>
+template <class T, class V>
void LLCullResult::pushBack(T& head, U32& count, V* val)
{
- head[count] = val;
- head.push_back(NULL);
- count++;
+ head[count] = val;
+ head.push_back(NULL);
+ count++;
}
void LLCullResult::clear()
{
- mVisibleGroupsSize = 0;
- mVisibleGroupsEnd = &mVisibleGroups[0];
+ mVisibleGroupsSize = 0;
+ mVisibleGroupsEnd = &mVisibleGroups[0];
- mAlphaGroupsSize = 0;
- mAlphaGroupsEnd = &mAlphaGroups[0];
+ mAlphaGroupsSize = 0;
+ mAlphaGroupsEnd = &mAlphaGroups[0];
mRiggedAlphaGroupsSize = 0;
mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0];
- mOcclusionGroupsSize = 0;
- mOcclusionGroupsEnd = &mOcclusionGroups[0];
+ mOcclusionGroupsSize = 0;
+ mOcclusionGroupsEnd = &mOcclusionGroups[0];
- mDrawableGroupsSize = 0;
- mDrawableGroupsEnd = &mDrawableGroups[0];
+ mDrawableGroupsSize = 0;
+ mDrawableGroupsEnd = &mDrawableGroups[0];
- mVisibleListSize = 0;
- mVisibleListEnd = &mVisibleList[0];
+ mVisibleListSize = 0;
+ mVisibleListEnd = &mVisibleList[0];
- mVisibleBridgeSize = 0;
- mVisibleBridgeEnd = &mVisibleBridge[0];
+ mVisibleBridgeSize = 0;
+ mVisibleBridgeEnd = &mVisibleBridge[0];
- for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
- {
- for (U32 j = 0; j < mRenderMapSize[i]; j++)
- {
- mRenderMap[i][j] = 0;
- }
- mRenderMapSize[i] = 0;
- mRenderMapEnd[i] = &(mRenderMap[i][0]);
- }
+ for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
+ {
+ for (U32 j = 0; j < mRenderMapSize[i]; j++)
+ {
+ mRenderMap[i][j] = 0;
+ }
+ mRenderMapSize[i] = 0;
+ mRenderMapEnd[i] = &(mRenderMap[i][0]);
+ }
}
LLCullResult::sg_iterator LLCullResult::beginVisibleGroups()
{
- return &mVisibleGroups[0];
+ return &mVisibleGroups[0];
}
LLCullResult::sg_iterator LLCullResult::endVisibleGroups()
{
- return mVisibleGroupsEnd;
+ return mVisibleGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginAlphaGroups()
{
- return &mAlphaGroups[0];
+ return &mAlphaGroups[0];
}
LLCullResult::sg_iterator LLCullResult::endAlphaGroups()
{
- return mAlphaGroupsEnd;
+ return mAlphaGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginRiggedAlphaGroups()
@@ -3938,80 +4011,80 @@ LLCullResult::sg_iterator LLCullResult::endRiggedAlphaGroups()
LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()
{
- return &mOcclusionGroups[0];
+ return &mOcclusionGroups[0];
}
LLCullResult::sg_iterator LLCullResult::endOcclusionGroups()
{
- return mOcclusionGroupsEnd;
+ return mOcclusionGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginDrawableGroups()
{
- return &mDrawableGroups[0];
+ return &mDrawableGroups[0];
}
LLCullResult::sg_iterator LLCullResult::endDrawableGroups()
{
- return mDrawableGroupsEnd;
+ return mDrawableGroupsEnd;
}
LLCullResult::drawable_iterator LLCullResult::beginVisibleList()
{
- return &mVisibleList[0];
+ return &mVisibleList[0];
}
LLCullResult::drawable_iterator LLCullResult::endVisibleList()
{
- return mVisibleListEnd;
+ return mVisibleListEnd;
}
LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge()
{
- return &mVisibleBridge[0];
+ return &mVisibleBridge[0];
}
LLCullResult::bridge_iterator LLCullResult::endVisibleBridge()
{
- return mVisibleBridgeEnd;
+ return mVisibleBridgeEnd;
}
LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type)
{
- return &mRenderMap[type][0];
+ return &mRenderMap[type][0];
}
LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type)
{
- return mRenderMapEnd[type];
+ return mRenderMapEnd[type];
}
void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
{
- if (mVisibleGroupsSize < mVisibleGroupsAllocated)
- {
- mVisibleGroups[mVisibleGroupsSize] = group;
- }
- else
- {
- pushBack(mVisibleGroups, mVisibleGroupsAllocated, group);
- }
- ++mVisibleGroupsSize;
- mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize];
+ if (mVisibleGroupsSize < mVisibleGroupsAllocated)
+ {
+ mVisibleGroups[mVisibleGroupsSize] = group;
+ }
+ else
+ {
+ pushBack(mVisibleGroups, mVisibleGroupsAllocated, group);
+ }
+ ++mVisibleGroupsSize;
+ mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize];
}
void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
{
- if (mAlphaGroupsSize < mAlphaGroupsAllocated)
- {
- mAlphaGroups[mAlphaGroupsSize] = group;
- }
- else
- {
- pushBack(mAlphaGroups, mAlphaGroupsAllocated, group);
- }
- ++mAlphaGroupsSize;
- mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize];
+ if (mAlphaGroupsSize < mAlphaGroupsAllocated)
+ {
+ mAlphaGroups[mAlphaGroupsSize] = group;
+ }
+ else
+ {
+ pushBack(mAlphaGroups, mAlphaGroupsAllocated, group);
+ }
+ ++mAlphaGroupsSize;
+ mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize];
}
void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group)
@@ -4030,16 +4103,16 @@ void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group)
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
{
- if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)
- {
- mOcclusionGroups[mOcclusionGroupsSize] = group;
- }
- else
- {
- pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group);
- }
- ++mOcclusionGroupsSize;
- mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize];
+ if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)
+ {
+ mOcclusionGroups[mOcclusionGroupsSize] = group;
+ }
+ else
+ {
+ pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group);
+ }
+ ++mOcclusionGroupsSize;
+ mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize];
}
void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
@@ -4048,16 +4121,16 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
// group must NOT be in the drawble groups list already
llassert(std::find(&mDrawableGroups[0], mDrawableGroupsEnd, group) == mDrawableGroupsEnd);
#endif
- if (mDrawableGroupsSize < mDrawableGroupsAllocated)
- {
- mDrawableGroups[mDrawableGroupsSize] = group;
- }
- else
- {
- pushBack(mDrawableGroups, mDrawableGroupsAllocated, group);
- }
- ++mDrawableGroupsSize;
- mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize];
+ if (mDrawableGroupsSize < mDrawableGroupsAllocated)
+ {
+ mDrawableGroups[mDrawableGroupsSize] = group;
+ }
+ else
+ {
+ pushBack(mDrawableGroups, mDrawableGroupsAllocated, group);
+ }
+ ++mDrawableGroupsSize;
+ mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize];
}
void LLCullResult::pushDrawable(LLDrawable* drawable)
@@ -4066,56 +4139,56 @@ void LLCullResult::pushDrawable(LLDrawable* drawable)
// drawable must NOT be in the visible list already
llassert(std::find(&mVisibleList[0], mVisibleListEnd, drawable) == mVisibleListEnd);
#endif
- if (mVisibleListSize < mVisibleListAllocated)
- {
- mVisibleList[mVisibleListSize] = drawable;
- }
- else
- {
- pushBack(mVisibleList, mVisibleListAllocated, drawable);
- }
- ++mVisibleListSize;
- mVisibleListEnd = &mVisibleList[mVisibleListSize];
+ if (mVisibleListSize < mVisibleListAllocated)
+ {
+ mVisibleList[mVisibleListSize] = drawable;
+ }
+ else
+ {
+ pushBack(mVisibleList, mVisibleListAllocated, drawable);
+ }
+ ++mVisibleListSize;
+ mVisibleListEnd = &mVisibleList[mVisibleListSize];
}
void LLCullResult::pushBridge(LLSpatialBridge* bridge)
{
- if (mVisibleBridgeSize < mVisibleBridgeAllocated)
- {
- mVisibleBridge[mVisibleBridgeSize] = bridge;
- }
- else
- {
- pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge);
- }
- ++mVisibleBridgeSize;
- mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize];
+ if (mVisibleBridgeSize < mVisibleBridgeAllocated)
+ {
+ mVisibleBridge[mVisibleBridgeSize] = bridge;
+ }
+ else
+ {
+ pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge);
+ }
+ ++mVisibleBridgeSize;
+ mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize];
}
void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
{
- if (mRenderMapSize[type] < mRenderMapAllocated[type])
- {
- mRenderMap[type][mRenderMapSize[type]] = draw_info;
- }
- else
- {
- pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info);
- }
- ++mRenderMapSize[type];
- mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]);
+ if (mRenderMapSize[type] < mRenderMapAllocated[type])
+ {
+ mRenderMap[type][mRenderMapSize[type]] = draw_info;
+ }
+ else
+ {
+ pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info);
+ }
+ ++mRenderMapSize[type];
+ mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]);
}
void LLCullResult::assertDrawMapsEmpty()
{
- for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
- {
- if (mRenderMapSize[i] != 0)
- {
- LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!"
- << " (mRenderMapSize[" << i << "] = " << mRenderMapSize[i] << ")" << LL_ENDL;
- }
- }
+ for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
+ {
+ if (mRenderMapSize[i] != 0)
+ {
+ LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!"
+ << " (mRenderMapSize[" << i << "] = " << mRenderMapSize[i] << ")" << LL_ENDL;
+ }
+ }
}
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 93e1f9c774..804afe6266 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llsurface.cpp
* @brief Implementation of LLSurface class
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -66,82 +66,82 @@ S32 LLSurface::sTextureSize = 256;
// ---------------- LLSurface:: Public Members ---------------
LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
- mGridsPerEdge(0),
- mOOGridsPerEdge(0.f),
- mPatchesPerEdge(0),
- mNumberOfPatches(0),
- mType(type),
- mDetailTextureScale(0.f),
- mOriginGlobal(0.0, 0.0, 0.0),
- mSTexturep(NULL),
- mWaterTexturep(NULL),
- mGridsPerPatchEdge(0),
- mMetersPerGrid(1.0f),
- mMetersPerEdge(1.0f),
- mRegionp(regionp)
+ mGridsPerEdge(0),
+ mOOGridsPerEdge(0.f),
+ mPatchesPerEdge(0),
+ mNumberOfPatches(0),
+ mType(type),
+ mDetailTextureScale(0.f),
+ mOriginGlobal(0.0, 0.0, 0.0),
+ mSTexturep(NULL),
+ mWaterTexturep(NULL),
+ mGridsPerPatchEdge(0),
+ mMetersPerGrid(1.0f),
+ mMetersPerEdge(1.0f),
+ mRegionp(regionp)
{
- // Surface data
- mSurfaceZ = NULL;
- mNorm = NULL;
+ // Surface data
+ mSurfaceZ = NULL;
+ mNorm = NULL;
- // Patch data
- mPatchList = NULL;
+ // Patch data
+ mPatchList = NULL;
- // One of each for each camera
- mVisiblePatchCount = 0;
+ // One of each for each camera
+ mVisiblePatchCount = 0;
- mHasZData = FALSE;
- // "uninitialized" min/max z
- mMinZ = 10000.f;
- mMaxZ = -10000.f;
+ mHasZData = FALSE;
+ // "uninitialized" min/max z
+ mMinZ = 10000.f;
+ mMaxZ = -10000.f;
- mWaterObjp = NULL;
+ mWaterObjp = NULL;
- // In here temporarily.
- mSurfacePatchUpdateCount = 0;
+ // In here temporarily.
+ mSurfacePatchUpdateCount = 0;
- for (S32 i = 0; i < 8; i++)
- {
- mNeighbors[i] = NULL;
- }
+ for (S32 i = 0; i < 8; i++)
+ {
+ mNeighbors[i] = NULL;
+ }
}
LLSurface::~LLSurface()
{
- delete [] mSurfaceZ;
- mSurfaceZ = NULL;
-
- delete [] mNorm;
-
- mGridsPerEdge = 0;
- mGridsPerPatchEdge = 0;
- mPatchesPerEdge = 0;
- mNumberOfPatches = 0;
- destroyPatchData();
-
- LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep);
- if (!poolp)
- {
- LL_WARNS() << "No pool for terrain on destruction!" << LL_ENDL;
- }
- else if (poolp->mReferences.empty())
- {
- gPipeline.removePool(poolp);
- // Don't enable this until we blitz the draw pool for it as well. -- djs
- if (mSTexturep)
- {
- mSTexturep = NULL;
- }
- if (mWaterTexturep)
- {
- mWaterTexturep = NULL;
- }
- }
- else
- {
- LL_ERRS() << "Terrain pool not empty!" << LL_ENDL;
- }
+ delete [] mSurfaceZ;
+ mSurfaceZ = NULL;
+
+ delete [] mNorm;
+
+ mGridsPerEdge = 0;
+ mGridsPerPatchEdge = 0;
+ mPatchesPerEdge = 0;
+ mNumberOfPatches = 0;
+ destroyPatchData();
+
+ LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep);
+ if (!poolp)
+ {
+ LL_WARNS() << "No pool for terrain on destruction!" << LL_ENDL;
+ }
+ else if (poolp->mReferences.empty())
+ {
+ gPipeline.removePool(poolp);
+ // Don't enable this until we blitz the draw pool for it as well. -- djs
+ if (mSTexturep)
+ {
+ mSTexturep = NULL;
+ }
+ if (mWaterTexturep)
+ {
+ mWaterTexturep = NULL;
+ }
+ }
+ else
+ {
+ LL_ERRS() << "Terrain pool not empty!" << LL_ENDL;
+ }
}
void LLSurface::initClasses()
@@ -150,537 +150,538 @@ void LLSurface::initClasses()
void LLSurface::setRegion(LLViewerRegion *regionp)
{
- mRegionp = regionp;
- mWaterObjp = NULL; // depends on regionp, needs recreating
+ mRegionp = regionp;
+ mWaterObjp = NULL; // depends on regionp, needs recreating
}
// Assumes that arguments are powers of 2, and that
-// grids_per_edge / grids_per_patch_edge = power of 2
+// grids_per_edge / grids_per_patch_edge = power of 2
void LLSurface::create(const S32 grids_per_edge,
- const S32 grids_per_patch_edge,
- const LLVector3d &origin_global,
- const F32 width)
+ const S32 grids_per_patch_edge,
+ const LLVector3d &origin_global,
+ const F32 width)
{
- // Initialize various constants for the surface
- mGridsPerEdge = grids_per_edge + 1; // Add 1 for the east and north buffer
- mOOGridsPerEdge = 1.f / mGridsPerEdge;
- mGridsPerPatchEdge = grids_per_patch_edge;
- mPatchesPerEdge = (mGridsPerEdge - 1) / mGridsPerPatchEdge;
- mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge;
- mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1));
- mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1);
-
- mOriginGlobal.setVec(origin_global);
-
- mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale());
-
- S32 number_of_grids = mGridsPerEdge * mGridsPerEdge;
-
- /////////////////////////////////////
- //
- // Initialize data arrays for surface
- ///
- mSurfaceZ = new F32[number_of_grids];
- mNorm = new LLVector3[number_of_grids];
-
- // Reset the surface to be a flat square grid
- for(S32 i=0; i < number_of_grids; i++)
- {
- // Surface is flat and zero
- // Normals all point up
- mSurfaceZ[i] = 0.0f;
- mNorm[i].setVec(0.f, 0.f, 1.f);
- }
+ // Initialize various constants for the surface
+ mGridsPerEdge = grids_per_edge + 1; // Add 1 for the east and north buffer
+ mOOGridsPerEdge = 1.f / mGridsPerEdge;
+ mGridsPerPatchEdge = grids_per_patch_edge;
+ mPatchesPerEdge = (mGridsPerEdge - 1) / mGridsPerPatchEdge;
+ mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge;
+ mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1));
+ mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1);
+
+ mOriginGlobal.setVec(origin_global);
+
+ mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale());
+
+ S32 number_of_grids = mGridsPerEdge * mGridsPerEdge;
+
+ /////////////////////////////////////
+ //
+ // Initialize data arrays for surface
+ ///
+ mSurfaceZ = new F32[number_of_grids];
+ mNorm = new LLVector3[number_of_grids];
+
+ // Reset the surface to be a flat square grid
+ for(S32 i=0; i < number_of_grids; i++)
+ {
+ // Surface is flat and zero
+ // Normals all point up
+ mSurfaceZ[i] = 0.0f;
+ mNorm[i].setVec(0.f, 0.f, 1.f);
+ }
- mVisiblePatchCount = 0;
+ mVisiblePatchCount = 0;
- ///////////////////////
- //
- // Initialize textures
- //
+ ///////////////////////
+ //
+ // Initialize textures
+ //
- initTextures();
+ initTextures();
- // Has to be done after texture initialization
- createPatchData();
+ // Has to be done after texture initialization
+ createPatchData();
}
LLViewerTexture* LLSurface::getSTexture()
{
- if (mSTexturep.notNull() && !mSTexturep->hasGLTexture())
- {
- createSTexture();
- }
- return mSTexturep;
+ if (mSTexturep.notNull() && !mSTexturep->hasGLTexture())
+ {
+ createSTexture();
+ }
+ return mSTexturep;
}
LLViewerTexture* LLSurface::getWaterTexture()
{
- if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture())
- {
- createWaterTexture();
- }
- return mWaterTexturep;
+ if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture())
+ {
+ createWaterTexture();
+ }
+ return mWaterTexturep;
}
void LLSurface::createSTexture()
{
- if (!mSTexturep)
- {
- // Fill with dummy gray data.
- // GL NOT ACTIVE HERE
- LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3);
- U8 *default_texture = raw->getData();
- for (S32 i = 0; i < sTextureSize; i++)
- {
- for (S32 j = 0; j < sTextureSize; j++)
- {
- *(default_texture + (i*sTextureSize + j)*3) = 128;
- *(default_texture + (i*sTextureSize + j)*3 + 1) = 128;
- *(default_texture + (i*sTextureSize + j)*3 + 2) = 128;
- }
- }
-
- mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
- mSTexturep->dontDiscard();
- gGL.getTexUnit(0)->bind(mSTexturep);
- mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ if (!mSTexturep)
+ {
+ // Fill with dummy gray data.
+ // GL NOT ACTIVE HERE
+ LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3);
+ U8 *default_texture = raw->getData();
+ for (S32 i = 0; i < sTextureSize; i++)
+ {
+ for (S32 j = 0; j < sTextureSize; j++)
+ {
+ *(default_texture + (i*sTextureSize + j)*3) = 128;
+ *(default_texture + (i*sTextureSize + j)*3 + 1) = 128;
+ *(default_texture + (i*sTextureSize + j)*3 + 2) = 128;
+ }
+ }
+
+ mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ mSTexturep->dontDiscard();
+ gGL.getTexUnit(0)->bind(mSTexturep);
+ mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
}
void LLSurface::createWaterTexture()
{
- if (!mWaterTexturep)
- {
- // Create the water texture
- LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4);
- U8 *default_texture = raw->getData();
- for (S32 i = 0; i < sTextureSize/2; i++)
- {
- for (S32 j = 0; j < sTextureSize/2; j++)
- {
- *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0];
- *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1];
- *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2];
- *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3];
- }
- }
-
- mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
- mWaterTexturep->dontDiscard();
- gGL.getTexUnit(0)->bind(mWaterTexturep);
- mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ if (!mWaterTexturep)
+ {
+ // Create the water texture
+ LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4);
+ U8 *default_texture = raw->getData();
+ for (S32 i = 0; i < sTextureSize/2; i++)
+ {
+ for (S32 j = 0; j < sTextureSize/2; j++)
+ {
+ *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0];
+ *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1];
+ *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2];
+ *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3];
+ }
+ }
+
+ mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ mWaterTexturep->dontDiscard();
+ gGL.getTexUnit(0)->bind(mWaterTexturep);
+ mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
}
void LLSurface::initTextures()
{
- ///////////////////////
- //
- // Main surface texture
- //
- createSTexture();
-
- ///////////////////////
- //
- // Water texture
- //
- if (gSavedSettings.getBOOL("RenderWater") )
- {
- createWaterTexture();
- mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
- gPipeline.createObject(mWaterObjp);
- LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
- water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet
- mWaterObjp->setPositionGlobal(water_pos_global);
- }
+ ///////////////////////
+ //
+ // Main surface texture
+ //
+ createSTexture();
+
+ ///////////////////////
+ //
+ // Water texture
+ //
+ if (gSavedSettings.getBOOL("RenderWater") )
+ {
+ createWaterTexture();
+ mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
+ gPipeline.createObject(mWaterObjp);
+ LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
+ water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet
+ mWaterObjp->setPositionGlobal(water_pos_global);
+ }
}
-void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
+void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
{
- LLVector3d new_origin_global;
- mOriginGlobal = origin_global;
- LLSurfacePatch *patchp;
- S32 i, j;
- // Need to update the southwest corners of the patches
- for (j=0; j<mPatchesPerEdge; j++)
- {
- for (i=0; i<mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, j);
-
- new_origin_global = patchp->getOriginGlobal();
-
- new_origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
- new_origin_global.mdV[1] = mOriginGlobal.mdV[1] + j * mMetersPerGrid * mGridsPerPatchEdge;
- patchp->setOriginGlobal(new_origin_global);
- }
- }
-
- // Hack!
- if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull())
- {
- const F64 x = origin_global.mdV[VX] + 128.0;
- const F64 y = origin_global.mdV[VY] + 128.0;
- const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ];
-
- LLVector3d water_origin_global(x, y, z);
-
- mWaterObjp->setPositionGlobal(water_origin_global);
- }
+ LLVector3d new_origin_global;
+ mOriginGlobal = origin_global;
+ LLSurfacePatch *patchp;
+ S32 i, j;
+ // Need to update the southwest corners of the patches
+ for (j=0; j<mPatchesPerEdge; j++)
+ {
+ for (i=0; i<mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, j);
+
+ new_origin_global = patchp->getOriginGlobal();
+
+ new_origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
+ new_origin_global.mdV[1] = mOriginGlobal.mdV[1] + j * mMetersPerGrid * mGridsPerPatchEdge;
+ patchp->setOriginGlobal(new_origin_global);
+ }
+ }
+
+ // Hack!
+ if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull())
+ {
+ const F64 x = origin_global.mdV[VX] + 128.0;
+ const F64 y = origin_global.mdV[VY] + 128.0;
+ const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ];
+
+ LLVector3d water_origin_global(x, y, z);
+
+ mWaterObjp->setPositionGlobal(water_origin_global);
+ }
}
void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
{
- S32 i;
- for (i = 0; i < 8; i++)
- {
- if ( mNeighbors[i] != NULL )
- {
- uniqueRegions.push_back( mNeighbors[i]->getRegion() );
- }
- }
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if ( mNeighbors[i] != NULL )
+ {
+ uniqueRegions.push_back( mNeighbors[i]->getRegion() );
+ }
+ }
}
void LLSurface::getNeighboringRegionsStatus( std::vector<S32>& regions )
{
- S32 i;
- for (i = 0; i < 8; i++)
- {
- if ( mNeighbors[i] != NULL )
- {
- regions.push_back( i );
- }
- }
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if ( mNeighbors[i] != NULL )
+ {
+ regions.push_back( i );
+ }
+ }
}
void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
{
- S32 i;
- LLSurfacePatch *patchp, *neighbor_patchp;
-
- mNeighbors[direction] = neighborp;
- neighborp->mNeighbors[gDirOpposite[direction]] = this;
-
- // Connect patches
- if (NORTHEAST == direction)
- {
- patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
- neighbor_patchp = neighborp->getPatch(0, 0);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- patchp->updateNorthEdge(); // Only update one of north or east.
- patchp->dirtyZ();
- }
- else if (NORTHWEST == direction)
- {
- patchp = getPatch(0, mPatchesPerEdge - 1);
- neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
- }
- else if (SOUTHWEST == direction)
- {
- patchp = getPatch(0, 0);
- neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- neighbor_patchp->updateNorthEdge(); // Only update one of north or east.
- neighbor_patchp->dirtyZ();
- }
- else if (SOUTHEAST == direction)
- {
- patchp = getPatch(mPatchesPerEdge - 1, 0);
- neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
- }
- else if (EAST == direction)
- {
- // Do east/west connections, first
- for (i = 0; i < (S32)mPatchesPerEdge; i++)
- {
- patchp = getPatch(mPatchesPerEdge - 1, i);
- neighbor_patchp = neighborp->getPatch(0, i);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- patchp->updateEastEdge();
- patchp->dirtyZ();
- }
-
- // Now do northeast/southwest connections
- for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
- {
- patchp = getPatch(mPatchesPerEdge - 1, i);
- neighbor_patchp = neighborp->getPatch(0, i+1);
-
- patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
- neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
- }
- // Now do southeast/northwest connections
- for (i = 1; i < (S32)mPatchesPerEdge; i++)
- {
- patchp = getPatch(mPatchesPerEdge - 1, i);
- neighbor_patchp = neighborp->getPatch(0, i-1);
-
- patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
- neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
- }
- }
- else if (NORTH == direction)
- {
- // Do north/south connections, first
- for (i = 0; i < (S32)mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, mPatchesPerEdge - 1);
- neighbor_patchp = neighborp->getPatch(i, 0);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- patchp->updateNorthEdge();
- patchp->dirtyZ();
- }
-
- // Do northeast/southwest connections
- for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
- {
- patchp = getPatch(i, mPatchesPerEdge - 1);
- neighbor_patchp = neighborp->getPatch(i+1, 0);
-
- patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
- neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
- }
- // Do southeast/northwest connections
- for (i = 1; i < (S32)mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, mPatchesPerEdge - 1);
- neighbor_patchp = neighborp->getPatch(i-1, 0);
-
- patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
- neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
- }
- }
- else if (WEST == direction)
- {
- // Do east/west connections, first
- for (i = 0; i < mPatchesPerEdge; i++)
- {
- patchp = getPatch(0, i);
- neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- neighbor_patchp->updateEastEdge();
- neighbor_patchp->dirtyZ();
- }
-
- // Now do northeast/southwest connections
- for (i = 1; i < mPatchesPerEdge; i++)
- {
- patchp = getPatch(0, i);
- neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1);
-
- patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
- neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
- }
-
- // Now do northwest/southeast connections
- for (i = 0; i < mPatchesPerEdge - 1; i++)
- {
- patchp = getPatch(0, i);
- neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1);
-
- patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
- neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
- }
- }
- else if (SOUTH == direction)
- {
- // Do north/south connections, first
- for (i = 0; i < mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, 0);
- neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1);
-
- patchp->connectNeighbor(neighbor_patchp, direction);
- neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
-
- neighbor_patchp->updateNorthEdge();
- neighbor_patchp->dirtyZ();
- }
-
- // Now do northeast/southwest connections
- for (i = 1; i < mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, 0);
- neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1);
-
- patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
- neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
- }
- // Now do northeast/southwest connections
- for (i = 0; i < mPatchesPerEdge - 1; i++)
- {
- patchp = getPatch(i, 0);
- neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1);
-
- patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
- neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
- }
- }
+ S32 i;
+ LLSurfacePatch *patchp, *neighbor_patchp;
+
+ mNeighbors[direction] = neighborp;
+ neighborp->mNeighbors[gDirOpposite[direction]] = this;
+
+ // Connect patches
+ if (NORTHEAST == direction)
+ {
+ patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
+ neighbor_patchp = neighborp->getPatch(0, 0);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ patchp->updateNorthEdge(); // Only update one of north or east.
+ patchp->dirtyZ();
+ }
+ else if (NORTHWEST == direction)
+ {
+ patchp = getPatch(0, mPatchesPerEdge - 1);
+ neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+ }
+ else if (SOUTHWEST == direction)
+ {
+ patchp = getPatch(0, 0);
+ neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ neighbor_patchp->updateNorthEdge(); // Only update one of north or east.
+ neighbor_patchp->dirtyZ();
+ }
+ else if (SOUTHEAST == direction)
+ {
+ patchp = getPatch(mPatchesPerEdge - 1, 0);
+ neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+ }
+ else if (EAST == direction)
+ {
+ // Do east/west connections, first
+ for (i = 0; i < (S32)mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(mPatchesPerEdge - 1, i);
+ neighbor_patchp = neighborp->getPatch(0, i);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ patchp->updateEastEdge();
+ patchp->dirtyZ();
+ }
+
+ // Now do northeast/southwest connections
+ for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
+ {
+ patchp = getPatch(mPatchesPerEdge - 1, i);
+ neighbor_patchp = neighborp->getPatch(0, i+1);
+
+ patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
+ neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
+ }
+ // Now do southeast/northwest connections
+ for (i = 1; i < (S32)mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(mPatchesPerEdge - 1, i);
+ neighbor_patchp = neighborp->getPatch(0, i-1);
+
+ patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
+ neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
+ }
+ }
+ else if (NORTH == direction)
+ {
+ // Do north/south connections, first
+ for (i = 0; i < (S32)mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, mPatchesPerEdge - 1);
+ neighbor_patchp = neighborp->getPatch(i, 0);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ patchp->updateNorthEdge();
+ patchp->dirtyZ();
+ }
+
+ // Do northeast/southwest connections
+ for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
+ {
+ patchp = getPatch(i, mPatchesPerEdge - 1);
+ neighbor_patchp = neighborp->getPatch(i+1, 0);
+
+ patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
+ neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
+ }
+ // Do southeast/northwest connections
+ for (i = 1; i < (S32)mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, mPatchesPerEdge - 1);
+ neighbor_patchp = neighborp->getPatch(i-1, 0);
+
+ patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
+ neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
+ }
+ }
+ else if (WEST == direction)
+ {
+ // Do east/west connections, first
+ for (i = 0; i < mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(0, i);
+ neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ neighbor_patchp->updateEastEdge();
+ neighbor_patchp->dirtyZ();
+ }
+
+ // Now do northeast/southwest connections
+ for (i = 1; i < mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(0, i);
+ neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
+ neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
+ }
+
+ // Now do northwest/southeast connections
+ for (i = 0; i < mPatchesPerEdge - 1; i++)
+ {
+ patchp = getPatch(0, i);
+ neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1);
+
+ patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
+ neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
+ }
+ }
+ else if (SOUTH == direction)
+ {
+ // Do north/south connections, first
+ for (i = 0; i < mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, 0);
+ neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, direction);
+ neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
+
+ neighbor_patchp->updateNorthEdge();
+ neighbor_patchp->dirtyZ();
+ }
+
+ // Now do northeast/southwest connections
+ for (i = 1; i < mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, 0);
+ neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
+ neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
+ }
+ // Now do northeast/southwest connections
+ for (i = 0; i < mPatchesPerEdge - 1; i++)
+ {
+ patchp = getPatch(i, 0);
+ neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1);
+
+ patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
+ neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
+ }
+ }
}
void LLSurface::disconnectNeighbor(LLSurface *surfacep)
{
- S32 i;
- for (i = 0; i < 8; i++)
- {
- if (surfacep == mNeighbors[i])
- {
- mNeighbors[i] = NULL;
- }
- }
-
- // Iterate through surface patches, removing any connectivity to removed surface.
- for (i = 0; i < mNumberOfPatches; i++)
- {
- (mPatchList + i)->disconnectNeighbor(surfacep);
- }
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if (surfacep == mNeighbors[i])
+ {
+ mNeighbors[i] = NULL;
+ }
+ }
+
+ // Iterate through surface patches, removing any connectivity to removed surface.
+ for (i = 0; i < mNumberOfPatches; i++)
+ {
+ (mPatchList + i)->disconnectNeighbor(surfacep);
+ }
}
void LLSurface::disconnectAllNeighbors()
{
- S32 i;
- for (i = 0; i < 8; i++)
- {
- if (mNeighbors[i])
- {
- mNeighbors[i]->disconnectNeighbor(this);
- mNeighbors[i] = NULL;
- }
- }
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if (mNeighbors[i])
+ {
+ mNeighbors[i]->disconnectNeighbor(this);
+ mNeighbors[i] = NULL;
+ }
+ }
}
const LLVector3d &LLSurface::getOriginGlobal() const
{
- return mOriginGlobal;
+ return mOriginGlobal;
}
LLVector3 LLSurface::getOriginAgent() const
{
- return gAgent.getPosAgentFromGlobal(mOriginGlobal);
+ return gAgent.getPosAgentFromGlobal(mOriginGlobal);
}
F32 LLSurface::getMetersPerGrid() const
{
- return mMetersPerGrid;
+ return mMetersPerGrid;
}
S32 LLSurface::getGridsPerEdge() const
{
- return mGridsPerEdge;
+ return mGridsPerEdge;
}
S32 LLSurface::getPatchesPerEdge() const
{
- return mPatchesPerEdge;
+ return mPatchesPerEdge;
}
S32 LLSurface::getGridsPerPatchEdge() const
{
- return mGridsPerPatchEdge;
+ return mGridsPerPatchEdge;
}
void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)
{
- llassert(x >= 0);
- llassert(y >= 0);
- llassert(x < mGridsPerEdge);
- llassert(y < mGridsPerEdge);
- mSurfaceZ[x + y*mGridsPerEdge] += delta;
+ llassert(x >= 0);
+ llassert(y >= 0);
+ llassert(x < mGridsPerEdge);
+ llassert(y < mGridsPerEdge);
+ mSurfaceZ[x + y*mGridsPerEdge] += delta;
}
-void LLSurface::updatePatchVisibilities(LLAgent &agent)
+void LLSurface::updatePatchVisibilities(LLAgent &agent)
{
- if (gShiftFrame)
- {
- return;
- }
-
- LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
-
- LLSurfacePatch *patchp;
-
- mVisiblePatchCount = 0;
- for (S32 i=0; i<mNumberOfPatches; i++)
- {
- patchp = mPatchList + i;
-
- patchp->updateVisibility();
- if (patchp->getVisible())
- {
- mVisiblePatchCount++;
- patchp->updateCameraDistanceRegion(pos_region);
- }
- }
+ if (gShiftFrame)
+ {
+ return;
+ }
+
+ LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
+
+ LLSurfacePatch *patchp;
+
+ mVisiblePatchCount = 0;
+ for (S32 i=0; i<mNumberOfPatches; i++)
+ {
+ patchp = mPatchList + i;
+
+ patchp->updateVisibility();
+ if (patchp->getVisible())
+ {
+ mVisiblePatchCount++;
+ patchp->updateCameraDistanceRegion(pos_region);
+ }
+ }
}
-BOOL LLSurface::idleUpdate(F32 max_update_time)
+template<bool PBR>
+bool LLSurface::idleUpdate(F32 max_update_time)
{
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
- {
- return FALSE;
- }
-
- // Perform idle time update of non-critical stuff.
- // In this case, texture and normal updates.
- LLTimer update_timer;
- BOOL did_update = FALSE;
-
- // If the Z height data has changed, we need to rebuild our
- // property line vertex arrays.
- if (mDirtyPatchList.size() > 0)
- {
- getRegion()->dirtyHeights();
- }
-
- // Always call updateNormals() / updateVerticalStats()
- // every frame to avoid artifacts
- for(std::set<LLSurfacePatch *>::iterator iter = mDirtyPatchList.begin();
- iter != mDirtyPatchList.end(); )
- {
- std::set<LLSurfacePatch *>::iterator curiter = iter++;
- LLSurfacePatch *patchp = *curiter;
- patchp->updateNormals();
- patchp->updateVerticalStats();
- if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time)
- {
- if (patchp->updateTexture())
- {
- did_update = TRUE;
- patchp->clearDirty();
- mDirtyPatchList.erase(curiter);
- }
- }
- }
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
+ {
+ return false;
+ }
+
+ // Perform idle time update of non-critical stuff.
+ // In this case, texture and normal updates.
+ LLTimer update_timer;
+ bool did_update = false;
+
+ // If the Z height data has changed, we need to rebuild our
+ // property line vertex arrays.
+ if (mDirtyPatchList.size() > 0)
+ {
+ getRegion()->dirtyHeights();
+ }
+
+ // Always call updateNormals() / updateVerticalStats()
+ // every frame to avoid artifacts
+ for(std::set<LLSurfacePatch *>::iterator iter = mDirtyPatchList.begin();
+ iter != mDirtyPatchList.end(); )
+ {
+ std::set<LLSurfacePatch *>::iterator curiter = iter++;
+ LLSurfacePatch *patchp = *curiter;
+ patchp->updateNormals<PBR>();
+ patchp->updateVerticalStats();
+ if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time)
+ {
+ if (patchp->updateTexture())
+ {
+ did_update = true;
+ patchp->clearDirty();
+ mDirtyPatchList.erase(curiter);
+ }
+ }
+ }
if (did_update)
{
@@ -688,73 +689,76 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
mRegionp->updateReflectionProbes();
}
- return did_update;
+ return did_update;
}
-void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch)
-{
-
- LLPatchHeader ph;
- S32 j, i;
- S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE];
- LLSurfacePatch *patchp;
+template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
+template bool LLSurface::idleUpdate</*PBR=*/true>(F32 max_update_time);
- init_patch_decompressor(gopp->patch_size);
- gopp->stride = mGridsPerEdge;
- set_group_of_patch_header(gopp);
+void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch)
+{
- while (1)
- {
- decode_patch_header(bitpack, &ph);
- if (ph.quant_wbits == END_OF_PATCHES)
- {
- break;
- }
-
- i = ph.patchids >> 5;
- j = ph.patchids & 0x1F;
-
- if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge))
- {
- LL_WARNS() << "Received invalid terrain packet - patch header patch ID incorrect!"
- << " patches per edge " << mPatchesPerEdge
- << " i " << i
- << " j " << j
- << " dc_offset " << ph.dc_offset
- << " range " << (S32)ph.range
- << " quant_wbits " << (S32)ph.quant_wbits
- << " patchids " << (S32)ph.patchids
- << LL_ENDL;
- return;
- }
-
- patchp = &mPatchList[j*mPatchesPerEdge + i];
-
-
- decode_patch(bitpack, patch);
- decompress_patch(patchp->getDataZ(), patch, &ph);
-
- // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats.
- patchp->updateNorthEdge();
- patchp->updateEastEdge();
- if (patchp->getNeighborPatch(WEST))
- {
- patchp->getNeighborPatch(WEST)->updateEastEdge();
- }
- if (patchp->getNeighborPatch(SOUTHWEST))
- {
- patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge();
- patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge();
- }
- if (patchp->getNeighborPatch(SOUTH))
- {
- patchp->getNeighborPatch(SOUTH)->updateNorthEdge();
- }
-
- // Dirty patch statistics, and flag that the patch has data.
- patchp->dirtyZ();
- patchp->setHasReceivedData();
- }
+ LLPatchHeader ph;
+ S32 j, i;
+ S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE];
+ LLSurfacePatch *patchp;
+
+ init_patch_decompressor(gopp->patch_size);
+ gopp->stride = mGridsPerEdge;
+ set_group_of_patch_header(gopp);
+
+ while (1)
+ {
+ decode_patch_header(bitpack, &ph);
+ if (ph.quant_wbits == END_OF_PATCHES)
+ {
+ break;
+ }
+
+ i = ph.patchids >> 5;
+ j = ph.patchids & 0x1F;
+
+ if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge))
+ {
+ LL_WARNS() << "Received invalid terrain packet - patch header patch ID incorrect!"
+ << " patches per edge " << mPatchesPerEdge
+ << " i " << i
+ << " j " << j
+ << " dc_offset " << ph.dc_offset
+ << " range " << (S32)ph.range
+ << " quant_wbits " << (S32)ph.quant_wbits
+ << " patchids " << (S32)ph.patchids
+ << LL_ENDL;
+ return;
+ }
+
+ patchp = &mPatchList[j*mPatchesPerEdge + i];
+
+
+ decode_patch(bitpack, patch);
+ decompress_patch(patchp->getDataZ(), patch, &ph);
+
+ // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats.
+ patchp->updateNorthEdge();
+ patchp->updateEastEdge();
+ if (patchp->getNeighborPatch(WEST))
+ {
+ patchp->getNeighborPatch(WEST)->updateEastEdge();
+ }
+ if (patchp->getNeighborPatch(SOUTHWEST))
+ {
+ patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge();
+ patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge();
+ }
+ if (patchp->getNeighborPatch(SOUTH))
+ {
+ patchp->getNeighborPatch(SOUTH)->updateNorthEdge();
+ }
+
+ // Dirty patch statistics, and flag that the patch has data.
+ patchp->dirtyZ();
+ patchp->setHasReceivedData();
+ }
}
@@ -762,157 +766,157 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
// "position" is region-local
BOOL LLSurface::containsPosition(const LLVector3 &position)
{
- if (position.mV[VX] < 0.0f || position.mV[VX] > mMetersPerEdge ||
- position.mV[VY] < 0.0f || position.mV[VY] > mMetersPerEdge)
- {
- return FALSE;
- }
- return TRUE;
+ if (position.mV[VX] < 0.0f || position.mV[VX] > mMetersPerEdge ||
+ position.mV[VY] < 0.0f || position.mV[VY] > mMetersPerEdge)
+ {
+ return FALSE;
+ }
+ return TRUE;
}
F32 LLSurface::resolveHeightRegion(const F32 x, const F32 y) const
{
- F32 height = 0.0f;
- F32 oometerspergrid = 1.f/mMetersPerGrid;
-
- // Check to see if v is actually above surface
- // We use (mGridsPerEdge-1) below rather than (mGridsPerEdge)
- // becuase of the east and north buffers
-
- if (x >= 0.f &&
- x <= mMetersPerEdge &&
- y >= 0.f &&
- y <= mMetersPerEdge)
- {
- const S32 left = llfloor(x * oometerspergrid);
- const S32 bottom = llfloor(y * oometerspergrid);
-
- // Don't walk off the edge of the array!
- const S32 right = ( left+1 < (S32)mGridsPerEdge-1 ? left+1 : left );
- const S32 top = ( bottom+1 < (S32)mGridsPerEdge-1 ? bottom+1 : bottom );
-
- // Figure out if v is in first or second triangle of the square
- // and calculate the slopes accordingly
- // | |
- // -(i,j+1)---(i+1,j+1)--
- // | 1 / | ^
- // | / 2 | |
- // | / | j
- // --(i,j)----(i+1,j)--
- // | |
- //
- // i ->
- // where N = mGridsPerEdge
-
- const F32 left_bottom = getZ( left, bottom );
- const F32 right_bottom = getZ( right, bottom );
- const F32 left_top = getZ( left, top );
- const F32 right_top = getZ( right, top );
-
- // dx and dy are incremental steps from (mSurface + k)
- F32 dx = x - left * mMetersPerGrid;
- F32 dy = y - bottom * mMetersPerGrid;
-
- if (dy > dx)
- {
- // triangle 1
- dy *= left_top - left_bottom;
- dx *= right_top - left_top;
- }
- else
- {
- // triangle 2
- dx *= right_bottom - left_bottom;
- dy *= right_top - right_bottom;
- }
- height = left_bottom + (dx + dy) * oometerspergrid;
- }
- return height;
+ F32 height = 0.0f;
+ F32 oometerspergrid = 1.f/mMetersPerGrid;
+
+ // Check to see if v is actually above surface
+ // We use (mGridsPerEdge-1) below rather than (mGridsPerEdge)
+ // becuase of the east and north buffers
+
+ if (x >= 0.f &&
+ x <= mMetersPerEdge &&
+ y >= 0.f &&
+ y <= mMetersPerEdge)
+ {
+ const S32 left = llfloor(x * oometerspergrid);
+ const S32 bottom = llfloor(y * oometerspergrid);
+
+ // Don't walk off the edge of the array!
+ const S32 right = ( left+1 < (S32)mGridsPerEdge-1 ? left+1 : left );
+ const S32 top = ( bottom+1 < (S32)mGridsPerEdge-1 ? bottom+1 : bottom );
+
+ // Figure out if v is in first or second triangle of the square
+ // and calculate the slopes accordingly
+ // | |
+ // -(i,j+1)---(i+1,j+1)--
+ // | 1 / | ^
+ // | / 2 | |
+ // | / | j
+ // --(i,j)----(i+1,j)--
+ // | |
+ //
+ // i ->
+ // where N = mGridsPerEdge
+
+ const F32 left_bottom = getZ( left, bottom );
+ const F32 right_bottom = getZ( right, bottom );
+ const F32 left_top = getZ( left, top );
+ const F32 right_top = getZ( right, top );
+
+ // dx and dy are incremental steps from (mSurface + k)
+ F32 dx = x - left * mMetersPerGrid;
+ F32 dy = y - bottom * mMetersPerGrid;
+
+ if (dy > dx)
+ {
+ // triangle 1
+ dy *= left_top - left_bottom;
+ dx *= right_top - left_top;
+ }
+ else
+ {
+ // triangle 2
+ dx *= right_bottom - left_bottom;
+ dy *= right_top - right_bottom;
+ }
+ height = left_bottom + (dx + dy) * oometerspergrid;
+ }
+ return height;
}
F32 LLSurface::resolveHeightGlobal(const LLVector3d& v) const
{
- if (!mRegionp)
- {
- return 0.f;
- }
-
- LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(v);
-
- return resolveHeightRegion(pos_region);
+ if (!mRegionp)
+ {
+ return 0.f;
+ }
+
+ LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(v);
+
+ return resolveHeightRegion(pos_region);
}
LLVector3 LLSurface::resolveNormalGlobal(const LLVector3d& pos_global) const
{
- if (!mSurfaceZ)
- {
- // Hmm. Uninitialized surface!
- return LLVector3::z_axis;
- }
- //
- // Returns the vector normal to a surface at location specified by vector v
- //
- F32 oometerspergrid = 1.f/mMetersPerGrid;
- LLVector3 normal;
- F32 dzx, dzy;
-
- if (pos_global.mdV[VX] >= mOriginGlobal.mdV[VX] &&
- pos_global.mdV[VX] < mOriginGlobal.mdV[VX] + mMetersPerEdge &&
- pos_global.mdV[VY] >= mOriginGlobal.mdV[VY] &&
- pos_global.mdV[VY] < mOriginGlobal.mdV[VY] + mMetersPerEdge)
- {
- U32 i, j, k;
- F32 dx, dy;
- i = (U32) ((pos_global.mdV[VX] - mOriginGlobal.mdV[VX]) * oometerspergrid);
- j = (U32) ((pos_global.mdV[VY] - mOriginGlobal.mdV[VY]) * oometerspergrid );
- k = i + j*mGridsPerEdge;
-
- // Figure out if v is in first or second triangle of the square
- // and calculate the slopes accordingly
- // | |
- // -(k+N)---(k+1+N)--
- // | 1 / | ^
- // | / 2 | |
- // | / | j
- // --(k)----(k+1)--
- // | |
- //
- // i ->
- // where N = mGridsPerEdge
-
- // dx and dy are incremental steps from (mSurface + k)
- dx = (F32)(pos_global.mdV[VX] - i*mMetersPerGrid - mOriginGlobal.mdV[VX]);
- dy = (F32)(pos_global.mdV[VY] - j*mMetersPerGrid - mOriginGlobal.mdV[VY]);
- if (dy > dx)
- { // triangle 1
- dzx = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + mGridsPerEdge);
- dzy = *(mSurfaceZ + k) - *(mSurfaceZ + k + mGridsPerEdge);
- normal.setVec(-dzx,dzy,1);
- }
- else
- { // triangle 2
- dzx = *(mSurfaceZ + k) - *(mSurfaceZ + k + 1);
- dzy = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + 1);
- normal.setVec(dzx,-dzy,1);
- }
- }
- normal.normVec();
- return normal;
+ if (!mSurfaceZ)
+ {
+ // Hmm. Uninitialized surface!
+ return LLVector3::z_axis;
+ }
+ //
+ // Returns the vector normal to a surface at location specified by vector v
+ //
+ F32 oometerspergrid = 1.f/mMetersPerGrid;
+ LLVector3 normal;
+ F32 dzx, dzy;
+
+ if (pos_global.mdV[VX] >= mOriginGlobal.mdV[VX] &&
+ pos_global.mdV[VX] < mOriginGlobal.mdV[VX] + mMetersPerEdge &&
+ pos_global.mdV[VY] >= mOriginGlobal.mdV[VY] &&
+ pos_global.mdV[VY] < mOriginGlobal.mdV[VY] + mMetersPerEdge)
+ {
+ U32 i, j, k;
+ F32 dx, dy;
+ i = (U32) ((pos_global.mdV[VX] - mOriginGlobal.mdV[VX]) * oometerspergrid);
+ j = (U32) ((pos_global.mdV[VY] - mOriginGlobal.mdV[VY]) * oometerspergrid );
+ k = i + j*mGridsPerEdge;
+
+ // Figure out if v is in first or second triangle of the square
+ // and calculate the slopes accordingly
+ // | |
+ // -(k+N)---(k+1+N)--
+ // | 1 / | ^
+ // | / 2 | |
+ // | / | j
+ // --(k)----(k+1)--
+ // | |
+ //
+ // i ->
+ // where N = mGridsPerEdge
+
+ // dx and dy are incremental steps from (mSurface + k)
+ dx = (F32)(pos_global.mdV[VX] - i*mMetersPerGrid - mOriginGlobal.mdV[VX]);
+ dy = (F32)(pos_global.mdV[VY] - j*mMetersPerGrid - mOriginGlobal.mdV[VY]);
+ if (dy > dx)
+ { // triangle 1
+ dzx = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + mGridsPerEdge);
+ dzy = *(mSurfaceZ + k) - *(mSurfaceZ + k + mGridsPerEdge);
+ normal.setVec(-dzx,dzy,1);
+ }
+ else
+ { // triangle 2
+ dzx = *(mSurfaceZ + k) - *(mSurfaceZ + k + 1);
+ dzy = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + 1);
+ normal.setVec(dzx,-dzy,1);
+ }
+ }
+ normal.normVec();
+ return normal;
}
LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
{
-// x and y should be region-local coordinates.
+// x and y should be region-local coordinates.
// If x and y are outside of the surface, then the returned
// index will be for the nearest boundary patch.
//
// 12 | 13| 14| 15
-// | | |
+// | | |
// +---+---+---+---+
// | 12| 13| 14| 15|
// ----+---+---+---+---+-----
@@ -922,393 +926,393 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
// ----+---+---+---+---+-----
// | 0 | 1 | 2 | 3 |
// +---+---+---+---+
-// | | |
+// | | |
// 0 | 1 | 2 | 3
//
// When x and y are not region-local do the following first
- S32 i, j;
- if (x < 0.0f)
- {
- i = 0;
- }
- else if (x >= mMetersPerEdge)
- {
- i = mPatchesPerEdge - 1;
- }
- else
- {
- i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge));
- }
-
- if (y < 0.0f)
- {
- j = 0;
- }
- else if (y >= mMetersPerEdge)
- {
- j = mPatchesPerEdge - 1;
- }
- else
- {
- j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge));
- }
-
- // *NOTE: Super paranoia code follows.
- S32 index = i + j * mPatchesPerEdge;
- if((index < 0) || (index >= mNumberOfPatches))
- {
- if(0 == mNumberOfPatches)
- {
- LL_WARNS() << "No patches for current region!" << LL_ENDL;
- return NULL;
- }
- S32 old_index = index;
- index = llclamp(old_index, 0, (mNumberOfPatches - 1));
- LL_WARNS() << "Clamping out of range patch index " << old_index
- << " to " << index << LL_ENDL;
- }
- return &(mPatchList[index]);
+ S32 i, j;
+ if (x < 0.0f)
+ {
+ i = 0;
+ }
+ else if (x >= mMetersPerEdge)
+ {
+ i = mPatchesPerEdge - 1;
+ }
+ else
+ {
+ i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge));
+ }
+
+ if (y < 0.0f)
+ {
+ j = 0;
+ }
+ else if (y >= mMetersPerEdge)
+ {
+ j = mPatchesPerEdge - 1;
+ }
+ else
+ {
+ j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge));
+ }
+
+ // *NOTE: Super paranoia code follows.
+ S32 index = i + j * mPatchesPerEdge;
+ if((index < 0) || (index >= mNumberOfPatches))
+ {
+ if(0 == mNumberOfPatches)
+ {
+ LL_WARNS() << "No patches for current region!" << LL_ENDL;
+ return NULL;
+ }
+ S32 old_index = index;
+ index = llclamp(old_index, 0, (mNumberOfPatches - 1));
+ LL_WARNS() << "Clamping out of range patch index " << old_index
+ << " to " << index << LL_ENDL;
+ }
+ return &(mPatchList[index]);
}
LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const
{
- return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]);
+ return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]);
}
LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const
{
- llassert(mRegionp);
- LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);
- return resolvePatchRegion(pos_region);
+ llassert(mRegionp);
+ LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);
+ return resolvePatchRegion(pos_region);
}
-std::ostream& operator<<(std::ostream &s, const LLSurface &S)
+std::ostream& operator<<(std::ostream &s, const LLSurface &S)
{
- s << "{ \n";
- s << " mGridsPerEdge = " << S.mGridsPerEdge - 1 << " + 1\n";
- s << " mGridsPerPatchEdge = " << S.mGridsPerPatchEdge << "\n";
- s << " mPatchesPerEdge = " << S.mPatchesPerEdge << "\n";
- s << " mOriginGlobal = " << S.mOriginGlobal << "\n";
- s << " mMetersPerGrid = " << S.mMetersPerGrid << "\n";
- s << " mVisiblePatchCount = " << S.mVisiblePatchCount << "\n";
- s << "}";
- return s;
+ s << "{ \n";
+ s << " mGridsPerEdge = " << S.mGridsPerEdge - 1 << " + 1\n";
+ s << " mGridsPerPatchEdge = " << S.mGridsPerPatchEdge << "\n";
+ s << " mPatchesPerEdge = " << S.mPatchesPerEdge << "\n";
+ s << " mOriginGlobal = " << S.mOriginGlobal << "\n";
+ s << " mMetersPerGrid = " << S.mMetersPerGrid << "\n";
+ s << " mVisiblePatchCount = " << S.mVisiblePatchCount << "\n";
+ s << "}";
+ return s;
}
// ---------------- LLSurface:: Protected ----------------
-void LLSurface::createPatchData()
+void LLSurface::createPatchData()
{
- // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set
- // TODO -- check for create() called when surface is not empty
- S32 i, j;
- LLSurfacePatch *patchp;
-
- // Allocate memory
- mPatchList = new LLSurfacePatch[mNumberOfPatches];
-
- // One of each for each camera
- mVisiblePatchCount = mNumberOfPatches;
-
- for (j=0; j<mPatchesPerEdge; j++)
- {
- for (i=0; i<mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, j);
- patchp->setSurface(this);
- }
- }
-
- for (j=0; j<mPatchesPerEdge; j++)
- {
- for (i=0; i<mPatchesPerEdge; i++)
- {
- patchp = getPatch(i, j);
- patchp->mHasReceivedData = FALSE;
- patchp->mSTexUpdate = TRUE;
-
- S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge;
-
- patchp->setDataZ(mSurfaceZ + data_offset);
- patchp->setDataNorm(mNorm + data_offset);
-
-
- // We make each patch point to its neighbors so we can do resolution checking
- // when butting up different resolutions. Patches that don't have neighbors
- // somewhere will point to NULL on that side.
- if (i < mPatchesPerEdge-1)
- {
- patchp->setNeighborPatch(EAST,getPatch(i+1, j));
- }
- else
- {
- patchp->setNeighborPatch(EAST, NULL);
- }
-
- if (j < mPatchesPerEdge-1)
- {
- patchp->setNeighborPatch(NORTH, getPatch(i, j+1));
- }
- else
- {
- patchp->setNeighborPatch(NORTH, NULL);
- }
-
- if (i > 0)
- {
- patchp->setNeighborPatch(WEST, getPatch(i - 1, j));
- }
- else
- {
- patchp->setNeighborPatch(WEST, NULL);
- }
-
- if (j > 0)
- {
- patchp->setNeighborPatch(SOUTH, getPatch(i, j-1));
- }
- else
- {
- patchp->setNeighborPatch(SOUTH, NULL);
- }
-
- if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1))
- {
- patchp->setNeighborPatch(NORTHEAST, getPatch(i + 1, j + 1));
- }
- else
- {
- patchp->setNeighborPatch(NORTHEAST, NULL);
- }
-
- if (i > 0 && j < (mPatchesPerEdge-1))
- {
- patchp->setNeighborPatch(NORTHWEST, getPatch(i - 1, j + 1));
- }
- else
- {
- patchp->setNeighborPatch(NORTHWEST, NULL);
- }
-
- if (i > 0 && j > 0)
- {
- patchp->setNeighborPatch(SOUTHWEST, getPatch(i - 1, j - 1));
- }
- else
- {
- patchp->setNeighborPatch(SOUTHWEST, NULL);
- }
-
- if (i < (mPatchesPerEdge-1) && j > 0)
- {
- patchp->setNeighborPatch(SOUTHEAST, getPatch(i + 1, j - 1));
- }
- else
- {
- patchp->setNeighborPatch(SOUTHEAST, NULL);
- }
-
- LLVector3d origin_global;
- origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
- origin_global.mdV[1] = mOriginGlobal.mdV[0] + j * mMetersPerGrid * mGridsPerPatchEdge;
- origin_global.mdV[2] = 0.f;
- patchp->setOriginGlobal(origin_global);
- }
- }
+ // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set
+ // TODO -- check for create() called when surface is not empty
+ S32 i, j;
+ LLSurfacePatch *patchp;
+
+ // Allocate memory
+ mPatchList = new LLSurfacePatch[mNumberOfPatches];
+
+ // One of each for each camera
+ mVisiblePatchCount = mNumberOfPatches;
+
+ for (j=0; j<mPatchesPerEdge; j++)
+ {
+ for (i=0; i<mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, j);
+ patchp->setSurface(this);
+ }
+ }
+
+ for (j=0; j<mPatchesPerEdge; j++)
+ {
+ for (i=0; i<mPatchesPerEdge; i++)
+ {
+ patchp = getPatch(i, j);
+ patchp->mHasReceivedData = FALSE;
+ patchp->mSTexUpdate = TRUE;
+
+ S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge;
+
+ patchp->setDataZ(mSurfaceZ + data_offset);
+ patchp->setDataNorm(mNorm + data_offset);
+
+
+ // We make each patch point to its neighbors so we can do resolution checking
+ // when butting up different resolutions. Patches that don't have neighbors
+ // somewhere will point to NULL on that side.
+ if (i < mPatchesPerEdge-1)
+ {
+ patchp->setNeighborPatch(EAST,getPatch(i+1, j));
+ }
+ else
+ {
+ patchp->setNeighborPatch(EAST, NULL);
+ }
+
+ if (j < mPatchesPerEdge-1)
+ {
+ patchp->setNeighborPatch(NORTH, getPatch(i, j+1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(NORTH, NULL);
+ }
+
+ if (i > 0)
+ {
+ patchp->setNeighborPatch(WEST, getPatch(i - 1, j));
+ }
+ else
+ {
+ patchp->setNeighborPatch(WEST, NULL);
+ }
+
+ if (j > 0)
+ {
+ patchp->setNeighborPatch(SOUTH, getPatch(i, j-1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(SOUTH, NULL);
+ }
+
+ if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1))
+ {
+ patchp->setNeighborPatch(NORTHEAST, getPatch(i + 1, j + 1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(NORTHEAST, NULL);
+ }
+
+ if (i > 0 && j < (mPatchesPerEdge-1))
+ {
+ patchp->setNeighborPatch(NORTHWEST, getPatch(i - 1, j + 1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(NORTHWEST, NULL);
+ }
+
+ if (i > 0 && j > 0)
+ {
+ patchp->setNeighborPatch(SOUTHWEST, getPatch(i - 1, j - 1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(SOUTHWEST, NULL);
+ }
+
+ if (i < (mPatchesPerEdge-1) && j > 0)
+ {
+ patchp->setNeighborPatch(SOUTHEAST, getPatch(i + 1, j - 1));
+ }
+ else
+ {
+ patchp->setNeighborPatch(SOUTHEAST, NULL);
+ }
+
+ LLVector3d origin_global;
+ origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
+ origin_global.mdV[1] = mOriginGlobal.mdV[0] + j * mMetersPerGrid * mGridsPerPatchEdge;
+ origin_global.mdV[2] = 0.f;
+ patchp->setOriginGlobal(origin_global);
+ }
+ }
}
void LLSurface::destroyPatchData()
{
- // Delete all of the cached patch data for these patches.
+ // Delete all of the cached patch data for these patches.
- delete [] mPatchList;
- mPatchList = NULL;
- mVisiblePatchCount = 0;
+ delete [] mPatchList;
+ mPatchList = NULL;
+ mVisiblePatchCount = 0;
}
void LLSurface::setTextureSize(const S32 texture_size)
{
- sTextureSize = texture_size;
+ sTextureSize = texture_size;
}
U32 LLSurface::getRenderLevel(const U32 render_stride) const
{
- return mPVArray.mRenderLevelp[render_stride];
+ return mPVArray.mRenderLevelp[render_stride];
}
U32 LLSurface::getRenderStride(const U32 render_level) const
{
- return mPVArray.mRenderStridep[render_level];
+ return mPVArray.mRenderStridep[render_level];
}
LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const
{
- if ((x < 0) || (x >= mPatchesPerEdge))
- {
- LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
- return NULL;
- }
- if ((y < 0) || (y >= mPatchesPerEdge))
- {
- LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
- return NULL;
- }
-
- return mPatchList + x + y*mPatchesPerEdge;
+ if ((x < 0) || (x >= mPatchesPerEdge))
+ {
+ LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
+ return NULL;
+ }
+ if ((y < 0) || (y >= mPatchesPerEdge))
+ {
+ LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
+ return NULL;
+ }
+
+ return mPatchList + x + y*mPatchesPerEdge;
}
void LLSurface::dirtyAllPatches()
{
- S32 i;
- for (i = 0; i < mNumberOfPatches; i++)
- {
- mPatchList[i].dirtyZ();
- }
+ S32 i;
+ for (i = 0; i < mNumberOfPatches; i++)
+ {
+ mPatchList[i].dirtyZ();
+ }
}
void LLSurface::dirtySurfacePatch(LLSurfacePatch *patchp)
{
- // Put surface patch on dirty surface patch list
- mDirtyPatchList.insert(patchp);
+ // Put surface patch on dirty surface patch list
+ mDirtyPatchList.insert(patchp);
}
void LLSurface::setWaterHeight(F32 height)
{
- if (!mWaterObjp.isNull())
- {
- LLVector3 water_pos_region = mWaterObjp->getPositionRegion();
- bool changed = water_pos_region.mV[VZ] != height;
- water_pos_region.mV[VZ] = height;
- mWaterObjp->setPositionRegion(water_pos_region);
- if (changed)
- {
- LLWorld::getInstance()->updateWaterObjects();
- }
- }
- else
- {
- LL_WARNS() << "LLSurface::setWaterHeight with no water object!" << LL_ENDL;
- }
+ if (!mWaterObjp.isNull())
+ {
+ LLVector3 water_pos_region = mWaterObjp->getPositionRegion();
+ bool changed = water_pos_region.mV[VZ] != height;
+ water_pos_region.mV[VZ] = height;
+ mWaterObjp->setPositionRegion(water_pos_region);
+ if (changed)
+ {
+ LLWorld::getInstance()->updateWaterObjects();
+ }
+ }
+ else
+ {
+ LL_WARNS() << "LLSurface::setWaterHeight with no water object!" << LL_ENDL;
+ }
}
F32 LLSurface::getWaterHeight() const
{
- if (!mWaterObjp.isNull())
- {
- // we have a water object, the usual case
- return mWaterObjp->getPositionRegion().mV[VZ];
- }
- else
- {
- return DEFAULT_WATER_HEIGHT;
- }
+ if (!mWaterObjp.isNull())
+ {
+ // we have a water object, the usual case
+ return mWaterObjp->getPositionRegion().mV[VZ];
+ }
+ else
+ {
+ return DEFAULT_WATER_HEIGHT;
+ }
}
BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
- const F32 width, const F32 height)
+ const F32 width, const F32 height)
{
- LL_PROFILE_ZONE_SCOPED
- if (!getWaterTexture())
- {
- return FALSE;
- }
-
- S32 tex_width = mWaterTexturep->getWidth();
- S32 tex_height = mWaterTexturep->getHeight();
- S32 tex_comps = mWaterTexturep->getComponents();
- S32 tex_stride = tex_width * tex_comps;
- LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
- U8 *rawp = raw->getData();
-
- F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width;
- F32 scale_inv = 1.f / scale;
-
- S32 x_begin, y_begin, x_end, y_end;
-
- x_begin = ll_round(x * scale_inv);
- y_begin = ll_round(y * scale_inv);
- x_end = ll_round((x + width) * scale_inv);
- y_end = ll_round((y + width) * scale_inv);
-
- if (x_end > tex_width)
- {
- x_end = tex_width;
- }
- if (y_end > tex_width)
- {
- y_end = tex_width;
- }
-
- // OK, for now, just have the composition value equal the height at the point.
- LLVector3 location;
- LLColor4U coloru;
-
- const F32 WATER_HEIGHT = getWaterHeight();
-
- S32 i, j, offset;
- for (j = y_begin; j < y_end; j++)
- {
- for (i = x_begin; i < x_end; i++)
- {
- //F32 nv[2];
- //nv[0] = i/256.f;
- //nv[1] = j/256.f;
- // const S32 modulation = noise2(nv)*40;
- offset = j*tex_stride + i*tex_comps;
- location.mV[VX] = i*scale;
- location.mV[VY] = j*scale;
-
- // Sample multiple points
- const F32 height = resolveHeightRegion(location);
-
- if (height > WATER_HEIGHT)
- {
- // Above water...
- coloru = MAX_WATER_COLOR;
- coloru.mV[3] = ABOVE_WATERLINE_ALPHA;
- *(rawp + offset++) = coloru.mV[0];
- *(rawp + offset++) = coloru.mV[1];
- *(rawp + offset++) = coloru.mV[2];
- *(rawp + offset++) = coloru.mV[3];
- }
- else
- {
- // Want non-linear curve for transparency gradient
- coloru = MAX_WATER_COLOR;
- const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT));
- S32 alpha = 64 + ll_round((255-64)*frac);
-
- alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha);
- alpha = llmax(64, alpha);
-
- coloru.mV[3] = alpha;
- *(rawp + offset++) = coloru.mV[0];
- *(rawp + offset++) = coloru.mV[1];
- *(rawp + offset++) = coloru.mV[2];
- *(rawp + offset++) = coloru.mV[3];
- }
- }
- }
-
- if (!mWaterTexturep->hasGLTexture())
- {
- mWaterTexturep->createGLTexture(0, raw);
- }
-
- mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin);
- return TRUE;
+ LL_PROFILE_ZONE_SCOPED
+ if (!getWaterTexture())
+ {
+ return FALSE;
+ }
+
+ S32 tex_width = mWaterTexturep->getWidth();
+ S32 tex_height = mWaterTexturep->getHeight();
+ S32 tex_comps = mWaterTexturep->getComponents();
+ S32 tex_stride = tex_width * tex_comps;
+ LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
+ U8 *rawp = raw->getData();
+
+ F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width;
+ F32 scale_inv = 1.f / scale;
+
+ S32 x_begin, y_begin, x_end, y_end;
+
+ x_begin = ll_round(x * scale_inv);
+ y_begin = ll_round(y * scale_inv);
+ x_end = ll_round((x + width) * scale_inv);
+ y_end = ll_round((y + width) * scale_inv);
+
+ if (x_end > tex_width)
+ {
+ x_end = tex_width;
+ }
+ if (y_end > tex_width)
+ {
+ y_end = tex_width;
+ }
+
+ // OK, for now, just have the composition value equal the height at the point.
+ LLVector3 location;
+ LLColor4U coloru;
+
+ const F32 WATER_HEIGHT = getWaterHeight();
+
+ S32 i, j, offset;
+ for (j = y_begin; j < y_end; j++)
+ {
+ for (i = x_begin; i < x_end; i++)
+ {
+ //F32 nv[2];
+ //nv[0] = i/256.f;
+ //nv[1] = j/256.f;
+ // const S32 modulation = noise2(nv)*40;
+ offset = j*tex_stride + i*tex_comps;
+ location.mV[VX] = i*scale;
+ location.mV[VY] = j*scale;
+
+ // Sample multiple points
+ const F32 height = resolveHeightRegion(location);
+
+ if (height > WATER_HEIGHT)
+ {
+ // Above water...
+ coloru = MAX_WATER_COLOR;
+ coloru.mV[3] = ABOVE_WATERLINE_ALPHA;
+ *(rawp + offset++) = coloru.mV[0];
+ *(rawp + offset++) = coloru.mV[1];
+ *(rawp + offset++) = coloru.mV[2];
+ *(rawp + offset++) = coloru.mV[3];
+ }
+ else
+ {
+ // Want non-linear curve for transparency gradient
+ coloru = MAX_WATER_COLOR;
+ const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT));
+ S32 alpha = 64 + ll_round((255-64)*frac);
+
+ alpha = llmin(ll_round((F32)MAX_WATER_COLOR.mV[3]), alpha);
+ alpha = llmax(64, alpha);
+
+ coloru.mV[3] = alpha;
+ *(rawp + offset++) = coloru.mV[0];
+ *(rawp + offset++) = coloru.mV[1];
+ *(rawp + offset++) = coloru.mV[2];
+ *(rawp + offset++) = coloru.mV[3];
+ }
+ }
+ }
+
+ if (!mWaterTexturep->hasGLTexture())
+ {
+ mWaterTexturep->createGLTexture(0, raw);
+ }
+
+ mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin);
+ return TRUE;
}
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index ca86e2334e..b7b47d2a1c 100644
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llsurface.h
* @brief Description of LLSurface class
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -52,9 +52,9 @@ static const U8 NORTH_EDGE = 0x02;
static const U8 WEST_EDGE = 0x04;
static const U8 SOUTH_EDGE = 0x08;
-static const S32 ONE_MORE_THAN_NEIGHBOR = 1;
-static const S32 EQUAL_TO_NEIGHBOR = 0;
-static const S32 ONE_LESS_THAN_NEIGHBOR = -1;
+static const S32 ONE_MORE_THAN_NEIGHBOR = 1;
+static const S32 EQUAL_TO_NEIGHBOR = 0;
+static const S32 ONE_LESS_THAN_NEIGHBOR = -1;
const S32 ABOVE_WATERLINE_ALPHA = 32; // The alpha of water when the land elevation is above the waterline.
@@ -63,198 +63,202 @@ class LLSurfacePatch;
class LLBitPack;
class LLGroupHeader;
-class LLSurface
+class LLSurface
{
public:
- LLSurface(U32 type, LLViewerRegion *regionp = NULL);
- virtual ~LLSurface();
-
- static void initClasses(); // Do class initialization for LLSurface and its child classes.
+ LLSurface(U32 type, LLViewerRegion *regionp = NULL);
+ virtual ~LLSurface();
- void create(const S32 surface_grid_width,
- const S32 surface_patch_width,
- const LLVector3d &origin_global,
- const F32 width); // Allocates and initializes surface
+ static void initClasses(); // Do class initialization for LLSurface and its child classes.
- void setRegion(LLViewerRegion *regionp);
+ void create(const S32 surface_grid_width,
+ const S32 surface_patch_width,
+ const LLVector3d &origin_global,
+ const F32 width); // Allocates and initializes surface
- void setOriginGlobal(const LLVector3d &origin_global);
+ void setRegion(LLViewerRegion *regionp);
- void connectNeighbor(LLSurface *neighborp, U32 direction);
- void disconnectNeighbor(LLSurface *neighborp);
- void disconnectAllNeighbors();
+ void setOriginGlobal(const LLVector3d &origin_global);
- virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch);
- virtual void updatePatchVisibilities(LLAgent &agent);
+ void connectNeighbor(LLSurface *neighborp, U32 direction);
+ void disconnectNeighbor(LLSurface *neighborp);
+ void disconnectAllNeighbors();
- inline F32 getZ(const U32 k) const { return mSurfaceZ[k]; }
- inline F32 getZ(const S32 i, const S32 j) const { return mSurfaceZ[i + j*mGridsPerEdge]; }
+ virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch);
+ virtual void updatePatchVisibilities(LLAgent &agent);
- LLVector3 getOriginAgent() const;
- const LLVector3d &getOriginGlobal() const;
- F32 getMetersPerGrid() const;
- S32 getGridsPerEdge() const;
- S32 getPatchesPerEdge() const;
- S32 getGridsPerPatchEdge() const;
- U32 getRenderStride(const U32 render_level) const;
- U32 getRenderLevel(const U32 render_stride) const;
+ inline F32 getZ(const U32 k) const { return mSurfaceZ[k]; }
+ inline F32 getZ(const S32 i, const S32 j) const { return mSurfaceZ[i + j*mGridsPerEdge]; }
- // Returns the height of the surface immediately above (or below) location,
- // or if location is not above surface returns zero.
- F32 resolveHeightRegion(const F32 x, const F32 y) const;
- F32 resolveHeightRegion(const LLVector3 &location) const
- { return resolveHeightRegion( location.mV[VX], location.mV[VY] ); }
- F32 resolveHeightGlobal(const LLVector3d &position_global) const;
- LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface
+ LLVector3 getOriginAgent() const;
+ const LLVector3d &getOriginGlobal() const;
+ F32 getMetersPerGrid() const;
+ S32 getGridsPerEdge() const;
+ S32 getPatchesPerEdge() const;
+ S32 getGridsPerPatchEdge() const;
+ U32 getRenderStride(const U32 render_level) const;
+ U32 getRenderLevel(const U32 render_stride) const;
- LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const;
- LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const;
- LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const;
+ // Returns the height of the surface immediately above (or below) location,
+ // or if location is not above surface returns zero.
+ F32 resolveHeightRegion(const F32 x, const F32 y) const;
+ F32 resolveHeightRegion(const LLVector3 &location) const
+ { return resolveHeightRegion( location.mV[VX], location.mV[VY] ); }
+ F32 resolveHeightGlobal(const LLVector3d &position_global) const;
+ LLVector3 resolveNormalGlobal(const LLVector3d& v) const; // Returns normal to surface
- // Update methods (called during idle, normally)
- BOOL idleUpdate(F32 max_update_time);
+ LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const;
+ LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const;
+ LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const;
- BOOL containsPosition(const LLVector3 &position);
+ // Update methods (called during idle, normally)
+ template<bool PBR>
+ bool idleUpdate(F32 max_update_time);
- void moveZ(const S32 x, const S32 y, const F32 delta);
+ BOOL containsPosition(const LLVector3 &position);
- LLViewerRegion *getRegion() const { return mRegionp; }
+ void moveZ(const S32 x, const S32 y, const F32 delta);
- F32 getMinZ() const { return mMinZ; }
- F32 getMaxZ() const { return mMaxZ; }
+ LLViewerRegion *getRegion() const { return mRegionp; }
- void setWaterHeight(F32 height);
- F32 getWaterHeight() const;
+ F32 getMinZ() const { return mMinZ; }
+ F32 getMaxZ() const { return mMaxZ; }
- LLViewerTexture *getSTexture();
- LLViewerTexture *getWaterTexture();
- BOOL hasZData() const { return mHasZData; }
+ void setWaterHeight(F32 height);
+ F32 getWaterHeight() const;
- void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters
+ LLViewerTexture *getSTexture();
+ LLViewerTexture *getWaterTexture();
+ BOOL hasZData() const { return mHasZData; }
- void dirtySurfacePatch(LLSurfacePatch *patchp);
- LLVOWater *getWaterObj() { return mWaterObjp; }
+ void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters
- static void setTextureSize(const S32 texture_size);
+ void dirtySurfacePatch(LLSurfacePatch *patchp);
+ LLVOWater *getWaterObj() { return mWaterObjp; }
- friend class LLSurfacePatch;
- friend std::ostream& operator<<(std::ostream &s, const LLSurface &S);
-
- void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
- void getNeighboringRegionsStatus( std::vector<S32>& regions );
+ static void setTextureSize(const S32 texture_size);
+ friend class LLSurfacePatch;
+ friend std::ostream& operator<<(std::ostream &s, const LLSurface &S);
+
+ void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+ void getNeighboringRegionsStatus( std::vector<S32>& regions );
+
public:
- // Number of grid points on one side of a region, including +1 buffer for
- // north and east edge.
- S32 mGridsPerEdge;
-
- F32 mOOGridsPerEdge; // Inverse of grids per edge
+ // Number of grid points on one side of a region, including +1 buffer for
+ // north and east edge.
+ S32 mGridsPerEdge;
- S32 mPatchesPerEdge; // Number of patches on one side of a region
- S32 mNumberOfPatches; // Total number of patches
+ F32 mOOGridsPerEdge; // Inverse of grids per edge
+ S32 mPatchesPerEdge; // Number of patches on one side of a region
+ S32 mNumberOfPatches; // Total number of patches
- // Each surface points at 8 neighbors (or NULL)
- // +---+---+---+
- // |NW | N | NE|
- // +---+---+---+
- // | W | 0 | E |
- // +---+---+---+
- // |SW | S | SE|
- // +---+---+---+
- LLSurface *mNeighbors[8]; // Adjacent patches
- U32 mType; // Useful for identifying derived classes
+ // Each surface points at 8 neighbors (or NULL)
+ // +---+---+---+
+ // |NW | N | NE|
+ // +---+---+---+
+ // | W | 0 | E |
+ // +---+---+---+
+ // |SW | S | SE|
+ // +---+---+---+
+ LLSurface *mNeighbors[8]; // Adjacent patches
- F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface
+ U32 mType; // Useful for identifying derived classes
+
+ F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface
protected:
- void createSTexture();
- void createWaterTexture();
- void initTextures();
- void initWater();
-
+ void createSTexture();
+ void createWaterTexture();
+ void initTextures();
+ void initWater();
- void createPatchData(); // Allocates memory for patches.
- void destroyPatchData(); // Deallocates memory for patches.
- BOOL generateWaterTexture(const F32 x, const F32 y,
- const F32 width, const F32 height); // Generate texture from composition values.
+ void createPatchData(); // Allocates memory for patches.
+ void destroyPatchData(); // Deallocates memory for patches.
- //F32 updateTexture(LLSurfacePatch *ppatch);
+ BOOL generateWaterTexture(const F32 x, const F32 y,
+ const F32 width, const F32 height); // Generate texture from composition values.
- LLSurfacePatch *getPatch(const S32 x, const S32 y) const;
+ //F32 updateTexture(LLSurfacePatch *ppatch);
+
+ LLSurfacePatch *getPatch(const S32 x, const S32 y) const;
protected:
- LLVector3d mOriginGlobal; // In absolute frame
- LLSurfacePatch *mPatchList; // Array of all patches
+ LLVector3d mOriginGlobal; // In absolute frame
+ LLSurfacePatch *mPatchList; // Array of all patches
- // Array of grid data, mGridsPerEdge * mGridsPerEdge
- F32 *mSurfaceZ;
+ // Array of grid data, mGridsPerEdge * mGridsPerEdge
+ F32 *mSurfaceZ;
- // Array of grid normals, mGridsPerEdge * mGridsPerEdge
- LLVector3 *mNorm;
+ // Array of grid normals, mGridsPerEdge * mGridsPerEdge
+ LLVector3 *mNorm;
- std::set<LLSurfacePatch *> mDirtyPatchList;
+ std::set<LLSurfacePatch *> mDirtyPatchList;
- // The textures should never be directly initialized - use the setter methods!
- LLPointer<LLViewerTexture> mSTexturep; // Texture for surface
- LLPointer<LLViewerTexture> mWaterTexturep; // Water texture
+ // The textures should never be directly initialized - use the setter methods!
+ LLPointer<LLViewerTexture> mSTexturep; // Texture for surface
+ LLPointer<LLViewerTexture> mWaterTexturep; // Water texture
- LLPointer<LLVOWater> mWaterObjp;
+ LLPointer<LLVOWater> mWaterObjp;
- // When we want multiple cameras we'll need one of each these for each camera
- S32 mVisiblePatchCount;
+ // When we want multiple cameras we'll need one of each these for each camera
+ S32 mVisiblePatchCount;
- U32 mGridsPerPatchEdge; // Number of grid points on a side of a patch
- F32 mMetersPerGrid; // Converts (i,j) indecies to distance
- F32 mMetersPerEdge; // = mMetersPerGrid * (mGridsPerEdge-1)
+ U32 mGridsPerPatchEdge; // Number of grid points on a side of a patch
+ F32 mMetersPerGrid; // Converts (i,j) indecies to distance
+ F32 mMetersPerEdge; // = mMetersPerGrid * (mGridsPerEdge-1)
- LLPatchVertexArray mPVArray;
+ LLPatchVertexArray mPVArray;
- BOOL mHasZData; // We've received any patch data for this surface.
- F32 mMinZ; // min z for this region (during the session)
- F32 mMaxZ; // max z for this region (during the session)
+ BOOL mHasZData; // We've received any patch data for this surface.
+ F32 mMinZ; // min z for this region (during the session)
+ F32 mMaxZ; // max z for this region (during the session)
- S32 mSurfacePatchUpdateCount; // Number of frames since last update.
+ S32 mSurfacePatchUpdateCount; // Number of frames since last update.
private:
- LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using.
- static S32 sTextureSize; // Size of the surface texture
+ LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using.
+ static S32 sTextureSize; // Size of the surface texture
};
+extern template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
+extern template bool LLSurface::idleUpdate</*PBR=*/true>(F32 max_update_time);
+
// . __.
// Z /|\ /| Y North
-// | /
+// | /
// | / |<----------------- mGridsPerSurfaceEdge --------------->|
// | / __________________________________________________________
// |/______\ X /_______________________________________________________ /
-// / / / / / / / /M*M-2 /M*M-1 / /
-// /______/______/______/______/______/______/______/______/ /
-// / / / / / / / / / /
-// /______/______/______/______/______/______/______/______/ /
-// / / / / / / / / / /
-// /______/______/______/______/______/______/______/______/ /
-// West / / / / / / / / / /
+// / / / / / / / /M*M-2 /M*M-1 / /
+// /______/______/______/______/______/______/______/______/ /
+// / / / / / / / / / /
+// /______/______/______/______/______/______/______/______/ /
+// / / / / / / / / / /
+// /______/______/______/______/______/______/______/______/ /
+// West / / / / / / / / / /
// /______/______/______/______/______/______/______/______/ / East
-// /... / / / / / / / / /
-// /______/______/______/______/______/______/______/______/ /
-// _. / 2M / / / / / / / / /
-// /| /______/______/______/______/______/______/______/______/ /
-// / / M / M+1 / M+2 / ... / / / / 2M-1 / /
-// j /______/______/______/______/______/______/______/______/ /
-// / 0 / 1 / 2 / ... / / / / M-1 / /
-// /______/______/______/______/______/______/______/______/_/
+// /... / / / / / / / / /
+// /______/______/______/______/______/______/______/______/ /
+// _. / 2M / / / / / / / / /
+// /| /______/______/______/______/______/______/______/______/ /
+// / / M / M+1 / M+2 / ... / / / / 2M-1 / /
+// j /______/______/______/______/______/______/______/______/ /
+// / 0 / 1 / 2 / ... / / / / M-1 / /
+// /______/______/______/______/______/______/______/______/_/
// South |<-L->|
// i -->
//
// where M = mSurfPatchWidth
// and L = mPatchGridWidth
-//
+//
// Notice that mGridsPerSurfaceEdge = a power of two + 1
-// This provides a buffer on the east and north edges that will allow us to
+// This provides a buffer on the east and north edges that will allow us to
// fill the cracks between adjacent surfaces when rendering.
#endif
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index b71b6ae50c..92b1273041 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llsurfacepatch.cpp
* @brief LLSurfacePatch 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$
*/
@@ -46,987 +46,1154 @@ extern bool gShiftFrame;
extern U64MicrosecondsImplicit gFrameTime;
extern LLPipeline gPipeline;
-LLSurfacePatch::LLSurfacePatch()
-: mHasReceivedData(FALSE),
- mSTexUpdate(FALSE),
- mDirty(FALSE),
- mDirtyZStats(TRUE),
- mHeightsGenerated(FALSE),
- mDataOffset(0),
- mDataZ(NULL),
- mDataNorm(NULL),
- mVObjp(NULL),
- mOriginRegion(0.f, 0.f, 0.f),
- mCenterRegion(0.f, 0.f, 0.f),
- mMinZ(0.f),
- mMaxZ(0.f),
- mMeanZ(0.f),
- mRadius(0.f),
- mMinComposition(0.f),
- mMaxComposition(0.f),
- mMeanComposition(0.f),
- // This flag is used to communicate between adjacent surfaces and is
- // set to non-zero values by higher classes.
- mConnectedEdge(NO_EDGE),
- mLastUpdateTime(0),
- mSurfacep(NULL)
-{
- S32 i;
- for (i = 0; i < 8; i++)
- {
- setNeighborPatch(i, NULL);
- }
- for (i = 0; i < 9; i++)
- {
- mNormalsInvalid[i] = TRUE;
- }
+LLSurfacePatch::LLSurfacePatch()
+: mHasReceivedData(FALSE),
+ mSTexUpdate(FALSE),
+ mDirty(FALSE),
+ mDirtyZStats(TRUE),
+ mHeightsGenerated(FALSE),
+ mDataOffset(0),
+ mDataZ(NULL),
+ mDataNorm(NULL),
+ mVObjp(NULL),
+ mOriginRegion(0.f, 0.f, 0.f),
+ mCenterRegion(0.f, 0.f, 0.f),
+ mMinZ(0.f),
+ mMaxZ(0.f),
+ mMeanZ(0.f),
+ mRadius(0.f),
+ mMinComposition(0.f),
+ mMaxComposition(0.f),
+ mMeanComposition(0.f),
+ // This flag is used to communicate between adjacent surfaces and is
+ // set to non-zero values by higher classes.
+ mConnectedEdge(NO_EDGE),
+ mLastUpdateTime(0),
+ mSurfacep(NULL)
+{
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ setNeighborPatch(i, NULL);
+ }
+ for (i = 0; i < 9; i++)
+ {
+ mNormalsInvalid[i] = TRUE;
+ }
}
LLSurfacePatch::~LLSurfacePatch()
{
- mVObjp = NULL;
+ mVObjp = NULL;
}
void LLSurfacePatch::dirty()
{
- // These are outside of the loop in case we're still waiting for a dirty from the
- // texture being updated...
- if (mVObjp)
- {
- mVObjp->dirtyGeom();
- }
- else
- {
- LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
- }
-
- mDirtyZStats = TRUE;
- mHeightsGenerated = FALSE;
-
- if (!mDirty)
- {
- mDirty = TRUE;
- mSurfacep->dirtySurfacePatch(this);
- }
+ // These are outside of the loop in case we're still waiting for a dirty from the
+ // texture being updated...
+ if (mVObjp)
+ {
+ mVObjp->dirtyGeom();
+ }
+ else
+ {
+ LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
+ }
+
+ mDirtyZStats = TRUE;
+ mHeightsGenerated = FALSE;
+
+ if (!mDirty)
+ {
+ mDirty = TRUE;
+ mSurfacep->dirtySurfacePatch(this);
+ }
}
void LLSurfacePatch::setSurface(LLSurface *surfacep)
{
- mSurfacep = surfacep;
- if (mVObjp == (LLVOSurfacePatch *)NULL)
- {
- llassert(mSurfacep->mType == 'l');
-
- mVObjp = (LLVOSurfacePatch *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SURFACE_PATCH, mSurfacep->getRegion());
- mVObjp->setPatch(this);
- mVObjp->setPositionRegion(mCenterRegion);
- gPipeline.createObject(mVObjp);
- }
-}
+ mSurfacep = surfacep;
+ if (mVObjp == (LLVOSurfacePatch *)NULL)
+ {
+ llassert(mSurfacep->mType == 'l');
+
+ mVObjp = (LLVOSurfacePatch *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SURFACE_PATCH, mSurfacep->getRegion());
+ mVObjp->setPatch(this);
+ mVObjp->setPositionRegion(mCenterRegion);
+ gPipeline.createObject(mVObjp);
+ }
+}
void LLSurfacePatch::disconnectNeighbor(LLSurface *surfacep)
{
- U32 i;
- for (i = 0; i < 8; i++)
- {
- if (getNeighborPatch(i))
- {
- if (getNeighborPatch(i)->mSurfacep == surfacep)
- {
- setNeighborPatch(i, NULL);
- mNormalsInvalid[i] = TRUE;
- }
- }
- }
-
- // Clean up connected edges
- if (getNeighborPatch(EAST))
- {
- if (getNeighborPatch(EAST)->mSurfacep == surfacep)
- {
- mConnectedEdge &= ~EAST_EDGE;
- }
- }
- if (getNeighborPatch(NORTH))
- {
- if (getNeighborPatch(NORTH)->mSurfacep == surfacep)
- {
- mConnectedEdge &= ~NORTH_EDGE;
- }
- }
- if (getNeighborPatch(WEST))
- {
- if (getNeighborPatch(WEST)->mSurfacep == surfacep)
- {
- mConnectedEdge &= ~WEST_EDGE;
- }
- }
- if (getNeighborPatch(SOUTH))
- {
- if (getNeighborPatch(SOUTH)->mSurfacep == surfacep)
- {
- mConnectedEdge &= ~SOUTH_EDGE;
- }
- }
+ U32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if (getNeighborPatch(i))
+ {
+ if (getNeighborPatch(i)->mSurfacep == surfacep)
+ {
+ setNeighborPatch(i, NULL);
+ mNormalsInvalid[i] = TRUE;
+ }
+ }
+ }
+
+ // Clean up connected edges
+ if (getNeighborPatch(EAST))
+ {
+ if (getNeighborPatch(EAST)->mSurfacep == surfacep)
+ {
+ mConnectedEdge &= ~EAST_EDGE;
+ }
+ }
+ if (getNeighborPatch(NORTH))
+ {
+ if (getNeighborPatch(NORTH)->mSurfacep == surfacep)
+ {
+ mConnectedEdge &= ~NORTH_EDGE;
+ }
+ }
+ if (getNeighborPatch(WEST))
+ {
+ if (getNeighborPatch(WEST)->mSurfacep == surfacep)
+ {
+ mConnectedEdge &= ~WEST_EDGE;
+ }
+ }
+ if (getNeighborPatch(SOUTH))
+ {
+ if (getNeighborPatch(SOUTH)->mSurfacep == surfacep)
+ {
+ mConnectedEdge &= ~SOUTH_EDGE;
+ }
+ }
}
LLVector3 LLSurfacePatch::getPointAgent(const U32 x, const U32 y) const
{
- U32 surface_stride = mSurfacep->getGridsPerEdge();
- U32 point_offset = x + y*surface_stride;
- LLVector3 pos;
- pos = getOriginAgent();
- pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
- pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
- pos.mV[VZ] = *(mDataZ + point_offset);
- return pos;
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+ U32 point_offset = x + y*surface_stride;
+ LLVector3 pos;
+ pos = getOriginAgent();
+ pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
+ pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
+ pos.mV[VZ] = *(mDataZ + point_offset);
+ return pos;
}
LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const
{
- U32 surface_stride = mSurfacep->getGridsPerEdge();
- U32 point_offset = x + y*surface_stride;
- LLVector3 pos, rel_pos;
- pos = getOriginAgent();
- pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
- pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
- pos.mV[VZ] = *(mDataZ + point_offset);
- rel_pos = pos - mSurfacep->getOriginAgent();
- rel_pos *= 1.f/surface_stride;
- return LLVector2(rel_pos.mV[VX], rel_pos.mV[VY]);
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+ U32 point_offset = x + y*surface_stride;
+ LLVector3 pos, rel_pos;
+ pos = getOriginAgent();
+ pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
+ pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
+ pos.mV[VZ] = *(mDataZ + point_offset);
+ rel_pos = pos - mSurfacep->getOriginAgent();
+ rel_pos *= 1.f/surface_stride;
+ return LLVector2(rel_pos.mV[VX], rel_pos.mV[VY]);
}
void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal,
- LLVector2 *tex0, LLVector2 *tex1)
+ LLVector2 *tex0, LLVector2 *tex1)
{
- if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp)
- {
- return; // failsafe
- }
- llassert_always(vertex && normal && tex0 && tex1);
-
- U32 surface_stride = mSurfacep->getGridsPerEdge();
- U32 point_offset = x + y*surface_stride;
-
- *normal = getNormal(x, y);
-
- LLVector3 pos_agent = getOriginAgent();
- pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
- pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
- pos_agent.mV[VZ] = *(mDataZ + point_offset);
- *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent();
-
- LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
- LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
- tex0->mV[0] = tex_pos.mV[0];
- tex0->mV[1] = tex_pos.mV[1];
- tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y);
-
- const F32 xyScale = 4.9215f*7.f; //0.93284f;
- const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f);
-
- F32 vec[3] = {
+ if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp)
+ {
+ return; // failsafe
+ }
+ llassert_always(vertex && normal && tex0 && tex1);
+
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+ U32 point_offset = x + y*surface_stride;
+
+ *normal = getNormal(x, y);
+
+ LLVector3 pos_agent = getOriginAgent();
+ pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
+ pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
+ pos_agent.mV[VZ] = *(mDataZ + point_offset);
+ *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent();
+
+ LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
+ // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it.
+ // *NOTE: In the future, UVs and horizontal position will no longer have a 1:1 relationship for PBR terrain
+ LLVector3 tex_pos = rel_pos;
+ tex0->mV[0] = tex_pos.mV[0];
+ tex0->mV[1] = tex_pos.mV[1];
+ tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y);
+
+ const F32 xyScale = 4.9215f*7.f; //0.93284f;
+ const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f);
+
+ F32 vec[3] = {
(F32)fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f),
(F32)fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f),
- 0.f
- };
- F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f);
- tex1->mV[1] = rand_val;
+ 0.f
+ };
+ F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f);
+ tex1->mV[1] = rand_val;
}
-void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
+template<>
+void LLSurfacePatch::calcNormal</*PBR=*/false>(const U32 x, const U32 y, const U32 stride)
{
- U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
- U32 surface_stride = mSurfacep->getGridsPerEdge();
-
- const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
-
- S32 poffsets[2][2][2];
- poffsets[0][0][0] = x - stride;
- poffsets[0][0][1] = y - stride;
-
- poffsets[0][1][0] = x - stride;
- poffsets[0][1][1] = y + stride;
-
- poffsets[1][0][0] = x + stride;
- poffsets[1][0][1] = y - stride;
-
- poffsets[1][1][0] = x + stride;
- poffsets[1][1][1] = y + stride;
+ U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+
+ const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
+
+ S32 poffsets[2][2][2];
+ poffsets[0][0][0] = x - stride;
+ poffsets[0][0][1] = y - stride;
+
+ poffsets[0][1][0] = x - stride;
+ poffsets[0][1][1] = y + stride;
+
+ poffsets[1][0][0] = x + stride;
+ poffsets[1][0][1] = y - stride;
+
+ poffsets[1][1][0] = x + stride;
+ poffsets[1][1][1] = y + stride;
+
+ const LLSurfacePatch *ppatches[2][2];
+
+ // LLVector3 p1, p2, p3, p4;
+
+ ppatches[0][0] = this;
+ ppatches[0][1] = this;
+ ppatches[1][0] = this;
+ ppatches[1][1] = this;
+
+ U32 i, j;
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ if (poffsets[i][j][0] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(WEST))
+ {
+ poffsets[i][j][0] = 0;
+ }
+ else
+ {
+ poffsets[i][j][0] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
+ }
+ }
+ if (poffsets[i][j][1] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(SOUTH))
+ {
+ poffsets[i][j][1] = 0;
+ }
+ else
+ {
+ poffsets[i][j][1] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
+ }
+ }
+ if (poffsets[i][j][0] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(EAST))
+ {
+ poffsets[i][j][0] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][0] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
+ }
+ }
+ if (poffsets[i][j][1] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(NORTH))
+ {
+ poffsets[i][j][1] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][1] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
+ }
+ }
+ }
+ }
+
+ LLVector3 p00(-mpg,-mpg,
+ *(ppatches[0][0]->mDataZ
+ + poffsets[0][0][0]
+ + poffsets[0][0][1]*surface_stride));
+ LLVector3 p01(-mpg,+mpg,
+ *(ppatches[0][1]->mDataZ
+ + poffsets[0][1][0]
+ + poffsets[0][1][1]*surface_stride));
+ LLVector3 p10(+mpg,-mpg,
+ *(ppatches[1][0]->mDataZ
+ + poffsets[1][0][0]
+ + poffsets[1][0][1]*surface_stride));
+ LLVector3 p11(+mpg,+mpg,
+ *(ppatches[1][1]->mDataZ
+ + poffsets[1][1][0]
+ + poffsets[1][1][1]*surface_stride));
+
+ LLVector3 c1 = p11 - p00;
+ LLVector3 c2 = p01 - p10;
+
+ LLVector3 normal = c1;
+ normal %= c2;
+ normal.normVec();
+
+ llassert(mDataNorm);
+ *(mDataNorm + surface_stride * y + x) = normal;
+}
- const LLSurfacePatch *ppatches[2][2];
+template<>
+void LLSurfacePatch::calcNormal</*PBR=*/true>(const U32 x, const U32 y, const U32 stride)
+{
+ llassert(mDataNorm);
+ constexpr U32 index = 0;
- // LLVector3 p1, p2, p3, p4;
+ const U32 surface_stride = mSurfacep->getGridsPerEdge();
+ LLVector3& normal_out = *(mDataNorm + surface_stride * y + x);
+ calcNormalFlat(normal_out, x, y, index);
+}
- ppatches[0][0] = this;
- ppatches[0][1] = this;
- ppatches[1][0] = this;
- ppatches[1][1] = this;
+// Calculate the flat normal of a triangle whose least coordinate is specified by the given x,y values.
+// If index = 0, calculate the normal of the first triangle, otherwise calculate the normal of the second.
+void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index)
+{
+ llassert(index == 0 || index == 1);
+
+ U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+
+ // Vertex stride is always 1 because we want the flat surface of the current triangle face
+ constexpr U32 stride = 1;
+
+ const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
+
+ S32 poffsets[2][2][2];
+ poffsets[0][0][0] = x;
+ poffsets[0][0][1] = y;
+
+ poffsets[0][1][0] = x;
+ poffsets[0][1][1] = y + stride;
+
+ poffsets[1][0][0] = x + stride;
+ poffsets[1][0][1] = y;
+
+ poffsets[1][1][0] = x + stride;
+ poffsets[1][1][1] = y + stride;
+
+ const LLSurfacePatch *ppatches[2][2];
+
+ // LLVector3 p1, p2, p3, p4;
+
+ ppatches[0][0] = this;
+ ppatches[0][1] = this;
+ ppatches[1][0] = this;
+ ppatches[1][1] = this;
+
+ U32 i, j;
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ if (poffsets[i][j][0] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(WEST))
+ {
+ poffsets[i][j][0] = 0;
+ }
+ else
+ {
+ poffsets[i][j][0] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
+ }
+ }
+ if (poffsets[i][j][1] < 0)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(SOUTH))
+ {
+ poffsets[i][j][1] = 0;
+ }
+ else
+ {
+ poffsets[i][j][1] += patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
+ }
+ }
+ if (poffsets[i][j][0] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(EAST))
+ {
+ poffsets[i][j][0] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][0] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
+ }
+ }
+ if (poffsets[i][j][1] >= (S32)patch_width)
+ {
+ if (!ppatches[i][j]->getNeighborPatch(NORTH))
+ {
+ poffsets[i][j][1] = patch_width - 1;
+ }
+ else
+ {
+ poffsets[i][j][1] -= patch_width;
+ ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
+ }
+ }
+ }
+ }
+
+ LLVector3 p00(-mpg,-mpg,
+ *(ppatches[0][0]->mDataZ
+ + poffsets[0][0][0]
+ + poffsets[0][0][1]*surface_stride));
+ LLVector3 p01(-mpg,+mpg,
+ *(ppatches[0][1]->mDataZ
+ + poffsets[0][1][0]
+ + poffsets[0][1][1]*surface_stride));
+ LLVector3 p10(+mpg,-mpg,
+ *(ppatches[1][0]->mDataZ
+ + poffsets[1][0][0]
+ + poffsets[1][0][1]*surface_stride));
+ LLVector3 p11(+mpg,+mpg,
+ *(ppatches[1][1]->mDataZ
+ + poffsets[1][1][0]
+ + poffsets[1][1][1]*surface_stride));
+
+ // Triangle index / coordinate convention
+ // for a single surface patch
+ //
+ // p01 p11
+ //
+ // ^ ._____.
+ // | |\ |
+ // | | \ 1 |
+ // | | \ |
+ // | 0 \ |
+ // y |____\|
+ //
+ // p00 x ---> p10
+ //
+ // (z up / out of the screen due to right-handed coordinate system)
+
+ LLVector3 normal;
+ if (index == 0)
+ {
+ LLVector3 c1 = p10 - p00;
+ LLVector3 c2 = p01 - p00;
- U32 i, j;
- for (i = 0; i < 2; i++)
+ normal = c1;
+ normal %= c2;
+ normal.normVec();
+ }
+ else // index == 1
{
- for (j = 0; j < 2; j++)
- {
- if (poffsets[i][j][0] < 0)
- {
- if (!ppatches[i][j]->getNeighborPatch(WEST))
- {
- poffsets[i][j][0] = 0;
- }
- else
- {
- poffsets[i][j][0] += patch_width;
- ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
- }
- }
- if (poffsets[i][j][1] < 0)
- {
- if (!ppatches[i][j]->getNeighborPatch(SOUTH))
- {
- poffsets[i][j][1] = 0;
- }
- else
- {
- poffsets[i][j][1] += patch_width;
- ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
- }
- }
- if (poffsets[i][j][0] >= (S32)patch_width)
- {
- if (!ppatches[i][j]->getNeighborPatch(EAST))
- {
- poffsets[i][j][0] = patch_width - 1;
- }
- else
- {
- poffsets[i][j][0] -= patch_width;
- ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
- }
- }
- if (poffsets[i][j][1] >= (S32)patch_width)
- {
- if (!ppatches[i][j]->getNeighborPatch(NORTH))
- {
- poffsets[i][j][1] = patch_width - 1;
- }
- else
- {
- poffsets[i][j][1] -= patch_width;
- ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
- }
- }
- }
+ LLVector3 c1 = p11 - p01;
+ LLVector3 c2 = p11 - p10;
+
+ normal = c1;
+ normal %= c2;
+ normal.normVec();
}
- LLVector3 p00(-mpg,-mpg,
- *(ppatches[0][0]->mDataZ
- + poffsets[0][0][0]
- + poffsets[0][0][1]*surface_stride));
- LLVector3 p01(-mpg,+mpg,
- *(ppatches[0][1]->mDataZ
- + poffsets[0][1][0]
- + poffsets[0][1][1]*surface_stride));
- LLVector3 p10(+mpg,-mpg,
- *(ppatches[1][0]->mDataZ
- + poffsets[1][0][0]
- + poffsets[1][0][1]*surface_stride));
- LLVector3 p11(+mpg,+mpg,
- *(ppatches[1][1]->mDataZ
- + poffsets[1][1][0]
- + poffsets[1][1][1]*surface_stride));
-
- LLVector3 c1 = p11 - p00;
- LLVector3 c2 = p01 - p10;
-
- LLVector3 normal = c1;
- normal %= c2;
- normal.normVec();
-
- llassert(mDataNorm);
- *(mDataNorm + surface_stride * y + x) = normal;
+ llassert(&normal_out);
+ normal_out = normal;
}
const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const
{
- U32 surface_stride = mSurfacep->getGridsPerEdge();
- llassert(mDataNorm);
- return *(mDataNorm + surface_stride * y + x);
+ U32 surface_stride = mSurfacep->getGridsPerEdge();
+ llassert(mDataNorm);
+ return *(mDataNorm + surface_stride * y + x);
}
void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region)
{
- if (LLPipeline::sDynamicLOD)
- {
- if (!gShiftFrame)
- {
- LLVector3 dv = pos_region;
- dv -= mCenterRegion;
- mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
- llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
- }
- }
- else
- {
- mVisInfo.mDistance = 0.f;
- }
+ if (LLPipeline::sDynamicLOD)
+ {
+ if (!gShiftFrame)
+ {
+ LLVector3 dv = pos_region;
+ dv -= mCenterRegion;
+ mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
+ llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+ }
+ }
+ else
+ {
+ mVisInfo.mDistance = 0.f;
+ }
}
F32 LLSurfacePatch::getDistance() const
{
- return mVisInfo.mDistance;
+ return mVisInfo.mDistance;
}
// Called when a patch has changed its height field
// data.
-void LLSurfacePatch::updateVerticalStats()
+void LLSurfacePatch::updateVerticalStats()
{
- if (!mDirtyZStats)
- {
- return;
- }
-
- U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
- U32 grids_per_edge = mSurfacep->getGridsPerEdge();
- F32 meters_per_grid = mSurfacep->getMetersPerGrid();
-
- U32 i, j, k;
- F32 z, total;
-
- llassert(mDataZ);
- z = *(mDataZ);
-
- mMinZ = z;
- mMaxZ = z;
-
- k = 0;
- total = 0.0f;
-
- // Iterate to +1 because we need to do the edges correctly.
- for (j=0; j<(grids_per_patch_edge+1); j++)
- {
- for (i=0; i<(grids_per_patch_edge+1); i++)
- {
- z = *(mDataZ + i + j*grids_per_edge);
-
- if (z < mMinZ)
- {
- mMinZ = z;
- }
- if (z > mMaxZ)
- {
- mMaxZ = z;
- }
- total += z;
- k++;
- }
- }
- mMeanZ = total / (F32) k;
- mCenterRegion.mV[VZ] = 0.5f * (mMinZ + mMaxZ);
-
- LLVector3 diam_vec(meters_per_grid*grids_per_patch_edge,
- meters_per_grid*grids_per_patch_edge,
- mMaxZ - mMinZ);
- mRadius = diam_vec.magVec() * 0.5f;
-
- mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ);
- mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ);
- mSurfacep->mHasZData = TRUE;
- mSurfacep->getRegion()->calculateCenterGlobal();
-
- if (mVObjp)
- {
- mVObjp->dirtyPatch();
- }
- mDirtyZStats = FALSE;
+ if (!mDirtyZStats)
+ {
+ return;
+ }
+
+ U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
+ U32 grids_per_edge = mSurfacep->getGridsPerEdge();
+ F32 meters_per_grid = mSurfacep->getMetersPerGrid();
+
+ U32 i, j, k;
+ F32 z, total;
+
+ llassert(mDataZ);
+ z = *(mDataZ);
+
+ mMinZ = z;
+ mMaxZ = z;
+
+ k = 0;
+ total = 0.0f;
+
+ // Iterate to +1 because we need to do the edges correctly.
+ for (j=0; j<(grids_per_patch_edge+1); j++)
+ {
+ for (i=0; i<(grids_per_patch_edge+1); i++)
+ {
+ z = *(mDataZ + i + j*grids_per_edge);
+
+ if (z < mMinZ)
+ {
+ mMinZ = z;
+ }
+ if (z > mMaxZ)
+ {
+ mMaxZ = z;
+ }
+ total += z;
+ k++;
+ }
+ }
+ mMeanZ = total / (F32) k;
+ mCenterRegion.mV[VZ] = 0.5f * (mMinZ + mMaxZ);
+
+ LLVector3 diam_vec(meters_per_grid*grids_per_patch_edge,
+ meters_per_grid*grids_per_patch_edge,
+ mMaxZ - mMinZ);
+ mRadius = diam_vec.magVec() * 0.5f;
+
+ mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ);
+ mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ);
+ mSurfacep->mHasZData = TRUE;
+ mSurfacep->getRegion()->calculateCenterGlobal();
+
+ if (mVObjp)
+ {
+ mVObjp->dirtyPatch();
+ }
+ mDirtyZStats = FALSE;
}
-void LLSurfacePatch::updateNormals()
+template<bool PBR>
+void LLSurfacePatch::updateNormals()
{
- if (mSurfacep->mType == 'w')
- {
- return;
- }
- U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
- U32 grids_per_edge = mSurfacep->getGridsPerEdge();
-
- BOOL dirty_patch = FALSE;
-
- U32 i, j;
- // update the east edge
- if (mNormalsInvalid[EAST] || mNormalsInvalid[NORTHEAST] || mNormalsInvalid[SOUTHEAST])
- {
- for (j = 0; j <= grids_per_patch_edge; j++)
- {
- calcNormal(grids_per_patch_edge, j, 2);
- calcNormal(grids_per_patch_edge - 1, j, 2);
- calcNormal(grids_per_patch_edge - 2, j, 2);
- }
-
- dirty_patch = TRUE;
- }
-
- // update the north edge
- if (mNormalsInvalid[NORTHEAST] || mNormalsInvalid[NORTH] || mNormalsInvalid[NORTHWEST])
- {
- for (i = 0; i <= grids_per_patch_edge; i++)
- {
- calcNormal(i, grids_per_patch_edge, 2);
- calcNormal(i, grids_per_patch_edge - 1, 2);
- calcNormal(i, grids_per_patch_edge - 2, 2);
- }
-
- dirty_patch = TRUE;
- }
-
- // update the west edge
- if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST])
- {
- for (j = 0; j < grids_per_patch_edge; j++)
- {
- calcNormal(0, j, 2);
- calcNormal(1, j, 2);
- }
- dirty_patch = TRUE;
- }
-
- // update the south edge
- if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST])
- {
- for (i = 0; i < grids_per_patch_edge; i++)
- {
- calcNormal(i, 0, 2);
- calcNormal(i, 1, 2);
- }
- dirty_patch = TRUE;
- }
-
- // Invalidating the northeast corner is different, because depending on what the adjacent neighbors are,
- // we'll want to do different things.
- if (mNormalsInvalid[NORTHEAST])
- {
- if (!getNeighborPatch(NORTHEAST))
- {
- if (!getNeighborPatch(NORTH))
- {
- if (!getNeighborPatch(EAST))
- {
- // No north or east neighbors. Pull from the diagonal in your own patch.
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
- }
- else
- {
- if (getNeighborPatch(EAST)->getHasReceivedData())
- {
- // East, but not north. Pull from your east neighbor's northwest point.
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge);
- }
- else
- {
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
- }
- }
- }
- else
- {
- // We have a north.
- if (getNeighborPatch(EAST))
- {
- // North and east neighbors, but not northeast.
- // Pull from diagonal in your own patch.
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
- }
- else
- {
- if (getNeighborPatch(NORTH)->getHasReceivedData())
- {
- // North, but not east. Pull from your north neighbor's southeast corner.
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1));
- }
- else
- {
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
- }
- }
- }
- }
- else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep)
- {
- if (
- (!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep))
- &&
- (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep)))
- {
- *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
- *(getNeighborPatch(NORTHEAST)->mDataZ);
- }
- }
- else
- {
- // We've got a northeast patch in the same surface.
- // The z and normals will be handled by that patch.
- }
- calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2);
- calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
- calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
- calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
- dirty_patch = TRUE;
- }
-
- // update the middle normals
- if (mNormalsInvalid[MIDDLE])
- {
- for (j=2; j < grids_per_patch_edge - 2; j++)
- {
- for (i=2; i < grids_per_patch_edge - 2; i++)
- {
- calcNormal(i, j, 2);
- }
- }
- dirty_patch = TRUE;
- }
-
- if (dirty_patch)
- {
- mSurfacep->dirtySurfacePatch(this);
- }
-
- for (i = 0; i < 9; i++)
- {
- mNormalsInvalid[i] = FALSE;
- }
+ if (mSurfacep->mType == 'w')
+ {
+ return;
+ }
+ U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
+ U32 grids_per_edge = mSurfacep->getGridsPerEdge();
+
+ BOOL dirty_patch = FALSE;
+
+ U32 i, j;
+ // update the east edge
+ if (mNormalsInvalid[EAST] || mNormalsInvalid[NORTHEAST] || mNormalsInvalid[SOUTHEAST])
+ {
+ for (j = 0; j <= grids_per_patch_edge; j++)
+ {
+ calcNormal<PBR>(grids_per_patch_edge, j, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, j, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 2, j, 2);
+ }
+
+ dirty_patch = TRUE;
+ }
+
+ // update the north edge
+ if (mNormalsInvalid[NORTHEAST] || mNormalsInvalid[NORTH] || mNormalsInvalid[NORTHWEST])
+ {
+ for (i = 0; i <= grids_per_patch_edge; i++)
+ {
+ calcNormal<PBR>(i, grids_per_patch_edge, 2);
+ calcNormal<PBR>(i, grids_per_patch_edge - 1, 2);
+ calcNormal<PBR>(i, grids_per_patch_edge - 2, 2);
+ }
+
+ dirty_patch = TRUE;
+ }
+
+ // update the west edge
+ if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST])
+ {
+ for (j = 0; j < grids_per_patch_edge; j++)
+ {
+ calcNormal<PBR>(0, j, 2);
+ calcNormal<PBR>(1, j, 2);
+ }
+ dirty_patch = TRUE;
+ }
+
+ // update the south edge
+ if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST])
+ {
+ for (i = 0; i < grids_per_patch_edge; i++)
+ {
+ calcNormal<PBR>(i, 0, 2);
+ calcNormal<PBR>(i, 1, 2);
+ }
+ dirty_patch = TRUE;
+ }
+
+ // Invalidating the northeast corner is different, because depending on what the adjacent neighbors are,
+ // we'll want to do different things.
+ if (mNormalsInvalid[NORTHEAST])
+ {
+ if (!getNeighborPatch(NORTHEAST))
+ {
+ if (!getNeighborPatch(NORTH))
+ {
+ if (!getNeighborPatch(EAST))
+ {
+ // No north or east neighbors. Pull from the diagonal in your own patch.
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
+ }
+ else
+ {
+ if (getNeighborPatch(EAST)->getHasReceivedData())
+ {
+ // East, but not north. Pull from your east neighbor's northwest point.
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge);
+ }
+ else
+ {
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
+ }
+ }
+ }
+ else
+ {
+ // We have a north.
+ if (getNeighborPatch(EAST))
+ {
+ // North and east neighbors, but not northeast.
+ // Pull from diagonal in your own patch.
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
+ }
+ else
+ {
+ if (getNeighborPatch(NORTH)->getHasReceivedData())
+ {
+ // North, but not east. Pull from your north neighbor's southeast corner.
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1));
+ }
+ else
+ {
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
+ }
+ }
+ }
+ }
+ else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep)
+ {
+ if (
+ (!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep))
+ &&
+ (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep)))
+ {
+ *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
+ *(getNeighborPatch(NORTHEAST)->mDataZ);
+ }
+ }
+ else
+ {
+ // We've got a northeast patch in the same surface.
+ // The z and normals will be handled by that patch.
+ }
+ calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge, 2);
+ calcNormal<PBR>(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
+ calcNormal<PBR>(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
+ dirty_patch = TRUE;
+ }
+
+ // update the middle normals
+ if (mNormalsInvalid[MIDDLE])
+ {
+ for (j=2; j < grids_per_patch_edge - 2; j++)
+ {
+ for (i=2; i < grids_per_patch_edge - 2; i++)
+ {
+ calcNormal<PBR>(i, j, 2);
+ }
+ }
+ dirty_patch = TRUE;
+ }
+
+ if (dirty_patch)
+ {
+ mSurfacep->dirtySurfacePatch(this);
+ }
+
+ for (i = 0; i < 9; i++)
+ {
+ mNormalsInvalid[i] = FALSE;
+ }
}
+template void LLSurfacePatch::updateNormals</*PBR=*/false>();
+template void LLSurfacePatch::updateNormals</*PBR=*/true>();
+
void LLSurfacePatch::updateEastEdge()
{
- U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
- U32 grids_per_edge = mSurfacep->getGridsPerEdge();
-
- U32 j, k;
- F32 *west_surface, *east_surface;
-
- if (!getNeighborPatch(EAST))
- {
- west_surface = mDataZ + grids_per_patch_edge;
- east_surface = mDataZ + grids_per_patch_edge - 1;
- }
- else if (mConnectedEdge & EAST_EDGE)
- {
- west_surface = mDataZ + grids_per_patch_edge;
- east_surface = getNeighborPatch(EAST)->mDataZ;
- }
- else
- {
- return;
- }
-
- // If patchp is on the east edge of its surface, then we update the east
- // side buffer
- for (j=0; j < grids_per_patch_edge; j++)
- {
- k = j * grids_per_edge;
- *(west_surface + k) = *(east_surface + k); // update buffer Z
- }
+ U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
+ U32 grids_per_edge = mSurfacep->getGridsPerEdge();
+
+ U32 j, k;
+ F32 *west_surface, *east_surface;
+
+ if (!getNeighborPatch(EAST))
+ {
+ west_surface = mDataZ + grids_per_patch_edge;
+ east_surface = mDataZ + grids_per_patch_edge - 1;
+ }
+ else if (mConnectedEdge & EAST_EDGE)
+ {
+ west_surface = mDataZ + grids_per_patch_edge;
+ east_surface = getNeighborPatch(EAST)->mDataZ;
+ }
+ else
+ {
+ return;
+ }
+
+ // If patchp is on the east edge of its surface, then we update the east
+ // side buffer
+ for (j=0; j < grids_per_patch_edge; j++)
+ {
+ k = j * grids_per_edge;
+ *(west_surface + k) = *(east_surface + k); // update buffer Z
+ }
}
void LLSurfacePatch::updateNorthEdge()
{
- U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
- U32 grids_per_edge = mSurfacep->getGridsPerEdge();
-
- U32 i;
- F32 *south_surface, *north_surface;
-
- if (!getNeighborPatch(NORTH))
- {
- south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
- north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge;
- }
- else if (mConnectedEdge & NORTH_EDGE)
- {
- south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
- north_surface = getNeighborPatch(NORTH)->mDataZ;
- }
- else
- {
- return;
- }
-
- // Update patchp's north edge ...
- for (i=0; i<grids_per_patch_edge; i++)
- {
- *(south_surface + i) = *(north_surface + i); // update buffer Z
- }
+ U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
+ U32 grids_per_edge = mSurfacep->getGridsPerEdge();
+
+ U32 i;
+ F32 *south_surface, *north_surface;
+
+ if (!getNeighborPatch(NORTH))
+ {
+ south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
+ north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge;
+ }
+ else if (mConnectedEdge & NORTH_EDGE)
+ {
+ south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
+ north_surface = getNeighborPatch(NORTH)->mDataZ;
+ }
+ else
+ {
+ return;
+ }
+
+ // Update patchp's north edge ...
+ for (i=0; i<grids_per_patch_edge; i++)
+ {
+ *(south_surface + i) = *(north_surface + i); // update buffer Z
+ }
}
BOOL LLSurfacePatch::updateTexture()
{
- if (mSTexUpdate) // Update texture as needed
- {
- F32 meters_per_grid = getSurface()->getMetersPerGrid();
- F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
-
- if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData())
- && (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData())
- && (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData())
- && (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData()))
- {
- LLViewerRegion *regionp = getSurface()->getRegion();
- LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
-
- // Have to figure out a better way to deal with these edge conditions...
- LLVLComposition* comp = regionp->getComposition();
- if (!mHeightsGenerated)
- {
- F32 patch_size = meters_per_grid*(grids_per_patch_edge+1);
- if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY],
- patch_size, patch_size))
- {
- mHeightsGenerated = TRUE;
- }
- else
- {
- return FALSE;
- }
- }
-
- if (comp->generateComposition())
- {
- if (mVObjp)
- {
- mVObjp->dirtyGeom();
- gPipeline.markGLRebuild(mVObjp);
- return !mSTexUpdate;
- }
- }
- }
- return FALSE;
- }
- else
- {
- return TRUE;
- }
+ if (mSTexUpdate) // Update texture as needed
+ {
+ F32 meters_per_grid = getSurface()->getMetersPerGrid();
+ F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
+
+ if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData())
+ && (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData())
+ && (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData())
+ && (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData()))
+ {
+ LLViewerRegion *regionp = getSurface()->getRegion();
+ LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
+
+ // Have to figure out a better way to deal with these edge conditions...
+ LLVLComposition* comp = regionp->getComposition();
+ if (!mHeightsGenerated)
+ {
+ F32 patch_size = meters_per_grid*(grids_per_patch_edge+1);
+ if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY],
+ patch_size, patch_size))
+ {
+ mHeightsGenerated = TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ if (comp->generateComposition())
+ {
+ if (mVObjp)
+ {
+ mVObjp->dirtyGeom();
+ gPipeline.markGLRebuild(mVObjp);
+ return !mSTexUpdate;
+ }
+ }
+ }
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
}
void LLSurfacePatch::updateGL()
{
- LL_PROFILE_ZONE_SCOPED
- F32 meters_per_grid = getSurface()->getMetersPerGrid();
- F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
-
- LLViewerRegion *regionp = getSurface()->getRegion();
- LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
-
- LLVLComposition* comp = regionp->getComposition();
-
- updateCompositionStats();
- F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
- if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY],
- tex_patch_size, tex_patch_size))
- {
- mSTexUpdate = FALSE;
-
- // Also generate the water texture
- mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
- tex_patch_size, tex_patch_size);
- }
+ LL_PROFILE_ZONE_SCOPED
+ F32 meters_per_grid = getSurface()->getMetersPerGrid();
+ F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
+
+ LLViewerRegion *regionp = getSurface()->getRegion();
+ LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
+
+ LLVLComposition* comp = regionp->getComposition();
+
+ updateCompositionStats();
+ F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
+ if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY],
+ tex_patch_size, tex_patch_size))
+ {
+ mSTexUpdate = FALSE;
+
+ // Also generate the water texture
+ mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
+ tex_patch_size, tex_patch_size);
+ }
}
void LLSurfacePatch::dirtyZ()
{
- mSTexUpdate = TRUE;
-
- // Invalidate all normals in this patch
- U32 i;
- for (i = 0; i < 9; i++)
- {
- mNormalsInvalid[i] = TRUE;
- }
-
- // Invalidate normals in this and neighboring patches
- for (i = 0; i < 8; i++)
- {
- if (getNeighborPatch(i))
- {
- getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE;
- getNeighborPatch(i)->dirty();
- if (i < 4)
- {
- getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE;
- getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE;
- }
- }
- }
-
- dirty();
- mLastUpdateTime = gFrameTime;
+ mSTexUpdate = TRUE;
+
+ // Invalidate all normals in this patch
+ U32 i;
+ for (i = 0; i < 9; i++)
+ {
+ mNormalsInvalid[i] = TRUE;
+ }
+
+ // Invalidate normals in this and neighboring patches
+ for (i = 0; i < 8; i++)
+ {
+ if (getNeighborPatch(i))
+ {
+ getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE;
+ getNeighborPatch(i)->dirty();
+ if (i < 4)
+ {
+ getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE;
+ getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE;
+ }
+ }
+ }
+
+ dirty();
+ mLastUpdateTime = gFrameTime;
}
const U64 &LLSurfacePatch::getLastUpdateTime() const
{
- return mLastUpdateTime;
+ return mLastUpdateTime;
}
F32 LLSurfacePatch::getMaxZ() const
{
- return mMaxZ;
+ return mMaxZ;
}
F32 LLSurfacePatch::getMinZ() const
{
- return mMinZ;
+ return mMinZ;
}
void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
{
- mOriginGlobal = origin_global;
+ mOriginGlobal = origin_global;
- LLVector3 origin_region;
- origin_region.setVec(mOriginGlobal - mSurfacep->getOriginGlobal());
+ LLVector3 origin_region;
+ origin_region.setVec(mOriginGlobal - mSurfacep->getOriginGlobal());
- mOriginRegion = origin_region;
- mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
- mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
-
- mVisInfo.mbIsVisible = FALSE;
- mVisInfo.mDistance = 512.0f;
- mVisInfo.mRenderLevel = 0;
- mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge();
+ mOriginRegion = origin_region;
+ mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
+ mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
+ mVisInfo.mbIsVisible = FALSE;
+ mVisInfo.mDistance = 512.0f;
+ mVisInfo.mRenderLevel = 0;
+ mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge();
+
}
void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction)
{
- llassert(neighbor_patchp);
- mNormalsInvalid[direction] = TRUE;
- neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
-
- setNeighborPatch(direction, neighbor_patchp);
- neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this);
-
- if (EAST == direction)
- {
- mConnectedEdge |= EAST_EDGE;
- neighbor_patchp->mConnectedEdge |= WEST_EDGE;
- }
- else if (NORTH == direction)
- {
- mConnectedEdge |= NORTH_EDGE;
- neighbor_patchp->mConnectedEdge |= SOUTH_EDGE;
- }
- else if (WEST == direction)
- {
- mConnectedEdge |= WEST_EDGE;
- neighbor_patchp->mConnectedEdge |= EAST_EDGE;
- }
- else if (SOUTH == direction)
- {
- mConnectedEdge |= SOUTH_EDGE;
- neighbor_patchp->mConnectedEdge |= NORTH_EDGE;
- }
+ llassert(neighbor_patchp);
+ mNormalsInvalid[direction] = TRUE;
+ neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
+
+ setNeighborPatch(direction, neighbor_patchp);
+ neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this);
+
+ if (EAST == direction)
+ {
+ mConnectedEdge |= EAST_EDGE;
+ neighbor_patchp->mConnectedEdge |= WEST_EDGE;
+ }
+ else if (NORTH == direction)
+ {
+ mConnectedEdge |= NORTH_EDGE;
+ neighbor_patchp->mConnectedEdge |= SOUTH_EDGE;
+ }
+ else if (WEST == direction)
+ {
+ mConnectedEdge |= WEST_EDGE;
+ neighbor_patchp->mConnectedEdge |= EAST_EDGE;
+ }
+ else if (SOUTH == direction)
+ {
+ mConnectedEdge |= SOUTH_EDGE;
+ neighbor_patchp->mConnectedEdge |= NORTH_EDGE;
+ }
}
void LLSurfacePatch::updateVisibility()
{
- if (mVObjp.isNull())
- {
- return;
- }
-
- const F32 DEFAULT_DELTA_ANGLE = (0.15f);
- U32 old_render_stride, max_render_stride;
- U32 new_render_level;
- F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid();
- U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
-
- LLVector4a center;
- center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV);
- LLVector4a radius;
- radius.splat(mRadius);
-
- // sphere in frustum on global coordinates
- if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
- {
- // We now need to calculate the render stride based on patchp's distance
- // from LLCamera render_stride is governed by a relation something like this...
- //
- // delta_angle * patch.distance
- // render_stride <= ----------------------------------------
- // mMetersPerGrid
- //
- // where 'delta_angle' is the desired solid angle of the average polgon on a patch.
- //
- // Any render_stride smaller than the RHS would be 'satisfactory'. Smaller
- // strides give more resolution, but efficiency suggests that we use the largest
- // of the render_strides that obey the relation. Flexibility is achieved by
- // modulating 'delta_angle' until we have an acceptable number of triangles.
-
- old_render_stride = mVisInfo.mRenderStride;
-
- // Calculate the render_stride using information in agent
- max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance);
- max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge);
-
- // We only use render_strides that are powers of two, so we use look-up tables to figure out
- // the render_level and corresponding render_stride
- new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride);
- mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level);
-
- if ((mVisInfo.mRenderStride != old_render_stride))
- // The reason we check !mbIsVisible is because non-visible patches normals
- // are not updated when their data is changed. When this changes we can get
- // rid of mbIsVisible altogether.
- {
- if (mVObjp)
- {
- mVObjp->dirtyGeom();
- if (getNeighborPatch(WEST))
- {
- getNeighborPatch(WEST)->mVObjp->dirtyGeom();
- }
- if (getNeighborPatch(SOUTH))
- {
- getNeighborPatch(SOUTH)->mVObjp->dirtyGeom();
- }
- }
- }
- mVisInfo.mbIsVisible = TRUE;
- }
- else
- {
- mVisInfo.mbIsVisible = FALSE;
- }
+ if (mVObjp.isNull())
+ {
+ return;
+ }
+
+ const F32 DEFAULT_DELTA_ANGLE = (0.15f);
+ U32 old_render_stride, max_render_stride;
+ U32 new_render_level;
+ F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid();
+ U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
+
+ LLVector4a center;
+ center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV);
+ LLVector4a radius;
+ radius.splat(mRadius);
+
+ // sphere in frustum on global coordinates
+ if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
+ {
+ // We now need to calculate the render stride based on patchp's distance
+ // from LLCamera render_stride is governed by a relation something like this...
+ //
+ // delta_angle * patch.distance
+ // render_stride <= ----------------------------------------
+ // mMetersPerGrid
+ //
+ // where 'delta_angle' is the desired solid angle of the average polgon on a patch.
+ //
+ // Any render_stride smaller than the RHS would be 'satisfactory'. Smaller
+ // strides give more resolution, but efficiency suggests that we use the largest
+ // of the render_strides that obey the relation. Flexibility is achieved by
+ // modulating 'delta_angle' until we have an acceptable number of triangles.
+
+ old_render_stride = mVisInfo.mRenderStride;
+
+ // Calculate the render_stride using information in agent
+ max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance);
+ max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge);
+
+ // We only use render_strides that are powers of two, so we use look-up tables to figure out
+ // the render_level and corresponding render_stride
+ new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride);
+ mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level);
+
+ if ((mVisInfo.mRenderStride != old_render_stride))
+ // The reason we check !mbIsVisible is because non-visible patches normals
+ // are not updated when their data is changed. When this changes we can get
+ // rid of mbIsVisible altogether.
+ {
+ if (mVObjp)
+ {
+ mVObjp->dirtyGeom();
+ if (getNeighborPatch(WEST))
+ {
+ getNeighborPatch(WEST)->mVObjp->dirtyGeom();
+ }
+ if (getNeighborPatch(SOUTH))
+ {
+ getNeighborPatch(SOUTH)->mVObjp->dirtyGeom();
+ }
+ }
+ }
+ mVisInfo.mbIsVisible = TRUE;
+ }
+ else
+ {
+ mVisInfo.mbIsVisible = FALSE;
+ }
}
const LLVector3d &LLSurfacePatch::getOriginGlobal() const
{
- return mOriginGlobal;
+ return mOriginGlobal;
}
LLVector3 LLSurfacePatch::getOriginAgent() const
{
- return gAgent.getPosAgentFromGlobal(mOriginGlobal);
+ return gAgent.getPosAgentFromGlobal(mOriginGlobal);
}
BOOL LLSurfacePatch::getVisible() const
{
- return mVisInfo.mbIsVisible;
+ return mVisInfo.mbIsVisible;
}
U32 LLSurfacePatch::getRenderStride() const
{
- return mVisInfo.mRenderStride;
+ return mVisInfo.mRenderStride;
}
S32 LLSurfacePatch::getRenderLevel() const
{
- return mVisInfo.mRenderLevel;
+ return mVisInfo.mRenderLevel;
}
void LLSurfacePatch::setHasReceivedData()
{
- mHasReceivedData = TRUE;
+ mHasReceivedData = TRUE;
}
BOOL LLSurfacePatch::getHasReceivedData() const
{
- return mHasReceivedData;
+ return mHasReceivedData;
}
const LLVector3 &LLSurfacePatch::getCenterRegion() const
{
- return mCenterRegion;
+ return mCenterRegion;
}
void LLSurfacePatch::updateCompositionStats()
{
- LLViewerLayer *vlp = mSurfacep->getRegion()->getComposition();
-
- F32 x, y, width, height, mpg, min, mean, max;
-
- LLVector3 origin = getOriginAgent() - mSurfacep->getOriginAgent();
- mpg = mSurfacep->getMetersPerGrid();
- x = origin.mV[VX];
- y = origin.mV[VY];
- width = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
- height = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
-
- mean = 0.f;
- min = vlp->getValueScaled(x, y);
- max= min;
- U32 count = 0;
- F32 i, j;
- for (j = 0; j < height; j += mpg)
- {
- for (i = 0; i < width; i += mpg)
- {
- F32 comp = vlp->getValueScaled(x + i, y + j);
- mean += comp;
- min = llmin(min, comp);
- max = llmax(max, comp);
- count++;
- }
- }
- mean /= count;
-
- mMinComposition = min;
- mMeanComposition = mean;
- mMaxComposition = max;
+ LLViewerLayer *vlp = mSurfacep->getRegion()->getComposition();
+
+ F32 x, y, width, height, mpg, min, mean, max;
+
+ LLVector3 origin = getOriginAgent() - mSurfacep->getOriginAgent();
+ mpg = mSurfacep->getMetersPerGrid();
+ x = origin.mV[VX];
+ y = origin.mV[VY];
+ width = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
+ height = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
+
+ mean = 0.f;
+ min = vlp->getValueScaled(x, y);
+ max= min;
+ U32 count = 0;
+ F32 i, j;
+ for (j = 0; j < height; j += mpg)
+ {
+ for (i = 0; i < width; i += mpg)
+ {
+ F32 comp = vlp->getValueScaled(x + i, y + j);
+ mean += comp;
+ min = llmin(min, comp);
+ max = llmax(max, comp);
+ count++;
+ }
+ }
+ mean /= count;
+
+ mMinComposition = min;
+ mMeanComposition = mean;
+ mMaxComposition = max;
}
F32 LLSurfacePatch::getMeanComposition() const
{
- return mMeanComposition;
+ return mMeanComposition;
}
F32 LLSurfacePatch::getMinComposition() const
{
- return mMinComposition;
+ return mMinComposition;
}
F32 LLSurfacePatch::getMaxComposition() const
{
- return mMaxComposition;
+ return mMaxComposition;
}
void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp)
{
- mNeighborPatches[direction] = neighborp;
- mNormalsInvalid[direction] = TRUE;
- if (direction < 4)
- {
- mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE;
- mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE;
- }
+ mNeighborPatches[direction] = neighborp;
+ mNormalsInvalid[direction] = TRUE;
+ if (direction < 4)
+ {
+ mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE;
+ mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE;
+ }
}
LLSurfacePatch *LLSurfacePatch::getNeighborPatch(const U32 direction) const
{
- return mNeighborPatches[direction];
+ return mNeighborPatches[direction];
}
void LLSurfacePatch::clearVObj()
{
- mVObjp = NULL;
+ mVObjp = NULL;
}
diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h
index 43843aba0b..ec3864ce44 100644
--- a/indra/newview/llsurfacepatch.h
+++ b/indra/newview/llsurfacepatch.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llsurfacepatch.h
* @brief LLSurfacePatch class definition
*
* $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$
*/
@@ -37,149 +37,162 @@ class LLVector2;
class LLColor4U;
class LLAgent;
-// A patch shouldn't know about its visibility since that really depends on the
+// A patch shouldn't know about its visibility since that really depends on the
// camera that is looking (or not looking) at it. So, anything about a patch
// that is specific to a camera should be in the class below.
class LLPatchVisibilityInfo
{
public:
- LLPatchVisibilityInfo() :
- mbIsVisible(FALSE),
- mDistance(0.f),
- mRenderLevel(0),
- mRenderStride(0) { };
- ~LLPatchVisibilityInfo() { };
-
- BOOL mbIsVisible;
- F32 mDistance; // Distance from camera
- S32 mRenderLevel;
- U32 mRenderStride;
+ LLPatchVisibilityInfo() :
+ mbIsVisible(FALSE),
+ mDistance(0.f),
+ mRenderLevel(0),
+ mRenderStride(0) { };
+ ~LLPatchVisibilityInfo() { };
+
+ BOOL mbIsVisible;
+ F32 mDistance; // Distance from camera
+ S32 mRenderLevel;
+ U32 mRenderStride;
};
-class LLSurfacePatch
+class LLSurfacePatch
{
public:
- LLSurfacePatch();
- ~LLSurfacePatch();
-
- void reset(const U32 id);
- void connectNeighbor(LLSurfacePatch *neighborp, const U32 direction);
- void disconnectNeighbor(LLSurface *surfacep);
-
- void setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp);
- LLSurfacePatch *getNeighborPatch(const U32 direction) const;
-
- void colorPatch(const U8 r, const U8 g, const U8 b);
-
- BOOL updateTexture();
-
- void updateVerticalStats();
- void updateCompositionStats();
- void updateNormals();
-
- void updateEastEdge();
- void updateNorthEdge();
-
- void updateCameraDistanceRegion( const LLVector3 &pos_region);
- void updateVisibility();
- void updateGL();
-
- void dirtyZ(); // Dirty the z values of this patch
- void setHasReceivedData();
- BOOL getHasReceivedData() const;
-
- F32 getDistance() const;
- F32 getMaxZ() const;
- F32 getMinZ() const;
- F32 getMeanComposition() const;
- F32 getMinComposition() const;
- F32 getMaxComposition() const;
- const LLVector3 &getCenterRegion() const;
- const U64 &getLastUpdateTime() const;
- LLSurface *getSurface() const { return mSurfacep; }
- LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset.
- LLVector2 getTexCoords(const U32 x, const U32 y) const;
-
- void calcNormal(const U32 x, const U32 y, const U32 stride);
- const LLVector3 &getNormal(const U32 x, const U32 y) const;
-
- void eval(const U32 x, const U32 y, const U32 stride,
- LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1);
-
-
-
- LLVector3 getOriginAgent() const;
- const LLVector3d &getOriginGlobal() const;
- void setOriginGlobal(const LLVector3d &origin_global);
-
- // connectivity -- each LLPatch points at 5 neighbors (or NULL)
- // +---+---+---+
- // | | 2 | 5 |
- // +---+---+---+
- // | 3 | 0 | 1 |
- // +---+---+---+
- // | 6 | 4 | |
- // +---+---+---+
-
-
- BOOL getVisible() const;
- U32 getRenderStride() const;
- S32 getRenderLevel() const;
-
- void setSurface(LLSurface *surfacep);
- void setDataZ(F32 *data_z) { mDataZ = data_z; }
- void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; }
- F32 *getDataZ() const { return mDataZ; }
-
- void dirty(); // Mark this surface patch as dirty...
- void clearDirty() { mDirty = FALSE; }
-
- void clearVObj();
+ LLSurfacePatch();
+ ~LLSurfacePatch();
+
+ void reset(const U32 id);
+ void connectNeighbor(LLSurfacePatch *neighborp, const U32 direction);
+ void disconnectNeighbor(LLSurface *surfacep);
+
+ void setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp);
+ LLSurfacePatch *getNeighborPatch(const U32 direction) const;
+
+ void colorPatch(const U8 r, const U8 g, const U8 b);
+
+ BOOL updateTexture();
+
+ void updateVerticalStats();
+ void updateCompositionStats();
+ template<bool PBR>
+ void updateNormals();
+
+ void updateEastEdge();
+ void updateNorthEdge();
+
+ void updateCameraDistanceRegion( const LLVector3 &pos_region);
+ void updateVisibility();
+ void updateGL();
+
+ void dirtyZ(); // Dirty the z values of this patch
+ void setHasReceivedData();
+ BOOL getHasReceivedData() const;
+
+ F32 getDistance() const;
+ F32 getMaxZ() const;
+ F32 getMinZ() const;
+ F32 getMeanComposition() const;
+ F32 getMinComposition() const;
+ F32 getMaxComposition() const;
+ const LLVector3 &getCenterRegion() const;
+ const U64 &getLastUpdateTime() const;
+ LLSurface *getSurface() const { return mSurfacep; }
+ LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset.
+ LLVector2 getTexCoords(const U32 x, const U32 y) const;
+
+ // Per-vertex normals
+ // *TODO: PBR=true is a test implementation solely for proof-of-concept.
+ // Final implementation would likely be very different and may not even use
+ // this function. If we decide to keep calcNormalFlat, remove index as it
+ // is a debug parameter for testing.
+ template<bool PBR>
+ void calcNormal(const U32 x, const U32 y, const U32 stride);
+ const LLVector3 &getNormal(const U32 x, const U32 y) const;
+
+ // Per-triangle normals for flat edges
+ void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */);
+
+ void eval(const U32 x, const U32 y, const U32 stride,
+ LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1);
+
+
+
+ LLVector3 getOriginAgent() const;
+ const LLVector3d &getOriginGlobal() const;
+ void setOriginGlobal(const LLVector3d &origin_global);
+
+ // connectivity -- each LLPatch points at 5 neighbors (or NULL)
+ // +---+---+---+
+ // | | 2 | 5 |
+ // +---+---+---+
+ // | 3 | 0 | 1 |
+ // +---+---+---+
+ // | 6 | 4 | |
+ // +---+---+---+
+
+
+ BOOL getVisible() const;
+ U32 getRenderStride() const;
+ S32 getRenderLevel() const;
+
+ void setSurface(LLSurface *surfacep);
+ void setDataZ(F32 *data_z) { mDataZ = data_z; }
+ void setDataNorm(LLVector3 *data_norm) { mDataNorm = data_norm; }
+ F32 *getDataZ() const { return mDataZ; }
+
+ void dirty(); // Mark this surface patch as dirty...
+ void clearDirty() { mDirty = FALSE; }
+
+ void clearVObj();
public:
- BOOL mHasReceivedData; // has the patch EVER received height data?
- BOOL mSTexUpdate; // Does the surface texture need to be updated?
+ BOOL mHasReceivedData; // has the patch EVER received height data?
+ BOOL mSTexUpdate; // Does the surface texture need to be updated?
protected:
- LLSurfacePatch *mNeighborPatches[8]; // Adjacent patches
- BOOL mNormalsInvalid[9]; // Which normals are invalid
+ LLSurfacePatch *mNeighborPatches[8]; // Adjacent patches
+ BOOL mNormalsInvalid[9]; // Which normals are invalid
- BOOL mDirty;
- BOOL mDirtyZStats;
- BOOL mHeightsGenerated;
+ BOOL mDirty;
+ BOOL mDirtyZStats;
+ BOOL mHeightsGenerated;
- U32 mDataOffset;
- F32 *mDataZ;
- LLVector3 *mDataNorm;
+ U32 mDataOffset;
+ F32 *mDataZ;
+ LLVector3 *mDataNorm;
- // Pointer to the LLVOSurfacePatch object which is used in the new renderer.
- LLPointer<LLVOSurfacePatch> mVObjp;
+ // Pointer to the LLVOSurfacePatch object which is used in the new renderer.
+ LLPointer<LLVOSurfacePatch> mVObjp;
- // All of the camera-dependent stuff should be in its own class...
- LLPatchVisibilityInfo mVisInfo;
+ // All of the camera-dependent stuff should be in its own class...
+ LLPatchVisibilityInfo mVisInfo;
- // pointers to beginnings of patch data fields
- LLVector3d mOriginGlobal;
- LLVector3 mOriginRegion;
+ // pointers to beginnings of patch data fields
+ LLVector3d mOriginGlobal;
+ LLVector3 mOriginRegion;
- // height field stats
- LLVector3 mCenterRegion; // Center in region-local coords
- F32 mMinZ, mMaxZ, mMeanZ;
- F32 mRadius;
+ // height field stats
+ LLVector3 mCenterRegion; // Center in region-local coords
+ F32 mMinZ, mMaxZ, mMeanZ;
+ F32 mRadius;
- F32 mMinComposition;
- F32 mMaxComposition;
- F32 mMeanComposition;
+ F32 mMinComposition;
+ F32 mMaxComposition;
+ F32 mMeanComposition;
- U8 mConnectedEdge; // This flag is non-zero iff patch is on at least one edge
- // of LLSurface that is "connected" to another LLSurface
- U64 mLastUpdateTime; // Time patch was last updated
+ U8 mConnectedEdge; // This flag is non-zero iff patch is on at least one edge
+ // of LLSurface that is "connected" to another LLSurface
+ U64 mLastUpdateTime; // Time patch was last updated
- LLSurface *mSurfacep; // Pointer to "parent" surface
+ LLSurface *mSurfacep; // Pointer to "parent" surface
};
+extern template void LLSurfacePatch::updateNormals</*PBR=*/false>();
+extern template void LLSurfacePatch::updateNormals</*PBR=*/true>();
+
#endif // LL_LLSURFACEPATCH_H
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index fbbec56020..91c2755ea5 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file lltexturectrl.cpp
* @author Richard Nelson, James Cook
* @brief LLTextureCtrl class implementation including related functions
@@ -6,21 +6,21 @@
* $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$
*/
@@ -49,7 +49,7 @@
#include "llmaterialeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
-#include "llviewermenufile.h" // LLFilePickerReplyThread
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llpermissions.h"
#include "llpreviewtexture.h"
#include "llsaleinfo.h"
@@ -72,6 +72,7 @@
#include "llradiogroup.h"
#include "llfloaterreg.h"
+#include "llgltfmaterialpreviewmgr.h"
#include "lllocalbitmaps.h"
#include "lllocalgltfmaterials.h"
#include "llerror.h"
@@ -104,7 +105,7 @@ LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm)
items,
LLInventoryModel::INCLUDE_TRASH,
asset_id_matches);
-
+
LLUUID res;
if (items.size())
{
@@ -142,53 +143,53 @@ bool get_can_copy_texture(LLUUID asset_id)
S32 LLFloaterTexturePicker::sLastPickerMode = 0;
-LLFloaterTexturePicker::LLFloaterTexturePicker(
- LLView* owner,
- LLUUID image_asset_id,
- LLUUID default_image_asset_id,
- LLUUID blank_image_asset_id,
- BOOL tentative,
- BOOL allow_no_texture,
- const std::string& label,
- PermissionMask immediate_filter_perm_mask,
- PermissionMask dnd_filter_perm_mask,
- BOOL can_apply_immediately,
- LLUIImagePtr fallback_image,
+LLFloaterTexturePicker::LLFloaterTexturePicker(
+ LLView* owner,
+ LLUUID image_asset_id,
+ LLUUID default_image_asset_id,
+ LLUUID blank_image_asset_id,
+ BOOL tentative,
+ BOOL allow_no_texture,
+ const std::string& label,
+ PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image,
EPickInventoryType pick_type)
-: LLFloater(LLSD()),
- mOwner( owner ),
- mImageAssetID( image_asset_id ),
- mOriginalImageAssetID(image_asset_id),
- mFallbackImage(fallback_image),
- mDefaultImageAssetID(default_image_asset_id),
- mBlankImageAssetID(blank_image_asset_id),
- mTentative(tentative),
- mAllowNoTexture(allow_no_texture),
- mLabel(label),
- mTentativeLabel(NULL),
- mResolutionLabel(NULL),
- mActive( TRUE ),
- mFilterEdit(NULL),
- mImmediateFilterPermMask(immediate_filter_perm_mask),
- mDnDFilterPermMask(dnd_filter_perm_mask),
- mContextConeOpacity(0.f),
- mSelectedItemPinned( FALSE ),
- mCanApply(true),
- mCanPreview(true),
+: LLFloater(LLSD()),
+ mOwner( owner ),
+ mImageAssetID( image_asset_id ),
+ mOriginalImageAssetID(image_asset_id),
+ mFallbackImage(fallback_image),
+ mDefaultImageAssetID(default_image_asset_id),
+ mBlankImageAssetID(blank_image_asset_id),
+ mTentative(tentative),
+ mAllowNoTexture(allow_no_texture),
+ mLabel(label),
+ mTentativeLabel(NULL),
+ mResolutionLabel(NULL),
+ mActive( TRUE ),
+ mFilterEdit(NULL),
+ mImmediateFilterPermMask(immediate_filter_perm_mask),
+ mDnDFilterPermMask(dnd_filter_perm_mask),
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE ),
+ mCanApply(true),
+ mCanPreview(true),
mLimitsSet(false),
mMaxDim(S32_MAX),
mMinDim(0),
- mPreviewSettingChanged(false),
- mOnFloaterCommitCallback(NULL),
- mOnFloaterCloseCallback(NULL),
- mSetImageAssetIDCallback(NULL),
- mOnUpdateImageStatsCallback(NULL),
- mBakeTextureEnabled(FALSE),
+ mPreviewSettingChanged(false),
+ mOnFloaterCommitCallback(NULL),
+ mOnFloaterCloseCallback(NULL),
+ mSetImageAssetIDCallback(NULL),
+ mOnUpdateImageStatsCallback(NULL),
+ mBakeTextureEnabled(FALSE),
mInventoryPickType(pick_type)
{
- mCanApplyImmediately = can_apply_immediately;
- buildFromFile("floater_texture_ctrl.xml");
- setCanMinimize(FALSE);
+ mCanApplyImmediately = can_apply_immediately;
+ buildFromFile("floater_texture_ctrl.xml");
+ setCanMinimize(FALSE);
}
LLFloaterTexturePicker::~LLFloaterTexturePicker()
@@ -197,27 +198,27 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker()
void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/)
{
- if( ((mImageAssetID != image_id) || mTentative) && mActive)
- {
- mNoCopyTextureSelected = FALSE;
- mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
- mImageAssetID = image_id;
-
- if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
- {
- if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2)
- {
- mModeSelector->selectByValue(2);
- onModeSelect(0,this);
- }
- }
- else
- {
- if (mModeSelector->getValue().asInteger() == 2)
- {
- mModeSelector->selectByValue(0);
- onModeSelect(0,this);
- }
+ if( ((mImageAssetID != image_id) || mTentative) && mActive)
+ {
+ mNoCopyTextureSelected = FALSE;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+ mImageAssetID = image_id;
+
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
+ {
+ if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2)
+ {
+ mModeSelector->selectByValue(2);
+ onModeSelect(0,this);
+ }
+ }
+ else
+ {
+ if (mModeSelector->getValue().asInteger() == 2)
+ {
+ mModeSelector->selectByValue(0);
+ onModeSelect(0,this);
+ }
LLUUID item_id;
LLFolderView* root_folder = mInventoryPanel->getRootFolder();
@@ -229,7 +230,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
if (mInventoryPickType == PICK_MATERIAL
- && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && mImageAssetID == BLANK_MATERIAL_ASSET_ID
&& itemp && itemp->getAssetUUID().isNull())
{
item_id = inv_view->getUUID();
@@ -243,27 +244,27 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
{
item_id = findItemID(mImageAssetID, FALSE);
}
- if (item_id.isNull())
- {
- mInventoryPanel->getRootFolder()->clearSelection();
- }
- else
- {
- LLInventoryItem* itemp = gInventory.getItem(item_id);
- if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
- {
- // no copy texture
- getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
- mNoCopyTextureSelected = TRUE;
- }
- }
-
- if (set_selection)
- {
- mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
- }
- }
- }
+ if (item_id.isNull())
+ {
+ mInventoryPanel->getRootFolder()->clearSelection();
+ }
+ else
+ {
+ LLInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ // no copy texture
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
+ mNoCopyTextureSelected = TRUE;
+ }
+ }
+
+ if (set_selection)
+ {
+ mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
+ }
+ }
+ }
}
void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection)
@@ -272,23 +273,23 @@ void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bo
if (mInventoryPickType == PICK_MATERIAL && asset_id.isNull())
{
// If an inventory item has a null asset, consider it a valid blank material(gltf)
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
setImageID(asset_id, set_selection);
}
-void LLFloaterTexturePicker::setActive( BOOL active )
+void LLFloaterTexturePicker::setActive( BOOL active )
{
- if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
- {
- stopUsingPipette();
- }
- mActive = active;
+ if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
+ {
+ stopUsingPipette();
+ }
+ mActive = active;
}
void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
{
- mCanApplyImmediately = b;
+ mCanApplyImmediately = b;
LLUICtrl *apply_checkbox = getChild<LLUICtrl>("apply_immediate_check");
apply_checkbox->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
@@ -297,10 +298,10 @@ void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
void LLFloaterTexturePicker::stopUsingPipette()
{
- if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance())
- {
- LLToolMgr::getInstance()->clearTransientTool();
- }
+ if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance())
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
+ }
}
bool LLFloaterTexturePicker::updateImageStats()
@@ -358,13 +359,13 @@ bool LLFloaterTexturePicker::updateImageStats()
mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
}
}
- else if (mTexturep.notNull())
- {
- //RN: have we received header data for this image?
+ else if (mTexturep.notNull())
+ {
+ //RN: have we received header data for this image?
S32 width = mTexturep->getFullWidth();
S32 height = mTexturep->getFullHeight();
- if (width > 0 && height > 0)
- {
+ if (width > 0 && height > 0)
+ {
if ((mLimitsSet && (width != height))
|| width < mMinDim
|| width > mMaxDim
@@ -386,16 +387,16 @@ bool LLFloaterTexturePicker::updateImageStats()
{
mOnUpdateImageStatsCallback(mTexturep);
}
- }
- else
- {
- mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
- }
- }
- else
- {
- mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
- }
+ }
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
+ }
+ }
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
+ }
mResolutionLabel->setVisible(result);
mResolutionWarning->setVisible(!result);
@@ -414,16 +415,16 @@ bool LLFloaterTexturePicker::updateImageStats()
}
// virtual
-BOOL LLFloaterTexturePicker::handleDragAndDrop(
- S32 x, S32 y, MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg)
+BOOL LLFloaterTexturePicker::handleDragAndDrop(
+ S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg)
{
- BOOL handled = FALSE;
+ BOOL handled = FALSE;
- bool is_mesh = cargo_type == DAD_MESH;
+ bool is_mesh = cargo_type == DAD_MESH;
bool is_texture = cargo_type == DAD_TEXTURE;
bool is_material = cargo_type == DAD_MATERIAL;
@@ -441,83 +442,83 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
allow_dnd = is_texture || is_mesh || is_material;
}
- if (allow_dnd)
- {
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
-
- BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
- BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
- BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
- gAgent.getID());
-
- PermissionMask item_perm_mask = 0;
- if (copy) item_perm_mask |= PERM_COPY;
- if (mod) item_perm_mask |= PERM_MODIFY;
- if (xfer) item_perm_mask |= PERM_TRANSFER;
-
- PermissionMask filter_perm_mask = mDnDFilterPermMask;
- if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
- {
- if (drop)
- {
+ if (allow_dnd)
+ {
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+ BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
+ BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID());
+
+ PermissionMask item_perm_mask = 0;
+ if (copy) item_perm_mask |= PERM_COPY;
+ if (mod) item_perm_mask |= PERM_MODIFY;
+ if (xfer) item_perm_mask |= PERM_TRANSFER;
+
+ PermissionMask filter_perm_mask = mDnDFilterPermMask;
+ if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
+ {
+ if (drop)
+ {
setImageIDFromItem(item);
- commitIfImmediateSet();
- }
+ commitIfImmediateSet();
+ }
- *accept = ACCEPT_YES_SINGLE;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
- }
- else
- {
- *accept = ACCEPT_NO;
- }
+ *accept = ACCEPT_YES_SINGLE;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
- handled = TRUE;
- LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << LL_ENDL;
+ handled = TRUE;
+ LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << LL_ENDL;
- return handled;
+ return handled;
}
BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
{
- LLFolderView* root_folder = mInventoryPanel->getRootFolder();
-
- if (root_folder && mFilterEdit)
- {
- if (mFilterEdit->hasFocus()
- && (key == KEY_RETURN || key == KEY_DOWN)
- && mask == MASK_NONE)
- {
- if (!root_folder->getCurSelectedItem())
- {
- LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID());
- if (itemp)
- {
- root_folder->setSelection(itemp, FALSE, FALSE);
- }
- }
- root_folder->scrollToShowSelection();
-
- // move focus to inventory proper
- mInventoryPanel->setFocus(TRUE);
-
- // treat this as a user selection of the first filtered result
- commitIfImmediateSet();
-
- return TRUE;
- }
-
- if (mInventoryPanel->hasFocus() && key == KEY_UP)
- {
- mFilterEdit->focusFirstItem(TRUE);
- }
- }
-
- return LLFloater::handleKeyHere(key, mask);
+ LLFolderView* root_folder = mInventoryPanel->getRootFolder();
+
+ if (root_folder && mFilterEdit)
+ {
+ if (mFilterEdit->hasFocus()
+ && (key == KEY_RETURN || key == KEY_DOWN)
+ && mask == MASK_NONE)
+ {
+ if (!root_folder->getCurSelectedItem())
+ {
+ LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID());
+ if (itemp)
+ {
+ root_folder->setSelection(itemp, FALSE, FALSE);
+ }
+ }
+ root_folder->scrollToShowSelection();
+
+ // move focus to inventory proper
+ mInventoryPanel->setFocus(TRUE);
+
+ // treat this as a user selection of the first filtered result
+ commitIfImmediateSet();
+
+ return TRUE;
+ }
+
+ if (mInventoryPanel->hasFocus() && key == KEY_UP)
+ {
+ mFilterEdit->focusFirstItem(TRUE);
+ }
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
}
void LLFloaterTexturePicker::onOpen(const LLSD& key)
@@ -531,28 +532,30 @@ void LLFloaterTexturePicker::onOpen(const LLSD& key)
void LLFloaterTexturePicker::onClose(bool app_quitting)
{
- if (mOwner && mOnFloaterCloseCallback)
- {
- mOnFloaterCloseCallback();
- }
- stopUsingPipette();
+ if (mOwner && mOnFloaterCloseCallback)
+ {
+ mOnFloaterCloseCallback();
+ }
+ stopUsingPipette();
sLastPickerMode = mModeSelector->getValue().asInteger();
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
}
// virtual
BOOL LLFloaterTexturePicker::postBuild()
{
- LLFloater::postBuild();
+ LLFloater::postBuild();
- if (!mLabel.empty())
- {
- std::string pick = getString("pick title");
+ if (!mLabel.empty())
+ {
+ std::string pick = getString("pick title");
+
+ setTitle(pick + mLabel);
+ }
+ mTentativeLabel = getChild<LLTextBox>("Multiple");
- setTitle(pick + mLabel);
- }
- mTentativeLabel = getChild<LLTextBox>("Multiple");
-
- mResolutionLabel = getChild<LLTextBox>("size_lbl");
+ mResolutionLabel = getChild<LLTextBox>("size_lbl");
mResolutionWarning = getChild<LLTextBox>("over_limit_lbl");
@@ -573,70 +576,70 @@ BOOL LLFloaterTexturePicker::postBuild()
mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
- mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
+ mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
- mModeSelector = getChild<LLComboBox>("mode_selection");
- mModeSelector->setCommitCallback(onModeSelect, this);
- mModeSelector->selectByValue(0);
+ mModeSelector = getChild<LLComboBox>("mode_selection");
+ mModeSelector->setCommitCallback(onModeSelect, this);
+ mModeSelector->selectByValue(0);
- if(mInventoryPanel)
- {
+ if(mInventoryPanel)
+ {
// to avoid having to make an assumption about which option is
// selected at startup, we call the same function that is triggered
// when a texture/materials/both choice is made and let it take care
// of setting the filters
refreshInventoryFilter();
- mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
- mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
- mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
+ 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);
+ // Disable auto selecting first filtered item because it takes away
+ // selection from the item set by LLTextureCtrl owning this floater.
+ mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE);
- // Commented out to scroll to currently selected texture. See EXT-5403.
- // // store this filter as the default one
- // mInventoryPanel->getRootFolder()->getFilter().markDefault();
+ // Commented out to scroll to currently selected texture. See EXT-5403.
+ // // store this filter as the default one
+ // mInventoryPanel->getRootFolder()->getFilter().markDefault();
- // Commented out to stop opening all folders with textures
- // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
+ // Commented out to stop opening all folders with textures
+ // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
- // don't put keyboard focus on selected item, because the selection callback
- // will assume that this was user input
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
- if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL)
- {
- mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
- }
- }
+ if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL)
+ {
+ mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ }
+ }
- childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this);
- childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this);
- childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this);
+ childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this);
+ childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this);
+ childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this);
- mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
- mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
+ mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
+ mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
refreshLocalList();
- mNoCopyTextureSelected = FALSE;
+ mNoCopyTextureSelected = FALSE;
- getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
- childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
+ childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
- getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
- childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
- childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
-
- mSavedFolderState.setApply(FALSE);
+ getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
+ childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
+ childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
- LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
+ mSavedFolderState.setApply(FALSE);
- getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);
+ LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
+
+ getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);
- setBakeTextureEnabled(TRUE);
- return TRUE;
+ setBakeTextureEnabled(TRUE);
+ return TRUE;
}
// virtual
@@ -647,18 +650,19 @@ void LLFloaterTexturePicker::draw()
// This is going to spam mOnUpdateImageStatsCallback,
// either move elsewhere or fix to cause update once per image
- bool valid_dims = updateImageStats();
+ bool valid_dims = updateImageStats();
- // if we're inactive, gray out "apply immediate" checkbox
- getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
- mSelectBtn->setEnabled(mActive && mCanApply && valid_dims);
- mPipetteBtn->setEnabled(mActive);
+ // if we're inactive, gray out "apply immediate" checkbox
+ getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
+ mSelectBtn->setEnabled(mActive && mCanApply && valid_dims);
+ mPipetteBtn->setEnabled(mActive);
mPipetteBtn->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
- //BOOL allow_copy = FALSE;
- if( mOwner )
- {
- mTexturep = NULL;
+ //BOOL allow_copy = FALSE;
+ if( mOwner )
+ {
+ mTexturep = NULL;
+ LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
mGLTFMaterial = NULL;
if (mImageAssetID.notNull())
{
@@ -666,10 +670,27 @@ void LLFloaterTexturePicker::draw()
{
mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
+ if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get())))
+ {
+ // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
+ if (mGLTFMaterial.isNull())
+ {
+ mGLTFPreview = nullptr;
+ }
+ else
+ {
+ mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
+ }
+ }
+ if (mGLTFPreview)
+ {
+ mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
}
else
{
LLPointer<LLViewerFetchedTexture> texture = NULL;
+ mGLTFPreview = nullptr;
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
{
@@ -679,7 +700,7 @@ void LLFloaterTexturePicker::draw()
if (obj)
{
LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
- texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+ texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
}
}
@@ -693,115 +714,113 @@ void LLFloaterTexturePicker::draw()
}
}
- if (mTentativeLabel)
- {
- mTentativeLabel->setVisible( FALSE );
- }
+ if (mTentativeLabel)
+ {
+ mTentativeLabel->setVisible( FALSE );
+ }
- mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
- mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative);
- mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
+ mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
+ mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative);
+ mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
- LLFloater::draw();
+ LLFloater::draw();
- if( isMinimized() )
- {
- return;
- }
+ if( isMinimized() )
+ {
+ return;
+ }
- // Border
- LLRect border = getChildView("preview_widget")->getRect();
- gl_rect_2d( border, LLColor4::black, FALSE );
+ // Border
+ LLRect border = getChildView("preview_widget")->getRect();
+ gl_rect_2d( border, LLColor4::black, FALSE );
- // Interior
- LLRect interior = border;
- interior.stretch( -1 );
+ // Interior
+ LLRect interior = border;
+ interior.stretch( -1 );
- // If the floater is focused, don't apply its alpha to the texture (STORM-677).
- const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLViewerTexture* texture = nullptr;
+ // If the floater is focused, don't apply its alpha to the texture (STORM-677).
+ const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+ LLViewerTexture* preview;
if (mGLTFMaterial)
{
- texture = mGLTFMaterial->getUITexture();
+ preview = mGLTFPreview.get();
}
else
{
- texture = mTexturep.get();
- }
-
- if( texture )
- {
- if( texture->getComponents() == 4 )
- {
- gl_rect_2d_checkerboard( interior, alpha );
- }
-
- gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), texture, UI_VERTEX_COLOR % alpha );
-
- // Pump the priority
- texture->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
- }
- else if (!mFallbackImage.isNull())
- {
- mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
- }
- else
- {
- gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
-
- // Draw X
- gl_draw_x(interior, LLColor4::black );
- }
-
- // Draw Tentative Label over the image
- if( mTentative && !mViewModel->isDirty() )
- {
- mTentativeLabel->setVisible( TRUE );
- drawChild(mTentativeLabel);
- }
-
- if (mSelectedItemPinned) return;
-
- LLFolderView* folder_view = mInventoryPanel->getRootFolder();
- if (!folder_view) return;
-
- LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
-
- bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
- filter.isNotDefault();
-
- // After inventory panel filter is applied we have to update
- // constraint rect for the selected item because of folder view
- // AutoSelectOverride set to TRUE. We force PinningSelectedItem
- // flag to FALSE state and setting filter "dirty" to update
- // scroll container to show selected item (see LLFolderView::doIdle()).
- if (!is_filter_active && !mSelectedItemPinned)
- {
- folder_view->setPinningSelectedItem(mSelectedItemPinned);
- folder_view->getViewModelItem()->dirtyFilter();
- mSelectedItemPinned = TRUE;
- }
- }
+ preview = mTexturep.get();
+ }
+
+ if( preview )
+ {
+ preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ if( preview->getComponents() == 4 )
+ {
+ gl_rect_2d_checkerboard( interior, alpha );
+ }
+
+ gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha );
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
+ }
+ else
+ {
+ gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
+
+ // Draw X
+ gl_draw_x(interior, LLColor4::black );
+ }
+
+ // Draw Tentative Label over the image
+ if( mTentative && !mViewModel->isDirty() )
+ {
+ mTentativeLabel->setVisible( TRUE );
+ drawChild(mTentativeLabel);
+ }
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
+
+ bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
+ filter.isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->getViewModelItem()->dirtyFilter();
+ mSelectedItemPinned = TRUE;
+ }
+ }
}
const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library)
{
- if (asset_id.isNull())
- {
+ if (asset_id.isNull())
+ {
// null asset id means, no material or texture assigned
return LLUUID::null;
- }
+ }
LLUUID loockup_id = asset_id;
- if (mInventoryPickType == PICK_MATERIAL && loockup_id == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID)
+ if (mInventoryPickType == PICK_MATERIAL && loockup_id == BLANK_MATERIAL_ASSET_ID)
{
// default asset id means we are looking for an inventory item with a default asset UUID (null)
loockup_id = LLUUID::null;
}
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
if (loockup_id.isNull())
{
@@ -825,44 +844,44 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co
}
- 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->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;
+ 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->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;
}
void LLFloaterTexturePicker::commitIfImmediateSet()
{
- if (!mNoCopyTextureSelected && mCanApply)
- {
+ if (!mNoCopyTextureSelected && mCanApply)
+ {
commitCallback(LLTextureCtrl::TEXTURE_CHANGE);
- }
+ }
}
void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
@@ -889,7 +908,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
if (mInventoryPickType == PICK_MATERIAL
- && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && mImageAssetID == BLANK_MATERIAL_ASSET_ID
&& itemp && itemp->getAssetUUID().isNull())
{
inventory_id = inv_view->getUUID();
@@ -944,40 +963,40 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
}
void LLFloaterTexturePicker::commitCancel()
{
- if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
- {
- mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null);
- }
+ if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
+ {
+ mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null);
+ }
}
// static
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->setCanApply(true, true);
- if (self->mOwner)
- {
- self->setImageID( self->getDefaultImageAssetID() );
- }
- self->commitIfImmediateSet();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
+ if (self->mOwner)
+ {
+ self->setImageID( self->getDefaultImageAssetID() );
+ }
+ self->commitIfImmediateSet();
}
// static
void LLFloaterTexturePicker::onBtnBlank(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->setCanApply(true, true);
- self->setImageID( self->getBlankImageAssetID() );
- self->commitIfImmediateSet();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
+ self->setImageID( self->getBlankImageAssetID() );
+ self->commitIfImmediateSet();
}
// static
void LLFloaterTexturePicker::onBtnNone(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setCanApply(true, true);
- self->setImageID( LLUUID::null );
+ self->setImageID( LLUUID::null );
self->commitIfImmediateSet();
}
@@ -985,88 +1004,88 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata)
// static
void LLFloaterTexturePicker::onBtnRevert(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->setImageID( self->mOriginalImageAssetID );
- // TODO: Change this to tell the owner to cancel. It needs to be
- // smart enough to restore multi-texture selections.
- self->mOwner->onFloaterCommit();
- self->mViewModel->resetDirty();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setImageID( self->mOriginalImageAssetID );
+ // TODO: Change this to tell the owner to cancel. It needs to be
+ // smart enough to restore multi-texture selections.
+ self->mOwner->onFloaterCommit();
+ self->mViewModel->resetDirty();
}*/
// static
void LLFloaterTexturePicker::onBtnCancel(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->setImageID( self->mOriginalImageAssetID );
- if (self->mOnFloaterCommitCallback)
- {
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null);
- }
- self->mViewModel->resetDirty();
- self->closeFloater();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setImageID( self->mOriginalImageAssetID );
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null);
+ }
+ self->mViewModel->resetDirty();
+ self->closeFloater();
}
// static
void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- if (self->mOnFloaterCommitCallback)
- {
- self->commitCallback(LLTextureCtrl::TEXTURE_SELECT);
- }
- self->closeFloater();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->commitCallback(LLTextureCtrl::TEXTURE_SELECT);
+ }
+ self->closeFloater();
}
void LLFloaterTexturePicker::onBtnPipette()
{
- BOOL pipette_active = getChild<LLUICtrl>("Pipette")->getValue().asBoolean();
- pipette_active = !pipette_active;
- if (pipette_active)
- {
- LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
- }
- else
- {
- LLToolMgr::getInstance()->clearTransientTool();
- }
+ BOOL pipette_active = getChild<LLUICtrl>("Pipette")->getValue().asBoolean();
+ pipette_active = !pipette_active;
+ if (pipette_active)
+ {
+ LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
+ }
+ else
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
+ }
}
void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
- if (items.size())
- {
- LLFolderViewItem* first_item = items.front();
- LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
- mNoCopyTextureSelected = FALSE;
- if (itemp)
- {
- if (!mTextureSelectedCallback.empty())
- {
- mTextureSelectedCallback(itemp);
- }
- if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
- {
- mNoCopyTextureSelected = TRUE;
- }
+ if (items.size())
+ {
+ LLFolderViewItem* first_item = items.front();
+ LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
+ mNoCopyTextureSelected = FALSE;
+ if (itemp)
+ {
+ if (!mTextureSelectedCallback.empty())
+ {
+ mTextureSelectedCallback(itemp);
+ }
+ if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ mNoCopyTextureSelected = TRUE;
+ }
setImageIDFromItem(itemp, false);
- mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
- if(!mPreviewSettingChanged)
- {
- mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
- }
- else
- {
- mPreviewSettingChanged = false;
- }
-
- if (user_action && mCanPreview)
- {
- // only commit intentional selections, not implicit ones
- commitIfImmediateSet();
- }
- }
- }
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if(!mPreviewSettingChanged)
+ {
+ mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
+ }
+ else
+ {
+ mPreviewSettingChanged = false;
+ }
+
+ if (user_action && mCanPreview)
+ {
+ // only commit intentional selections, not implicit ones
+ commitIfImmediateSet();
+ }
+ }
+ }
}
// static
@@ -1098,18 +1117,18 @@ void LLFloaterTexturePicker::onBtnAdd(void* userdata)
// static
void LLFloaterTexturePicker::onBtnRemove(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
- if (!selected_items.empty())
- {
+ if (!selected_items.empty())
+ {
- for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
- iter != selected_items.end(); iter++)
- {
- LLScrollListItem* list_item = *iter;
- if (list_item)
- {
+ for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
+ iter != selected_items.end(); iter++)
+ {
+ LLScrollListItem* list_item = *iter;
+ if (list_item)
+ {
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
@@ -1122,28 +1141,28 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
{
LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
}
- }
- }
+ }
+ }
- self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
- self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
+ self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
+ self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
self->refreshLocalList();
- }
+ }
}
// static
void LLFloaterTexturePicker::onBtnUpload(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
- if (selected_items.empty())
- {
- return;
- }
+ if (selected_items.empty())
+ {
+ return;
+ }
- /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
- in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
+ /* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
+ in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
@@ -1172,16 +1191,16 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata)
//static
void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
- bool has_selection = !selected_items.empty();
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ std::vector<LLScrollListItem*> selected_items = self->mLocalScrollCtrl->getAllSelected();
+ bool has_selection = !selected_items.empty();
- self->getChild<LLButton>("l_rem_btn")->setEnabled(has_selection);
- self->getChild<LLButton>("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2));
- /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */
+ self->getChild<LLButton>("l_rem_btn")->setEnabled(has_selection);
+ self->getChild<LLButton>("l_upl_btn")->setEnabled(has_selection && (selected_items.size() < 2));
+ /* since multiple-localbitmap upload is not implemented, upl button gets disabled if more than one is selected. */
- if (has_selection)
- {
+ if (has_selection)
+ {
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
@@ -1196,114 +1215,114 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
}
- if (self->mSetImageAssetIDCallback)
- {
- self->mSetImageAssetIDCallback(inworld_id);
- }
+ if (self->mSetImageAssetIDCallback)
+ {
+ self->mSetImageAssetIDCallback(inworld_id);
+ }
- if (self->childGetValue("apply_immediate_check").asBoolean())
- {
- if (self->mOnFloaterCommitCallback)
- {
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id);
- }
- }
- }
+ if (self->childGetValue("apply_immediate_check").asBoolean())
+ {
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id);
+ }
+ }
+ }
}
// static
void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
{
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
+ LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
- LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
+ LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
+ gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
- picker->commitIfImmediateSet();
+ picker->commitIfImmediateSet();
}
//static
void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data;
- LLComboBox* combo_box = (LLComboBox*)ctrl;
-
- S8 type = combo_box->getValue().asInteger();
-
- LLUUID imageID = self->mDefaultImageAssetID;
- if (type == 0)
- {
- imageID = IMG_USE_BAKED_HEAD;
- }
- else if (type == 1)
- {
- imageID = IMG_USE_BAKED_UPPER;
- }
- else if (type == 2)
- {
- imageID = IMG_USE_BAKED_LOWER;
- }
- else if (type == 3)
- {
- imageID = IMG_USE_BAKED_EYES;
- }
- else if (type == 4)
- {
- imageID = IMG_USE_BAKED_SKIRT;
- }
- else if (type == 5)
- {
- imageID = IMG_USE_BAKED_HAIR;
- }
- else if (type == 6)
- {
- imageID = IMG_USE_BAKED_LEFTARM;
- }
- else if (type == 7)
- {
- imageID = IMG_USE_BAKED_LEFTLEG;
- }
- else if (type == 8)
- {
- imageID = IMG_USE_BAKED_AUX1;
- }
- else if (type == 9)
- {
- imageID = IMG_USE_BAKED_AUX2;
- }
- else if (type == 10)
- {
- imageID = IMG_USE_BAKED_AUX3;
- }
-
- self->setImageID(imageID);
- self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
- if (!self->mPreviewSettingChanged)
- {
- self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
- }
- else
- {
- self->mPreviewSettingChanged = false;
- }
-
- if (self->mCanPreview)
- {
- // only commit intentional selections, not implicit ones
- self->commitIfImmediateSet();
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data;
+ LLComboBox* combo_box = (LLComboBox*)ctrl;
+
+ S8 type = combo_box->getValue().asInteger();
+
+ LLUUID imageID = self->mDefaultImageAssetID;
+ if (type == 0)
+ {
+ imageID = IMG_USE_BAKED_HEAD;
+ }
+ else if (type == 1)
+ {
+ imageID = IMG_USE_BAKED_UPPER;
+ }
+ else if (type == 2)
+ {
+ imageID = IMG_USE_BAKED_LOWER;
+ }
+ else if (type == 3)
+ {
+ imageID = IMG_USE_BAKED_EYES;
+ }
+ else if (type == 4)
+ {
+ imageID = IMG_USE_BAKED_SKIRT;
+ }
+ else if (type == 5)
+ {
+ imageID = IMG_USE_BAKED_HAIR;
+ }
+ else if (type == 6)
+ {
+ imageID = IMG_USE_BAKED_LEFTARM;
+ }
+ else if (type == 7)
+ {
+ imageID = IMG_USE_BAKED_LEFTLEG;
+ }
+ else if (type == 8)
+ {
+ imageID = IMG_USE_BAKED_AUX1;
+ }
+ else if (type == 9)
+ {
+ imageID = IMG_USE_BAKED_AUX2;
+ }
+ else if (type == 10)
+ {
+ imageID = IMG_USE_BAKED_AUX3;
+ }
+
+ self->setImageID(imageID);
+ self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if (!self->mPreviewSettingChanged)
+ {
+ self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
+ }
+ else
+ {
+ self->mPreviewSettingChanged = false;
+ }
+
+ if (self->mCanPreview)
+ {
+ // only commit intentional selections, not implicit ones
+ self->commitIfImmediateSet();
+ }
}
void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool inworld_image)
{
- mSelectBtn->setEnabled(can_apply);
- getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview && inworld_image);
- getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
+ mSelectBtn->setEnabled(can_apply);
+ getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview && inworld_image);
+ getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
- mCanApply = can_apply;
- mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false;
- mPreviewSettingChanged = true;
+ mCanApply = can_apply;
+ mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false;
+ mPreviewSettingChanged = true;
}
void LLFloaterTexturePicker::setMinDimentionsLimits(S32 min_dim)
@@ -1317,36 +1336,36 @@ void LLFloaterTexturePicker::setMinDimentionsLimits(S32 min_dim)
void LLFloaterTexturePicker::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);
+ 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 LLFloaterTexturePicker::changeMode()
@@ -1476,24 +1495,24 @@ void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
{
- BOOL changed = (enabled != mBakeTextureEnabled);
+ BOOL changed = (enabled != mBakeTextureEnabled);
- mBakeTextureEnabled = enabled;
- mModeSelector->setEnabledByValue(2, enabled);
-
- if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2))
- {
- mModeSelector->selectByValue(0);
- }
+ mBakeTextureEnabled = enabled;
+ mModeSelector->setEnabledByValue(2, enabled);
- if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
- {
- if (mModeSelector->getValue().asInteger() != 2)
- {
- mModeSelector->selectByValue(2);
- }
- }
- onModeSelect(0, this);
+ if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2))
+ {
+ mModeSelector->selectByValue(0);
+ }
+
+ if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
+ {
+ if (mModeSelector->getValue().asInteger() != 2)
+ {
+ mModeSelector->selectByValue(2);
+ }
+ }
+ onModeSelect(0, this);
}
void LLFloaterTexturePicker::setInventoryPickType(EPickInventoryType type)
@@ -1584,10 +1603,10 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& fi
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
- LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
- if (inventory_item_id.notNull())
- {
- LLToolPipette::getInstance()->setResult(TRUE, "");
+ LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
+ if (inventory_item_id.notNull())
+ {
+ LLToolPipette::getInstance()->setResult(TRUE, "");
if (mInventoryPickType == PICK_MATERIAL)
{
// tes have no data about material ids
@@ -1600,21 +1619,21 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
setImageID(te.getID());
}
- mNoCopyTextureSelected = FALSE;
- LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
-
- if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
- {
- // no copy texture
- mNoCopyTextureSelected = TRUE;
- }
+ mNoCopyTextureSelected = FALSE;
+ LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
- commitIfImmediateSet();
- }
- else
- {
- LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture"));
- }
+ if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ // no copy texture
+ mNoCopyTextureSelected = TRUE;
+ }
+
+ commitIfImmediateSet();
+ }
+ else
+ {
+ LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture"));
+ }
}
///////////////////////////////////////////////////////////////////////
@@ -1623,107 +1642,107 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
static LLDefaultChildRegistry::Register<LLTextureCtrl> r("texture_picker");
LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
-: LLUICtrl(p),
- mDragCallback(NULL),
- mDropCallback(NULL),
- mOnCancelCallback(NULL),
- mOnCloseCallback(NULL),
- mOnSelectCallback(NULL),
- mBorderColor( p.border_color() ),
- mAllowNoTexture( p.allow_no_texture ),
- mAllowLocalTexture( TRUE ),
- mImmediateFilterPermMask( PERM_NONE ),
- mCanApplyImmediately( FALSE ),
- mNeedsRawImageData( FALSE ),
- mValid( TRUE ),
- mShowLoadingPlaceholder( TRUE ),
- mOpenTexPreview(false),
+: LLUICtrl(p),
+ mDragCallback(NULL),
+ mDropCallback(NULL),
+ mOnCancelCallback(NULL),
+ mOnCloseCallback(NULL),
+ mOnSelectCallback(NULL),
+ mBorderColor( p.border_color() ),
+ mAllowNoTexture( p.allow_no_texture ),
+ mAllowLocalTexture( TRUE ),
+ mImmediateFilterPermMask( PERM_NONE ),
+ mCanApplyImmediately( FALSE ),
+ mNeedsRawImageData( FALSE ),
+ mValid( TRUE ),
+ mShowLoadingPlaceholder( TRUE ),
+ mOpenTexPreview(false),
mBakeTextureEnabled(true),
- mInventoryPickType(PICK_TEXTURE),
- mImageAssetID(p.image_id),
- mDefaultImageAssetID(p.default_image_id),
- mDefaultImageName(p.default_image_name),
- mFallbackImage(p.fallback_image)
-{
-
- // Default of defaults is white image for diff tex
- //
- setBlankImageAssetID(IMG_WHITE);
-
- setAllowNoTexture(p.allow_no_texture);
- setCanApplyImmediately(p.can_apply_immediately);
- mCommitOnSelection = !p.no_commit_on_selection;
-
- LLTextBox::Params params(p.caption_text);
- params.name(p.label);
- params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
- params.initial_value(p.label());
- params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
- mCaption = LLUICtrlFactory::create<LLTextBox> (params);
- addChild( mCaption );
-
- S32 image_top = getRect().getHeight();
- S32 image_bottom = BTN_HEIGHT_SMALL;
- S32 image_middle = (image_top + image_bottom) / 2;
- S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight();
-
- LLTextBox::Params tentative_label_p(p.multiselect_text);
- tentative_label_p.name("Multiple");
- tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 ));
- tentative_label_p.follows.flags(FOLLOWS_ALL);
- mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p);
-
- // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion
- LLStyle::Params style_params;
- style_params.color = LLColor4::white;
-
- mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params);
- mTentativeLabel->setHAlign(LLFontGL::HCENTER);
- addChild( mTentativeLabel );
-
- LLRect border_rect = getLocalRect();
- border_rect.mBottom += BTN_HEIGHT_SMALL;
- LLViewBorder::Params vbparams(p.border);
- vbparams.name("border");
- vbparams.rect(border_rect);
- mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams);
- addChild(mBorder);
-
- mLoadingPlaceholderString = LLTrans::getString("texture_loading");
+ mInventoryPickType(p.pick_type),
+ mImageAssetID(p.image_id),
+ mDefaultImageAssetID(p.default_image_id),
+ mDefaultImageName(p.default_image_name),
+ mFallbackImage(p.fallback_image)
+{
+
+ // Default of defaults is white image for diff tex
+ //
+ setBlankImageAssetID(IMG_WHITE);
+
+ setAllowNoTexture(p.allow_no_texture);
+ setCanApplyImmediately(p.can_apply_immediately);
+ mCommitOnSelection = !p.no_commit_on_selection;
+
+ LLTextBox::Params params(p.caption_text);
+ params.name(p.label);
+ params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ params.initial_value(p.label());
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ mCaption = LLUICtrlFactory::create<LLTextBox> (params);
+ addChild( mCaption );
+
+ S32 image_top = getRect().getHeight();
+ S32 image_bottom = BTN_HEIGHT_SMALL;
+ S32 image_middle = (image_top + image_bottom) / 2;
+ S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight();
+
+ LLTextBox::Params tentative_label_p(p.multiselect_text);
+ tentative_label_p.name("Multiple");
+ tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 ));
+ tentative_label_p.follows.flags(FOLLOWS_ALL);
+ mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p);
+
+ // It is no longer possible to associate a style with a textbox, so it has to be done in this fashion
+ LLStyle::Params style_params;
+ style_params.color = LLColor4::white;
+
+ mTentativeLabel->setText(LLTrans::getString("multiple_textures"), style_params);
+ mTentativeLabel->setHAlign(LLFontGL::HCENTER);
+ addChild( mTentativeLabel );
+
+ LLRect border_rect = getLocalRect();
+ border_rect.mBottom += BTN_HEIGHT_SMALL;
+ LLViewBorder::Params vbparams(p.border);
+ vbparams.name("border");
+ vbparams.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams);
+ addChild(mBorder);
+
+ mLoadingPlaceholderString = LLTrans::getString("texture_loading");
}
LLTextureCtrl::~LLTextureCtrl()
{
- closeDependentFloater();
+ closeDependentFloater();
}
void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder)
{
- mShowLoadingPlaceholder = showLoadingPlaceholder;
+ mShowLoadingPlaceholder = showLoadingPlaceholder;
}
void LLTextureCtrl::setCaption(const std::string& caption)
{
- mCaption->setText( caption );
+ mCaption->setText( caption );
}
void LLTextureCtrl::setCanApplyImmediately(BOOL b)
{
- mCanApplyImmediately = b;
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp )
- {
- floaterp->setCanApplyImmediately(b);
- }
+ mCanApplyImmediately = b;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp )
+ {
+ floaterp->setCanApplyImmediately(b);
+ }
}
void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
{
- LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
- if( floaterp )
- {
- floaterp->setCanApply(can_preview, can_apply);
- }
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if( floaterp )
+ {
+ floaterp->setCanApply(can_preview, can_apply);
+ }
}
void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
@@ -1737,182 +1756,195 @@ void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
}
}
-void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask)
+void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask)
{
setImmediateFilterPermMask(mask);
setDnDFilterPermMask(mask);
}
-void LLTextureCtrl::setVisible( BOOL visible )
+void LLTextureCtrl::onVisibilityChange(BOOL new_visibility)
{
- if( !visible )
+ if (!new_visibility)
{
- closeDependentFloater();
- }
- LLUICtrl::setVisible( visible );
-}
-
-void LLTextureCtrl::setEnabled( BOOL enabled )
-{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp )
- {
- floaterp->setActive(enabled);
- }
- if( enabled )
- {
- std::string tooltip;
- if (floaterp) tooltip = floaterp->getString("choose_picture");
- setToolTip( tooltip );
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
}
else
{
- setToolTip( std::string() );
- // *TODO: would be better to keep floater open and show
- // disabled state.
- closeDependentFloater();
+ llassert(!mGLTFPreview);
}
+}
- mCaption->setEnabled( enabled );
+void LLTextureCtrl::setVisible( BOOL visible )
+{
+ if( !visible )
+ {
+ closeDependentFloater();
+ }
+ LLUICtrl::setVisible( visible );
+}
- LLView::setEnabled( enabled );
+void LLTextureCtrl::setEnabled( BOOL enabled )
+{
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp )
+ {
+ floaterp->setActive(enabled);
+ }
+ if( enabled )
+ {
+ std::string tooltip;
+ if (floaterp) tooltip = floaterp->getString("choose_picture");
+ setToolTip( tooltip );
+ }
+ else
+ {
+ setToolTip( std::string() );
+ // *TODO: would be better to keep floater open and show
+ // disabled state.
+ closeDependentFloater();
+ }
+
+ mCaption->setEnabled( enabled );
+
+ LLView::setEnabled( enabled );
}
void LLTextureCtrl::setValid(BOOL valid )
{
- mValid = valid;
- if (!valid)
- {
- LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if (pickerp)
- {
- pickerp->setActive(FALSE);
- }
- }
+ mValid = valid;
+ if (!valid)
+ {
+ LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (pickerp)
+ {
+ pickerp->setActive(FALSE);
+ }
+ }
}
// virtual
void LLTextureCtrl::clear()
{
- setImageAssetID(LLUUID::null);
+ setImageAssetID(LLUUID::null);
}
void LLTextureCtrl::setLabel(const std::string& label)
{
- mLabel = label;
- mCaption->setText(label);
+ mLabel = label;
+ mCaption->setText(label);
}
void LLTextureCtrl::showPicker(BOOL take_focus)
{
- // show hourglass cursor when loading inventory window
- // because inventory construction is slooow
- getWindow()->setCursor(UI_CURSOR_WAIT);
- LLFloater* floaterp = mFloaterHandle.get();
-
- // Show the dialog
- if( floaterp )
- {
- floaterp->openFloater();
- }
- else
- {
- floaterp = new LLFloaterTexturePicker(
- this,
- getImageAssetID(),
- getDefaultImageAssetID(),
- getBlankImageAssetID(),
- getTentative(),
- getAllowNoTexture(),
- mLabel,
- mImmediateFilterPermMask,
- mDnDFilterPermMask,
- mCanApplyImmediately,
- mFallbackImage,
- mInventoryPickType);
- mFloaterHandle = floaterp->getHandle();
-
- LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
- if (texture_floaterp && mOnTextureSelectedCallback)
- {
- texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
- }
- if (texture_floaterp && mOnCloseCallback)
- {
- texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this));
- }
- if (texture_floaterp)
- {
- texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5));
- }
- if (texture_floaterp)
- {
- texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
-
- texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
- }
-
- LLFloater* root_floater = gFloaterView->getParentFloater(this);
- if (root_floater)
- root_floater->addDependentFloater(floaterp);
- floaterp->openFloater();
- }
-
- LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
- if (picker_floater)
- {
- picker_floater->setLocalTextureEnabled(mAllowLocalTexture);
- }
-
- if (take_focus)
- {
- floaterp->setFocus(TRUE);
- }
+ // show hourglass cursor when loading inventory window
+ // because inventory construction is slooow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloater* floaterp = mFloaterHandle.get();
+
+ // Show the dialog
+ if( floaterp )
+ {
+ floaterp->openFloater();
+ }
+ else
+ {
+ floaterp = new LLFloaterTexturePicker(
+ this,
+ getImageAssetID(),
+ getDefaultImageAssetID(),
+ getBlankImageAssetID(),
+ getTentative(),
+ getAllowNoTexture(),
+ mLabel,
+ mImmediateFilterPermMask,
+ mDnDFilterPermMask,
+ mCanApplyImmediately,
+ mFallbackImage,
+ mInventoryPickType);
+ mFloaterHandle = floaterp->getHandle();
+
+ LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (texture_floaterp && mOnTextureSelectedCallback)
+ {
+ texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
+ }
+ if (texture_floaterp && mOnCloseCallback)
+ {
+ texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this));
+ }
+ if (texture_floaterp)
+ {
+ texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5));
+ }
+ if (texture_floaterp)
+ {
+ texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
+
+ texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+ }
+
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(floaterp);
+ floaterp->openFloater();
+ }
+
+ LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (picker_floater)
+ {
+ picker_floater->setLocalTextureEnabled(mAllowLocalTexture);
+ }
+
+ if (take_focus)
+ {
+ floaterp->setFocus(TRUE);
+ }
}
void LLTextureCtrl::closeDependentFloater()
{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp && floaterp->isInVisibleChain())
- {
- floaterp->setOwner(NULL);
- floaterp->setVisible(FALSE);
- floaterp->closeFloater();
- }
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp && floaterp->isInVisibleChain())
+ {
+ floaterp->setOwner(NULL);
+ floaterp->setVisible(FALSE);
+ floaterp->closeFloater();
+ }
}
// Allow us to download textures quickly when floater is shown
class LLTextureFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
{
public:
- virtual void done()
- {
- // We need to find textures in all folders, so get the main
- // background download going.
- LLInventoryModelBackgroundFetch::instance().start();
- gInventory.removeObserver(this);
- delete this;
- }
+ virtual void done()
+ {
+ // We need to find textures in all folders, so get the main
+ // background download going.
+ LLInventoryModelBackgroundFetch::instance().start();
+ gInventory.removeObserver(this);
+ delete this;
+ }
};
BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask)
{
- getWindow()->setCursor(mBorder->parentPointInView(x,y) ? UI_CURSOR_HAND : UI_CURSOR_ARROW);
- return TRUE;
+ getWindow()->setCursor(mBorder->parentPointInView(x,y) ? UI_CURSOR_HAND : UI_CURSOR_ARROW);
+ return TRUE;
}
BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
- BOOL handled = LLUICtrl::handleMouseDown( x, y , mask );
+ BOOL handled = LLUICtrl::handleMouseDown( x, y , mask );
- if (!handled && mBorder->parentPointInView(x, y))
- {
- if (!mOpenTexPreview)
- {
- showPicker(FALSE);
+ if (!handled && mBorder->parentPointInView(x, y))
+ {
+ if (!mOpenTexPreview)
+ {
+ showPicker(FALSE);
if (mInventoryPickType == PICK_MATERIAL)
{
//grab materials first...
@@ -1923,48 +1955,48 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
//grab textures first...
LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
}
- //...then start full inventory fetch.
+ //...then start full inventory fetch.
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
{
LLInventoryModelBackgroundFetch::instance().start();
}
- handled = TRUE;
- }
- else
- {
- if (getImageAssetID().notNull())
- {
- LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
- if (preview_texture && !preview_texture->isDependent())
- {
- LLFloater* root_floater = gFloaterView->getParentFloater(this);
- if (root_floater)
- {
- root_floater->addDependentFloater(preview_texture);
- preview_texture->hideCtrlButtons();
- }
- }
- }
- }
- }
-
- return handled;
+ handled = TRUE;
+ }
+ else
+ {
+ if (getImageAssetID().notNull())
+ {
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
+ if (preview_texture && !preview_texture->isDependent())
+ {
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(preview_texture);
+ preview_texture->hideCtrlButtons();
+ }
+ }
+ }
+ }
+ }
+
+ return handled;
}
void LLTextureCtrl::onFloaterClose()
{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if (floaterp)
- {
- if (mOnCloseCallback)
- {
- mOnCloseCallback(this,LLSD());
- }
- floaterp->setOwner(NULL);
- }
+ if (floaterp)
+ {
+ if (mOnCloseCallback)
+ {
+ mOnCloseCallback(this,LLSD());
+ }
+ floaterp->setOwner(NULL);
+ }
- mFloaterHandle.markDead();
+ mFloaterHandle.markDead();
}
void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id)
@@ -1972,18 +2004,18 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( floaterp && getEnabled())
- {
- if (op == TEXTURE_CANCEL)
- mViewModel->resetDirty();
- // If the "no_commit_on_selection" parameter is set
- // we get dirty only when user presses OK in the picker
- // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
- else if (mCommitOnSelection || op == TEXTURE_SELECT)
- mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
- if(floaterp->isDirty() || asset_id.notNull()) // mModelView->setDirty does not work.
- {
- setTentative( FALSE );
+ {
+ if (op == TEXTURE_CANCEL)
+ mViewModel->resetDirty();
+ // If the "no_commit_on_selection" parameter is set
+ // we get dirty only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ else if (mCommitOnSelection || op == TEXTURE_SELECT)
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
+ if(floaterp->isDirty() || asset_id.notNull()) // mModelView->setDirty does not work.
+ {
+ setTentative( FALSE );
switch(source)
{
@@ -2012,76 +2044,76 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << ", mImageItemID: " << mImageItemID << LL_ENDL;
- if (op == TEXTURE_SELECT && mOnSelectCallback)
- {
+ if (op == TEXTURE_SELECT && mOnSelectCallback)
+ {
mOnSelectCallback(this, LLSD());
- }
- else if (op == TEXTURE_CANCEL && mOnCancelCallback)
- {
- mOnCancelCallback( this, LLSD() );
- }
- else
- {
- // If the "no_commit_on_selection" parameter is set
- // we commit only when user presses OK in the picker
- // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ }
+ else if (op == TEXTURE_CANCEL && mOnCancelCallback)
+ {
+ mOnCancelCallback( this, LLSD() );
+ }
+ else
+ {
+ // If the "no_commit_on_selection" parameter is set
+ // we commit only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
if (mCommitOnSelection || op == TEXTURE_SELECT)
{
onCommit();
}
- }
- }
- }
+ }
+ }
+ }
}
void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
{
- mOnTextureSelectedCallback = cb;
- LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
- if (floaterp)
- {
- floaterp->setTextureSelectedCallback(cb);
- }
+ mOnTextureSelectedCallback = cb;
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if (floaterp)
+ {
+ floaterp->setTextureSelectedCallback(cb);
+ }
}
-void LLTextureCtrl::setImageAssetName(const std::string& name)
+void LLTextureCtrl::setImageAssetName(const std::string& name)
{
- LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
- if(imagep)
- {
- LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
- if(pTexture)
- {
- LLUUID id = pTexture->getID();
- setImageAssetID(id);
- }
- }
+ LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
+ if(imagep)
+ {
+ LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
+ if(pTexture)
+ {
+ LLUUID id = pTexture->getID();
+ setImageAssetID(id);
+ }
+ }
}
void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
{
- if( mImageAssetID != asset_id )
- {
- mImageItemID.setNull();
- mImageAssetID = asset_id;
+ if( mImageAssetID != asset_id )
+ {
+ mImageItemID.setNull();
+ mImageAssetID = asset_id;
mLocalTrackingID.setNull();
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp && getEnabled() )
- {
- floaterp->setImageID( asset_id );
- floaterp->resetDirty();
- }
- }
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp && getEnabled() )
+ {
+ floaterp->setImageID( asset_id );
+ floaterp->resetDirty();
+ }
+ }
}
void LLTextureCtrl::setBakeTextureEnabled(bool enabled)
{
mBakeTextureEnabled = enabled;
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if (floaterp)
- {
- floaterp->setBakeTextureEnabled(enabled);
- }
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setBakeTextureEnabled(enabled);
+ }
}
void LLTextureCtrl::setInventoryPickType(EPickInventoryType type)
@@ -2095,16 +2127,16 @@ void LLTextureCtrl::setInventoryPickType(EPickInventoryType type)
}
BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg)
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg)
{
- BOOL handled = FALSE;
+ BOOL handled = FALSE;
- // this downcast may be invalid - but if the second test below
- // returns true, then the cast was valid, and we can perform
- // the third test without problems.
- LLInventoryItem* item = (LLInventoryItem*)cargo_data;
+ // this downcast may be invalid - but if the second test below
+ // returns true, then the cast was valid, and we can perform
+ // the third test without problems.
+ LLInventoryItem* item = (LLInventoryItem*)cargo_data;
bool is_mesh = cargo_type == DAD_MESH;
bool is_texture = cargo_type == DAD_TEXTURE;
@@ -2124,213 +2156,238 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
allow_dnd = is_texture || is_mesh || is_material;
}
- if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg))
- {
- if (drop)
- {
- if(doDrop(item))
- {
- if (!mCommitOnSelection)
- mViewModel->setDirty();
+ if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg))
+ {
+ if (drop)
+ {
+ if(doDrop(item))
+ {
+ if (!mCommitOnSelection)
+ mViewModel->setDirty();
- // This removes the 'Multiple' overlay, since
- // there is now only one texture selected.
- setTentative( FALSE );
- onCommit();
- }
- }
+ // This removes the 'Multiple' overlay, since
+ // there is now only one texture selected.
+ setTentative( FALSE );
+ onCommit();
+ }
+ }
- *accept = ACCEPT_YES_SINGLE;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
+ *accept = ACCEPT_YES_SINGLE;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
- handled = TRUE;
- LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl " << getName() << LL_ENDL;
+ handled = TRUE;
+ LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl " << getName() << LL_ENDL;
- return handled;
+ return handled;
}
void LLTextureCtrl::draw()
{
- mBorder->setKeyboardFocusHighlight(hasFocus());
-
- if (!mValid)
- {
- mTexturep = NULL;
- }
- else if (!mImageAssetID.isNull())
- {
- LLPointer<LLViewerFetchedTexture> texture = NULL;
+ mBorder->setKeyboardFocusHighlight(hasFocus());
- if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
- {
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if (obj)
- {
- LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
- texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
- }
-
- }
+ LLPointer<LLViewerTexture> preview = NULL;
- if (texture.isNull())
- {
+ if (!mValid)
+ {
+ mTexturep = NULL;
+ mGLTFMaterial = NULL;
+ mGLTFPreview = NULL;
+ }
+ else if (!mImageAssetID.isNull())
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
+ {
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ if (obj)
+ {
+ LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
+ mTexturep = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+ mGLTFMaterial = NULL;
+ mGLTFPreview = NULL;
+
+ preview = mTexturep;
+ }
+
+ }
+
+ if (preview.isNull())
+ {
+ LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
+ mGLTFMaterial = NULL;
+ mTexturep = NULL;
if (mInventoryPickType == PICK_MATERIAL)
{
- LLPointer<LLFetchedGLTFMaterial> material = gGLTFMaterialList.getMaterial(mImageAssetID);
- if (material)
+ mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID);
+ if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get())))
{
- texture = material->getUITexture();
+ // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
+ if (mGLTFMaterial.isNull())
+ {
+ mGLTFPreview = nullptr;
+ }
+ else
+ {
+ mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
+ }
}
+ if (mGLTFPreview)
+ {
+ mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
+
+ preview = mGLTFPreview;
}
else
{
- texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
- texture->forceToSaveRawImage(0);
- }
- }
-
- mTexturep = texture;
- }
- else//mImageAssetID == LLUUID::null
- {
- mTexturep = NULL;
- }
-
- // Border
- LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
- gl_rect_2d( border, mBorderColor.get(), FALSE );
-
- // Interior
- LLRect interior = border;
- interior.stretch( -1 );
-
- // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
- const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- if( mTexturep )
- {
- if( mTexturep->getComponents() == 4 )
- {
- gl_rect_2d_checkerboard( interior, alpha );
- }
-
- gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
- mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
- }
- else if (!mFallbackImage.isNull())
- {
- mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
- }
- else
- {
- gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
-
- // Draw X
- gl_draw_x( interior, LLColor4::black );
- }
-
- mTentativeLabel->setVisible( getTentative() );
-
- // Show "Loading..." string on the top left corner while this texture is loading.
- // Using the discard level, do not show the string if the texture is almost but not
- // fully loaded.
- if (mTexturep.notNull() &&
- (!mTexturep->isFullyLoaded()) &&
- (mShowLoadingPlaceholder == TRUE))
- {
- U32 v_offset = 25;
- LLFontGL* font = LLFontGL::getFontSansSerif();
-
- // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god
- if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike())
- {
- font->renderUTF8(
- mLoadingPlaceholderString,
- 0,
- llfloor(interior.mLeft+3),
- llfloor(interior.mTop-v_offset),
- LLColor4::white,
- LLFontGL::LEFT,
- LLFontGL::BASELINE,
- LLFontGL::DROP_SHADOW);
- }
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mTexturep->forceToSaveRawImage(0);
- // Optionally show more detailed information.
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- LLFontGL* font = LLFontGL::getFontSansSerif();
- std::string tdesc;
- // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best).
-
- v_offset += 12;
- tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0));
- font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
- LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
-
- v_offset += 12;
- tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel());
- font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
- LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
-
- v_offset += 12;
- tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str());
- font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
- LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
- }
- }
-
- LLUICtrl::draw();
+ preview = mTexturep;
+ }
+ }
+ }
+ else//mImageAssetID == LLUUID::null
+ {
+ mTexturep = NULL;
+ mGLTFMaterial = NULL;
+ mGLTFPreview = NULL;
+ }
+
+ // Border
+ LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
+ gl_rect_2d( border, mBorderColor.get(), FALSE );
+
+ // Interior
+ LLRect interior = border;
+ interior.stretch( -1 );
+
+ // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
+ const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+ if( preview )
+ {
+ if( preview->getComponents() == 4 )
+ {
+ gl_rect_2d_checkerboard( interior, alpha );
+ }
+
+ gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha);
+ preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
+ }
+ else
+ {
+ gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
+
+ // Draw X
+ gl_draw_x( interior, LLColor4::black );
+ }
+
+ mTentativeLabel->setVisible( getTentative() );
+
+ // Show "Loading..." string on the top left corner while this texture is loading.
+ // Using the discard level, do not show the string if the texture is almost but not
+ // fully loaded.
+ if (mTexturep.notNull() &&
+ (!mTexturep->isFullyLoaded()) &&
+ (mShowLoadingPlaceholder == TRUE))
+ {
+ U32 v_offset = 25;
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+
+ // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god
+ if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike())
+ {
+ font->renderUTF8(
+ mLoadingPlaceholderString,
+ 0,
+ llfloor(interior.mLeft+3),
+ llfloor(interior.mTop-v_offset),
+ LLColor4::white,
+ LLFontGL::LEFT,
+ LLFontGL::BASELINE,
+ LLFontGL::DROP_SHADOW);
+ }
+
+ // Optionally show more detailed information.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+ std::string tdesc;
+ // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best).
+
+ v_offset += 12;
+ tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0));
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+ }
+ }
+
+ LLUICtrl::draw();
}
BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg)
{
- BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
- BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
- BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
- gAgent.getID());
-
- PermissionMask item_perm_mask = 0;
- if (copy) item_perm_mask |= PERM_COPY;
- if (mod) item_perm_mask |= PERM_MODIFY;
- if (xfer) item_perm_mask |= PERM_TRANSFER;
-
- PermissionMask filter_perm_mask = mImmediateFilterPermMask;
- if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
- {
- if(mDragCallback)
- {
- return mDragCallback(this, item);
- }
- else
- {
- return TRUE;
- }
- }
- else
- {
+ BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
+ BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID());
+
+ PermissionMask item_perm_mask = 0;
+ if (copy) item_perm_mask |= PERM_COPY;
+ if (mod) item_perm_mask |= PERM_MODIFY;
+ if (xfer) item_perm_mask |= PERM_TRANSFER;
+
+ PermissionMask filter_perm_mask = mImmediateFilterPermMask;
+ if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
+ {
+ if(mDragCallback)
+ {
+ return mDragCallback(this, item);
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
PermissionMask mask = PERM_COPY | PERM_TRANSFER;
if ((filter_perm_mask & mask) == mask
&& cargo_type == DAD_TEXTURE)
{
tooltip_msg.assign(LLTrans::getString("TooltipTextureRestrictedDrop"));
}
- return FALSE;
- }
+ return FALSE;
+ }
}
BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
{
- // call the callback if it exists.
- if(mDropCallback)
- {
- // if it returns TRUE, we return TRUE, and therefore the
- // commit is called above.
- return mDropCallback(this, item);
- }
+ // call the callback if it exists.
+ if(mDropCallback)
+ {
+ // if it returns TRUE, we return TRUE, and therefore the
+ // commit is called above.
+ return mDropCallback(this, item);
+ }
// no callback installed, so just set the image ids and carry on.
LLUUID asset_id = item->getAssetUUID();
@@ -2338,32 +2395,42 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
if (mInventoryPickType == PICK_MATERIAL && asset_id.isNull())
{
// If an inventory material has a null asset, consider it a valid blank material(gltf)
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
- setImageAssetID(asset_id);
- mImageItemID = item->getUUID();
- return TRUE;
+ setImageAssetID(asset_id);
+ mImageItemID = item->getUUID();
+ return TRUE;
}
BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
{
- if( ' ' == uni_char )
- {
- showPicker(TRUE);
- return TRUE;
- }
- return LLUICtrl::handleUnicodeCharHere(uni_char);
+ if( ' ' == uni_char )
+ {
+ showPicker(TRUE);
+ return TRUE;
+ }
+ return LLUICtrl::handleUnicodeCharHere(uni_char);
}
void LLTextureCtrl::setValue( const LLSD& value )
{
- setImageAssetID(value.asUUID());
+ setImageAssetID(value.asUUID());
}
LLSD LLTextureCtrl::getValue() const
{
- return LLSD(getImageAssetID());
+ return LLSD(getImageAssetID());
+}
+
+namespace LLInitParam
+{
+ void TypeValues<EPickInventoryType>::declareValues()
+ {
+ declare("texture_material", PICK_TEXTURE_MATERIAL);
+ declare("texture", PICK_TEXTURE);
+ declare("material", PICK_MATERIAL);
+ }
}
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 9328c2316e..f193b0c083 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file lltexturectrl.h
* @author Richard Nelson, James Cook
* @brief LLTextureCtrl class header file including related functions
@@ -6,21 +6,21 @@
* $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$
*/
@@ -64,13 +64,6 @@ bool get_is_predefined_texture(LLUUID asset_id);
LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false);
bool get_can_copy_texture(LLUUID image_id);
-enum LLPickerSource
-{
- PICKER_INVENTORY,
- PICKER_LOCAL,
- PICKER_BAKE,
- PICKER_UNKNOWN, // on cancel, default ids
-};
typedef enum e_pick_inventory_type
{
@@ -79,6 +72,23 @@ typedef enum e_pick_inventory_type
PICK_MATERIAL = 2,
} EPickInventoryType;
+namespace LLInitParam
+{
+ template<>
+ struct TypeValues<EPickInventoryType> : public TypeValuesHelper<EPickInventoryType>
+ {
+ static void declareValues();
+ };
+}
+
+enum LLPickerSource
+{
+ PICKER_INVENTORY,
+ PICKER_LOCAL,
+ PICKER_BAKE,
+ PICKER_UNKNOWN, // on cancel, default ids
+};
+
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
@@ -87,147 +97,151 @@ class LLTextureCtrl
: public LLUICtrl
{
public:
- typedef enum e_texture_pick_op
- {
- TEXTURE_CHANGE,
- TEXTURE_SELECT,
- TEXTURE_CANCEL
- } ETexturePickOp;
+ typedef enum e_texture_pick_op
+ {
+ TEXTURE_CHANGE,
+ TEXTURE_SELECT,
+ TEXTURE_CANCEL
+ } ETexturePickOp;
public:
- struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
- {
- Optional<LLUUID> image_id;
- Optional<LLUUID> default_image_id;
- Optional<std::string> default_image_name;
- Optional<bool> allow_no_texture;
- Optional<bool> can_apply_immediately;
- Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty
- // only on DnD or when OK is pressed in the picker
- Optional<S32> label_width;
- Optional<LLUIColor> border_color;
- Optional<LLUIImage*> fallback_image;
-
- Optional<LLTextBox::Params> multiselect_text,
- caption_text;
-
- Optional<LLViewBorder::Params> border;
-
- Params()
- : image_id("image"),
- default_image_id("default_image_id"),
- default_image_name("default_image_name"),
- allow_no_texture("allow_no_texture", false),
- can_apply_immediately("can_apply_immediately"),
- no_commit_on_selection("no_commit_on_selection", false),
- label_width("label_width", -1),
- border_color("border_color"),
- fallback_image("fallback_image"),
- multiselect_text("multiselect_text"),
- caption_text("caption_text"),
- border("border")
- {}
- };
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUUID> image_id;
+ Optional<LLUUID> default_image_id;
+ Optional<std::string> default_image_name;
+ Optional<EPickInventoryType> pick_type;
+ Optional<bool> allow_no_texture;
+ Optional<bool> can_apply_immediately;
+ Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty
+ // only on DnD or when OK is pressed in the picker
+ Optional<S32> label_width;
+ Optional<LLUIColor> border_color;
+ Optional<LLUIImage*> fallback_image;
+
+ Optional<LLTextBox::Params> multiselect_text,
+ caption_text;
+
+ Optional<LLViewBorder::Params> border;
+
+ Params()
+ : image_id("image"),
+ default_image_id("default_image_id"),
+ default_image_name("default_image_name"),
+ pick_type("pick_type", PICK_TEXTURE),
+ allow_no_texture("allow_no_texture", false),
+ can_apply_immediately("can_apply_immediately"),
+ no_commit_on_selection("no_commit_on_selection", false),
+ label_width("label_width", -1),
+ border_color("border_color"),
+ fallback_image("fallback_image"),
+ multiselect_text("multiselect_text"),
+ caption_text("caption_text"),
+ border("border")
+ {}
+ };
protected:
- LLTextureCtrl(const Params&);
- friend class LLUICtrlFactory;
+ LLTextureCtrl(const Params&);
+ friend class LLUICtrlFactory;
public:
- virtual ~LLTextureCtrl();
+ virtual ~LLTextureCtrl();
- // LLView interface
+ // LLView interface
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleUnicodeCharHere(llwchar uni_char);
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg) override;
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleUnicodeCharHere(llwchar uni_char) override;
- virtual void draw();
- virtual void setVisible( BOOL visible );
- virtual void setEnabled( BOOL enabled );
+ void draw() override;
+ void setVisible( BOOL visible ) override;
+ void setEnabled( BOOL enabled ) override;
- void setValid(BOOL valid);
+ void onVisibilityChange(BOOL new_visibility) override;
+
+ void setValid(BOOL valid);
// LLUICtrl interface
- virtual void clear();
+ void clear() override;
// Takes a UUID, wraps get/setImageAssetID
- virtual void setValue(const LLSD& value);
- virtual LLSD getValue() const;
-
- // LLTextureCtrl interface
- void showPicker(BOOL take_focus);
- bool isPickerShown() { return !mFloaterHandle.isDead(); }
- void setLabel(const std::string& label);
- void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
- const std::string& getLabel() const { return mLabel; }
+ void setValue(const LLSD& value) override;
+ LLSD getValue() const override;
- void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; }
- bool getAllowNoTexture() const { return mAllowNoTexture; }
+ // LLTextureCtrl interface
+ void showPicker(BOOL take_focus);
+ bool isPickerShown() { return !mFloaterHandle.isDead(); }
+ void setLabel(const std::string& label);
+ void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
+ const std::string& getLabel() const { return mLabel; }
- void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; }
- BOOL getAllowLocalTexture() const { return mAllowLocalTexture; }
+ void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; }
+ bool getAllowNoTexture() const { return mAllowNoTexture; }
- const LLUUID& getImageItemID() { return mImageItemID; }
+ void setAllowLocalTexture(BOOL b) { mAllowLocalTexture = b; }
+ BOOL getAllowLocalTexture() const { return mAllowLocalTexture; }
- virtual void setImageAssetName(const std::string& name);
+ const LLUUID& getImageItemID() { return mImageItemID; }
- void setImageAssetID(const LLUUID &image_asset_id);
- const LLUUID& getImageAssetID() const { return mImageAssetID; }
+ virtual void setImageAssetName(const std::string& name);
+
+ void setImageAssetID(const LLUUID &image_asset_id);
+ const LLUUID& getImageAssetID() const { return mImageAssetID; }
- void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; }
- const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; }
+ void setDefaultImageAssetID( const LLUUID& id ) { mDefaultImageAssetID = id; }
+ const LLUUID& getDefaultImageAssetID() const { return mDefaultImageAssetID; }
- const std::string& getDefaultImageName() const { return mDefaultImageName; }
+ const std::string& getDefaultImageName() const { return mDefaultImageName; }
- void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
- const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+ void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
+ const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
- void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
+ void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
- void setCaption(const std::string& caption);
- void setCanApplyImmediately(BOOL b);
+ void setCaption(const std::string& caption);
+ void setCanApplyImmediately(BOOL b);
- void setCanApply(bool can_preview, bool can_apply);
+ void setCanApply(bool can_preview, bool can_apply);
- void setImmediateFilterPermMask(PermissionMask mask);
- void setDnDFilterPermMask(PermissionMask mask)
- { mDnDFilterPermMask = mask; }
- PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
+ void setImmediateFilterPermMask(PermissionMask mask);
+ void setDnDFilterPermMask(PermissionMask mask)
+ { mDnDFilterPermMask = mask; }
+ PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
void setFilterPermissionMasks(PermissionMask mask);
- void closeDependentFloater();
+ void closeDependentFloater();
- void onFloaterClose();
- void onFloaterCommit(ETexturePickOp op,
+ void onFloaterClose();
+ void onFloaterCommit(ETexturePickOp op,
LLPickerSource source,
const LLUUID& local_id,
const LLUUID& inv_id,
const LLUUID& tracking_id);
- // This call is returned when a drag is detected. Your callback
- // should return TRUE if the drag is acceptable.
- void setDragCallback(drag_n_drop_callback cb) { mDragCallback = cb; }
+ // This call is returned when a drag is detected. Your callback
+ // should return TRUE if the drag is acceptable.
+ void setDragCallback(drag_n_drop_callback cb) { mDragCallback = cb; }
- // This callback is called when the drop happens. Return TRUE if
- // the drop happened - resulting in an on commit callback, but not
- // necessariliy any other change.
- void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
+ // This callback is called when the drop happens. Return TRUE if
+ // the drop happened - resulting in an on commit callback, but not
+ // necessariliy any other change.
+ void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
+
+ void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
+ void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; }
+ void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
- void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
- void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; }
- void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
+ /*
+ * callback for changing texture selection in inventory list of texture floater
+ */
+ void setOnTextureSelectedCallback(texture_selected_callback cb);
- /*
- * callback for changing texture selection in inventory list of texture floater
- */
- void setOnTextureSelectedCallback(texture_selected_callback cb);
+ void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
- void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
-
- LLViewerFetchedTexture* getTexture() { return mTexturep; }
+ LLViewerFetchedTexture* getTexture() { return mTexturep; }
void setBakeTextureEnabled(bool enabled);
bool getBakeTextureEnabled() const { return mBakeTextureEnabled; }
@@ -239,43 +253,45 @@ public:
LLUUID getLocalTrackingID() { return mLocalTrackingID; }
private:
- BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);
- BOOL doDrop(LLInventoryItem* item);
+ BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);
+ BOOL doDrop(LLInventoryItem* item);
private:
- drag_n_drop_callback mDragCallback;
- drag_n_drop_callback mDropCallback;
- commit_callback_t mOnCancelCallback;
- commit_callback_t mOnSelectCallback;
- commit_callback_t mOnCloseCallback;
- texture_selected_callback mOnTextureSelectedCallback;
- LLPointer<LLViewerFetchedTexture> mTexturep;
- LLUIColor mBorderColor;
- LLUUID mImageItemID;
- LLUUID mImageAssetID;
- LLUUID mDefaultImageAssetID;
- LLUUID mBlankImageAssetID;
- LLUUID mLocalTrackingID;
- LLUIImagePtr mFallbackImage;
- std::string mDefaultImageName;
- LLHandle<LLFloater> mFloaterHandle;
- LLTextBox* mTentativeLabel;
- LLTextBox* mCaption;
- std::string mLabel;
- BOOL mAllowNoTexture; // If true, the user can select "none" as an option
- BOOL mAllowLocalTexture;
- PermissionMask mImmediateFilterPermMask;
- PermissionMask mDnDFilterPermMask;
- BOOL mCanApplyImmediately;
- BOOL mCommitOnSelection;
- BOOL mNeedsRawImageData;
- LLViewBorder* mBorder;
- BOOL mValid;
- BOOL mShowLoadingPlaceholder;
- std::string mLoadingPlaceholderString;
- S32 mLabelWidth;
- bool mOpenTexPreview;
- bool mBakeTextureEnabled;
+ drag_n_drop_callback mDragCallback;
+ drag_n_drop_callback mDropCallback;
+ commit_callback_t mOnCancelCallback;
+ commit_callback_t mOnSelectCallback;
+ commit_callback_t mOnCloseCallback;
+ texture_selected_callback mOnTextureSelectedCallback;
+ LLPointer<LLViewerFetchedTexture> mTexturep;
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+ LLPointer<LLViewerTexture> mGLTFPreview;
+ LLUIColor mBorderColor;
+ LLUUID mImageItemID;
+ LLUUID mImageAssetID;
+ LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
+ LLUUID mLocalTrackingID;
+ LLUIImagePtr mFallbackImage;
+ std::string mDefaultImageName;
+ LLHandle<LLFloater> mFloaterHandle;
+ LLTextBox* mTentativeLabel;
+ LLTextBox* mCaption;
+ std::string mLabel;
+ BOOL mAllowNoTexture; // If true, the user can select "none" as an option
+ BOOL mAllowLocalTexture;
+ PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
+ BOOL mCanApplyImmediately;
+ BOOL mCommitOnSelection;
+ BOOL mNeedsRawImageData;
+ LLViewBorder* mBorder;
+ BOOL mValid;
+ BOOL mShowLoadingPlaceholder;
+ std::string mLoadingPlaceholderString;
+ S32 mLabelWidth;
+ bool mOpenTexPreview;
+ bool mBakeTextureEnabled;
EPickInventoryType mInventoryPickType;
};
@@ -289,90 +305,90 @@ typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_
class LLFloaterTexturePicker : public LLFloater
{
public:
- LLFloaterTexturePicker(
- LLView* owner,
- LLUUID image_asset_id,
- LLUUID default_image_asset_id,
- LLUUID blank_image_asset_id,
- BOOL tentative,
- BOOL allow_no_texture,
- const std::string& label,
- PermissionMask immediate_filter_perm_mask,
- PermissionMask dnd_filter_perm_mask,
- BOOL can_apply_immediately,
- LLUIImagePtr fallback_image_name,
- EPickInventoryType pick_type);
-
- virtual ~LLFloaterTexturePicker();
-
- // LLView overrides
- /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg);
- /*virtual*/ void draw();
- /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
-
- // LLFloater overrides
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_settings);
-
- // New functions
- void setImageID(const LLUUID& image_asset_id, bool set_selection = true);
- bool updateImageStats(); // true if within limits
- const LLUUID& getAssetID() { return mImageAssetID; }
- const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library = FALSE);
- void setCanApplyImmediately(BOOL b);
-
- void setActive(BOOL active);
-
- LLView* getOwner() const { return mOwner; }
- void setOwner(LLView* owner) { mOwner = owner; }
- void stopUsingPipette();
-
- void commitIfImmediateSet();
+ LLFloaterTexturePicker(
+ LLView* owner,
+ LLUUID image_asset_id,
+ LLUUID default_image_asset_id,
+ LLUUID blank_image_asset_id,
+ BOOL tentative,
+ BOOL allow_no_texture,
+ const std::string& label,
+ PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image_name,
+ EPickInventoryType pick_type);
+
+ virtual ~LLFloaterTexturePicker();
+
+ // LLView overrides
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg);
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+
+ // LLFloater overrides
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_settings);
+
+ // New functions
+ void setImageID(const LLUUID& image_asset_id, bool set_selection = true);
+ bool updateImageStats(); // true if within limits
+ const LLUUID& getAssetID() { return mImageAssetID; }
+ const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library = FALSE);
+ void setCanApplyImmediately(BOOL b);
+
+ void setActive(BOOL active);
+
+ LLView* getOwner() const { return mOwner; }
+ void setOwner(LLView* owner) { mOwner = owner; }
+ void stopUsingPipette();
+
+ void commitIfImmediateSet();
void commitCallback(LLTextureCtrl::ETexturePickOp op);
- void commitCancel();
+ void commitCancel();
- void onFilterEdit(const std::string& search_string);
+ void onFilterEdit(const std::string& search_string);
- void setCanApply(bool can_preview, bool can_apply, bool inworld_image = true);
+ void setCanApply(bool can_preview, bool can_apply, bool inworld_image = true);
void setMinDimentionsLimits(S32 min_dim);
- void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }
- void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
- void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
- void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
- void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; }
- const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
- const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
-
- static void onBtnSetToDefault(void* userdata);
- static void onBtnSelect(void* userdata);
- static void onBtnCancel(void* userdata);
- void onBtnPipette();
- //static void onBtnRevert( void* userdata );
- static void onBtnBlank(void* userdata);
- static void onBtnNone(void* userdata);
- void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
- void onTextureSelect(const LLTextureEntry& te);
-
- static void onModeSelect(LLUICtrl* ctrl, void *userdata);
- static void onBtnAdd(void* userdata);
- static void onBtnRemove(void* userdata);
- static void onBtnUpload(void* userdata);
- static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
-
- static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata);
-
- void setLocalTextureEnabled(BOOL enabled);
- void setBakeTextureEnabled(BOOL enabled);
+ void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }
+ void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
+ void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
+ void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
+ void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; }
+ const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
+ const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
+
+ static void onBtnSetToDefault(void* userdata);
+ static void onBtnSelect(void* userdata);
+ static void onBtnCancel(void* userdata);
+ void onBtnPipette();
+ //static void onBtnRevert( void* userdata );
+ static void onBtnBlank(void* userdata);
+ static void onBtnNone(void* userdata);
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+ static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
+ void onTextureSelect(const LLTextureEntry& te);
+
+ static void onModeSelect(LLUICtrl* ctrl, void *userdata);
+ static void onBtnAdd(void* userdata);
+ static void onBtnRemove(void* userdata);
+ static void onBtnUpload(void* userdata);
+ static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
+
+ static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata);
+
+ void setLocalTextureEnabled(BOOL enabled);
+ void setBakeTextureEnabled(BOOL enabled);
void setInventoryPickType(EPickInventoryType type);
void setImmediateFilterPermMask(PermissionMask mask);
- static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
+ static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
protected:
void changeMode();
@@ -380,40 +396,41 @@ protected:
void refreshInventoryFilter();
void setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection = true);
- LLPointer<LLViewerTexture> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
- LLView* mOwner;
-
- LLUUID mImageAssetID; // Currently selected texture
- LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
- LLUUID mDefaultImageAssetID;
- LLUUID mBlankImageAssetID;
- BOOL mTentative;
- BOOL mAllowNoTexture;
- LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
- LLUUID mOriginalImageAssetID;
-
- std::string mLabel;
-
- LLTextBox* mTentativeLabel;
- LLTextBox* mResolutionLabel;
+ LLPointer<LLViewerTexture> mGLTFPreview;
+ LLView* mOwner;
+
+ LLUUID mImageAssetID; // Currently selected texture
+ LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
+ LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
+ BOOL mTentative;
+ BOOL mAllowNoTexture;
+ LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
+ LLUUID mOriginalImageAssetID;
+
+ std::string mLabel;
+
+ LLTextBox* mTentativeLabel;
+ LLTextBox* mResolutionLabel;
LLTextBox* mResolutionWarning;
- std::string mPendingName;
- BOOL mActive;
-
- LLFilterEditor* mFilterEdit;
- LLInventoryPanel* mInventoryPanel;
- PermissionMask mImmediateFilterPermMask;
- PermissionMask mDnDFilterPermMask;
- BOOL mCanApplyImmediately;
- BOOL mNoCopyTextureSelected;
- F32 mContextConeOpacity;
- LLSaveFolderState mSavedFolderState;
- BOOL mSelectedItemPinned;
-
- LLComboBox* mModeSelector;
- LLScrollListCtrl* mLocalScrollCtrl;
+ std::string mPendingName;
+ BOOL mActive;
+
+ LLFilterEditor* mFilterEdit;
+ LLInventoryPanel* mInventoryPanel;
+ PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
+ BOOL mCanApplyImmediately;
+ BOOL mNoCopyTextureSelected;
+ F32 mContextConeOpacity;
+ LLSaveFolderState mSavedFolderState;
+ BOOL mSelectedItemPinned;
+
+ LLComboBox* mModeSelector;
+ LLScrollListCtrl* mLocalScrollCtrl;
LLButton* mDefaultBtn;
LLButton* mNoneBtn;
LLButton* mBlankBtn;
@@ -422,22 +439,22 @@ protected:
LLButton* mCancelBtn;
private:
- bool mCanApply;
- bool mCanPreview;
- bool mPreviewSettingChanged;
+ bool mCanApply;
+ bool mCanPreview;
+ bool mPreviewSettingChanged;
bool mLimitsSet;
S32 mMaxDim;
S32 mMinDim;
EPickInventoryType mInventoryPickType;
- texture_selected_callback mTextureSelectedCallback;
- floater_close_callback mOnFloaterCloseCallback;
- floater_commit_callback mOnFloaterCommitCallback;
- set_image_asset_id_callback mSetImageAssetIDCallback;
- set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
+ texture_selected_callback mTextureSelectedCallback;
+ floater_close_callback mOnFloaterCloseCallback;
+ floater_commit_callback mOnFloaterCommitCallback;
+ set_image_asset_id_callback mSetImageAssetIDCallback;
+ set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
- BOOL mBakeTextureEnabled;
+ BOOL mBakeTextureEnabled;
static S32 sLastPickerMode;
};
diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp
index cd1b071574..4e41f9959a 100644
--- a/indra/newview/lltinygltfhelper.cpp
+++ b/indra/newview/lltinygltfhelper.cpp
@@ -87,20 +87,30 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
{
strip_alpha_channel(mr_img);
- if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
+ if (occlusion_img)
{
- // occlusion is a distinct texture from pbrMetallicRoughness
- // pack into mr red channel
- int occlusion_idx = material.occlusionTexture.index;
- int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
- if (occlusion_idx != mr_idx)
+ if (material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
{
- //scale occlusion image to match resolution of mr image
- occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
-
- copy_red_channel(occlusion_img, mr_img);
+ // occlusion is a distinct texture from pbrMetallicRoughness
+ // pack into mr red channel
+ int occlusion_idx = material.occlusionTexture.index;
+ int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (occlusion_idx != mr_idx)
+ {
+ //scale occlusion image to match resolution of mr image
+ occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
+
+ copy_red_channel(occlusion_img, mr_img);
+ }
}
}
+ else if (material.occlusionTexture.index == -1)
+ {
+ // no occlusion, make sure red channel of ORM is all 255
+ occlusion_img = new LLImageRaw(mr_img->getWidth(), mr_img->getHeight(), 3);
+ occlusion_img->clear(255, 255, 255);
+ copy_red_channel(occlusion_img, mr_img);
+ }
}
else if (occlusion_img)
{
@@ -147,7 +157,7 @@ const tinygltf::Image * LLTinyGLTFHelper::getImageFromTextureIndex(const tinyglt
return nullptr;
}
-LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, std::string & name)
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, std::string & name, bool flip)
{
const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
LLImageRaw* rawImage = nullptr;
@@ -159,14 +169,17 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny
{
name = image->name;
rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
- rawImage->verticalFlip();
+ if (flip)
+ {
+ rawImage->verticalFlip();
+ }
rawImage->optimizeAwayAlpha();
}
return rawImage;
}
-LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index)
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, bool flip)
{
const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
LLImageRaw* rawImage = nullptr;
@@ -177,7 +190,10 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny
image->component <= 4)
{
rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
- rawImage->verticalFlip();
+ if (flip)
+ {
+ rawImage->verticalFlip();
+ }
rawImage->optimizeAwayAlpha();
}
@@ -187,7 +203,7 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny
bool LLTinyGLTFHelper::loadModel(const std::string& filename, tinygltf::Model& model_in)
{
std::string exten = gDirUtilp->getExtension(filename);
-
+
if (exten == "gltf" || exten == "glb")
{
tinygltf::TinyGLTF loader;
@@ -224,7 +240,7 @@ bool LLTinyGLTFHelper::loadModel(const std::string& filename, tinygltf::Model& m
LL_WARNS("GLTF") << "Cannot load. File has no materials " << filename << LL_ENDL;
return false;
}
-
+
return true;
}
@@ -237,7 +253,8 @@ bool LLTinyGLTFHelper::getMaterialFromModel(
const tinygltf::Model& model_in,
S32 mat_index,
LLFetchedGLTFMaterial* material,
- std::string& material_name)
+ std::string& material_name,
+ bool flip)
{
llassert(material);
@@ -256,18 +273,18 @@ bool LLTinyGLTFHelper::getMaterialFromModel(
material_name = material_in.name;
// get base color texture
- LLPointer<LLImageRaw> base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index);
+ LLPointer<LLImageRaw> base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, flip);
// get normal map
- LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index);
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, flip);
// get metallic-roughness texture
- LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index);
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, flip);
// get emissive texture
- LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index);
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, flip);
// get occlusion map if needed
LLPointer<LLImageRaw> occlusion_img;
if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
{
- occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index);
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, flip);
}
LLPointer<LLViewerFetchedTexture> base_color_tex;
diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h
index 256f6c854f..da505b41e9 100644
--- a/indra/newview/lltinygltfhelper.h
+++ b/indra/newview/lltinygltfhelper.h
@@ -38,10 +38,8 @@ namespace LLTinyGLTFHelper
{
LLColor4 getColor(const std::vector<double>& in);
const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index);
- LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name);
- LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
-
- LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name, bool flip = true);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, bool flip = true);
bool loadModel(const std::string& filename, tinygltf::Model& model_out);
@@ -50,7 +48,8 @@ namespace LLTinyGLTFHelper
const tinygltf::Model& model,
S32 mat_index,
LLFetchedGLTFMaterial* material,
- std::string& material_name);
+ std::string& material_name,
+ bool flip = true);
void initFetchedTextures(tinygltf::Material& material,
LLPointer<LLImageRaw>& base_color_img,
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 7e70c25d5e..293c47bf73 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lltooldraganddrop.cpp
* @brief LLToolDragAndDrop 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$
*/
@@ -69,887 +69,887 @@
class LLNoPreferredType : public LLInventoryCollectFunctor
{
public:
- LLNoPreferredType() {}
- virtual ~LLNoPreferredType() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
- {
- if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE))
- {
- return true;
- }
- return false;
- }
+ LLNoPreferredType() {}
+ virtual ~LLNoPreferredType() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item)
+ {
+ if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE))
+ {
+ return true;
+ }
+ return false;
+ }
};
class LLNoPreferredTypeOrItem : public LLInventoryCollectFunctor
{
public:
- LLNoPreferredTypeOrItem() {}
- virtual ~LLNoPreferredTypeOrItem() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
- {
- if (item) return true;
- if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE))
- {
- return true;
- }
- return false;
- }
+ LLNoPreferredTypeOrItem() {}
+ virtual ~LLNoPreferredTypeOrItem() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item)
+ {
+ if (item) return true;
+ if (cat && (cat->getPreferredType() == LLFolderType::FT_NONE))
+ {
+ return true;
+ }
+ return false;
+ }
};
class LLDroppableItem : public LLInventoryCollectFunctor
{
public:
- LLDroppableItem(BOOL is_transfer) :
- mCountLosing(0), mIsTransfer(is_transfer) {}
- virtual ~LLDroppableItem() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item);
- S32 countNoCopy() const { return mCountLosing; }
+ LLDroppableItem(BOOL is_transfer) :
+ mCountLosing(0), mIsTransfer(is_transfer) {}
+ virtual ~LLDroppableItem() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+ S32 countNoCopy() const { return mCountLosing; }
protected:
- S32 mCountLosing;
- BOOL mIsTransfer;
+ S32 mCountLosing;
+ BOOL mIsTransfer;
};
bool LLDroppableItem::operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
-{
- bool allowed = false;
- if (item)
- {
- allowed = itemTransferCommonlyAllowed(item);
-
- if (allowed
- && mIsTransfer
- && !item->getPermissions().allowOperationBy(PERM_TRANSFER,
- gAgent.getID()))
- {
- allowed = false;
- }
- if (allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- ++mCountLosing;
- }
- }
- return allowed;
+ LLInventoryItem* item)
+{
+ bool allowed = false;
+ if (item)
+ {
+ allowed = itemTransferCommonlyAllowed(item);
+
+ if (allowed
+ && mIsTransfer
+ && !item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID()))
+ {
+ allowed = false;
+ }
+ if (allowed && !item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ ++mCountLosing;
+ }
+ }
+ return allowed;
}
class LLDropCopyableItems : public LLInventoryCollectFunctor
{
public:
- LLDropCopyableItems() {}
- virtual ~LLDropCopyableItems() {}
- virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
+ LLDropCopyableItems() {}
+ virtual ~LLDropCopyableItems() {}
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
};
bool LLDropCopyableItems::operator()(
- LLInventoryCategory* cat,
- LLInventoryItem* item)
-{
- bool allowed = false;
- if (item)
- {
- allowed = itemTransferCommonlyAllowed(item);
- if (allowed &&
- !item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- // whoops, can't copy it - don't allow it.
- allowed = false;
- }
- }
- return allowed;
-}
-
-// Starts a fetch on folders and items. This is really not used
+ LLInventoryCategory* cat,
+ LLInventoryItem* item)
+{
+ bool allowed = false;
+ if (item)
+ {
+ allowed = itemTransferCommonlyAllowed(item);
+ if (allowed &&
+ !item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ // whoops, can't copy it - don't allow it.
+ allowed = false;
+ }
+ }
+ return allowed;
+}
+
+// Starts a fetch on folders and items. This is really not used
// as an observer in the traditional sense; we're just using it to
// request a fetch and we don't care about when/if the response arrives.
class LLCategoryFireAndForget : public LLInventoryFetchComboObserver
{
public:
- LLCategoryFireAndForget(const uuid_vec_t& folder_ids,
- const uuid_vec_t& item_ids) :
- LLInventoryFetchComboObserver(folder_ids, item_ids)
- {}
- ~LLCategoryFireAndForget() {}
- virtual void done()
- {
- /* no-op: it's fire n forget right? */
- LL_DEBUGS() << "LLCategoryFireAndForget::done()" << LL_ENDL;
- }
+ LLCategoryFireAndForget(const uuid_vec_t& folder_ids,
+ const uuid_vec_t& item_ids) :
+ LLInventoryFetchComboObserver(folder_ids, item_ids)
+ {}
+ ~LLCategoryFireAndForget() {}
+ virtual void done()
+ {
+ /* no-op: it's fire n forget right? */
+ LL_DEBUGS() << "LLCategoryFireAndForget::done()" << LL_ENDL;
+ }
};
class LLCategoryDropObserver : public LLInventoryFetchItemsObserver
{
public:
- LLCategoryDropObserver(
- const uuid_vec_t& ids,
- const LLUUID& obj_id, LLToolDragAndDrop::ESource src) :
- LLInventoryFetchItemsObserver(ids),
- mObjectID(obj_id),
- mSource(src)
- {}
- ~LLCategoryDropObserver() {}
- virtual void done();
+ LLCategoryDropObserver(
+ const uuid_vec_t& ids,
+ const LLUUID& obj_id, LLToolDragAndDrop::ESource src) :
+ LLInventoryFetchItemsObserver(ids),
+ mObjectID(obj_id),
+ mSource(src)
+ {}
+ ~LLCategoryDropObserver() {}
+ virtual void done();
protected:
- LLUUID mObjectID;
- LLToolDragAndDrop::ESource mSource;
+ LLUUID mObjectID;
+ LLToolDragAndDrop::ESource mSource;
};
void LLCategoryDropObserver::done()
{
- gInventory.removeObserver(this);
- LLViewerObject* dst_obj = gObjectList.findObject(mObjectID);
- if (dst_obj)
- {
- // *FIX: coalesce these...
- LLInventoryItem* item = NULL;
- uuid_vec_t::iterator it = mComplete.begin();
- uuid_vec_t::iterator end = mComplete.end();
- for(; it < end; ++it)
- {
- item = gInventory.getItem(*it);
- if (item)
- {
- LLToolDragAndDrop::dropInventory(
- dst_obj,
- item,
- mSource,
- LLUUID::null);
- }
- }
- }
- delete this;
+ gInventory.removeObserver(this);
+ LLViewerObject* dst_obj = gObjectList.findObject(mObjectID);
+ if (dst_obj)
+ {
+ // *FIX: coalesce these...
+ LLInventoryItem* item = NULL;
+ uuid_vec_t::iterator it = mComplete.begin();
+ uuid_vec_t::iterator end = mComplete.end();
+ for(; it < end; ++it)
+ {
+ item = gInventory.getItem(*it);
+ if (item)
+ {
+ LLToolDragAndDrop::dropInventory(
+ dst_obj,
+ item,
+ mSource,
+ LLUUID::null);
+ }
+ }
+ }
+ delete this;
}
S32 LLToolDragAndDrop::sOperationId = 0;
LLToolDragAndDrop::DragAndDropEntry::DragAndDropEntry(dragOrDrop3dImpl f_none,
- dragOrDrop3dImpl f_self,
- dragOrDrop3dImpl f_avatar,
- dragOrDrop3dImpl f_object,
- dragOrDrop3dImpl f_land) :
- LLDictionaryEntry("")
+ dragOrDrop3dImpl f_self,
+ dragOrDrop3dImpl f_avatar,
+ dragOrDrop3dImpl f_object,
+ dragOrDrop3dImpl f_land) :
+ LLDictionaryEntry("")
{
- mFunctions[DT_NONE] = f_none;
- mFunctions[DT_SELF] = f_self;
- mFunctions[DT_AVATAR] = f_avatar;
- mFunctions[DT_OBJECT] = f_object;
- mFunctions[DT_LAND] = f_land;
+ mFunctions[DT_NONE] = f_none;
+ mFunctions[DT_SELF] = f_self;
+ mFunctions[DT_AVATAR] = f_avatar;
+ mFunctions[DT_OBJECT] = f_object;
+ mFunctions[DT_LAND] = f_land;
}
LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::LLDragAndDropDictionary::get(EDragAndDropType dad_type, LLToolDragAndDrop::EDropTarget drop_target)
{
- const DragAndDropEntry *entry = lookup(dad_type);
- if (entry)
- {
- return (entry->mFunctions[(U8)drop_target]);
- }
- return &LLToolDragAndDrop::dad3dNULL;
+ const DragAndDropEntry *entry = lookup(dad_type);
+ if (entry)
+ {
+ return (entry->mFunctions[(U8)drop_target]);
+ }
+ return &LLToolDragAndDrop::dad3dNULL;
}
LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
{
- // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND
- // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
- addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
+ // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND
+ // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
+ addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand));
- addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- 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));
+ addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand));
+ addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ 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));
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?
+ // TODO: gesture on self could play it? edit it?
};
LLToolDragAndDrop::LLToolDragAndDrop()
-: LLTool(std::string("draganddrop"), NULL),
- mCargoCount(0),
- mDragStartX(0),
- mDragStartY(0),
- mSource(SOURCE_AGENT),
- mCursor(UI_CURSOR_NO),
- mLastAccept(ACCEPT_NO),
- mDrop(FALSE),
- mCurItemIndex(0)
+: LLTool(std::string("draganddrop"), NULL),
+ mCargoCount(0),
+ mDragStartX(0),
+ mDragStartY(0),
+ mSource(SOURCE_AGENT),
+ mCursor(UI_CURSOR_NO),
+ mLastAccept(ACCEPT_NO),
+ mDrop(FALSE),
+ mCurItemIndex(0)
{
}
void LLToolDragAndDrop::setDragStart(S32 x, S32 y)
{
- mDragStartX = x;
- mDragStartY = y;
+ mDragStartX = x;
+ mDragStartY = y;
}
BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y)
{
- static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3);
-
- S32 mouse_delta_x = x - mDragStartX;
- S32 mouse_delta_y = y - mDragStartY;
-
- return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold;
+ static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3);
+
+ S32 mouse_delta_x = x - mDragStartX;
+ S32 mouse_delta_y = y - mDragStartY;
+
+ return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold;
}
void LLToolDragAndDrop::beginDrag(EDragAndDropType type,
- const LLUUID& cargo_id,
- ESource source,
- const LLUUID& source_id,
- const LLUUID& object_id)
-{
- if (type == DAD_NONE)
- {
- LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL;
- return;
- }
- mCargoTypes.clear();
- mCargoTypes.push_back(type);
- mCargoIDs.clear();
- mCargoIDs.push_back(cargo_id);
- mSource = source;
- mSourceID = source_id;
- mObjectID = object_id;
-
- setMouseCapture( TRUE );
- LLToolMgr::getInstance()->setTransientTool( this );
- mCursor = UI_CURSOR_NO;
- if ((mCargoTypes[0] == DAD_CATEGORY)
- && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)))
- {
- LLInventoryCategory* cat = gInventory.getCategory(cargo_id);
- // go ahead and fire & forget the descendents if we are not
- // dragging a protected folder.
- if (cat)
- {
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLNoPreferredTypeOrItem is_not_preferred;
- uuid_vec_t folder_ids;
- uuid_vec_t item_ids;
- if (is_not_preferred(cat, NULL))
- {
- folder_ids.push_back(cargo_id);
- }
- gInventory.collectDescendentsIf(
- cargo_id,
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_not_preferred);
- S32 count = cats.size();
- S32 i;
- for(i = 0; i < count; ++i)
- {
- folder_ids.push_back(cats.at(i)->getUUID());
- }
- count = items.size();
- for(i = 0; i < count; ++i)
- {
- item_ids.push_back(items.at(i)->getUUID());
- }
- if (!folder_ids.empty() || !item_ids.empty())
- {
- LLCategoryFireAndForget *fetcher = new LLCategoryFireAndForget(folder_ids, item_ids);
- fetcher->startFetch();
- delete fetcher;
- }
- }
- }
+ const LLUUID& cargo_id,
+ ESource source,
+ const LLUUID& source_id,
+ const LLUUID& object_id)
+{
+ if (type == DAD_NONE)
+ {
+ LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL;
+ return;
+ }
+ mCargoTypes.clear();
+ mCargoTypes.push_back(type);
+ mCargoIDs.clear();
+ mCargoIDs.push_back(cargo_id);
+ mSource = source;
+ mSourceID = source_id;
+ mObjectID = object_id;
+
+ setMouseCapture( TRUE );
+ LLToolMgr::getInstance()->setTransientTool( this );
+ mCursor = UI_CURSOR_NO;
+ if ((mCargoTypes[0] == DAD_CATEGORY)
+ && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)))
+ {
+ LLInventoryCategory* cat = gInventory.getCategory(cargo_id);
+ // go ahead and fire & forget the descendents if we are not
+ // dragging a protected folder.
+ if (cat)
+ {
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLNoPreferredTypeOrItem is_not_preferred;
+ uuid_vec_t folder_ids;
+ uuid_vec_t item_ids;
+ if (is_not_preferred(cat, NULL))
+ {
+ folder_ids.push_back(cargo_id);
+ }
+ gInventory.collectDescendentsIf(
+ cargo_id,
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_not_preferred);
+ S32 count = cats.size();
+ S32 i;
+ for(i = 0; i < count; ++i)
+ {
+ folder_ids.push_back(cats.at(i)->getUUID());
+ }
+ count = items.size();
+ for(i = 0; i < count; ++i)
+ {
+ item_ids.push_back(items.at(i)->getUUID());
+ }
+ if (!folder_ids.empty() || !item_ids.empty())
+ {
+ LLCategoryFireAndForget *fetcher = new LLCategoryFireAndForget(folder_ids, item_ids);
+ fetcher->startFetch();
+ delete fetcher;
+ }
+ }
+ }
}
void LLToolDragAndDrop::beginMultiDrag(
- const std::vector<EDragAndDropType> types,
- const uuid_vec_t& cargo_ids,
- ESource source,
- const LLUUID& source_id)
-{
- // assert on public api is evil
- //llassert( type != DAD_NONE );
-
- std::vector<EDragAndDropType>::const_iterator types_it;
- for (types_it = types.begin(); types_it != types.end(); ++types_it)
- {
- if (DAD_NONE == *types_it)
- {
- LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL;
- return;
- }
- }
- mCargoTypes = types;
- mCargoIDs = cargo_ids;
- mSource = source;
- mSourceID = source_id;
-
- setMouseCapture( TRUE );
- LLToolMgr::getInstance()->setTransientTool( this );
- mCursor = UI_CURSOR_NO;
- if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
- {
- // find categories (i.e. inventory folders) in the cargo.
- LLInventoryCategory* cat = NULL;
- S32 count = llmin(cargo_ids.size(), types.size());
- std::set<LLUUID> cat_ids;
- for(S32 i = 0; i < count; ++i)
- {
- cat = gInventory.getCategory(cargo_ids[i]);
- if (cat)
- {
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLNoPreferredType is_not_preferred;
- if (is_not_preferred(cat, NULL))
- {
- cat_ids.insert(cat->getUUID());
- }
- gInventory.collectDescendentsIf(
- cat->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_not_preferred);
- S32 cat_count = cats.size();
- for(S32 i = 0; i < cat_count; ++i)
- {
- cat_ids.insert(cat->getUUID());
- }
- }
- }
- if (!cat_ids.empty())
- {
- uuid_vec_t folder_ids;
- uuid_vec_t item_ids;
- std::back_insert_iterator<uuid_vec_t> copier(folder_ids);
- std::copy(cat_ids.begin(), cat_ids.end(), copier);
- LLCategoryFireAndForget fetcher(folder_ids, item_ids);
- }
- }
+ const std::vector<EDragAndDropType> types,
+ const uuid_vec_t& cargo_ids,
+ ESource source,
+ const LLUUID& source_id)
+{
+ // assert on public api is evil
+ //llassert( type != DAD_NONE );
+
+ std::vector<EDragAndDropType>::const_iterator types_it;
+ for (types_it = types.begin(); types_it != types.end(); ++types_it)
+ {
+ if (DAD_NONE == *types_it)
+ {
+ LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL;
+ return;
+ }
+ }
+ mCargoTypes = types;
+ mCargoIDs = cargo_ids;
+ mSource = source;
+ mSourceID = source_id;
+
+ setMouseCapture( TRUE );
+ LLToolMgr::getInstance()->setTransientTool( this );
+ mCursor = UI_CURSOR_NO;
+ if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
+ {
+ // find categories (i.e. inventory folders) in the cargo.
+ LLInventoryCategory* cat = NULL;
+ S32 count = llmin(cargo_ids.size(), types.size());
+ std::set<LLUUID> cat_ids;
+ for(S32 i = 0; i < count; ++i)
+ {
+ cat = gInventory.getCategory(cargo_ids[i]);
+ if (cat)
+ {
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLNoPreferredType is_not_preferred;
+ if (is_not_preferred(cat, NULL))
+ {
+ cat_ids.insert(cat->getUUID());
+ }
+ gInventory.collectDescendentsIf(
+ cat->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_not_preferred);
+ S32 cat_count = cats.size();
+ for(S32 i = 0; i < cat_count; ++i)
+ {
+ cat_ids.insert(cat->getUUID());
+ }
+ }
+ }
+ if (!cat_ids.empty())
+ {
+ uuid_vec_t folder_ids;
+ uuid_vec_t item_ids;
+ std::back_insert_iterator<uuid_vec_t> copier(folder_ids);
+ std::copy(cat_ids.begin(), cat_ids.end(), copier);
+ LLCategoryFireAndForget fetcher(folder_ids, item_ids);
+ }
+ }
}
void LLToolDragAndDrop::endDrag()
{
- mEndDragSignal();
- LLSelectMgr::getInstance()->unhighlightAll();
- setMouseCapture(FALSE);
+ mEndDragSignal();
+ LLSelectMgr::getInstance()->unhighlightAll();
+ setMouseCapture(FALSE);
}
void LLToolDragAndDrop::onMouseCaptureLost()
{
- // Called whenever the drag ends or if mouse capture is simply lost
- LLToolMgr::getInstance()->clearTransientTool();
- mCargoTypes.clear();
- mCargoIDs.clear();
- mSource = SOURCE_AGENT;
- mSourceID.setNull();
- mObjectID.setNull();
- mCustomMsg.clear();
+ // Called whenever the drag ends or if mouse capture is simply lost
+ LLToolMgr::getInstance()->clearTransientTool();
+ mCargoTypes.clear();
+ mCargoIDs.clear();
+ mSource = SOURCE_AGENT;
+ mSourceID.setNull();
+ mObjectID.setNull();
+ mCustomMsg.clear();
}
BOOL LLToolDragAndDrop::handleMouseUp( S32 x, S32 y, MASK mask )
{
- if (hasMouseCapture())
- {
- EAcceptance acceptance = ACCEPT_NO;
- dragOrDrop( x, y, mask, TRUE, &acceptance );
- endDrag();
- }
- return TRUE;
+ if (hasMouseCapture())
+ {
+ EAcceptance acceptance = ACCEPT_NO;
+ dragOrDrop( x, y, mask, TRUE, &acceptance );
+ endDrag();
+ }
+ return TRUE;
}
ECursorType LLToolDragAndDrop::acceptanceToCursor( EAcceptance acceptance )
{
- switch (acceptance)
- {
- case ACCEPT_YES_MULTI:
- if (mCargoIDs.size() > 1)
- {
- mCursor = UI_CURSOR_ARROWDRAGMULTI;
- }
- else
- {
- mCursor = UI_CURSOR_ARROWDRAG;
- }
- break;
- case ACCEPT_YES_SINGLE:
- if (mCargoIDs.size() > 1)
- {
- mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
- mCursor = UI_CURSOR_NO;
- }
- else
- {
- mCursor = UI_CURSOR_ARROWDRAG;
- }
- break;
-
- case ACCEPT_NO_LOCKED:
- mCursor = UI_CURSOR_NOLOCKED;
- break;
-
- case ACCEPT_NO_CUSTOM:
- mToolTipMsg = mCustomMsg;
- mCursor = UI_CURSOR_NO;
- break;
-
-
- case ACCEPT_NO:
- mCursor = UI_CURSOR_NO;
- break;
-
- case ACCEPT_YES_COPY_MULTI:
- if (mCargoIDs.size() > 1)
- {
- mCursor = UI_CURSOR_ARROWCOPYMULTI;
- }
- else
- {
- mCursor = UI_CURSOR_ARROWCOPY;
- }
- break;
- case ACCEPT_YES_COPY_SINGLE:
- if (mCargoIDs.size() > 1)
- {
- mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
- mCursor = UI_CURSOR_NO;
- }
- else
- {
- mCursor = UI_CURSOR_ARROWCOPY;
- }
- break;
- case ACCEPT_POSTPONED:
- break;
- default:
- llassert( FALSE );
- }
-
- return mCursor;
+ switch (acceptance)
+ {
+ case ACCEPT_YES_MULTI:
+ if (mCargoIDs.size() > 1)
+ {
+ mCursor = UI_CURSOR_ARROWDRAGMULTI;
+ }
+ else
+ {
+ mCursor = UI_CURSOR_ARROWDRAG;
+ }
+ break;
+ case ACCEPT_YES_SINGLE:
+ if (mCargoIDs.size() > 1)
+ {
+ mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
+ mCursor = UI_CURSOR_NO;
+ }
+ else
+ {
+ mCursor = UI_CURSOR_ARROWDRAG;
+ }
+ break;
+
+ case ACCEPT_NO_LOCKED:
+ mCursor = UI_CURSOR_NOLOCKED;
+ break;
+
+ case ACCEPT_NO_CUSTOM:
+ mToolTipMsg = mCustomMsg;
+ mCursor = UI_CURSOR_NO;
+ break;
+
+
+ case ACCEPT_NO:
+ mCursor = UI_CURSOR_NO;
+ break;
+
+ case ACCEPT_YES_COPY_MULTI:
+ if (mCargoIDs.size() > 1)
+ {
+ mCursor = UI_CURSOR_ARROWCOPYMULTI;
+ }
+ else
+ {
+ mCursor = UI_CURSOR_ARROWCOPY;
+ }
+ break;
+ case ACCEPT_YES_COPY_SINGLE:
+ if (mCargoIDs.size() > 1)
+ {
+ mToolTipMsg = LLTrans::getString("TooltipMustSingleDrop");
+ mCursor = UI_CURSOR_NO;
+ }
+ else
+ {
+ mCursor = UI_CURSOR_ARROWCOPY;
+ }
+ break;
+ case ACCEPT_POSTPONED:
+ break;
+ default:
+ llassert( FALSE );
+ }
+
+ return mCursor;
}
BOOL LLToolDragAndDrop::handleHover( S32 x, S32 y, MASK mask )
{
- EAcceptance acceptance = ACCEPT_NO;
- dragOrDrop( x, y, mask, FALSE, &acceptance );
+ EAcceptance acceptance = ACCEPT_NO;
+ dragOrDrop( x, y, mask, FALSE, &acceptance );
- ECursorType cursor = acceptanceToCursor(acceptance);
- gViewerWindow->getWindow()->setCursor( cursor );
+ ECursorType cursor = acceptanceToCursor(acceptance);
+ gViewerWindow->getWindow()->setCursor( cursor );
- LL_DEBUGS("UserInput") << "hover handled by LLToolDragAndDrop" << LL_ENDL;
- return TRUE;
+ LL_DEBUGS("UserInput") << "hover handled by LLToolDragAndDrop" << LL_ENDL;
+ return TRUE;
}
BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask)
{
- if (key == KEY_ESCAPE)
- {
- // cancel drag and drop operation
- endDrag();
- return TRUE;
- }
+ if (key == KEY_ESCAPE)
+ {
+ // cancel drag and drop operation
+ endDrag();
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (!mToolTipMsg.empty())
- {
- LLToolTipMgr::instance().unblockToolTips();
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(mToolTipMsg)
- .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" )));
- return TRUE;
- }
- return FALSE;
+ if (!mToolTipMsg.empty())
+ {
+ LLToolTipMgr::instance().unblockToolTips();
+ LLToolTipMgr::instance().show(LLToolTip::Params()
+ .message(mToolTipMsg)
+ .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" )));
+ return TRUE;
+ }
+ return FALSE;
}
void LLToolDragAndDrop::handleDeselect()
{
- mToolTipMsg.clear();
- mCustomMsg.clear();
+ mToolTipMsg.clear();
+ mCustomMsg.clear();
- LLToolTipMgr::instance().blockToolTips();
+ LLToolTipMgr::instance().blockToolTips();
}
// protected
-void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
- EAcceptance* acceptance)
-{
- *acceptance = ACCEPT_YES_MULTI;
-
- BOOL handled = FALSE;
-
- LLView* top_view = gFocusMgr.getTopCtrl();
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
-
- mToolTipMsg.clear();
-
- // Increment the operation id for every drop
- if (drop)
- {
- sOperationId++;
- }
-
- // For people drag and drop we don't need an actual inventory object,
- // instead we need the current cargo id, which should be a person id.
- bool is_uuid_dragged = (mSource == SOURCE_PEOPLE);
-
- if (top_view)
- {
- handled = TRUE;
-
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- S32 local_x, local_y;
- top_view->screenPointToLocal( x, y, &local_x, &local_y );
- EAcceptance item_acceptance = ACCEPT_NO;
-
- LLInventoryObject* cargo = locateInventory(item, cat);
- if (cargo)
- {
- handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)cargo,
- &item_acceptance,
- mToolTipMsg);
- }
- else if (is_uuid_dragged)
- {
- handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)&mCargoIDs[mCurItemIndex],
- &item_acceptance,
- mToolTipMsg);
- }
- if (handled)
- {
- // use sort order to determine priority of acceptance
- *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
- }
- }
-
- // all objects passed, go ahead and perform drop if necessary
- if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE)
- {
- if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
- mCargoIDs.size() > 1)
- {
- // tried to give multi-cargo to a single-acceptor - refuse and return.
- *acceptance = ACCEPT_NO;
- return;
- }
-
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- S32 local_x, local_y;
- EAcceptance item_acceptance;
- top_view->screenPointToLocal( x, y, &local_x, &local_y );
-
- LLInventoryObject* cargo = locateInventory(item, cat);
- if (cargo)
- {
- handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
- mCargoTypes[mCurItemIndex],
- (void*)cargo,
- &item_acceptance,
- mToolTipMsg);
- }
- else if (is_uuid_dragged)
- {
- handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)&mCargoIDs[mCurItemIndex],
- &item_acceptance,
- mToolTipMsg);
- }
- }
- }
- if (handled)
- {
- mLastAccept = (EAcceptance)*acceptance;
- }
- }
-
- if (!handled)
- {
- handled = TRUE;
-
- LLRootView* root_view = gViewerWindow->getRootView();
-
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- EAcceptance item_acceptance = ACCEPT_NO;
-
- LLInventoryObject* cargo = locateInventory(item, cat);
-
- // fix for EXT-3191
- if (cargo)
- {
- handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)cargo,
- &item_acceptance,
- mToolTipMsg);
- }
- else if (is_uuid_dragged)
- {
- handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)&mCargoIDs[mCurItemIndex],
- &item_acceptance,
- mToolTipMsg);
- }
- if (handled)
- {
- // use sort order to determine priority of acceptance
- *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
- }
- }
- // all objects passed, go ahead and perform drop if necessary
- if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED)
- {
- if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
- mCargoIDs.size() > 1)
- {
- // tried to give multi-cargo to a single-acceptor - refuse and return.
- *acceptance = ACCEPT_NO;
- return;
- }
-
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- EAcceptance item_acceptance;
-
- LLInventoryObject* cargo = locateInventory(item, cat);
- if (cargo)
- {
- handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
- mCargoTypes[mCurItemIndex],
- (void*)cargo,
- &item_acceptance,
- mToolTipMsg);
- }
- else if (is_uuid_dragged)
- {
- handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
- mCargoTypes[mCurItemIndex],
- (void*)&mCargoIDs[mCurItemIndex],
- &item_acceptance,
- mToolTipMsg);
- }
- }
- }
-
- if (handled)
- {
- mLastAccept = (EAcceptance)*acceptance;
- }
- }
-
- if (!handled)
- {
- // Disallow drag and drop to 3D from the marketplace
+void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
+ EAcceptance* acceptance)
+{
+ *acceptance = ACCEPT_YES_MULTI;
+
+ BOOL handled = FALSE;
+
+ LLView* top_view = gFocusMgr.getTopCtrl();
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+
+ mToolTipMsg.clear();
+
+ // Increment the operation id for every drop
+ if (drop)
+ {
+ sOperationId++;
+ }
+
+ // For people drag and drop we don't need an actual inventory object,
+ // instead we need the current cargo id, which should be a person id.
+ bool is_uuid_dragged = (mSource == SOURCE_PEOPLE);
+
+ if (top_view)
+ {
+ handled = TRUE;
+
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ S32 local_x, local_y;
+ top_view->screenPointToLocal( x, y, &local_x, &local_y );
+ EAcceptance item_acceptance = ACCEPT_NO;
+
+ LLInventoryObject* cargo = locateInventory(item, cat);
+ if (cargo)
+ {
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)cargo,
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ else if (is_uuid_dragged)
+ {
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ if (handled)
+ {
+ // use sort order to determine priority of acceptance
+ *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
+ }
+ }
+
+ // all objects passed, go ahead and perform drop if necessary
+ if (handled && drop && (U32)*acceptance >= ACCEPT_YES_COPY_SINGLE)
+ {
+ if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
+ mCargoIDs.size() > 1)
+ {
+ // tried to give multi-cargo to a single-acceptor - refuse and return.
+ *acceptance = ACCEPT_NO;
+ return;
+ }
+
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ S32 local_x, local_y;
+ EAcceptance item_acceptance;
+ top_view->screenPointToLocal( x, y, &local_x, &local_y );
+
+ LLInventoryObject* cargo = locateInventory(item, cat);
+ if (cargo)
+ {
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
+ mCargoTypes[mCurItemIndex],
+ (void*)cargo,
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ else if (is_uuid_dragged)
+ {
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ }
+ }
+ if (handled)
+ {
+ mLastAccept = (EAcceptance)*acceptance;
+ }
+ }
+
+ if (!handled)
+ {
+ handled = TRUE;
+
+ LLRootView* root_view = gViewerWindow->getRootView();
+
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ EAcceptance item_acceptance = ACCEPT_NO;
+
+ LLInventoryObject* cargo = locateInventory(item, cat);
+
+ // fix for EXT-3191
+ if (cargo)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)cargo,
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ else if (is_uuid_dragged)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ if (handled)
+ {
+ // use sort order to determine priority of acceptance
+ *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
+ }
+ }
+ // all objects passed, go ahead and perform drop if necessary
+ if (handled && drop && (U32)*acceptance > ACCEPT_NO_LOCKED)
+ {
+ if ((U32)*acceptance < ACCEPT_YES_COPY_MULTI &&
+ mCargoIDs.size() > 1)
+ {
+ // tried to give multi-cargo to a single-acceptor - refuse and return.
+ *acceptance = ACCEPT_NO;
+ return;
+ }
+
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ EAcceptance item_acceptance;
+
+ LLInventoryObject* cargo = locateInventory(item, cat);
+ if (cargo)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
+ mCargoTypes[mCurItemIndex],
+ (void*)cargo,
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ else if (is_uuid_dragged)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ }
+ }
+
+ if (handled)
+ {
+ mLastAccept = (EAcceptance)*acceptance;
+ }
+ }
+
+ if (!handled)
+ {
+ // Disallow drag and drop to 3D from the marketplace
const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
- if (marketplacelistings_id.notNull())
- {
- for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
- {
- if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], marketplacelistings_id))
- {
- *acceptance = ACCEPT_NO;
- mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld");
- return;
- }
- }
- }
-
- dragOrDrop3D( x, y, mask, drop, acceptance );
- }
+ if (marketplacelistings_id.notNull())
+ {
+ for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
+ {
+ if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], marketplacelistings_id))
+ {
+ *acceptance = ACCEPT_NO;
+ mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld");
+ return;
+ }
+ }
+ }
+
+ dragOrDrop3D( x, y, mask, drop, acceptance );
+ }
}
void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* acceptance )
{
- mDrop = drop;
- if (mDrop)
- {
- // don't allow drag and drop onto rigged or transparent objects
- pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE));
- }
- else
- {
- // don't allow drag and drop onto transparent objects
- gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, FALSE);
- }
+ mDrop = drop;
+ if (mDrop)
+ {
+ // don't allow drag and drop onto rigged or transparent objects
+ pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE));
+ }
+ else
+ {
+ // don't allow drag and drop onto transparent objects
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, FALSE);
+ }
- *acceptance = mLastAccept;
+ *acceptance = mLastAccept;
}
void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info)
{
- if (getInstance() != NULL)
- {
- getInstance()->pick(pick_info);
- }
+ if (getInstance() != NULL)
+ {
+ getInstance()->pick(pick_info);
+ }
}
void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
{
- EDropTarget target = DT_NONE;
- S32 hit_face = -1;
-
- LLViewerObject* hit_obj = pick_info.getObject();
- LLSelectMgr::getInstance()->unhighlightAll();
- bool highlight_object = false;
- // Treat attachments as part of the avatar they are attached to.
- if (hit_obj != NULL)
- {
- // don't allow drag and drop on grass, trees, etc.
- if (pick_info.mPickType == LLPickInfo::PICK_FLORA)
- {
- mCursor = UI_CURSOR_NO;
- gViewerWindow->getWindow()->setCursor( mCursor );
- return;
- }
-
- if (hit_obj->isAttachment() && !hit_obj->isHUDAttachment())
- {
- LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj );
- if (!avatar)
- {
- mLastAccept = ACCEPT_NO;
- mCursor = UI_CURSOR_NO;
- gViewerWindow->getWindow()->setCursor( mCursor );
- return;
- }
- hit_obj = avatar;
- }
-
- if (hit_obj->isAvatar())
- {
- if (((LLVOAvatar*) hit_obj)->isSelf())
- {
- target = DT_SELF;
- hit_face = -1;
- }
- else
- {
- target = DT_AVATAR;
- hit_face = -1;
- }
- }
- else
- {
- target = DT_OBJECT;
- hit_face = pick_info.mObjectFace;
- highlight_object = true;
- }
- }
- else if (pick_info.mPickType == LLPickInfo::PICK_LAND)
- {
- target = DT_LAND;
- hit_face = -1;
- }
-
- mLastAccept = ACCEPT_YES_MULTI;
-
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- const S32 item_index = mCurItemIndex;
- const EDragAndDropType dad_type = mCargoTypes[item_index];
- // Call the right implementation function
- mLastAccept = (EAcceptance)llmin(
- (U32)mLastAccept,
- (U32)callMemberFunction(*this,
- LLDragAndDropDictionary::instance().get(dad_type, target))
- (hit_obj, hit_face, pick_info.mKeyMask, FALSE));
- }
-
- if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE))
- {
- // if target allows multi-drop or there is only one item being dropped, go ahead
- if ((mLastAccept >= ACCEPT_YES_COPY_MULTI) || (mCargoIDs.size() == 1))
- {
- // Target accepts multi, or cargo is a single-drop
- for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
- {
- const S32 item_index = mCurItemIndex;
- const EDragAndDropType dad_type = mCargoTypes[item_index];
- // Call the right implementation function
- callMemberFunction(*this, LLDragAndDropDictionary::instance().get(dad_type, target))
- (hit_obj, hit_face, pick_info.mKeyMask, TRUE);
- }
- }
- else
- {
- // Target does not accept multi, but cargo is multi
- mLastAccept = ACCEPT_NO;
- }
- }
-
- if (highlight_object && mLastAccept > ACCEPT_NO_LOCKED)
- {
- // if any item being dragged will be applied to the object under our cursor
- // highlight that object
- for (S32 i = 0; i < (S32)mCargoIDs.size(); i++)
- {
- if (mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL))
- {
- LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj);
- break;
- }
- }
- }
- ECursorType cursor = acceptanceToCursor( mLastAccept );
- gViewerWindow->getWindow()->setCursor( cursor );
-
- mLastHitPos = pick_info.mPosGlobal;
- mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
+ EDropTarget target = DT_NONE;
+ S32 hit_face = -1;
+
+ LLViewerObject* hit_obj = pick_info.getObject();
+ LLSelectMgr::getInstance()->unhighlightAll();
+ bool highlight_object = false;
+ // Treat attachments as part of the avatar they are attached to.
+ if (hit_obj != NULL)
+ {
+ // don't allow drag and drop on grass, trees, etc.
+ if (pick_info.mPickType == LLPickInfo::PICK_FLORA)
+ {
+ mCursor = UI_CURSOR_NO;
+ gViewerWindow->getWindow()->setCursor( mCursor );
+ return;
+ }
+
+ if (hit_obj->isAttachment() && !hit_obj->isHUDAttachment())
+ {
+ LLVOAvatar* avatar = LLVOAvatar::findAvatarFromAttachment( hit_obj );
+ if (!avatar)
+ {
+ mLastAccept = ACCEPT_NO;
+ mCursor = UI_CURSOR_NO;
+ gViewerWindow->getWindow()->setCursor( mCursor );
+ return;
+ }
+ hit_obj = avatar;
+ }
+
+ if (hit_obj->isAvatar())
+ {
+ if (((LLVOAvatar*) hit_obj)->isSelf())
+ {
+ target = DT_SELF;
+ hit_face = -1;
+ }
+ else
+ {
+ target = DT_AVATAR;
+ hit_face = -1;
+ }
+ }
+ else
+ {
+ target = DT_OBJECT;
+ hit_face = pick_info.mObjectFace;
+ highlight_object = true;
+ }
+ }
+ else if (pick_info.mPickType == LLPickInfo::PICK_LAND)
+ {
+ target = DT_LAND;
+ hit_face = -1;
+ }
+
+ mLastAccept = ACCEPT_YES_MULTI;
+
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ const S32 item_index = mCurItemIndex;
+ const EDragAndDropType dad_type = mCargoTypes[item_index];
+ // Call the right implementation function
+ mLastAccept = (EAcceptance)llmin(
+ (U32)mLastAccept,
+ (U32)callMemberFunction(*this,
+ LLDragAndDropDictionary::instance().get(dad_type, target))
+ (hit_obj, hit_face, pick_info.mKeyMask, FALSE));
+ }
+
+ if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE))
+ {
+ // if target allows multi-drop or there is only one item being dropped, go ahead
+ if ((mLastAccept >= ACCEPT_YES_COPY_MULTI) || (mCargoIDs.size() == 1))
+ {
+ // Target accepts multi, or cargo is a single-drop
+ for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
+ {
+ const S32 item_index = mCurItemIndex;
+ const EDragAndDropType dad_type = mCargoTypes[item_index];
+ // Call the right implementation function
+ callMemberFunction(*this, LLDragAndDropDictionary::instance().get(dad_type, target))
+ (hit_obj, hit_face, pick_info.mKeyMask, TRUE);
+ }
+ }
+ else
+ {
+ // Target does not accept multi, but cargo is multi
+ mLastAccept = ACCEPT_NO;
+ }
+ }
+
+ if (highlight_object && mLastAccept > ACCEPT_NO_LOCKED)
+ {
+ // if any item being dragged will be applied to the object under our cursor
+ // highlight that object
+ for (S32 i = 0; i < (S32)mCargoIDs.size(); i++)
+ {
+ if (mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL))
+ {
+ LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj);
+ break;
+ }
+ }
+ }
+ ECursorType cursor = acceptanceToCursor( mLastAccept );
+ gViewerWindow->getWindow()->setCursor( cursor );
+
+ mLastHitPos = pick_info.mPosGlobal;
+ mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
}
// static
BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
-{
- if (!item) return FALSE;
-
- // Always succeed if....
- // material is from the library
- // or already in the contents of the object
- if (SOURCE_LIBRARY == source)
- {
- // dropping a material from the library always just works.
- return TRUE;
- }
-
- // In case the inventory has not been loaded (e.g. due to some recent operation
- // causing a dirty inventory) and we can do an update, stall the user
- // while fetching the inventory.
- //
- // Fetch if inventory is dirty and listener is present (otherwise we will not receive update)
- if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners())
- {
- hit_obj->requestInventory();
- LLSD args;
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (!item) return FALSE;
+
+ // Always succeed if....
+ // material is from the library
+ // or already in the contents of the object
+ if (SOURCE_LIBRARY == source)
+ {
+ // dropping a material from the library always just works.
+ return TRUE;
+ }
+
+ // In case the inventory has not been loaded (e.g. due to some recent operation
+ // causing a dirty inventory) and we can do an update, stall the user
+ // while fetching the inventory.
+ //
+ // Fetch if inventory is dirty and listener is present (otherwise we will not receive update)
+ if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners())
+ {
+ hit_obj->requestInventory();
+ LLSD args;
if (LLAssetType::AT_MATERIAL == item->getType())
{
args["ERROR_MESSAGE"] = "Unable to add material.\nPlease wait a few seconds and try again.";
@@ -958,117 +958,117 @@ BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
{
args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
}
- LLNotificationsUtil::add("ErrorMessage", args);
- return FALSE;
- }
+ LLNotificationsUtil::add("ErrorMessage", args);
+ return FALSE;
+ }
// Make sure to verify both id and type since 'null'
// is a shared default for some asset types.
if (hit_obj->getInventoryItemByAsset(item->getAssetUUID(), item->getType()))
- {
- // if the asset is already in the object's inventory
- // then it can always be added to a side.
- // This saves some work if the task's inventory is already loaded
- // and ensures that the asset item is only added once.
- return TRUE;
- }
-
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
- {
- // Check that we can add the material as inventory to the object
- if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
- {
- return FALSE;
- }
- // make sure the object has the material in it's inventory.
- if (SOURCE_AGENT == source)
- {
- // Remove the material from local inventory. The server
- // will actually remove the item from agent inventory.
- gInventory.deleteObject(item->getUUID());
- gInventory.notifyObservers();
- }
- else if (SOURCE_WORLD == source)
- {
- // *FIX: if the objects are in different regions, and the
- // source region has crashed, you can bypass these
- // permissions.
- LLViewerObject* src_obj = gObjectList.findObject(src_id);
- if (src_obj)
- {
- src_obj->removeInventory(item->getUUID());
- }
- else
- {
- LL_WARNS() << "Unable to find source object." << LL_ENDL;
- return FALSE;
- }
- }
- // Add the asset item to the target object's inventory.
+ {
+ // if the asset is already in the object's inventory
+ // then it can always be added to a side.
+ // This saves some work if the task's inventory is already loaded
+ // and ensures that the asset item is only added once.
+ return TRUE;
+ }
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ // Check that we can add the material as inventory to the object
+ if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
+ {
+ return FALSE;
+ }
+ // make sure the object has the material in it's inventory.
+ if (SOURCE_AGENT == source)
+ {
+ // Remove the material from local inventory. The server
+ // will actually remove the item from agent inventory.
+ gInventory.deleteObject(item->getUUID());
+ gInventory.notifyObservers();
+ }
+ else if (SOURCE_WORLD == source)
+ {
+ // *FIX: if the objects are in different regions, and the
+ // source region has crashed, you can bypass these
+ // permissions.
+ LLViewerObject* src_obj = gObjectList.findObject(src_id);
+ if (src_obj)
+ {
+ src_obj->removeInventory(item->getUUID());
+ }
+ else
+ {
+ LL_WARNS() << "Unable to find source object." << LL_ENDL;
+ return FALSE;
+ }
+ }
+ // Add the asset item to the target object's inventory.
if (LLAssetType::AT_TEXTURE == new_item->getType()
|| LLAssetType::AT_MATERIAL == new_item->getType())
{
hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
- else
- {
- hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
- // Force the object to update and refetch its inventory so it has this asset.
- hit_obj->dirtyInventory();
- hit_obj->requestInventory();
- // TODO: Check to see if adding the item was successful; if not, then
- // we should return false here. This will requre a separate listener
- // since without listener, we have no way to receive update
- }
- else if (!item->getPermissions().allowOperationBy(PERM_TRANSFER,
- gAgent.getID()))
- {
- // Check that we can add the asset as inventory to the object
- if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
- {
- return FALSE;
- }
- // *FIX: may want to make sure agent can paint hit_obj.
-
- // Add the asset item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType()
+ else
+ {
+ hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
+ // Force the object to update and refetch its inventory so it has this asset.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
+ }
+ else if (!item->getPermissions().allowOperationBy(PERM_TRANSFER,
+ gAgent.getID()))
+ {
+ // Check that we can add the asset as inventory to the object
+ if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
+ {
+ return FALSE;
+ }
+ // *FIX: may want to make sure agent can paint hit_obj.
+
+ // Add the asset item to the target object's inventory.
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
|| LLAssetType::AT_MATERIAL == new_item->getType())
- {
- hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
- else
- {
- hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
- // Force the object to update and refetch its inventory so it has this asset.
- hit_obj->dirtyInventory();
- hit_obj->requestInventory();
- // TODO: Check to see if adding the item was successful; if not, then
- // we should return false here. This will requre a separate listener
- // since without listener, we have no way to receive update
- }
- else if (LLAssetType::AT_MATERIAL == new_item->getType() &&
+ {
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
+ else
+ {
+ hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
+ // Force the object to update and refetch its inventory so it has this asset.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
+ }
+ else if (LLAssetType::AT_MATERIAL == new_item->getType() &&
!item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
- {
- // Check that we can add the material as inventory to the object
- if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
- {
- return FALSE;
- }
- // *FIX: may want to make sure agent can paint hit_obj.
-
- // Add the material item to the target object's inventory.
+ {
+ // Check that we can add the material as inventory to the object
+ if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
+ {
+ return FALSE;
+ }
+ // *FIX: may want to make sure agent can paint hit_obj.
+
+ // Add the material item to the target object's inventory.
hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- // Force the object to update and refetch its inventory so it has this material.
- hit_obj->dirtyInventory();
- hit_obj->requestInventory();
- // TODO: Check to see if adding the item was successful; if not, then
- // we should return false here. This will requre a separate listener
- // since without listener, we have no way to receive update
- }
- return TRUE;
+ // Force the object to update and refetch its inventory so it has this material.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
+ }
+ return TRUE;
}
void set_texture_to_material(LLViewerObject* hit_obj,
@@ -1077,64 +1077,84 @@ void set_texture_to_material(LLViewerObject* hit_obj,
LLGLTFMaterial::TextureInfo drop_channel)
{
LLTextureEntry* te = hit_obj->getTE(hit_face);
- if (te)
+ if (!te)
{
- LLPointer<LLGLTFMaterial> material = te->getGLTFMaterialOverride();
+ return;
+ }
- // make a copy to not invalidate existing
- // material for multiple objects
- if (material.isNull())
- {
- // Start with a material override which does not make any changes
- material = new LLGLTFMaterial();
- }
- else
- {
- material = new LLGLTFMaterial(*material);
- }
+ const LLUUID base_mat_id = hit_obj->getRenderMaterialID(hit_face);
+ if (base_mat_id.isNull())
+ {
+ return;
+ }
- switch (drop_channel)
- {
- case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
- default:
- {
- material->setBaseColorId(asset_id);
- }
- break;
+ if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners())
+ {
+ hit_obj->requestInventory();
+ return;
+ }
- case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
- {
- material->setOcclusionRoughnessMetallicId(asset_id);
- }
- break;
+ LLViewerInventoryItem* mat_item = hit_obj->getInventoryItemByAsset(base_mat_id);
+ if (mat_item && !mat_item->getPermissions().allowModifyBy(gAgentID))
+ {
+ return;
+ }
- case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
- {
- material->setEmissiveId(asset_id);
- }
- break;
+ LLPointer<LLGLTFMaterial> material = te->getGLTFMaterialOverride();
- case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
- {
- material->setNormalId(asset_id);
- }
- break;
- }
- LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
+ // make a copy to not invalidate existing
+ // material for multiple objects
+ if (material.isNull())
+ {
+ // Start with a material override which does not make any changes
+ material = new LLGLTFMaterial();
+ }
+ else
+ {
+ material = new LLGLTFMaterial(*material);
+ }
+
+ switch (drop_channel)
+ {
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
+ default:
+ {
+ material->setBaseColorId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
+ {
+ material->setOcclusionRoughnessMetallicId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
+ {
+ material->setEmissiveId(asset_id);
+ }
+ break;
+
+ case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
+ {
+ material->setNormalId(asset_id);
+ }
+ break;
}
+ LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
}
void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id,
bool remove_pbr)
{
- if (!item)
- {
- LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << LL_ENDL;
- return;
- }
+ if (!item)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << LL_ENDL;
+ return;
+ }
S32 num_faces = hit_obj->getNumTEs();
bool has_non_pbr_faces = false;
for (S32 face = 0; face < num_faces; face++)
@@ -1154,17 +1174,17 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
return;
}
}
- LLUUID asset_id = item->getAssetUUID();
+ LLUUID asset_id = item->getAssetUUID();
// Overrides require textures to be copy and transfer free
LLPermissions item_permissions = item->getPermissions();
bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID());
allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID());
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
- add(LLStatViewer::EDIT_TEXTURE, 1);
- for( S32 face = 0; face < num_faces; face++ )
- {
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
+ add(LLStatViewer::EDIT_TEXTURE, 1);
+ for( S32 face = 0; face < num_faces; face++ )
+ {
if (remove_pbr)
{
hit_obj->setRenderMaterialID(face, LLUUID::null);
@@ -1181,11 +1201,11 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
{
set_texture_to_material(hit_obj, face, asset_id, LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR);
}
- }
+ }
- // send the update to the simulator
+ // send the update to the simulator
LLGLTFMaterialList::flushUpdates(nullptr);
- hit_obj->sendTEUpdate();
+ hit_obj->sendTEUpdate();
}
void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj,
@@ -1262,7 +1282,7 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
if (asset_id.isNull())
{
// use blank material
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
hit_obj->setRenderMaterialID(hit_face, asset_id);
@@ -1298,7 +1318,7 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
if (asset_id.isNull())
{
// use blank material
- asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ asset_id = BLANK_MATERIAL_ASSET_ID;
}
hit_obj->setRenderMaterialIDs(asset_id);
@@ -1309,27 +1329,27 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
-{
- if (!item)
- {
- LL_WARNS() << "no inventory item." << LL_ENDL;
- return;
- }
- LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
- if(!success)
- {
- return;
- }
-
- LLSculptParams sculpt_params;
- sculpt_params.setSculptTexture(asset_id, LL_SCULPT_TYPE_MESH);
- hit_obj->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
-
- dialog_refresh_all();
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (!item)
+ {
+ LL_WARNS() << "no inventory item." << LL_ENDL;
+ return;
+ }
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if(!success)
+ {
+ return;
+ }
+
+ LLSculptParams sculpt_params;
+ sculpt_params.setSculptTexture(asset_id, LL_SCULPT_TYPE_MESH);
+ hit_obj->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+
+ dialog_refresh_all();
}
void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
@@ -1434,19 +1454,19 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
}
void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
- S32 hit_face,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id,
+ S32 hit_face,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id,
bool remove_pbr,
S32 tex_channel)
{
- if (hit_face == -1) return;
- if (!item)
- {
- LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL;
- return;
- }
+ if (hit_face == -1) return;
+ if (!item)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL;
+ return;
+ }
LLUUID asset_id = item->getAssetUUID();
@@ -1470,593 +1490,593 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
}
return;
}
- BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
- if (!success)
- {
- return;
- }
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
if (remove_pbr)
{
hit_obj->setRenderMaterialID(hit_face, LLUUID::null);
}
- // update viewer side image in anticipation of update from simulator
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
- add(LLStatViewer::EDIT_TEXTURE, 1);
+ // update viewer side image in anticipation of update from simulator
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
+ add(LLStatViewer::EDIT_TEXTURE, 1);
- LLTextureEntry* tep = hit_obj->getTE(hit_face);
+ LLTextureEntry* tep = hit_obj->getTE(hit_face);
- LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
- if (gFloaterTools->getVisible() && panel_face)
- {
+ if (gFloaterTools->getVisible() && panel_face)
+ {
tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel();
switch (tex_channel)
- {
+ {
- case 0:
- default:
- {
- hit_obj->setTEImage(hit_face, image);
- }
- break;
+ case 0:
+ default:
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+ break;
- case 1:
+ case 1:
if (tep)
- {
- LLMaterialPtr old_mat = tep->getMaterialParams();
- LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
- new_mat->setNormalID(asset_id);
- tep->setMaterialParams(new_mat);
- hit_obj->setTENormalMap(hit_face, asset_id);
- LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
- }
- break;
-
- case 2:
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setNormalID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTENormalMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+
+ case 2:
if (tep)
- {
- LLMaterialPtr old_mat = tep->getMaterialParams();
- LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
- new_mat->setSpecularID(asset_id);
- tep->setMaterialParams(new_mat);
- hit_obj->setTESpecularMap(hit_face, asset_id);
- LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
- }
- break;
- }
- }
- else
- {
- hit_obj->setTEImage(hit_face, image);
- }
-
- dialog_refresh_all();
-
- // send the update to the simulator
- hit_obj->sendTEUpdate();
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setSpecularID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTESpecularMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+ }
+ }
+ else
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
}
void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- BOOL active,
- ESource source,
- const LLUUID& src_id)
-{
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
- || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
- {
- LL_WARNS() << "Call to LLToolDragAndDrop::dropScript() from world"
- << " or notecard." << LL_ENDL;
- return;
- }
- if (hit_obj && item)
- {
- LLPointer<LLViewerInventoryItem> new_script = new LLViewerInventoryItem(item);
- if (!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- if (SOURCE_AGENT == source)
- {
- // Remove the script from local inventory. The server
- // will actually remove the item from agent inventory.
- gInventory.deleteObject(item->getUUID());
- gInventory.notifyObservers();
- }
- else if (SOURCE_WORLD == source)
- {
- // *FIX: if the objects are in different regions, and
- // the source region has crashed, you can bypass
- // these permissions.
- LLViewerObject* src_obj = gObjectList.findObject(src_id);
- if (src_obj)
- {
- src_obj->removeInventory(item->getUUID());
- }
- else
- {
- LL_WARNS() << "Unable to find source object." << LL_ENDL;
- return;
- }
- }
- }
- hit_obj->saveScript(new_script, active, true);
- gFloaterTools->dirty();
-
- // VEFFECT: SetScript
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setTargetObject(hit_obj);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- }
+ LLInventoryItem* item,
+ BOOL active,
+ ESource source,
+ const LLUUID& src_id)
+{
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
+ || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
+ {
+ LL_WARNS() << "Call to LLToolDragAndDrop::dropScript() from world"
+ << " or notecard." << LL_ENDL;
+ return;
+ }
+ if (hit_obj && item)
+ {
+ LLPointer<LLViewerInventoryItem> new_script = new LLViewerInventoryItem(item);
+ if (!item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ if (SOURCE_AGENT == source)
+ {
+ // Remove the script from local inventory. The server
+ // will actually remove the item from agent inventory.
+ gInventory.deleteObject(item->getUUID());
+ gInventory.notifyObservers();
+ }
+ else if (SOURCE_WORLD == source)
+ {
+ // *FIX: if the objects are in different regions, and
+ // the source region has crashed, you can bypass
+ // these permissions.
+ LLViewerObject* src_obj = gObjectList.findObject(src_id);
+ if (src_obj)
+ {
+ src_obj->removeInventory(item->getUUID());
+ }
+ else
+ {
+ LL_WARNS() << "Unable to find source object." << LL_ENDL;
+ return;
+ }
+ }
+ }
+ hit_obj->saveScript(new_script, active, true);
+ gFloaterTools->dirty();
+
+ // VEFFECT: SetScript
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(hit_obj);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
}
void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
- BOOL bypass_sim_raycast,
- BOOL from_task_inventory,
- BOOL remove_from_inventory)
-{
- LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos);
- if (!regionp)
- {
- LL_WARNS() << "Couldn't find region to rez object" << LL_ENDL;
- return;
- }
-
- //LL_INFOS() << "Rezzing object" << LL_ENDL;
- make_ui_sound("UISndObjectRezIn");
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return;
-
- //if (regionp
- // && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
- //{
- // LLFirstUse::useSandbox();
- //}
- // check if it cannot be copied, and mark as remove if it is -
- // this will remove the object from inventory after rez. Only
- // bother with this check if we would not normally remove from
- // inventory.
- if (!remove_from_inventory
- && !item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- remove_from_inventory = TRUE;
- }
-
- // Limit raycast to a single object.
- // Speeds up server raycast + avoid problems with server ray
- // hitting objects that were clipped by the near plane or culled
- // on the viewer.
- LLUUID ray_target_id;
- if (raycast_target)
- {
- ray_target_id = raycast_target->getID();
- }
- else
- {
- ray_target_id.setNull();
- }
-
- // Check if it's in the trash.
- bool is_in_trash = false;
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
- {
- is_in_trash = true;
- }
-
- LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null;
-
- // Select the object only if we're editing.
- BOOL rez_selected = LLToolMgr::getInstance()->inEdit();
-
-
- LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos);
- LLVector3 ray_end = regionp->getPosRegionFromGlobal(mLastHitPos);
- // currently the ray's end point is an approximation,
- // and is sometimes too short (causing failure.) so we
- // double the ray's length:
- if (bypass_sim_raycast == FALSE)
- {
- LLVector3 ray_direction = ray_start - ray_end;
- ray_end = ray_end - ray_direction;
- }
-
-
- // Message packing code should be it's own uninterrupted block
- LLMessageSystem* msg = gMessageSystem;
- if (mSource == SOURCE_NOTECARD)
- {
- LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard");
- msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
- }
- else
- {
- LLUIUsage::instance().logCommand("Object.RezObject");
- msg->newMessageFast(_PREHASH_RezObject);
- }
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
-
- msg->nextBlock("RezData");
- // if it's being rezzed from task inventory, we need to enable
- // saving it back into the task inventory.
- // *FIX: We can probably compress this to a single byte, since I
- // think folderid == mSourceID. This will be a later
- // optimization.
- msg->addUUIDFast(_PREHASH_FromTaskID, source_id);
- msg->addU8Fast(_PREHASH_BypassRaycast, (U8) bypass_sim_raycast);
- msg->addVector3Fast(_PREHASH_RayStart, ray_start);
- msg->addVector3Fast(_PREHASH_RayEnd, ray_end);
- msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
- msg->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE);
- msg->addBOOLFast(_PREHASH_RezSelected, rez_selected);
- msg->addBOOLFast(_PREHASH_RemoveItem, remove_from_inventory);
-
- // deal with permissions slam logic
- pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
-
- LLUUID folder_id = item->getParentUUID();
- if ((SOURCE_LIBRARY == mSource) || (is_in_trash))
- {
- // since it's coming from the library or trash, we want to not
- // 'take' it back to the same place.
- item->setParent(LLUUID::null);
- // *TODO this code isn't working - the parent (FolderID) is still
- // set when the object is "taken". so code on the "take" side is
- // checking for trash and library as well (llviewermenu.cpp)
- }
- if (mSource == SOURCE_NOTECARD)
- {
- msg->nextBlockFast(_PREHASH_NotecardData);
- msg->addUUIDFast(_PREHASH_NotecardItemID, mSourceID);
- msg->addUUIDFast(_PREHASH_ObjectID, mObjectID);
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addUUIDFast(_PREHASH_ItemID, item->getUUID());
- }
- else
- {
- msg->nextBlockFast(_PREHASH_InventoryData);
- item->packMessage(msg);
- }
- msg->sendReliable(regionp->getHost());
- // back out the change. no actual internal changes take place.
- item->setParent(folder_id);
-
- // If we're going to select it, get ready for the incoming
- // selected object.
- if (rez_selected)
- {
- LLSelectMgr::getInstance()->deselectAll();
- gViewerWindow->getWindow()->incBusyCount();
- }
-
- if (remove_from_inventory)
- {
- // Delete it from inventory immediately so that users cannot
- // easily bypass copy protection in laggy situations. If the
- // rez fails, we will put it back on the server.
- gInventory.deleteObject(item->getUUID());
- gInventory.notifyObservers();
- }
-
- // VEFFECT: DropObject
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setPositionGlobal(mLastHitPos);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
-
- add(LLStatViewer::OBJECT_REZ, 1);
+ BOOL bypass_sim_raycast,
+ BOOL from_task_inventory,
+ BOOL remove_from_inventory)
+{
+ LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos);
+ if (!regionp)
+ {
+ LL_WARNS() << "Couldn't find region to rez object" << LL_ENDL;
+ return;
+ }
+
+ //LL_INFOS() << "Rezzing object" << LL_ENDL;
+ make_ui_sound("UISndObjectRezIn");
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return;
+
+ //if (regionp
+ // && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
+ //{
+ // LLFirstUse::useSandbox();
+ //}
+ // check if it cannot be copied, and mark as remove if it is -
+ // this will remove the object from inventory after rez. Only
+ // bother with this check if we would not normally remove from
+ // inventory.
+ if (!remove_from_inventory
+ && !item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ remove_from_inventory = TRUE;
+ }
+
+ // Limit raycast to a single object.
+ // Speeds up server raycast + avoid problems with server ray
+ // hitting objects that were clipped by the near plane or culled
+ // on the viewer.
+ LLUUID ray_target_id;
+ if (raycast_target)
+ {
+ ray_target_id = raycast_target->getID();
+ }
+ else
+ {
+ ray_target_id.setNull();
+ }
+
+ // Check if it's in the trash.
+ bool is_in_trash = false;
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
+ {
+ is_in_trash = true;
+ }
+
+ LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null;
+
+ // Select the object only if we're editing.
+ BOOL rez_selected = LLToolMgr::getInstance()->inEdit();
+
+
+ LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos);
+ LLVector3 ray_end = regionp->getPosRegionFromGlobal(mLastHitPos);
+ // currently the ray's end point is an approximation,
+ // and is sometimes too short (causing failure.) so we
+ // double the ray's length:
+ if (bypass_sim_raycast == FALSE)
+ {
+ LLVector3 ray_direction = ray_start - ray_end;
+ ray_end = ray_end - ray_direction;
+ }
+
+
+ // Message packing code should be it's own uninterrupted block
+ LLMessageSystem* msg = gMessageSystem;
+ if (mSource == SOURCE_NOTECARD)
+ {
+ LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard");
+ msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
+ }
+ else
+ {
+ LLUIUsage::instance().logCommand("Object.RezObject");
+ msg->newMessageFast(_PREHASH_RezObject);
+ }
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+
+ msg->nextBlock("RezData");
+ // if it's being rezzed from task inventory, we need to enable
+ // saving it back into the task inventory.
+ // *FIX: We can probably compress this to a single byte, since I
+ // think folderid == mSourceID. This will be a later
+ // optimization.
+ msg->addUUIDFast(_PREHASH_FromTaskID, source_id);
+ msg->addU8Fast(_PREHASH_BypassRaycast, (U8) bypass_sim_raycast);
+ msg->addVector3Fast(_PREHASH_RayStart, ray_start);
+ msg->addVector3Fast(_PREHASH_RayEnd, ray_end);
+ msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
+ msg->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE);
+ msg->addBOOLFast(_PREHASH_RezSelected, rez_selected);
+ msg->addBOOLFast(_PREHASH_RemoveItem, remove_from_inventory);
+
+ // deal with permissions slam logic
+ pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
+
+ LLUUID folder_id = item->getParentUUID();
+ if ((SOURCE_LIBRARY == mSource) || (is_in_trash))
+ {
+ // since it's coming from the library or trash, we want to not
+ // 'take' it back to the same place.
+ item->setParent(LLUUID::null);
+ // *TODO this code isn't working - the parent (FolderID) is still
+ // set when the object is "taken". so code on the "take" side is
+ // checking for trash and library as well (llviewermenu.cpp)
+ }
+ if (mSource == SOURCE_NOTECARD)
+ {
+ msg->nextBlockFast(_PREHASH_NotecardData);
+ msg->addUUIDFast(_PREHASH_NotecardItemID, mSourceID);
+ msg->addUUIDFast(_PREHASH_ObjectID, mObjectID);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_ItemID, item->getUUID());
+ }
+ else
+ {
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ item->packMessage(msg);
+ }
+ msg->sendReliable(regionp->getHost());
+ // back out the change. no actual internal changes take place.
+ item->setParent(folder_id);
+
+ // If we're going to select it, get ready for the incoming
+ // selected object.
+ if (rez_selected)
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ gViewerWindow->getWindow()->incBusyCount();
+ }
+
+ if (remove_from_inventory)
+ {
+ // Delete it from inventory immediately so that users cannot
+ // easily bypass copy protection in laggy situations. If the
+ // rez fails, we will put it back on the server.
+ gInventory.deleteObject(item->getUUID());
+ gInventory.notifyObservers();
+ }
+
+ // VEFFECT: DropObject
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setPositionGlobal(mLastHitPos);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+
+ add(LLStatViewer::OBJECT_REZ, 1);
}
void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
-{
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
- || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
- {
- LL_WARNS() << "Call to LLToolDragAndDrop::dropInventory() from world"
- << " or notecard." << LL_ENDL;
- return;
- }
-
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- time_t creation_date = time_corrected();
- new_item->setCreationDate(creation_date);
-
- if (!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- if (SOURCE_AGENT == source)
- {
- // Remove the inventory item from local inventory. The
- // server will actually remove the item from agent
- // inventory.
- gInventory.deleteObject(item->getUUID());
- gInventory.notifyObservers();
- }
- else if (SOURCE_WORLD == source)
- {
- // *FIX: if the objects are in different regions, and the
- // source region has crashed, you can bypass these
- // permissions.
- LLViewerObject* src_obj = gObjectList.findObject(src_id);
- if (src_obj)
- {
- src_obj->removeInventory(item->getUUID());
- }
- else
- {
- LL_WARNS() << "Unable to find source object." << LL_ENDL;
- return;
- }
- }
- }
- hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- if (LLFloaterReg::instanceVisible("build"))
- {
- // *FIX: only show this if panel not expanded?
- LLFloaterReg::showInstance("build", "Content");
- }
-
- // VEFFECT: AddToInventory
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setTargetObject(hit_obj);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- gFloaterTools->dirty();
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if ((SOURCE_WORLD == LLToolDragAndDrop::getInstance()->mSource)
+ || (SOURCE_NOTECARD == LLToolDragAndDrop::getInstance()->mSource))
+ {
+ LL_WARNS() << "Call to LLToolDragAndDrop::dropInventory() from world"
+ << " or notecard." << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ time_t creation_date = time_corrected();
+ new_item->setCreationDate(creation_date);
+
+ if (!item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ if (SOURCE_AGENT == source)
+ {
+ // Remove the inventory item from local inventory. The
+ // server will actually remove the item from agent
+ // inventory.
+ gInventory.deleteObject(item->getUUID());
+ gInventory.notifyObservers();
+ }
+ else if (SOURCE_WORLD == source)
+ {
+ // *FIX: if the objects are in different regions, and the
+ // source region has crashed, you can bypass these
+ // permissions.
+ LLViewerObject* src_obj = gObjectList.findObject(src_id);
+ if (src_obj)
+ {
+ src_obj->removeInventory(item->getUUID());
+ }
+ else
+ {
+ LL_WARNS() << "Unable to find source object." << LL_ENDL;
+ return;
+ }
+ }
+ }
+ hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ if (LLFloaterReg::instanceVisible("build"))
+ {
+ // *FIX: only show this if panel not expanded?
+ LLFloaterReg::showInstance("build", "Content");
+ }
+
+ // VEFFECT: AddToInventory
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(hit_obj);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ gFloaterTools->dirty();
}
// accessor that looks at permissions, copyability, and names of
// inventory items to determine if a drop would be ok.
EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item, EDragAndDropType type)
{
- // check the basics
- if (!item || !obj) return ACCEPT_NO;
- // HACK: downcast
- LLViewerInventoryItem* vitem = (LLViewerInventoryItem*)item;
- if (!vitem->isFinished() && (type != DAD_CATEGORY))
- {
- // Note: for DAD_CATEGORY we assume that folder version check passed and folder
- // is complete, meaning that items inside are up to date.
- // (isFinished() == false) at the moment shows that item was loaded from cache.
- // Library or agent inventory only.
- return ACCEPT_NO;
- }
- if (vitem->getIsLinkType()) return ACCEPT_NO; // No giving away links
-
- // deny attempts to drop from an object onto itself. This is to
- // help make sure that drops that are from an object to an object
- // don't have to worry about order of evaluation. Think of this
- // like check for self in assignment.
- if(obj->getID() == item->getParentUUID())
- {
- return ACCEPT_NO;
- }
-
- //BOOL copy = (perm.allowCopyBy(gAgent.getID(),
- // gAgent.getGroupID())
- // && (obj->mPermModify || obj->mFlagAllowInventoryAdd));
- BOOL worn = FALSE;
- LLVOAvatarSelf* my_avatar = NULL;
- switch(item->getType())
- {
- case LLAssetType::AT_OBJECT:
- my_avatar = gAgentAvatarp;
- if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
- {
- worn = TRUE;
- }
- break;
- case LLAssetType::AT_BODYPART:
- case LLAssetType::AT_CLOTHING:
- if(gAgentWearables.isWearingItem(item->getUUID()))
- {
- worn = TRUE;
- }
- break;
- case LLAssetType::AT_CALLINGCARD:
- // Calling Cards in object are disabled for now
- // because of incomplete LSL support. See STORM-1117.
- return ACCEPT_NO;
- default:
- break;
- }
- const LLPermissions& perm = item->getPermissions();
- BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd());
- BOOL transfer = FALSE;
- if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID()))
- || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID()))
- {
- transfer = TRUE;
- }
- BOOL volume = (LL_PCODE_VOLUME == obj->getPCode());
- BOOL attached = obj->isAttachment();
- BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
- if(attached && !unrestricted)
- {
+ // check the basics
+ if (!item || !obj) return ACCEPT_NO;
+ // HACK: downcast
+ LLViewerInventoryItem* vitem = (LLViewerInventoryItem*)item;
+ if (!vitem->isFinished() && (type != DAD_CATEGORY))
+ {
+ // Note: for DAD_CATEGORY we assume that folder version check passed and folder
+ // is complete, meaning that items inside are up to date.
+ // (isFinished() == false) at the moment shows that item was loaded from cache.
+ // Library or agent inventory only.
+ return ACCEPT_NO;
+ }
+ if (vitem->getIsLinkType()) return ACCEPT_NO; // No giving away links
+
+ // deny attempts to drop from an object onto itself. This is to
+ // help make sure that drops that are from an object to an object
+ // don't have to worry about order of evaluation. Think of this
+ // like check for self in assignment.
+ if(obj->getID() == item->getParentUUID())
+ {
+ return ACCEPT_NO;
+ }
+
+ //BOOL copy = (perm.allowCopyBy(gAgent.getID(),
+ // gAgent.getGroupID())
+ // && (obj->mPermModify || obj->mFlagAllowInventoryAdd));
+ BOOL worn = FALSE;
+ LLVOAvatarSelf* my_avatar = NULL;
+ switch(item->getType())
+ {
+ case LLAssetType::AT_OBJECT:
+ my_avatar = gAgentAvatarp;
+ if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
+ {
+ worn = TRUE;
+ }
+ break;
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_CLOTHING:
+ if(gAgentWearables.isWearingItem(item->getUUID()))
+ {
+ worn = TRUE;
+ }
+ break;
+ case LLAssetType::AT_CALLINGCARD:
+ // Calling Cards in object are disabled for now
+ // because of incomplete LSL support. See STORM-1117.
+ return ACCEPT_NO;
+ default:
+ break;
+ }
+ const LLPermissions& perm = item->getPermissions();
+ BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd());
+ BOOL transfer = FALSE;
+ if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID()))
+ || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ transfer = TRUE;
+ }
+ BOOL volume = (LL_PCODE_VOLUME == obj->getPCode());
+ BOOL attached = obj->isAttachment();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if(attached && !unrestricted)
+ {
// Attachments are in world and in inventory simultaneously,
// at the moment server doesn't support such a situation.
- return ACCEPT_NO_LOCKED;
- }
- else if(modify && transfer && volume && !worn)
- {
- return ACCEPT_YES_MULTI;
- }
- else if(!modify)
- {
- return ACCEPT_NO_LOCKED;
- }
- return ACCEPT_NO;
+ return ACCEPT_NO_LOCKED;
+ }
+ else if(modify && transfer && volume && !worn)
+ {
+ return ACCEPT_YES_MULTI;
+ }
+ else if(!modify)
+ {
+ return ACCEPT_NO_LOCKED;
+ }
+ return ACCEPT_NO;
}
static void give_inventory_cb(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- // if Cancel pressed
- if (option == 1)
- {
- return;
- }
-
- LLSD payload = notification["payload"];
- const LLUUID& session_id = payload["session_id"];
- const LLUUID& agent_id = payload["agent_id"];
- LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]);
- LLViewerInventoryCategory * inv_cat = gInventory.getCategory(payload["item_id"]);
- if (NULL == inv_item && NULL == inv_cat)
- {
- llassert( FALSE );
- return;
- }
- bool successfully_shared;
- if (inv_item)
- {
- successfully_shared = LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id);
- }
- else
- {
- successfully_shared = LLGiveInventory::doGiveInventoryCategory(agent_id, inv_cat, session_id);
- }
- if (successfully_shared)
- {
- if ("avatarpicker" == payload["d&d_dest"].asString())
- {
- LLFloaterReg::hideInstance("avatar_picker");
- }
- LLNotificationsUtil::add("ItemsShared");
- }
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
+
+ LLSD payload = notification["payload"];
+ const LLUUID& session_id = payload["session_id"];
+ const LLUUID& agent_id = payload["agent_id"];
+ LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]);
+ LLViewerInventoryCategory * inv_cat = gInventory.getCategory(payload["item_id"]);
+ if (NULL == inv_item && NULL == inv_cat)
+ {
+ llassert( FALSE );
+ return;
+ }
+ bool successfully_shared;
+ if (inv_item)
+ {
+ successfully_shared = LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id);
+ }
+ else
+ {
+ successfully_shared = LLGiveInventory::doGiveInventoryCategory(agent_id, inv_cat, session_id);
+ }
+ if (successfully_shared)
+ {
+ if ("avatarpicker" == payload["d&d_dest"].asString())
+ {
+ LLFloaterReg::hideInstance("avatar_picker");
+ }
+ LLNotificationsUtil::add("ItemsShared");
+ }
}
static void show_object_sharing_confirmation(const std::string name,
- LLInventoryObject* inv_item,
- const LLSD& dest,
- const LLUUID& dest_agent,
- const LLUUID& session_id = LLUUID::null)
-{
- if (!inv_item)
- {
- llassert(NULL != inv_item);
- return;
- }
- LLSD substitutions;
- substitutions["RESIDENTS"] = name;
- substitutions["ITEMS"] = inv_item->getName();
- LLSD payload;
- payload["agent_id"] = dest_agent;
- payload["item_id"] = inv_item->getUUID();
- payload["session_id"] = session_id;
- payload["d&d_dest"] = dest.asString();
- LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb);
+ LLInventoryObject* inv_item,
+ const LLSD& dest,
+ const LLUUID& dest_agent,
+ const LLUUID& session_id = LLUUID::null)
+{
+ if (!inv_item)
+ {
+ llassert(NULL != inv_item);
+ return;
+ }
+ LLSD substitutions;
+ substitutions["RESIDENTS"] = name;
+ substitutions["ITEMS"] = inv_item->getName();
+ LLSD payload;
+ payload["agent_id"] = dest_agent;
+ payload["item_id"] = inv_item->getUUID();
+ payload["session_id"] = session_id;
+ payload["d&d_dest"] = dest.asString();
+ LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb);
}
static void get_name_cb(const LLUUID& id,
- const LLAvatarName& av_name,
- LLInventoryObject* inv_obj,
- const LLSD& dest,
- const LLUUID& dest_agent)
+ const LLAvatarName& av_name,
+ LLInventoryObject* inv_obj,
+ const LLSD& dest,
+ const LLUUID& dest_agent)
{
- show_object_sharing_confirmation(av_name.getUserName(),
- inv_obj,
- dest,
- id,
- LLUUID::null);
+ show_object_sharing_confirmation(av_name.getUserName(),
+ inv_obj,
+ dest,
+ id,
+ LLUUID::null);
}
// function used as drag-and-drop handler for simple agent give inventory requests
//static
bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- const LLSD& dest)
-{
- // check the type
- switch(cargo_type)
- {
- case DAD_TEXTURE:
- case DAD_SOUND:
- case DAD_LANDMARK:
- case DAD_SCRIPT:
- case DAD_OBJECT:
- case DAD_NOTECARD:
- case DAD_CLOTHING:
- case DAD_BODYPART:
- case DAD_ANIMATION:
- case DAD_GESTURE:
- case DAD_CALLINGCARD:
- case DAD_MESH:
- case DAD_CATEGORY:
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ const LLSD& dest)
+{
+ // check the type
+ switch(cargo_type)
+ {
+ case DAD_TEXTURE:
+ case DAD_SOUND:
+ case DAD_LANDMARK:
+ case DAD_SCRIPT:
+ case DAD_OBJECT:
+ case DAD_NOTECARD:
+ case DAD_CLOTHING:
+ case DAD_BODYPART:
+ case DAD_ANIMATION:
+ case DAD_GESTURE:
+ case DAD_CALLINGCARD:
+ case DAD_MESH:
+ case DAD_CATEGORY:
case DAD_SETTINGS:
case DAD_MATERIAL:
- {
- LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
- if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
- && LLGiveInventory::isInventoryGiveAcceptable(dynamic_cast<LLInventoryItem*>(inv_obj))))
- {
- // *TODO: get multiple object transfers working
- *accept = ACCEPT_YES_COPY_SINGLE;
- if(drop)
- {
- LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id);
-
- // If no IM session found get the destination agent's name by id.
- if (NULL == session)
- {
- LLAvatarName av_name;
-
- // If destination agent's name is found in cash proceed to showing the confirmation dialog.
- // Otherwise set up a callback to show the dialog when the name arrives.
- if (LLAvatarNameCache::get(dest_agent, &av_name))
- {
- show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null);
- }
- else
- {
- LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
- }
-
- return true;
- }
- std::string dest_name = session->mName;
- LLAvatarName av_name;
- if(LLAvatarNameCache::get(dest_agent, &av_name))
- {
- dest_name = av_name.getCompleteName();
- }
- // If an IM session with destination agent is found item offer will be logged in this session.
- show_object_sharing_confirmation(dest_name, inv_obj, dest, dest_agent, session_id);
- }
- }
- else
- {
- // It's not in the user's inventory (it's probably
- // in an object's contents), so disallow dragging
- // it here. You can't give something you don't
- // yet have.
- *accept = ACCEPT_NO;
- }
- break;
- }
- default:
- *accept = ACCEPT_NO;
- break;
- }
-
- return TRUE;
+ {
+ LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
+ if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
+ && LLGiveInventory::isInventoryGiveAcceptable(dynamic_cast<LLInventoryItem*>(inv_obj))))
+ {
+ // *TODO: get multiple object transfers working
+ *accept = ACCEPT_YES_COPY_SINGLE;
+ if(drop)
+ {
+ LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id);
+
+ // If no IM session found get the destination agent's name by id.
+ if (NULL == session)
+ {
+ LLAvatarName av_name;
+
+ // If destination agent's name is found in cash proceed to showing the confirmation dialog.
+ // Otherwise set up a callback to show the dialog when the name arrives.
+ if (LLAvatarNameCache::get(dest_agent, &av_name))
+ {
+ show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null);
+ }
+ else
+ {
+ LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
+ }
+
+ return true;
+ }
+ std::string dest_name = session->mName;
+ LLAvatarName av_name;
+ if(LLAvatarNameCache::get(dest_agent, &av_name))
+ {
+ dest_name = av_name.getCompleteName();
+ }
+ // If an IM session with destination agent is found item offer will be logged in this session.
+ show_object_sharing_confirmation(dest_name, inv_obj, dest, dest_agent, session_id);
+ }
+ }
+ else
+ {
+ // It's not in the user's inventory (it's probably
+ // in an object's contents), so disallow dragging
+ // it here. You can't give something you don't
+ // yet have.
+ *accept = ACCEPT_NO;
+ }
+ break;
+ }
+ default:
+ *accept = ACCEPT_NO;
+ break;
+ }
+
+ return TRUE;
}
@@ -2066,278 +2086,278 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
///
EAcceptance LLToolDragAndDrop::dad3dNULL(
- LLViewerObject*, S32, MASK, BOOL)
+ LLViewerObject*, S32, MASK, BOOL)
{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dNULL()" << LL_ENDL;
- return ACCEPT_NO;
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dNULL()" << LL_ENDL;
+ return ACCEPT_NO;
}
EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << LL_ENDL;
- // must be in the user's inventory
- if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
- {
- return ACCEPT_NO;
- }
-
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
-
- // must not be in the trash
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
- {
- return ACCEPT_NO;
- }
-
- // must not be already wearing it
- LLVOAvatarSelf* avatar = gAgentAvatarp;
- if( !avatar || avatar->isWearingAttachment(item->getUUID()) )
- {
- return ACCEPT_NO;
- }
-
- const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX);
- if(outbox_id.notNull() && gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
- {
- // Legacy
- return ACCEPT_NO;
- }
-
-
- if( drop )
- {
- if(mSource == SOURCE_LIBRARY)
- {
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- LLUUID::null,
- std::string(),
- cb);
- }
- else
- {
- rez_attachment(item, 0);
- }
- }
- return ACCEPT_YES_SINGLE;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << LL_ENDL;
+ // must be in the user's inventory
+ if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY)
+ {
+ return ACCEPT_NO;
+ }
+
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+
+ // must not be in the trash
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ // must not be already wearing it
+ LLVOAvatarSelf* avatar = gAgentAvatarp;
+ if( !avatar || avatar->isWearingAttachment(item->getUUID()) )
+ {
+ return ACCEPT_NO;
+ }
+
+ const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX);
+ if(outbox_id.notNull() && gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
+ {
+ // Legacy
+ return ACCEPT_NO;
+ }
+
+
+ if( drop )
+ {
+ if(mSource == SOURCE_LIBRARY)
+ {
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ else
+ {
+ rez_attachment(item, 0);
+ }
+ }
+ return ACCEPT_YES_SINGLE;
}
EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- if (mSource == SOURCE_WORLD)
- {
- return dad3dRezFromObjectOnLand(obj, face, mask, drop);
- }
-
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnLand()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
-
- LLVOAvatarSelf* my_avatar = gAgentAvatarp;
- if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
- {
- return ACCEPT_NO;
- }
-
- EAcceptance accept;
- BOOL remove_inventory;
-
- // Get initial settings based on shift key
- if (mask & MASK_SHIFT)
- {
- // For now, always make copy
- //accept = ACCEPT_YES_SINGLE;
- //remove_inventory = TRUE;
- accept = ACCEPT_YES_COPY_SINGLE;
- remove_inventory = FALSE;
- }
- else
- {
- accept = ACCEPT_YES_COPY_SINGLE;
- remove_inventory = FALSE;
- }
-
- // check if the item can be copied. If not, send that to the sim
- // which will remove the inventory item.
- if(!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- accept = ACCEPT_YES_SINGLE;
- remove_inventory = TRUE;
- }
-
- // Check if it's in the trash.
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
- {
- accept = ACCEPT_YES_SINGLE;
- }
-
- if(drop)
- {
- dropObject(obj, TRUE, FALSE, remove_inventory);
- }
-
- return accept;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ if (mSource == SOURCE_WORLD)
+ {
+ return dad3dRezFromObjectOnLand(obj, face, mask, drop);
+ }
+
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnLand()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+
+ LLVOAvatarSelf* my_avatar = gAgentAvatarp;
+ if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ EAcceptance accept;
+ BOOL remove_inventory;
+
+ // Get initial settings based on shift key
+ if (mask & MASK_SHIFT)
+ {
+ // For now, always make copy
+ //accept = ACCEPT_YES_SINGLE;
+ //remove_inventory = TRUE;
+ accept = ACCEPT_YES_COPY_SINGLE;
+ remove_inventory = FALSE;
+ }
+ else
+ {
+ accept = ACCEPT_YES_COPY_SINGLE;
+ remove_inventory = FALSE;
+ }
+
+ // check if the item can be copied. If not, send that to the sim
+ // which will remove the inventory item.
+ if(!item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ accept = ACCEPT_YES_SINGLE;
+ remove_inventory = TRUE;
+ }
+
+ // Check if it's in the trash.
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
+ {
+ accept = ACCEPT_YES_SINGLE;
+ }
+
+ if(drop)
+ {
+ dropObject(obj, TRUE, FALSE, remove_inventory);
+ }
+
+ return accept;
}
EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- // handle objects coming from object inventory
- if (mSource == SOURCE_WORLD)
- {
- return dad3dRezFromObjectOnObject(obj, face, mask, drop);
- }
-
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnObject()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- LLVOAvatarSelf* my_avatar = gAgentAvatarp;
- if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
- {
- return ACCEPT_NO;
- }
-
- if((mask & MASK_CONTROL))
- {
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if(mSource == SOURCE_NOTECARD)
- {
- return ACCEPT_NO;
- }
-
- EAcceptance rv = willObjectAcceptInventory(obj, item);
- if(drop && (ACCEPT_YES_SINGLE <= rv))
- {
- dropInventory(obj, item, mSource, mSourceID);
- }
- return rv;
- }
-
- EAcceptance accept;
- BOOL remove_inventory;
-
- if (mask & MASK_SHIFT)
- {
- // For now, always make copy
- //accept = ACCEPT_YES_SINGLE;
- //remove_inventory = TRUE;
- accept = ACCEPT_YES_COPY_SINGLE;
- remove_inventory = FALSE;
- }
- else
- {
- accept = ACCEPT_YES_COPY_SINGLE;
- remove_inventory = FALSE;
- }
-
- // check if the item can be copied. If not, send that to the sim
- // which will remove the inventory item.
- if(!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- accept = ACCEPT_YES_SINGLE;
- remove_inventory = TRUE;
- }
-
- // Check if it's in the trash.
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
- {
- accept = ACCEPT_YES_SINGLE;
- remove_inventory = TRUE;
- }
-
- if(drop)
- {
- dropObject(obj, FALSE, FALSE, remove_inventory);
- }
-
- return accept;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ // handle objects coming from object inventory
+ if (mSource == SOURCE_WORLD)
+ {
+ return dad3dRezFromObjectOnObject(obj, face, mask, drop);
+ }
+
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezObjectOnObject()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ LLVOAvatarSelf* my_avatar = gAgentAvatarp;
+ if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ if((mask & MASK_CONTROL))
+ {
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if(mSource == SOURCE_NOTECARD)
+ {
+ return ACCEPT_NO;
+ }
+
+ EAcceptance rv = willObjectAcceptInventory(obj, item);
+ if(drop && (ACCEPT_YES_SINGLE <= rv))
+ {
+ dropInventory(obj, item, mSource, mSourceID);
+ }
+ return rv;
+ }
+
+ EAcceptance accept;
+ BOOL remove_inventory;
+
+ if (mask & MASK_SHIFT)
+ {
+ // For now, always make copy
+ //accept = ACCEPT_YES_SINGLE;
+ //remove_inventory = TRUE;
+ accept = ACCEPT_YES_COPY_SINGLE;
+ remove_inventory = FALSE;
+ }
+ else
+ {
+ accept = ACCEPT_YES_COPY_SINGLE;
+ remove_inventory = FALSE;
+ }
+
+ // check if the item can be copied. If not, send that to the sim
+ // which will remove the inventory item.
+ if(!item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ accept = ACCEPT_YES_SINGLE;
+ remove_inventory = TRUE;
+ }
+
+ // Check if it's in the trash.
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
+ {
+ accept = ACCEPT_YES_SINGLE;
+ remove_inventory = TRUE;
+ }
+
+ if(drop)
+ {
+ dropObject(obj, FALSE, FALSE, remove_inventory);
+ }
+
+ return accept;
}
EAcceptance LLToolDragAndDrop::dad3dRezScript(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezScript()" << LL_ENDL;
-
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
- {
- return ACCEPT_NO;
- }
-
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- EAcceptance rv = willObjectAcceptInventory(obj, item);
- if(drop && (ACCEPT_YES_SINGLE <= rv))
- {
- // rez in the script active by default, rez in inactive if the
- // control key is being held down.
- BOOL active = ((mask & MASK_CONTROL) == 0);
-
- LLViewerObject* root_object = obj;
- if (obj && obj->getParent())
- {
- LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
- if (!parent_obj->isAvatar())
- {
- root_object = parent_obj;
- }
- }
-
- dropScript(root_object, item, active, mSource, mSourceID);
- }
- return rv;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezScript()" << LL_ENDL;
+
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
+ {
+ return ACCEPT_NO;
+ }
+
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ EAcceptance rv = willObjectAcceptInventory(obj, item);
+ if(drop && (ACCEPT_YES_SINGLE <= rv))
+ {
+ // rez in the script active by default, rez in inactive if the
+ // control key is being held down.
+ BOOL active = ((mask & MASK_CONTROL) == 0);
+
+ LLViewerObject* root_object = obj;
+ if (obj && obj->getParent())
+ {
+ LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
+ if (!parent_obj->isAvatar())
+ {
+ root_object = parent_obj;
+ }
+ }
+
+ dropScript(root_object, item, active, mSource, mSourceID);
+ }
+ return rv;
}
EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dApplyToObject()" << LL_ENDL;
-
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
- {
- return ACCEPT_NO;
- }
-
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dApplyToObject()" << LL_ENDL;
+
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
+ {
+ return ACCEPT_NO;
+ }
+
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
LLPermissions item_permissions = item->getPermissions();
- EAcceptance rv = willObjectAcceptInventory(obj, item);
- if((mask & MASK_CONTROL))
- {
- if((ACCEPT_YES_SINGLE <= rv) && drop)
- {
- dropInventory(obj, item, mSource, mSourceID);
- }
- return rv;
- }
- if(!obj->permModify())
- {
- return ACCEPT_NO_LOCKED;
- }
+ EAcceptance rv = willObjectAcceptInventory(obj, item);
+ if((mask & MASK_CONTROL))
+ {
+ if((ACCEPT_YES_SINGLE <= rv) && drop)
+ {
+ dropInventory(obj, item, mSource, mSourceID);
+ }
+ return rv;
+ }
+ if(!obj->permModify())
+ {
+ return ACCEPT_NO_LOCKED;
+ }
if (cargo_type == DAD_TEXTURE && (mask & MASK_ALT) == 0)
{
@@ -2369,10 +2389,10 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
}
}
- if(drop && (ACCEPT_YES_SINGLE <= rv))
- {
- if (cargo_type == DAD_TEXTURE)
- {
+ if(drop && (ACCEPT_YES_SINGLE <= rv))
+ {
+ if (cargo_type == DAD_TEXTURE)
+ {
bool all_faces = mask & MASK_SHIFT;
bool remove_pbr = mask & MASK_ALT;
if (item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()))
@@ -2394,7 +2414,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
dropTexture(obj, face, item, source, source_id, all_faces, remove_pbr);
});
}
- }
+ }
else if (cargo_type == DAD_MATERIAL)
{
bool all_faces = mask & MASK_SHIFT;
@@ -2418,32 +2438,32 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
});
}
}
- else if (cargo_type == DAD_MESH)
- {
- dropMesh(obj, item, mSource, mSourceID);
- }
- else
- {
- LL_WARNS() << "unsupported asset type" << LL_ENDL;
- }
-
- // VEFFECT: SetTexture
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setTargetObject(obj);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- }
+ else if (cargo_type == DAD_MESH)
+ {
+ dropMesh(obj, item, mSource, mSourceID);
+ }
+ else
+ {
+ LL_WARNS() << "unsupported asset type" << LL_ENDL;
+ }
+
+ // VEFFECT: SetTexture
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(obj);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
- // enable multi-drop, although last texture will win
- return ACCEPT_YES_MULTI;
+ // enable multi-drop, although last texture will win
+ return ACCEPT_YES_MULTI;
}
EAcceptance LLToolDragAndDrop::dad3dTextureObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
- return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
+ return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
}
EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
@@ -2453,506 +2473,506 @@ EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
}
EAcceptance LLToolDragAndDrop::dad3dMeshObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
- return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH);
+ return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH);
}
EAcceptance LLToolDragAndDrop::dad3dWearItem(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearItem()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
-
- if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
- {
- // it's in the agent inventory
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
- {
- return ACCEPT_NO;
- }
-
- if( drop )
- {
- // TODO: investigate wearables may not be loaded at this point EXT-8231
-
- LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
- }
- return ACCEPT_YES_MULTI;
- }
- else
- {
- // TODO: copy/move item to avatar's inventory and then wear it.
- return ACCEPT_NO;
- }
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearItem()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+
+ if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
+ {
+ // it's in the agent inventory
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ if( drop )
+ {
+ // TODO: investigate wearables may not be loaded at this point EXT-8231
+
+ LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
+ }
+ return ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ // TODO: copy/move item to avatar's inventory and then wear it.
+ return ACCEPT_NO;
+ }
}
EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dActivateGesture()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
-
- if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
- {
- // it's in the agent inventory
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
- {
- return ACCEPT_NO;
- }
-
- if( drop )
- {
- LLUUID item_id;
- if(mSource == SOURCE_LIBRARY)
- {
- // create item based on that one, and put it on if that
- // was a success.
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- LLUUID::null,
- std::string(),
- cb);
- }
- else
- {
- LLGestureMgr::instance().activateGesture(item->getUUID());
- gInventory.updateItem(item);
- gInventory.notifyObservers();
- }
- }
- return ACCEPT_YES_MULTI;
- }
- else
- {
- return ACCEPT_NO;
- }
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dActivateGesture()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+
+ if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY)
+ {
+ // it's in the agent inventory
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ if( drop )
+ {
+ LLUUID item_id;
+ if(mSource == SOURCE_LIBRARY)
+ {
+ // create item based on that one, and put it on if that
+ // was a success.
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ else
+ {
+ LLGestureMgr::instance().activateGesture(item->getUUID());
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+ return ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ return ACCEPT_NO;
+ }
}
EAcceptance LLToolDragAndDrop::dad3dWearCategory(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearCategory()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* category;
- locateInventory(item, category);
- if(!category) return ACCEPT_NO;
-
- if (drop)
- {
- // TODO: investigate wearables may not be loaded at this point EXT-8231
- }
-
- U32 max_items = gSavedSettings.getU32("WearFolderLimit");
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
- gInventory.collectDescendentsIf(category->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- not_worn);
- if (items.size() > max_items)
- {
- LLStringUtil::format_map_t args;
- args["AMOUNT"] = llformat("%d", max_items);
- mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
- return ACCEPT_NO_CUSTOM;
- }
-
- if(mSource == SOURCE_AGENT)
- {
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) )
- {
- return ACCEPT_NO;
- }
-
- const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX);
- if(outbox_id.notNull() && gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
- {
- // Legacy
- return ACCEPT_NO;
- }
-
- if(drop)
- {
- BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE );
- LLAppearanceMgr::instance().wearInventoryCategory(category, false, append);
- }
- return ACCEPT_YES_MULTI;
- }
- else if(mSource == SOURCE_LIBRARY)
- {
- if(drop)
- {
- LLAppearanceMgr::instance().wearInventoryCategory(category, true, false);
- }
- return ACCEPT_YES_MULTI;
- }
- else
- {
- // TODO: copy/move category to avatar's inventory and then wear it.
- return ACCEPT_NO;
- }
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dWearCategory()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* category;
+ locateInventory(item, category);
+ if(!category) return ACCEPT_NO;
+
+ if (drop)
+ {
+ // TODO: investigate wearables may not be loaded at this point EXT-8231
+ }
+
+ U32 max_items = gSavedSettings.getU32("WearFolderLimit");
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
+ gInventory.collectDescendentsIf(category->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ not_worn);
+ if (items.size() > max_items)
+ {
+ LLStringUtil::format_map_t args;
+ args["AMOUNT"] = llformat("%d", max_items);
+ mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
+ return ACCEPT_NO_CUSTOM;
+ }
+
+ if(mSource == SOURCE_AGENT)
+ {
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) )
+ {
+ return ACCEPT_NO;
+ }
+
+ const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX);
+ if(outbox_id.notNull() && gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
+ {
+ // Legacy
+ return ACCEPT_NO;
+ }
+
+ if(drop)
+ {
+ BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE );
+ LLAppearanceMgr::instance().wearInventoryCategory(category, false, append);
+ }
+ return ACCEPT_YES_MULTI;
+ }
+ else if(mSource == SOURCE_LIBRARY)
+ {
+ if(drop)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory(category, true, false);
+ }
+ return ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ // TODO: copy/move category to avatar's inventory and then wear it.
+ return ACCEPT_NO;
+ }
}
EAcceptance LLToolDragAndDrop::dad3dUpdateInventory(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dadUpdateInventory()" << LL_ENDL;
-
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
- {
- return ACCEPT_NO;
- }
-
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- LLViewerObject* root_object = obj;
- if (obj && obj->getParent())
- {
- LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
- if (!parent_obj->isAvatar())
- {
- root_object = parent_obj;
- }
- }
-
- EAcceptance rv = willObjectAcceptInventory(root_object, item);
- if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv))
- {
- dropInventory(root_object, item, mSource, mSourceID);
- }
- return rv;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dadUpdateInventory()" << LL_ENDL;
+
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource))
+ {
+ return ACCEPT_NO;
+ }
+
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ LLViewerObject* root_object = obj;
+ if (obj && obj->getParent())
+ {
+ LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
+ if (!parent_obj->isAvatar())
+ {
+ root_object = parent_obj;
+ }
+ }
+
+ EAcceptance rv = willObjectAcceptInventory(root_object, item);
+ if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv))
+ {
+ dropInventory(root_object, item, mSource, mSourceID);
+ }
+ return rv;
}
BOOL LLToolDragAndDrop::dadUpdateInventory(LLViewerObject* obj, BOOL drop)
{
- EAcceptance rv = dad3dUpdateInventory(obj, -1, MASK_NONE, drop);
- return (rv >= ACCEPT_YES_COPY_SINGLE);
+ EAcceptance rv = dad3dUpdateInventory(obj, -1, MASK_NONE, drop);
+ return (rv >= ACCEPT_YES_COPY_SINGLE);
}
EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << LL_ENDL;
- if (obj == NULL)
- {
- LL_WARNS() << "obj is NULL; aborting func with ACCEPT_NO" << LL_ENDL;
- return ACCEPT_NO;
- }
-
- if ((mSource != SOURCE_AGENT) && (mSource != SOURCE_LIBRARY))
- {
- return ACCEPT_NO;
- }
- if (obj->isAttachment())
- {
- return ACCEPT_NO_LOCKED;
- }
-
- LLViewerInventoryItem* item = NULL;
- LLViewerInventoryCategory* cat = NULL;
- locateInventory(item, cat);
- if (!cat)
- {
- return ACCEPT_NO;
- }
-
- // Find all the items in the category
- LLDroppableItem droppable(!obj->permYouOwner());
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendentsIf(cat->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- droppable);
- cats.push_back(cat);
- if (droppable.countNoCopy() > 0)
- {
- LL_WARNS() << "*** Need to confirm this step" << LL_ENDL;
- }
- LLViewerObject* root_object = obj;
- if (obj->getParent())
- {
- LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
- if (!parent_obj->isAvatar())
- {
- root_object = parent_obj;
- }
- }
-
- EAcceptance rv = ACCEPT_NO;
-
- // Check for accept
- for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin();
- cat_iter != cats.end();
- ++cat_iter)
- {
- const LLViewerInventoryCategory *cat = (*cat_iter);
- rv = gInventory.isCategoryComplete(cat->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO;
- if(rv < ACCEPT_YES_SINGLE)
- {
- LL_DEBUGS() << "Category " << cat->getUUID() << "is not complete." << LL_ENDL;
- break;
- }
- }
- if (ACCEPT_YES_COPY_SINGLE <= rv)
- {
- for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin();
- item_iter != items.end();
- ++item_iter)
- {
- LLViewerInventoryItem *item = (*item_iter);
- /*
- // Pass the base objects, not the links.
- if (item && item->getIsLinkType())
- {
- item = item->getLinkedItem();
- (*item_iter) = item;
- }
- */
- rv = willObjectAcceptInventory(root_object, item, DAD_CATEGORY);
- if (rv < ACCEPT_YES_COPY_SINGLE)
- {
- LL_DEBUGS() << "Object will not accept " << item->getUUID() << LL_ENDL;
- break;
- }
- }
- }
-
- // If every item is accepted, send it on
- if (drop && (ACCEPT_YES_COPY_SINGLE <= rv))
- {
- uuid_vec_t ids;
- for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin();
- item_iter != items.end();
- ++item_iter)
- {
- const LLViewerInventoryItem *item = (*item_iter);
- ids.push_back(item->getUUID());
- }
- LLCategoryDropObserver* dropper = new LLCategoryDropObserver(ids, obj->getID(), mSource);
- dropper->startFetch();
- if (dropper->isFinished())
- {
- dropper->done();
- }
- else
- {
- gInventory.addObserver(dropper);
- }
- }
- return rv;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << LL_ENDL;
+ if (obj == NULL)
+ {
+ LL_WARNS() << "obj is NULL; aborting func with ACCEPT_NO" << LL_ENDL;
+ return ACCEPT_NO;
+ }
+
+ if ((mSource != SOURCE_AGENT) && (mSource != SOURCE_LIBRARY))
+ {
+ return ACCEPT_NO;
+ }
+ if (obj->isAttachment())
+ {
+ return ACCEPT_NO_LOCKED;
+ }
+
+ LLViewerInventoryItem* item = NULL;
+ LLViewerInventoryCategory* cat = NULL;
+ locateInventory(item, cat);
+ if (!cat)
+ {
+ return ACCEPT_NO;
+ }
+
+ // Find all the items in the category
+ LLDroppableItem droppable(!obj->permYouOwner());
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendentsIf(cat->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ droppable);
+ cats.push_back(cat);
+ if (droppable.countNoCopy() > 0)
+ {
+ LL_WARNS() << "*** Need to confirm this step" << LL_ENDL;
+ }
+ LLViewerObject* root_object = obj;
+ if (obj->getParent())
+ {
+ LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent();
+ if (!parent_obj->isAvatar())
+ {
+ root_object = parent_obj;
+ }
+ }
+
+ EAcceptance rv = ACCEPT_NO;
+
+ // Check for accept
+ for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin();
+ cat_iter != cats.end();
+ ++cat_iter)
+ {
+ const LLViewerInventoryCategory *cat = (*cat_iter);
+ rv = gInventory.isCategoryComplete(cat->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO;
+ if(rv < ACCEPT_YES_SINGLE)
+ {
+ LL_DEBUGS() << "Category " << cat->getUUID() << "is not complete." << LL_ENDL;
+ break;
+ }
+ }
+ if (ACCEPT_YES_COPY_SINGLE <= rv)
+ {
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ LLViewerInventoryItem *item = (*item_iter);
+ /*
+ // Pass the base objects, not the links.
+ if (item && item->getIsLinkType())
+ {
+ item = item->getLinkedItem();
+ (*item_iter) = item;
+ }
+ */
+ rv = willObjectAcceptInventory(root_object, item, DAD_CATEGORY);
+ if (rv < ACCEPT_YES_COPY_SINGLE)
+ {
+ LL_DEBUGS() << "Object will not accept " << item->getUUID() << LL_ENDL;
+ break;
+ }
+ }
+ }
+
+ // If every item is accepted, send it on
+ if (drop && (ACCEPT_YES_COPY_SINGLE <= rv))
+ {
+ uuid_vec_t ids;
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLViewerInventoryItem *item = (*item_iter);
+ ids.push_back(item->getUUID());
+ }
+ LLCategoryDropObserver* dropper = new LLCategoryDropObserver(ids, obj->getID(), mSource);
+ dropper->startFetch();
+ if (dropper->isFinished())
+ {
+ dropper->done();
+ }
+ else
+ {
+ gInventory.addObserver(dropper);
+ }
+ }
+ return rv;
}
EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
- if ((mask & MASK_CONTROL))
- {
- return dad3dUpdateInventoryCategory(obj, face, mask, drop);
- }
- else
- {
- return ACCEPT_NO;
- }
+ if ((mask & MASK_CONTROL))
+ {
+ return dad3dUpdateInventoryCategory(obj, face, mask, drop);
+ }
+ else
+ {
+ return ACCEPT_NO;
+ }
}
BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
- BOOL drop)
+ BOOL drop)
{
- EAcceptance rv = dad3dUpdateInventoryCategory(obj, -1, MASK_NONE, drop);
- return (rv >= ACCEPT_YES_COPY_SINGLE);
+ EAcceptance rv = dad3dUpdateInventoryCategory(obj, -1, MASK_NONE, drop);
+ return (rv >= ACCEPT_YES_COPY_SINGLE);
}
EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << LL_ENDL;
-
- // item has to be in agent inventory.
- if(mSource != SOURCE_AGENT) return ACCEPT_NO;
-
- // find the item now.
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
- {
- // cannot give away no-transfer objects
- return ACCEPT_NO;
- }
- LLVOAvatarSelf* avatar = gAgentAvatarp;
- if(avatar && avatar->isWearingAttachment( item->getUUID() ) )
- {
- // You can't give objects that are attached to you
- return ACCEPT_NO;
- }
- if( obj && avatar )
- {
- if(drop)
- {
- LLGiveInventory::doGiveInventoryItem(obj->getID(), item );
- }
- // *TODO: deal with all the issues surrounding multi-object
- // inventory transfers.
- return ACCEPT_YES_SINGLE;
- }
- return ACCEPT_NO;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << LL_ENDL;
+
+ // item has to be in agent inventory.
+ if(mSource != SOURCE_AGENT) return ACCEPT_NO;
+
+ // find the item now.
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ // cannot give away no-transfer objects
+ return ACCEPT_NO;
+ }
+ LLVOAvatarSelf* avatar = gAgentAvatarp;
+ if(avatar && avatar->isWearingAttachment( item->getUUID() ) )
+ {
+ // You can't give objects that are attached to you
+ return ACCEPT_NO;
+ }
+ if( obj && avatar )
+ {
+ if(drop)
+ {
+ LLGiveInventory::doGiveInventoryItem(obj->getID(), item );
+ }
+ // *TODO: deal with all the issues surrounding multi-object
+ // inventory transfers.
+ return ACCEPT_YES_SINGLE;
+ }
+ return ACCEPT_NO;
}
EAcceptance LLToolDragAndDrop::dad3dGiveInventory(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventory()" << LL_ENDL;
- // item has to be in agent inventory.
- if(mSource != SOURCE_AGENT) return ACCEPT_NO;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- if (!LLGiveInventory::isInventoryGiveAcceptable(item))
- {
- return ACCEPT_NO;
- }
- if (drop && obj)
- {
- LLGiveInventory::doGiveInventoryItem(obj->getID(), item);
- }
- // *TODO: deal with all the issues surrounding multi-object
- // inventory transfers.
- return ACCEPT_YES_SINGLE;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventory()" << LL_ENDL;
+ // item has to be in agent inventory.
+ if(mSource != SOURCE_AGENT) return ACCEPT_NO;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ if (!LLGiveInventory::isInventoryGiveAcceptable(item))
+ {
+ return ACCEPT_NO;
+ }
+ if (drop && obj)
+ {
+ LLGiveInventory::doGiveInventoryItem(obj->getID(), item);
+ }
+ // *TODO: deal with all the issues surrounding multi-object
+ // inventory transfers.
+ return ACCEPT_YES_SINGLE;
}
EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL;
- if(drop && obj)
- {
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if(!cat) return ACCEPT_NO;
- LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat);
- }
- // *TODO: deal with all the issues surrounding multi-object
- // inventory transfers.
- return ACCEPT_YES_SINGLE;
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL;
+ if(drop && obj)
+ {
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if(!cat) return ACCEPT_NO;
+ LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat);
+ }
+ // *TODO: deal with all the issues surrounding multi-object
+ // inventory transfers.
+ return ACCEPT_YES_SINGLE;
}
EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << LL_ENDL;
- LLViewerInventoryItem* item = NULL;
- LLViewerInventoryCategory* cat = NULL;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
-
- if(!gAgent.allowOperation(PERM_COPY, item->getPermissions())
- || !item->getPermissions().allowTransferTo(LLUUID::null))
- {
- return ACCEPT_NO_LOCKED;
- }
- if(drop)
- {
- dropObject(obj, TRUE, TRUE, FALSE);
- }
- return ACCEPT_YES_SINGLE;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << LL_ENDL;
+ LLViewerInventoryItem* item = NULL;
+ LLViewerInventoryCategory* cat = NULL;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+
+ if(!gAgent.allowOperation(PERM_COPY, item->getPermissions())
+ || !item->getPermissions().allowTransferTo(LLUUID::null))
+ {
+ return ACCEPT_NO_LOCKED;
+ }
+ if(drop)
+ {
+ dropObject(obj, TRUE, TRUE, FALSE);
+ }
+ return ACCEPT_YES_SINGLE;
}
EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject(
- LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
-{
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << LL_ENDL;
- LLViewerInventoryItem* item;
- LLViewerInventoryCategory* cat;
- locateInventory(item, cat);
- if (!item || !item->isFinished()) return ACCEPT_NO;
- if((mask & MASK_CONTROL))
- {
- // *HACK: In order to resolve SL-22177, we need to block drags
- // from notecards and objects onto other objects.
- return ACCEPT_NO;
-
- // *HACK: uncomment this when appropriate
- //EAcceptance rv = willObjectAcceptInventory(obj, item);
- //if(drop && (ACCEPT_YES_SINGLE <= rv))
- //{
- // dropInventory(obj, item, mSource, mSourceID);
- //}
- //return rv;
- }
- if(!item->getPermissions().allowCopyBy(gAgent.getID(),
- gAgent.getGroupID())
- || !item->getPermissions().allowTransferTo(LLUUID::null))
- {
- return ACCEPT_NO_LOCKED;
- }
- if(drop)
- {
- dropObject(obj, FALSE, TRUE, FALSE);
- }
- return ACCEPT_YES_SINGLE;
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << LL_ENDL;
+ LLViewerInventoryItem* item;
+ LLViewerInventoryCategory* cat;
+ locateInventory(item, cat);
+ if (!item || !item->isFinished()) return ACCEPT_NO;
+ if((mask & MASK_CONTROL))
+ {
+ // *HACK: In order to resolve SL-22177, we need to block drags
+ // from notecards and objects onto other objects.
+ return ACCEPT_NO;
+
+ // *HACK: uncomment this when appropriate
+ //EAcceptance rv = willObjectAcceptInventory(obj, item);
+ //if(drop && (ACCEPT_YES_SINGLE <= rv))
+ //{
+ // dropInventory(obj, item, mSource, mSourceID);
+ //}
+ //return rv;
+ }
+ if(!item->getPermissions().allowCopyBy(gAgent.getID(),
+ gAgent.getGroupID())
+ || !item->getPermissions().allowTransferTo(LLUUID::null))
+ {
+ return ACCEPT_NO_LOCKED;
+ }
+ if(drop)
+ {
+ dropObject(obj, FALSE, TRUE, FALSE);
+ }
+ return ACCEPT_YES_SINGLE;
}
EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand(
- LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
-{
- return ACCEPT_NO;
- /*
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dCategoryOnLand()" << LL_ENDL;
- LLInventoryItem* item;
- LLInventoryCategory* cat;
- locateInventory(item, cat);
- if(!cat) return ACCEPT_NO;
- EAcceptance rv = ACCEPT_NO;
-
- // find all the items in the category
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLDropCopyableItems droppable;
- gInventory.collectDescendentsIf(cat->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- droppable);
- if(items.size() > 0)
- {
- rv = ACCEPT_YES_SINGLE;
- }
- if((rv >= ACCEPT_YES_COPY_SINGLE) && drop)
- {
- createContainer(items, cat->getName());
- return ACCEPT_NO;
- }
- return rv;
- */
+ LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
+{
+ return ACCEPT_NO;
+ /*
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dCategoryOnLand()" << LL_ENDL;
+ LLInventoryItem* item;
+ LLInventoryCategory* cat;
+ locateInventory(item, cat);
+ if(!cat) return ACCEPT_NO;
+ EAcceptance rv = ACCEPT_NO;
+
+ // find all the items in the category
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLDropCopyableItems droppable;
+ gInventory.collectDescendentsIf(cat->getUUID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ droppable);
+ if(items.size() > 0)
+ {
+ rv = ACCEPT_YES_SINGLE;
+ }
+ if((rv >= ACCEPT_YES_COPY_SINGLE) && drop)
+ {
+ createContainer(items, cat->getName());
+ return ACCEPT_NO;
+ }
+ return rv;
+ */
}
@@ -2960,163 +2980,163 @@ EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand(
// This shortcuts alot of steps to make a basic object
// w/ an inventory and a special permissions set
EAcceptance LLToolDragAndDrop::dad3dAssetOnLand(
- LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
-{
- return ACCEPT_NO;
- /*
- LL_DEBUGS() << "LLToolDragAndDrop::dad3dAssetOnLand()" << LL_ENDL;
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLViewerInventoryItem::item_array_t copyable_items;
- locateMultipleInventory(items, cats);
- if(!items.size()) return ACCEPT_NO;
- EAcceptance rv = ACCEPT_NO;
- for (S32 i = 0; i < items.size(); i++)
- {
- LLInventoryItem* item = items[i];
- if(item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- copyable_items.push_back(item);
- rv = ACCEPT_YES_SINGLE;
- }
- }
-
- if((rv >= ACCEPT_YES_COPY_SINGLE) && drop)
- {
- createContainer(copyable_items, NULL);
- }
-
- return rv;
- */
+ LLViewerObject *obj, S32 face, MASK mask, BOOL drop)
+{
+ return ACCEPT_NO;
+ /*
+ LL_DEBUGS() << "LLToolDragAndDrop::dad3dAssetOnLand()" << LL_ENDL;
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLViewerInventoryItem::item_array_t copyable_items;
+ locateMultipleInventory(items, cats);
+ if(!items.size()) return ACCEPT_NO;
+ EAcceptance rv = ACCEPT_NO;
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLInventoryItem* item = items[i];
+ if(item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ copyable_items.push_back(item);
+ rv = ACCEPT_YES_SINGLE;
+ }
+ }
+
+ if((rv >= ACCEPT_YES_COPY_SINGLE) && drop)
+ {
+ createContainer(copyable_items, NULL);
+ }
+
+ return rv;
+ */
}
LLInventoryObject* LLToolDragAndDrop::locateInventory(
- LLViewerInventoryItem*& item,
- LLViewerInventoryCategory*& cat)
-{
- item = NULL;
- cat = NULL;
-
- if (mCargoIDs.empty()
- || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop.
- {
- return NULL;
- }
-
- if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
- {
- // The object should be in user inventory.
- item = (LLViewerInventoryItem*)gInventory.getItem(mCargoIDs[mCurItemIndex]);
- cat = (LLViewerInventoryCategory*)gInventory.getCategory(mCargoIDs[mCurItemIndex]);
- }
- else if(mSource == SOURCE_WORLD)
- {
- // This object is in some task inventory somewhere.
- LLViewerObject* obj = gObjectList.findObject(mSourceID);
- if(obj)
- {
- if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY)
- || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY))
- {
- cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
- }
- else
- {
- item = (LLViewerInventoryItem*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
- }
- }
- }
- else if(mSource == SOURCE_NOTECARD)
- {
- LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", mSourceID);
- if(preview)
- {
- item = (LLViewerInventoryItem*)preview->getDragItem();
- }
- }
- else if(mSource == SOURCE_VIEWER)
- {
- item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
- }
-
- if(item) return item;
- if(cat) return cat;
- return NULL;
+ LLViewerInventoryItem*& item,
+ LLViewerInventoryCategory*& cat)
+{
+ item = NULL;
+ cat = NULL;
+
+ if (mCargoIDs.empty()
+ || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop.
+ {
+ return NULL;
+ }
+
+ if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
+ {
+ // The object should be in user inventory.
+ item = (LLViewerInventoryItem*)gInventory.getItem(mCargoIDs[mCurItemIndex]);
+ cat = (LLViewerInventoryCategory*)gInventory.getCategory(mCargoIDs[mCurItemIndex]);
+ }
+ else if(mSource == SOURCE_WORLD)
+ {
+ // This object is in some task inventory somewhere.
+ LLViewerObject* obj = gObjectList.findObject(mSourceID);
+ if(obj)
+ {
+ if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY)
+ || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY))
+ {
+ cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
+ }
+ else
+ {
+ item = (LLViewerInventoryItem*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]);
+ }
+ }
+ }
+ else if(mSource == SOURCE_NOTECARD)
+ {
+ LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", mSourceID);
+ if(preview)
+ {
+ item = (LLViewerInventoryItem*)preview->getDragItem();
+ }
+ }
+ else if(mSource == SOURCE_VIEWER)
+ {
+ item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
+ }
+
+ if(item) return item;
+ if(cat) return cat;
+ return NULL;
}
/*
LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryCategory::cat_array_t& cats,
- LLViewerInventoryItem::item_array_t& items)
-{
- if(mCargoIDs.size() == 0) return NULL;
- if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
- {
- // The object should be in user inventory.
- for (S32 i = 0; i < mCargoIDs.size(); i++)
- {
- LLInventoryItem* item = gInventory.getItem(mCargoIDs[i]);
- if (item)
- {
- items.push_back(item);
- }
- LLInventoryCategory* category = gInventory.getCategory(mCargoIDs[i]);
- if (category)
- {
- cats.push_back(category);
- }
- }
- }
- else if(mSource == SOURCE_WORLD)
- {
- // This object is in some task inventory somewhere.
- LLViewerObject* obj = gObjectList.findObject(mSourceID);
- if(obj)
- {
- if((mCargoType == DAD_CATEGORY)
- || (mCargoType == DAD_ROOT_CATEGORY))
- {
- // The object should be in user inventory.
- for (S32 i = 0; i < mCargoIDs.size(); i++)
- {
- LLInventoryCategory* category = (LLInventoryCategory*)obj->getInventoryObject(mCargoIDs[i]);
- if (category)
- {
- cats.push_back(category);
- }
- }
- }
- else
- {
- for (S32 i = 0; i < mCargoIDs.size(); i++)
- {
- LLInventoryItem* item = (LLInventoryItem*)obj->getInventoryObject(mCargoIDs[i]);
- if (item)
- {
- items.push_back(item);
- }
- }
- }
- }
- }
- else if(mSource == SOURCE_NOTECARD)
- {
- LLPreviewNotecard* card;
- card = (LLPreviewNotecard*)LLPreview::find(mSourceID);
- if(card)
- {
- items.push_back((LLInventoryItem*)card->getDragItem());
- }
- }
- if(items.size()) return items[0];
- if(cats.size()) return cats[0];
- return NULL;
+ LLViewerInventoryItem::item_array_t& items)
+{
+ if(mCargoIDs.size() == 0) return NULL;
+ if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
+ {
+ // The object should be in user inventory.
+ for (S32 i = 0; i < mCargoIDs.size(); i++)
+ {
+ LLInventoryItem* item = gInventory.getItem(mCargoIDs[i]);
+ if (item)
+ {
+ items.push_back(item);
+ }
+ LLInventoryCategory* category = gInventory.getCategory(mCargoIDs[i]);
+ if (category)
+ {
+ cats.push_back(category);
+ }
+ }
+ }
+ else if(mSource == SOURCE_WORLD)
+ {
+ // This object is in some task inventory somewhere.
+ LLViewerObject* obj = gObjectList.findObject(mSourceID);
+ if(obj)
+ {
+ if((mCargoType == DAD_CATEGORY)
+ || (mCargoType == DAD_ROOT_CATEGORY))
+ {
+ // The object should be in user inventory.
+ for (S32 i = 0; i < mCargoIDs.size(); i++)
+ {
+ LLInventoryCategory* category = (LLInventoryCategory*)obj->getInventoryObject(mCargoIDs[i]);
+ if (category)
+ {
+ cats.push_back(category);
+ }
+ }
+ }
+ else
+ {
+ for (S32 i = 0; i < mCargoIDs.size(); i++)
+ {
+ LLInventoryItem* item = (LLInventoryItem*)obj->getInventoryObject(mCargoIDs[i]);
+ if (item)
+ {
+ items.push_back(item);
+ }
+ }
+ }
+ }
+ }
+ else if(mSource == SOURCE_NOTECARD)
+ {
+ LLPreviewNotecard* card;
+ card = (LLPreviewNotecard*)LLPreview::find(mSourceID);
+ if(card)
+ {
+ items.push_back((LLInventoryItem*)card->getDragItem());
+ }
+ }
+ if(items.size()) return items[0];
+ if(cats.size()) return cats[0];
+ return NULL;
}
*/
// void LLToolDragAndDrop::createContainer(LLViewerInventoryItem::item_array_t &items, const char* preferred_name )
// {
-// LL_WARNS() << "LLToolDragAndDrop::createContainer()" << LL_ENDL;
-// return;
+// LL_WARNS() << "LLToolDragAndDrop::createContainer()" << LL_ENDL;
+// return;
// }
@@ -3124,13 +3144,13 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
void pack_permissions_slam(LLMessageSystem* msg, U32 flags, const LLPermissions& perms)
{
- // CRUFT -- the server no longer pays attention to this data
- U32 group_mask = perms.getMaskGroup();
- U32 everyone_mask = perms.getMaskEveryone();
- U32 next_owner_mask = perms.getMaskNextOwner();
-
- msg->addU32Fast(_PREHASH_ItemFlags, flags);
- msg->addU32Fast(_PREHASH_GroupMask, group_mask);
- msg->addU32Fast(_PREHASH_EveryoneMask, everyone_mask);
- msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_mask);
+ // CRUFT -- the server no longer pays attention to this data
+ U32 group_mask = perms.getMaskGroup();
+ U32 everyone_mask = perms.getMaskEveryone();
+ U32 next_owner_mask = perms.getMaskNextOwner();
+
+ msg->addU32Fast(_PREHASH_ItemFlags, flags);
+ msg->addU32Fast(_PREHASH_GroupMask, group_mask);
+ msg->addU32Fast(_PREHASH_EveryoneMask, everyone_mask);
+ msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_mask);
}
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index b294f42123..907cec4d17 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lltoolselect.cpp
* @brief LLToolSelect 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$
*/
@@ -42,8 +42,8 @@
#include "llviewercamera.h"
#include "llviewermenu.h"
#include "llviewerobject.h"
-#include "llviewerobjectlist.h"
-#include "llviewerregion.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llworld.h"
@@ -55,235 +55,235 @@ const F32 SELECTION_ROTATION_TRESHOLD = 0.1f;
const F32 SELECTION_SITTING_ROTATION_TRESHOLD = 3.2f; //radian
LLToolSelect::LLToolSelect( LLToolComposite* composite )
-: LLTool( std::string("Select"), composite ),
- mIgnoreGroup( FALSE )
+: LLTool( std::string("Select"), composite ),
+ mIgnoreGroup( FALSE )
{
}
// True if you selected an object.
BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
- // do immediate pick query
+ // do immediate pick query
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
BOOL pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
- mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, FALSE, TRUE, pick_reflection_probe);
+ mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, FALSE, TRUE, pick_reflection_probe);
- // Pass mousedown to agent
- LLTool::handleMouseDown(x, y, mask);
+ // Pass mousedown to agent
+ LLTool::handleMouseDown(x, y, mask);
- return mPick.getObject().notNull();
+ return mPick.getObject().notNull();
}
// static
LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root)
{
- LLViewerObject* object = pick.getObject();
- if (select_root)
- {
- object = object->getRootEdit();
- }
- BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
- BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
+ LLViewerObject* object = pick.getObject();
+ if (select_root)
+ {
+ object = object->getRootEdit();
+ }
+ BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
+ BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
// *NOTE: These settings must be cleaned up at bottom of function.
- if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
- {
- gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
- gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
- LLSelectMgr::getInstance()->setForceSelection(TRUE);
- }
-
- BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
-
- // If no object, check for icon, then just deselect
- if (!object)
- {
- LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon;
-
- if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject())
- {
- LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());
- }
- else if (!extend_select)
- {
- LLSelectMgr::getInstance()->deselectAll();
- }
- }
- else
- {
- BOOL already_selected = object->isSelected();
-
- if (already_selected &&
- object->getNumTEs() > 0 &&
- !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES))
- {
- const LLTextureEntry* tep = object->getTE(pick.mObjectFace);
- if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull())
- {
- // we were interacting with media and clicked on non selected face, drop media focus
- LLViewerMediaFocus::getInstance()->clearFocus();
- // selection was removed and zoom preserved by clearFocus(), continue with regular selection
- already_selected = false;
- extend_select = true;
- }
- }
-
- if ( extend_select )
- {
- if ( already_selected )
- {
- if ( ignore_group )
- {
- LLSelectMgr::getInstance()->deselectObjectOnly(object);
- }
- else
- {
- LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE);
- }
- }
- else
- {
- if ( ignore_group )
- {
- LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES);
- }
- else
- {
- LLSelectMgr::getInstance()->selectObjectAndFamily(object);
- }
- }
- }
- else
- {
- // Save the current zoom values because deselect resets them.
- F32 target_zoom;
- F32 current_zoom;
- LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom);
-
- // JC - Change behavior to make it easier to select children
- // of linked sets. 9/3/2002
- if( !already_selected || ignore_group)
- {
- // ...lose current selection in favor of just this object
- LLSelectMgr::getInstance()->deselectAll();
- }
-
- if ( ignore_group )
- {
- LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES);
- }
- else
- {
- LLSelectMgr::getInstance()->selectObjectAndFamily(object);
- }
-
- // restore the zoom to the previously stored values.
- LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom);
- }
-
- if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar
- LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments
- object != gAgentAvatarp) // and it's not you
- {
- // have avatar turn to face the selected object(s)
- LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal();
- selection_center = selection_center - gAgent.getPositionGlobal();
- LLVector3 selection_dir;
- selection_dir.setVec(selection_center);
- selection_dir.mV[VZ] = 0.f;
- selection_dir.normVec();
- if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f)
- {
- LLQuaternion target_rot;
- target_rot.shortestArc(LLVector3::x_axis, selection_dir);
- gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(),
- "",
- &target_rot,
- NULL,
- NULL,
- MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/,
- gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD);
- }
- }
-
- if (temp_select)
- {
- if (!already_selected)
- {
- LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit();
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- // this is just a temporary selection
- LLSelectNode* select_node = selection->findNode(root_object);
- if (select_node)
- {
- select_node->setTransient(TRUE);
- }
-
- LLViewerObject::const_child_list_t& child_list = root_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- select_node = selection->findNode(child);
- if (select_node)
- {
- select_node->setTransient(TRUE);
- }
- }
-
- }
- } //if(temp_select)
- } //if(!object)
-
- // Cleanup temp select settings above.
- if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar)
- {
- gSavedSettings.setBOOL("SelectOwnedOnly", select_owned);
- gSavedSettings.setBOOL("SelectMovableOnly", select_movable);
- LLSelectMgr::getInstance()->setForceSelection(FALSE);
- }
-
- return LLSelectMgr::getInstance()->getSelection();
+ if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ {
+ gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
+ gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
+ LLSelectMgr::getInstance()->setForceSelection(TRUE);
+ }
+
+ BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
+
+ // If no object, check for icon, then just deselect
+ if (!object)
+ {
+ LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon;
+
+ if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject())
+ {
+ LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());
+ }
+ else if (!extend_select)
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ }
+ }
+ else
+ {
+ BOOL already_selected = object->isSelected();
+
+ if (already_selected &&
+ object->getNumTEs() > 0 &&
+ !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES))
+ {
+ const LLTextureEntry* tep = object->getTE(pick.mObjectFace);
+ if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull())
+ {
+ // we were interacting with media and clicked on non selected face, drop media focus
+ LLViewerMediaFocus::getInstance()->clearFocus();
+ // selection was removed and zoom preserved by clearFocus(), continue with regular selection
+ already_selected = false;
+ extend_select = true;
+ }
+ }
+
+ if ( extend_select )
+ {
+ if ( already_selected )
+ {
+ if ( ignore_group )
+ {
+ LLSelectMgr::getInstance()->deselectObjectOnly(object);
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE);
+ }
+ }
+ else
+ {
+ if ( ignore_group )
+ {
+ LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES);
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->selectObjectAndFamily(object);
+ }
+ }
+ }
+ else
+ {
+ // Save the current zoom values because deselect resets them.
+ F32 target_zoom;
+ F32 current_zoom;
+ LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom);
+
+ // JC - Change behavior to make it easier to select children
+ // of linked sets. 9/3/2002
+ if( !already_selected || ignore_group)
+ {
+ // ...lose current selection in favor of just this object
+ LLSelectMgr::getInstance()->deselectAll();
+ }
+
+ if ( ignore_group )
+ {
+ LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES, pick.mGLTFNodeIndex, pick.mGLTFPrimitiveIndex);
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->selectObjectAndFamily(object);
+ }
+
+ // restore the zoom to the previously stored values.
+ LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom);
+ }
+
+ if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar
+ LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments
+ object != gAgentAvatarp) // and it's not you
+ {
+ // have avatar turn to face the selected object(s)
+ LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal();
+ selection_center = selection_center - gAgent.getPositionGlobal();
+ LLVector3 selection_dir;
+ selection_dir.setVec(selection_center);
+ selection_dir.mV[VZ] = 0.f;
+ selection_dir.normVec();
+ if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f)
+ {
+ LLQuaternion target_rot;
+ target_rot.shortestArc(LLVector3::x_axis, selection_dir);
+ gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(),
+ "",
+ &target_rot,
+ NULL,
+ NULL,
+ MAX_FAR_CLIP /*stop_distance, don't care since we are looking, not moving*/,
+ gAgentAvatarp->isSitting() ? SELECTION_SITTING_ROTATION_TRESHOLD : SELECTION_ROTATION_TRESHOLD);
+ }
+ }
+
+ if (temp_select)
+ {
+ if (!already_selected)
+ {
+ LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ // this is just a temporary selection
+ LLSelectNode* select_node = selection->findNode(root_object);
+ if (select_node)
+ {
+ select_node->setTransient(TRUE);
+ }
+
+ LLViewerObject::const_child_list_t& child_list = root_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ select_node = selection->findNode(child);
+ if (select_node)
+ {
+ select_node->setTransient(TRUE);
+ }
+ }
+
+ }
+ } //if(temp_select)
+ } //if(!object)
+
+ // Cleanup temp select settings above.
+ if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ {
+ gSavedSettings.setBOOL("SelectOwnedOnly", select_owned);
+ gSavedSettings.setBOOL("SelectMovableOnly", select_movable);
+ LLSelectMgr::getInstance()->setForceSelection(FALSE);
+ }
+
+ return LLSelectMgr::getInstance()->getSelection();
}
BOOL LLToolSelect::handleMouseUp(S32 x, S32 y, MASK mask)
{
- mIgnoreGroup = gSavedSettings.getBOOL("EditLinkedParts");
+ mIgnoreGroup = gSavedSettings.getBOOL("EditLinkedParts");
- handleObjectSelection(mPick, mIgnoreGroup, FALSE);
+ handleObjectSelection(mPick, mIgnoreGroup, FALSE);
- return LLTool::handleMouseUp(x, y, mask);
+ return LLTool::handleMouseUp(x, y, mask);
}
void LLToolSelect::handleDeselect()
{
- if( hasMouseCapture() )
- {
- setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly
- }
+ if( hasMouseCapture() )
+ {
+ setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly
+ }
}
void LLToolSelect::stopEditing()
{
- if( hasMouseCapture() )
- {
- setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly
- }
+ if( hasMouseCapture() )
+ {
+ setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly
+ }
}
void LLToolSelect::onMouseCaptureLost()
{
- // Finish drag
+ // Finish drag
- LLSelectMgr::getInstance()->enableSilhouette(TRUE);
+ LLSelectMgr::getInstance()->enableSilhouette(TRUE);
- // Clean up drag-specific variables
- mIgnoreGroup = FALSE;
+ // Clean up drag-specific variables
+ mIgnoreGroup = FALSE;
}
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 438b06f954..882e08935c 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -81,9 +81,9 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId,
{ }
-LLResourceUploadInfo::LLResourceUploadInfo(std::string name,
- std::string description, S32 compressionInfo,
- LLFolderType::EType destinationType, LLInventoryType::EType inventoryType,
+LLResourceUploadInfo::LLResourceUploadInfo(std::string name,
+ std::string description, S32 compressionInfo,
+ LLFolderType::EType destinationType, LLInventoryType::EType inventoryType,
U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) :
mName(name),
mDescription(description),
@@ -100,7 +100,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(std::string name,
mFolderId(LLUUID::null),
mItemId(LLUUID::null),
mAssetId(LLAssetID::null)
-{
+{
mTransactionId.generate();
}
@@ -156,9 +156,9 @@ LLSD LLResourceUploadInfo::generatePostBody()
body["next_owner_mask"] = LLSD::Integer(mNextOwnerPerms);
body["group_mask"] = LLSD::Integer(mGroupPerms);
body["everyone_mask"] = LLSD::Integer(mEveryonePerms);
+ body["expected_upload_cost"] = mExpectedUploadCost;
return body;
-
}
void LLResourceUploadInfo::logPreparedUpload()
@@ -311,39 +311,39 @@ std::string LLResourceUploadInfo::getDisplayName() const
bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type)
{
- U32 codec;
- return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false);
+ U32 codec;
+ return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false);
}
// static
bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload)
{
- bool succ = false;
- std::string exten_lc(exten);
- LLStringUtil::toLower(exten_lc);
- codec = LLImageBase::getCodecFromExtension(exten_lc);
- if (codec != IMG_CODEC_INVALID)
- {
- asset_type = LLAssetType::AT_TEXTURE;
- succ = true;
- }
- else if (exten_lc == "wav")
- {
- asset_type = LLAssetType::AT_SOUND;
- succ = true;
- }
- else if (exten_lc == "anim")
- {
- asset_type = LLAssetType::AT_ANIMATION;
- succ = true;
- }
- else if (!bulk_upload && (exten_lc == "bvh"))
- {
- asset_type = LLAssetType::AT_ANIMATION;
- succ = true;
- }
-
- return succ;
+ bool succ = false;
+ std::string exten_lc(exten);
+ LLStringUtil::toLower(exten_lc);
+ codec = LLImageBase::getCodecFromExtension(exten_lc);
+ if (codec != IMG_CODEC_INVALID)
+ {
+ asset_type = LLAssetType::AT_TEXTURE;
+ succ = true;
+ }
+ else if (exten_lc == "wav")
+ {
+ asset_type = LLAssetType::AT_SOUND;
+ succ = true;
+ }
+ else if (exten_lc == "anim")
+ {
+ asset_type = LLAssetType::AT_ANIMATION;
+ succ = true;
+ }
+ else if (!bulk_upload && (exten_lc == "bvh"))
+ {
+ asset_type = LLAssetType::AT_ANIMATION;
+ succ = true;
+ }
+
+ return succ;
}
//=========================================================================
@@ -385,8 +385,8 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
std::string exten = gDirUtilp->getExtension(getFileName());
LLAssetType::EType assetType = LLAssetType::AT_NONE;
- U32 codec = IMG_CODEC_INVALID;
- bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec);
+ U32 codec = IMG_CODEC_INVALID;
+ bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec);
std::string errorMessage;
std::string errorLabel;
@@ -455,53 +455,53 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
}
else if (exten == "anim")
{
- // Default unless everything succeeds
- errorLabel = "ProblemWithFile";
- error = true;
+ // Default unless everything succeeds
+ errorLabel = "ProblemWithFile";
+ error = true;
// read from getFileName()
- LLAPRFile infile;
- infile.open(getFileName(),LL_APR_RB);
- if (!infile.getFileHandle())
- {
- LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
- errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
- }
- else
- {
- S32 size = LLAPRFile::size(getFileName());
- U8* buffer = new U8[size];
- S32 size_read = infile.read(buffer,size);
- if (size_read != size)
- {
- errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
- }
- else
- {
- LLDataPackerBinaryBuffer dp(buffer, size);
- LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
- motionp->setCharacter(gAgentAvatarp);
- if (motionp->deserialize(dp, getAssetId(), false))
- {
- // write to temp file
- bool succ = motionp->dumpToFile(filename);
- if (succ)
- {
- assetType = LLAssetType::AT_ANIMATION;
- errorLabel = "";
- error = false;
- }
- else
- {
- errorMessage = "Failed saving temporary animation file";
- }
- }
- else
- {
- errorMessage = "Failed reading animation file";
- }
- }
- }
+ LLAPRFile infile;
+ infile.open(getFileName(),LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
+ errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
+ }
+ else
+ {
+ S32 size = LLAPRFile::size(getFileName());
+ U8* buffer = new U8[size];
+ S32 size_read = infile.read(buffer,size);
+ if (size_read != size)
+ {
+ errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
+ }
+ else
+ {
+ LLDataPackerBinaryBuffer dp(buffer, size);
+ LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
+ motionp->setCharacter(gAgentAvatarp);
+ if (motionp->deserialize(dp, getAssetId(), false))
+ {
+ // write to temp file
+ bool succ = motionp->dumpToFile(filename);
+ if (succ)
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ errorLabel = "";
+ error = false;
+ }
+ else
+ {
+ errorMessage = "Failed saving temporary animation file";
+ }
+ }
+ else
+ {
+ errorMessage = "Failed reading animation file";
+ }
+ }
+ }
}
else
{
@@ -596,10 +596,10 @@ LLSD LLNewBufferedResourceUploadInfo::exportTempFile()
{
std::string filename = gDirUtilp->getTempFilename();
- // copy buffer to the cache for upload
+ // copy buffer to the cache for upload
LLFileSystem file(getAssetId(), getAssetType(), LLFileSystem::APPEND);
file.write((U8*) mBuffer.c_str(), mBuffer.size());
-
+
return LLSD();
}
@@ -828,8 +828,8 @@ LLSD LLScriptAssetUpload::generatePostBody()
LLUUID LLViewerAssetUpload::EnqueueInventoryUpload(const std::string &url, const LLResourceUploadInfo::ptr_t &uploadInfo)
{
std::string procName("LLViewerAssetUpload::AssetInventoryUploadCoproc(");
-
- LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("Upload",
+
+ LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("Upload",
procName + LLAssetType::lookup(uploadInfo->getAssetType()) + ")",
boost::bind(&LLViewerAssetUpload::AssetInventoryUploadCoproc, _1, _2, url, uploadInfo));
@@ -838,7 +838,7 @@ LLUUID LLViewerAssetUpload::EnqueueInventoryUpload(const std::string &url, const
//=========================================================================
/*static*/
-void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter,
+void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter,
const LLUUID &id, std::string url, LLResourceUploadInfo::ptr_t uploadInfo)
{
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index d261190d22..9ba42e4f47 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewercamera.cpp
* @brief LLViewerCamera class implementation
*
* $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$
*/
@@ -48,7 +48,7 @@
#include "llgl.h"
#include "llglheaders.h"
#include "llquaternion.h"
-#include "llwindow.h" // getPixelAspectRatio()
+#include "llwindow.h" // getPixelAspectRatio()
#include "lltracerecording.h"
#include "llenvironment.h"
@@ -63,38 +63,38 @@ LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_
//glu pick matrix implementation borrowed from Mesa3D
glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport)
{
- GLfloat m[16];
- GLfloat sx, sy;
- GLfloat tx, ty;
-
- sx = viewport[2] / width;
- sy = viewport[3] / height;
- tx = (viewport[2] + 2.f * (viewport[0] - x)) / width;
- ty = (viewport[3] + 2.f * (viewport[1] - y)) / height;
-
- #define M(row,col) m[col*4+row]
- M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx;
- M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty;
- M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f;
- M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f;
- #undef M
-
- return glh::matrix4f(m);
+ GLfloat m[16];
+ GLfloat sx, sy;
+ GLfloat tx, ty;
+
+ sx = viewport[2] / width;
+ sy = viewport[3] / height;
+ tx = (viewport[2] + 2.f * (viewport[0] - x)) / width;
+ ty = (viewport[3] + 2.f * (viewport[1] - y)) / height;
+
+ #define M(row,col) m[col*4+row]
+ M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx;
+ M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty;
+ M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f;
+ M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f;
+ #undef M
+
+ return glh::matrix4f(m);
}
LLViewerCamera::LLViewerCamera() : LLCamera()
{
- calcProjection(getFar());
- mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
- mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
- mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
- mPixelMeterRatio = 0.f;
- mScreenPixelArea = 0;
- mZoomFactor = 1.f;
- mZoomSubregion = 1;
- mAverageSpeed = 0.f;
- mAverageAngularSpeed = 0.f;
- gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
+ calcProjection(getFar());
+ mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
+ mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
+ mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
+ mPixelMeterRatio = 0.f;
+ mScreenPixelArea = 0;
+ mZoomFactor = 1.f;
+ mZoomSubregion = 1;
+ mAverageSpeed = 0.f;
+ mAverageAngularSpeed = 0.f;
+ gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
}
void LLViewerCamera::updateCameraLocation(const LLVector3 &center, const LLVector3 &up_direction, const LLVector3 &point_of_interest)
@@ -133,61 +133,61 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center, const LLVecto
}
}
- setOriginAndLookAt(origin, up_direction, point_of_interest);
-
- mVelocityDir = origin - last_position ;
- F32 dpos = mVelocityDir.normVec() ;
- LLQuaternion rotation;
- rotation.shortestArc(last_axis, getAtAxis());
+ setOriginAndLookAt(origin, up_direction, point_of_interest);
- F32 x, y, z;
- F32 drot;
- rotation.getAngleAxis(&drot, &x, &y, &z);
+ mVelocityDir = origin - last_position ;
+ F32 dpos = mVelocityDir.normVec() ;
+ LLQuaternion rotation;
+ rotation.shortestArc(last_axis, getAtAxis());
- add(sVelocityStat, dpos);
- add(sAngularVelocityStat, drot);
+ F32 x, y, z;
+ F32 drot;
+ rotation.getAngleAxis(&drot, &x, &y, &z);
- mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50);
- mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat);
- mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));
+ add(sVelocityStat, dpos);
+ add(sAngularVelocityStat, drot);
+
+ mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50);
+ mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat);
+ mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));
- // update pixel meter ratio using default fov, not modified one
- mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5));
- // update screen pixel area
- mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect()));
+ // update pixel meter ratio using default fov, not modified one
+ mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5));
+ // update screen pixel area
+ mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect()));
}
const LLMatrix4 &LLViewerCamera::getProjection() const
{
- calcProjection(getFar());
- return mProjectionMatrix;
+ calcProjection(getFar());
+ return mProjectionMatrix;
}
const LLMatrix4 &LLViewerCamera::getModelview() const
{
- LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
- getMatrixToLocal(mModelviewMatrix);
- mModelviewMatrix *= cfr;
- return mModelviewMatrix;
+ LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
+ getMatrixToLocal(mModelviewMatrix);
+ mModelviewMatrix *= cfr;
+ return mModelviewMatrix;
}
void LLViewerCamera::calcProjection(const F32 far_distance) const
{
- F32 fov_y, z_far, z_near, aspect, f;
- fov_y = getView();
- z_far = far_distance;
- z_near = getNear();
- aspect = getAspect();
-
- f = 1/tan(fov_y*0.5f);
-
- mProjectionMatrix.setZero();
- mProjectionMatrix.mMatrix[0][0] = f/aspect;
- mProjectionMatrix.mMatrix[1][1] = f;
- mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far);
- mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far);
- mProjectionMatrix.mMatrix[2][3] = -1;
+ F32 fov_y, z_far, z_near, aspect, f;
+ fov_y = getView();
+ z_far = far_distance;
+ z_near = getNear();
+ aspect = getAspect();
+
+ f = 1/tan(fov_y*0.5f);
+
+ mProjectionMatrix.setZero();
+ mProjectionMatrix.mMatrix[0][0] = f/aspect;
+ mProjectionMatrix.mMatrix[1][1] = f;
+ mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far);
+ mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far);
+ mProjectionMatrix.mMatrix[2][3] = -1;
}
// Sets up opengl state for 3D drawing. If for selection, also
@@ -198,222 +198,222 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const
//static
void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks)
{
- GLint* viewport = (GLint*) gGLViewport;
- F64 model[16];
- F64 proj[16];
-
- for (U32 i = 0; i < 16; i++)
- {
- model[i] = (F64) gGLModelView[i];
- proj[i] = (F64) gGLProjection[i];
- }
-
- GLdouble objX,objY,objZ;
-
- LLVector3 frust[8];
-
- if (no_hacks)
- {
- gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
-
- gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);
- }
- else if (zflip)
- {
- gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
-
- gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
- frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);
-
- for (U32 i = 0; i < 4; i++)
- {
- frust[i+4] = frust[i+4]-frust[i];
- frust[i+4].normVec();
- frust[i+4] = frust[i] + frust[i+4]*camera.getFar();
- }
- }
- else
- {
- gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
- gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
- frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
-
- if (ortho)
- {
- LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f;
- for (U32 i = 0; i < 4; i++)
- {
- frust[i+4] = frust[i] + far_shift;
- }
- }
- else
- {
- for (U32 i = 0; i < 4; i++)
- {
- LLVector3 vec = frust[i] - camera.getOrigin();
- vec.normVec();
- frust[i+4] = camera.getOrigin() + vec*camera.getFar();
- }
- }
- }
-
- camera.calcAgentFrustumPlanes(frust);
+ GLint* viewport = (GLint*) gGLViewport;
+ F64 model[16];
+ F64 proj[16];
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ model[i] = (F64) gGLModelView[i];
+ proj[i] = (F64) gGLProjection[i];
+ }
+
+ GLdouble objX,objY,objZ;
+
+ LLVector3 frust[8];
+
+ if (no_hacks)
+ {
+ gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
+
+ gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);
+ }
+ else if (zflip)
+ {
+ gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
+
+ gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
+ frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);
+
+ for (U32 i = 0; i < 4; i++)
+ {
+ frust[i+4] = frust[i+4]-frust[i];
+ frust[i+4].normVec();
+ frust[i+4] = frust[i] + frust[i+4]*camera.getFar();
+ }
+ }
+ else
+ {
+ gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
+ gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
+ frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
+
+ if (ortho)
+ {
+ LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f;
+ for (U32 i = 0; i < 4; i++)
+ {
+ frust[i+4] = frust[i] + far_shift;
+ }
+ }
+ else
+ {
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLVector3 vec = frust[i] - camera.getOrigin();
+ vec.normVec();
+ frust[i+4] = camera.getOrigin() + vec*camera.getFar();
+ }
+ }
+ }
+
+ camera.calcAgentFrustumPlanes(frust);
}
void LLViewerCamera::setPerspective(BOOL for_selection,
- S32 x, S32 y_from_bot, S32 width, S32 height,
- BOOL limit_select_distance,
- F32 z_near, F32 z_far)
+ S32 x, S32 y_from_bot, S32 width, S32 height,
+ BOOL limit_select_distance,
+ F32 z_near, F32 z_far)
{
- F32 fov_y, aspect;
- fov_y = RAD_TO_DEG * getView();
- BOOL z_default_far = FALSE;
- if (z_far <= 0)
- {
- z_default_far = TRUE;
- z_far = getFar();
- }
- if (z_near <= 0)
- {
- z_near = getNear();
- }
- aspect = getAspect();
-
- // Load camera view matrix
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadIdentity();
-
- glh::matrix4f proj_mat;
-
- if (for_selection)
- {
- // make a tiny little viewport
- // anything drawn into this viewport will be "selected"
-
- GLint viewport[4];
- viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-
- proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport);
-
- if (limit_select_distance)
- {
- // ...select distance from control
- z_far = gSavedSettings.getF32("MaxSelectDistance");
- }
- else
- {
- z_far = gAgentCamera.mDrawDistance;
- }
- }
- else
- {
- // Only override the far clip if it's not passed in explicitly.
- if (z_default_far)
- {
- z_far = MAX_FAR_CLIP;
- }
- glViewport(x, y_from_bot, width, height);
- gGLViewport[0] = x;
- gGLViewport[1] = y_from_bot;
- gGLViewport[2] = width;
- gGLViewport[3] = height;
- }
-
- if (mZoomFactor > 1.f)
- {
- float offset = mZoomFactor - 1.f;
- int pos_y = mZoomSubregion / llceil(mZoomFactor);
- int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor));
- glh::matrix4f translate;
- translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f));
- glh::matrix4f scale;
- scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f));
-
- proj_mat = scale*proj_mat;
- proj_mat = translate*proj_mat;
- }
-
- calcProjection(z_far); // Update the projection matrix cache
-
- proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far);
-
- gGL.loadMatrix(proj_mat.m);
-
- for (U32 i = 0; i < 16; i++)
- {
- gGLProjection[i] = proj_mat.m[i];
- }
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION);
-
- GLfloat ogl_matrix[16];
-
- getOpenGLTransform(ogl_matrix);
-
- modelview *= glh::matrix4f(ogl_matrix);
-
- gGL.loadMatrix(modelview.m);
-
- if (for_selection && (width > 1 || height > 1))
- {
- // NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window)
- // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not
- // comfortable hacking on it.
- calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
- (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f,
- (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
- (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f);
-
- }
-
- // if not picking and not doing a snapshot, cache various GL matrices
- if (!for_selection && mZoomFactor == 1.f)
- {
- // Save GL matrices for access elsewhere in code, especially project_world_to_screen
- for (U32 i = 0; i < 16; i++)
- {
- gGLModelView[i] = modelview.m[i];
- }
- }
-
- updateFrustumPlanes(*this);
+ F32 fov_y, aspect;
+ fov_y = RAD_TO_DEG * getView();
+ BOOL z_default_far = FALSE;
+ if (z_far <= 0)
+ {
+ z_default_far = TRUE;
+ z_far = getFar();
+ }
+ if (z_near <= 0)
+ {
+ z_near = getNear();
+ }
+ aspect = getAspect();
+
+ // Load camera view matrix
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadIdentity();
+
+ glh::matrix4f proj_mat;
+
+ if (for_selection)
+ {
+ // make a tiny little viewport
+ // anything drawn into this viewport will be "selected"
+
+ GLint viewport[4];
+ viewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ viewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ viewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ viewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+
+ proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport);
+
+ if (limit_select_distance)
+ {
+ // ...select distance from control
+ z_far = gSavedSettings.getF32("MaxSelectDistance");
+ }
+ else
+ {
+ z_far = gAgentCamera.mDrawDistance;
+ }
+ }
+ else
+ {
+ // Only override the far clip if it's not passed in explicitly.
+ if (z_default_far)
+ {
+ z_far = MAX_FAR_CLIP;
+ }
+ glViewport(x, y_from_bot, width, height);
+ gGLViewport[0] = x;
+ gGLViewport[1] = y_from_bot;
+ gGLViewport[2] = width;
+ gGLViewport[3] = height;
+ }
+
+ if (mZoomFactor > 1.f)
+ {
+ float offset = mZoomFactor - 1.f;
+ int pos_y = mZoomSubregion / llceil(mZoomFactor);
+ int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor));
+ glh::matrix4f translate;
+ translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f));
+ glh::matrix4f scale;
+ scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f));
+
+ proj_mat = scale*proj_mat;
+ proj_mat = translate*proj_mat;
+ }
+
+ calcProjection(z_far); // Update the projection matrix cache
+
+ proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far);
+
+ gGL.loadMatrix(proj_mat.m);
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLProjection[i] = proj_mat.m[i];
+ }
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION);
+
+ GLfloat ogl_matrix[16];
+
+ getOpenGLTransform(ogl_matrix);
+
+ modelview *= glh::matrix4f(ogl_matrix);
+
+ gGL.loadMatrix(modelview.m);
+
+ if (for_selection && (width > 1 || height > 1))
+ {
+ // NB: as of this writing, i believe the code below is broken (doesn't take into account the world view, assumes entire window)
+ // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not
+ // comfortable hacking on it.
+ calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
+ (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f,
+ (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f,
+ (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f);
+
+ }
+
+ // if not picking and not doing a snapshot, cache various GL matrices
+ if (!for_selection && mZoomFactor == 1.f)
+ {
+ // Save GL matrices for access elsewhere in code, especially project_world_to_screen
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLModelView[i] = modelview.m[i];
+ }
+ }
+
+ updateFrustumPlanes(*this);
}
@@ -421,24 +421,24 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
// screen coordinates to the agent's region.
void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const
{
- GLdouble x, y, z;
-
- F64 mdlv[16];
- F64 proj[16];
-
- for (U32 i = 0; i < 16; i++)
- {
- mdlv[i] = (F64) gGLModelView[i];
- proj[i] = (F64) gGLProjection[i];
- }
-
- gluUnProject(
- GLdouble(screen_x), GLdouble(screen_y), 0.0,
- mdlv, proj, (GLint*)gGLViewport,
- &x,
- &y,
- &z );
- pos_agent->setVec( (F32)x, (F32)y, (F32)z );
+ GLdouble x, y, z;
+
+ F64 mdlv[16];
+ F64 proj[16];
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ mdlv[i] = (F64) gGLModelView[i];
+ proj[i] = (F64) gGLProjection[i];
+ }
+
+ gluUnProject(
+ GLdouble(screen_x), GLdouble(screen_y), 0.0,
+ mdlv, proj, (GLint*)gGLViewport,
+ &x,
+ &y,
+ &z );
+ pos_agent->setVec( (F32)x, (F32)y, (F32)z );
}
// Uses the last GL matrices set in set_perspective to project a point from
@@ -446,392 +446,398 @@ void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 scree
// the current window.
BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const
{
- BOOL in_front = TRUE;
- GLdouble x, y, z; // object's window coords, GL-style
-
- LLVector3 dir_to_point = pos_agent - getOrigin();
- dir_to_point /= dir_to_point.magVec();
-
- if (dir_to_point * getAtAxis() < 0.f)
- {
- if (clamp)
- {
- return FALSE;
- }
- else
- {
- in_front = FALSE;
- }
- }
-
- LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
- S32 viewport[4];
- viewport[0] = world_view_rect.mLeft;
- viewport[1] = world_view_rect.mBottom;
- viewport[2] = world_view_rect.getWidth();
- viewport[3] = world_view_rect.getHeight();
-
- F64 mdlv[16];
- F64 proj[16];
-
- for (U32 i = 0; i < 16; i++)
- {
- mdlv[i] = (F64) gGLModelView[i];
- proj[i] = (F64) gGLProjection[i];
- }
-
- if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
- mdlv, proj, (GLint*)viewport,
- &x, &y, &z))
- {
- // convert screen coordinates to virtual UI coordinates
- x /= gViewerWindow->getDisplayScale().mV[VX];
- y /= gViewerWindow->getDisplayScale().mV[VY];
-
- // should now have the x,y coords of grab_point in screen space
- LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
-
- // convert to pixel coordinates
- S32 int_x = lltrunc(x);
- S32 int_y = lltrunc(y);
-
- BOOL valid = TRUE;
-
- if (clamp)
- {
- if (int_x < world_rect.mLeft)
- {
- out_point.mX = world_rect.mLeft;
- valid = FALSE;
- }
- else if (int_x > world_rect.mRight)
- {
- out_point.mX = world_rect.mRight;
- valid = FALSE;
- }
- else
- {
- out_point.mX = int_x;
- }
-
- if (int_y < world_rect.mBottom)
- {
- out_point.mY = world_rect.mBottom;
- valid = FALSE;
- }
- else if (int_y > world_rect.mTop)
- {
- out_point.mY = world_rect.mTop;
- valid = FALSE;
- }
- else
- {
- out_point.mY = int_y;
- }
- return valid;
- }
- else
- {
- out_point.mX = int_x;
- out_point.mY = int_y;
-
- if (int_x < world_rect.mLeft)
- {
- valid = FALSE;
- }
- else if (int_x > world_rect.mRight)
- {
- valid = FALSE;
- }
- if (int_y < world_rect.mBottom)
- {
- valid = FALSE;
- }
- else if (int_y > world_rect.mTop)
- {
- valid = FALSE;
- }
-
- return in_front && valid;
- }
- }
- else
- {
- return FALSE;
- }
+ BOOL in_front = TRUE;
+ GLdouble x, y, z; // object's window coords, GL-style
+
+ LLVector3 dir_to_point = pos_agent - getOrigin();
+ dir_to_point /= dir_to_point.magVec();
+
+ if (dir_to_point * getAtAxis() < 0.f)
+ {
+ if (clamp)
+ {
+ return FALSE;
+ }
+ else
+ {
+ in_front = FALSE;
+ }
+ }
+
+ LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
+ S32 viewport[4];
+ viewport[0] = world_view_rect.mLeft;
+ viewport[1] = world_view_rect.mBottom;
+ viewport[2] = world_view_rect.getWidth();
+ viewport[3] = world_view_rect.getHeight();
+
+ F64 mdlv[16];
+ F64 proj[16];
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ mdlv[i] = (F64) gGLModelView[i];
+ proj[i] = (F64) gGLProjection[i];
+ }
+
+ if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
+ mdlv, proj, (GLint*)viewport,
+ &x, &y, &z))
+ {
+ // convert screen coordinates to virtual UI coordinates
+ x /= gViewerWindow->getDisplayScale().mV[VX];
+ y /= gViewerWindow->getDisplayScale().mV[VY];
+
+ // should now have the x,y coords of grab_point in screen space
+ LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
+
+ // convert to pixel coordinates
+ S32 int_x = lltrunc(x);
+ S32 int_y = lltrunc(y);
+
+ BOOL valid = TRUE;
+
+ if (clamp)
+ {
+ if (int_x < world_rect.mLeft)
+ {
+ out_point.mX = world_rect.mLeft;
+ valid = FALSE;
+ }
+ else if (int_x > world_rect.mRight)
+ {
+ out_point.mX = world_rect.mRight;
+ valid = FALSE;
+ }
+ else
+ {
+ out_point.mX = int_x;
+ }
+
+ if (int_y < world_rect.mBottom)
+ {
+ out_point.mY = world_rect.mBottom;
+ valid = FALSE;
+ }
+ else if (int_y > world_rect.mTop)
+ {
+ out_point.mY = world_rect.mTop;
+ valid = FALSE;
+ }
+ else
+ {
+ out_point.mY = int_y;
+ }
+ return valid;
+ }
+ else
+ {
+ out_point.mX = int_x;
+ out_point.mY = int_y;
+
+ if (int_x < world_rect.mLeft)
+ {
+ valid = FALSE;
+ }
+ else if (int_x > world_rect.mRight)
+ {
+ valid = FALSE;
+ }
+ if (int_y < world_rect.mBottom)
+ {
+ valid = FALSE;
+ }
+ else if (int_y > world_rect.mTop)
+ {
+ valid = FALSE;
+ }
+
+ return in_front && valid;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
}
// Uses the last GL matrices set in set_perspective to project a point from
// the agent's region space to the nearest edge in screen coordinates.
// Returns TRUE if projection succeeds.
BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
- LLCoordGL &out_point) const
+ LLCoordGL &out_point) const
{
- LLVector3 dir_to_point = pos_agent - getOrigin();
- dir_to_point /= dir_to_point.magVec();
-
- BOOL in_front = TRUE;
- if (dir_to_point * getAtAxis() < 0.f)
- {
- in_front = FALSE;
- }
-
- LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
- S32 viewport[4];
- viewport[0] = world_view_rect.mLeft;
- viewport[1] = world_view_rect.mBottom;
- viewport[2] = world_view_rect.getWidth();
- viewport[3] = world_view_rect.getHeight();
- GLdouble x, y, z; // object's window coords, GL-style
-
- F64 mdlv[16];
- F64 proj[16];
-
- for (U32 i = 0; i < 16; i++)
- {
- mdlv[i] = (F64) gGLModelView[i];
- proj[i] = (F64) gGLProjection[i];
- }
-
- if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
- pos_agent.mV[VZ], mdlv,
- proj, (GLint*)viewport,
- &x, &y, &z))
- {
- x /= gViewerWindow->getDisplayScale().mV[VX];
- y /= gViewerWindow->getDisplayScale().mV[VY];
- // should now have the x,y coords of grab_point in screen space
- const LLRect& world_rect = gViewerWindow->getWorldViewRectScaled();
-
- // ...sanity check
- S32 int_x = lltrunc(x);
- S32 int_y = lltrunc(y);
-
- // find the center
- GLdouble center_x = (GLdouble)world_rect.getCenterX();
- GLdouble center_y = (GLdouble)world_rect.getCenterY();
-
- if (x == center_x && y == center_y)
- {
- // can't project to edge from exact center
- return FALSE;
- }
-
- // find the line from center to local
- GLdouble line_x = x - center_x;
- GLdouble line_y = y - center_y;
-
- int_x = lltrunc(center_x);
- int_y = lltrunc(center_y);
-
-
- if (0.f == line_x)
- {
- // the slope of the line is undefined
- if (line_y > 0.f)
- {
- int_y = world_rect.mTop;
- }
- else
- {
- int_y = world_rect.mBottom;
- }
- }
- else if (0 == world_rect.getWidth())
- {
- // the diagonal slope of the view is undefined
- if (y < world_rect.mBottom)
- {
- int_y = world_rect.mBottom;
- }
- else if ( y > world_rect.mTop)
- {
- int_y = world_rect.mTop;
- }
- }
- else
- {
- F32 line_slope = (F32)(line_y / line_x);
- F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth());
-
- if (fabs(line_slope) > rect_slope)
- {
- if (line_y < 0.f)
- {
- // bottom
- int_y = world_rect.mBottom;
- }
- else
- {
- // top
- int_y = world_rect.mTop;
- }
- int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
- }
- else if (fabs(line_slope) < rect_slope)
- {
- if (line_x < 0.f)
- {
- // left
- int_x = world_rect.mLeft;
- }
- else
- {
- // right
- int_x = world_rect.mRight;
- }
- int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
- }
- else
- {
- // exactly parallel ==> push to the corners
- if (line_x > 0.f)
- {
- int_x = world_rect.mRight;
- }
- else
- {
- int_x = world_rect.mLeft;
- }
- if (line_y > 0.0f)
- {
- int_y = world_rect.mTop;
- }
- else
- {
- int_y = world_rect.mBottom;
- }
- }
- }
- if (!in_front)
- {
- int_x = world_rect.mLeft + world_rect.mRight - int_x;
- int_y = world_rect.mBottom + world_rect.mTop - int_y;
- }
-
- out_point.mX = int_x + world_rect.mLeft;
- out_point.mY = int_y + world_rect.mBottom;
- return TRUE;
- }
- return FALSE;
+ LLVector3 dir_to_point = pos_agent - getOrigin();
+ dir_to_point /= dir_to_point.magVec();
+
+ BOOL in_front = TRUE;
+ if (dir_to_point * getAtAxis() < 0.f)
+ {
+ in_front = FALSE;
+ }
+
+ LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
+ S32 viewport[4];
+ viewport[0] = world_view_rect.mLeft;
+ viewport[1] = world_view_rect.mBottom;
+ viewport[2] = world_view_rect.getWidth();
+ viewport[3] = world_view_rect.getHeight();
+ GLdouble x, y, z; // object's window coords, GL-style
+
+ F64 mdlv[16];
+ F64 proj[16];
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ mdlv[i] = (F64) gGLModelView[i];
+ proj[i] = (F64) gGLProjection[i];
+ }
+
+ if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
+ pos_agent.mV[VZ], mdlv,
+ proj, (GLint*)viewport,
+ &x, &y, &z))
+ {
+ x /= gViewerWindow->getDisplayScale().mV[VX];
+ y /= gViewerWindow->getDisplayScale().mV[VY];
+ // should now have the x,y coords of grab_point in screen space
+ const LLRect& world_rect = gViewerWindow->getWorldViewRectScaled();
+
+ // ...sanity check
+ S32 int_x = lltrunc(x);
+ S32 int_y = lltrunc(y);
+
+ // find the center
+ GLdouble center_x = (GLdouble)world_rect.getCenterX();
+ GLdouble center_y = (GLdouble)world_rect.getCenterY();
+
+ if (x == center_x && y == center_y)
+ {
+ // can't project to edge from exact center
+ return FALSE;
+ }
+
+ // find the line from center to local
+ GLdouble line_x = x - center_x;
+ GLdouble line_y = y - center_y;
+
+ int_x = lltrunc(center_x);
+ int_y = lltrunc(center_y);
+
+
+ if (0.f == line_x)
+ {
+ // the slope of the line is undefined
+ if (line_y > 0.f)
+ {
+ int_y = world_rect.mTop;
+ }
+ else
+ {
+ int_y = world_rect.mBottom;
+ }
+ }
+ else if (0 == world_rect.getWidth())
+ {
+ // the diagonal slope of the view is undefined
+ if (y < world_rect.mBottom)
+ {
+ int_y = world_rect.mBottom;
+ }
+ else if ( y > world_rect.mTop)
+ {
+ int_y = world_rect.mTop;
+ }
+ }
+ else
+ {
+ F32 line_slope = (F32)(line_y / line_x);
+ F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth());
+
+ if (fabs(line_slope) > rect_slope)
+ {
+ if (line_y < 0.f)
+ {
+ // bottom
+ int_y = world_rect.mBottom;
+ }
+ else
+ {
+ // top
+ int_y = world_rect.mTop;
+ }
+ int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
+ }
+ else if (fabs(line_slope) < rect_slope)
+ {
+ if (line_x < 0.f)
+ {
+ // left
+ int_x = world_rect.mLeft;
+ }
+ else
+ {
+ // right
+ int_x = world_rect.mRight;
+ }
+ int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
+ }
+ else
+ {
+ // exactly parallel ==> push to the corners
+ if (line_x > 0.f)
+ {
+ int_x = world_rect.mRight;
+ }
+ else
+ {
+ int_x = world_rect.mLeft;
+ }
+ if (line_y > 0.0f)
+ {
+ int_y = world_rect.mTop;
+ }
+ else
+ {
+ int_y = world_rect.mBottom;
+ }
+ }
+ }
+ if (!in_front)
+ {
+ int_x = world_rect.mLeft + world_rect.mRight - int_x;
+ int_y = world_rect.mBottom + world_rect.mTop - int_y;
+ }
+
+ out_point.mX = int_x + world_rect.mLeft;
+ out_point.mY = int_y + world_rect.mBottom;
+ return TRUE;
+ }
+ return FALSE;
}
void LLViewerCamera::getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right)
{
- LLVector3 to_vec = pos_agent - getOrigin();
+ LLVector3 to_vec = pos_agent - getOrigin();
- F32 at_dist = to_vec * getAtAxis();
+ F32 at_dist = to_vec * getAtAxis();
- F32 height_meters = at_dist* (F32)tan(getView()/2.f);
- F32 height_pixels = getViewHeightInPixels()/2.f;
+ F32 height_meters = at_dist* (F32)tan(getView()/2.f);
+ F32 height_pixels = getViewHeightInPixels()/2.f;
- F32 pixel_aspect = gViewerWindow->getWindow()->getPixelAspectRatio();
+ F32 pixel_aspect = gViewerWindow->getWindow()->getPixelAspectRatio();
- F32 meters_per_pixel = height_meters / height_pixels;
- up = getUpAxis() * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY];
- right = -1.f * pixel_aspect * meters_per_pixel * getLeftAxis() * gViewerWindow->getDisplayScale().mV[VX];
+ F32 meters_per_pixel = height_meters / height_pixels;
+ up = getUpAxis() * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY];
+ right = -1.f * pixel_aspect * meters_per_pixel * getLeftAxis() * gViewerWindow->getDisplayScale().mV[VX];
}
LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent)
{
- F32 dist = (pos_agent - getOrigin()).magVec();
- // Convert to screen space and back, preserving the depth.
- LLCoordGL screen_point;
- if (!projectPosAgentToScreen(pos_agent, screen_point, FALSE))
- {
- // Off the screen, just return the original position.
- return pos_agent;
- }
-
- LLVector3 ray_dir;
-
- projectScreenToPosAgent(screen_point.mX, screen_point.mY, &ray_dir);
- ray_dir -= getOrigin();
- ray_dir.normVec();
-
- LLVector3 pos_agent_rounded = getOrigin() + ray_dir*dist;
-
- /*
- LLVector3 pixel_x, pixel_y;
- getPixelVectors(pos_agent_rounded, pixel_y, pixel_x);
- pos_agent_rounded += 0.5f*pixel_x, 0.5f*pixel_y;
- */
- return pos_agent_rounded;
+ F32 dist = (pos_agent - getOrigin()).magVec();
+ // Convert to screen space and back, preserving the depth.
+ LLCoordGL screen_point;
+ if (!projectPosAgentToScreen(pos_agent, screen_point, FALSE))
+ {
+ // Off the screen, just return the original position.
+ return pos_agent;
+ }
+
+ LLVector3 ray_dir;
+
+ projectScreenToPosAgent(screen_point.mX, screen_point.mY, &ray_dir);
+ ray_dir -= getOrigin();
+ ray_dir.normVec();
+
+ LLVector3 pos_agent_rounded = getOrigin() + ray_dir*dist;
+
+ /*
+ LLVector3 pixel_x, pixel_y;
+ getPixelVectors(pos_agent_rounded, pixel_y, pixel_x);
+ pos_agent_rounded += 0.5f*pixel_x, 0.5f*pixel_y;
+ */
+ return pos_agent_rounded;
}
BOOL LLViewerCamera::cameraUnderWater() const
{
LLViewerRegion* regionp = LLWorld::instance().getRegionFromPosAgent(getOrigin());
- if (!regionp)
+ if (gPipeline.mHeroProbeManager.isMirrorPass())
{
- regionp = gAgent.getRegion();
+ // TODO: figure out how to handle this case
+ return FALSE;
}
- if(!regionp)
+ if (!regionp)
{
- return FALSE ;
+ regionp = gAgent.getRegion();
}
- return getOrigin().mV[VZ] < regionp->getWaterHeight();
+ if(!regionp)
+ {
+ return FALSE ;
+ }
+
+ return getOrigin().mV[VZ] < regionp->getWaterHeight();
}
BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
{
- S32 i, num_faces;
- LLDrawable* drawablep = volumep->mDrawable;
-
- if (!drawablep)
- {
- return FALSE;
- }
-
- LLVolume* volume = volumep->getVolume();
- if (!volume)
- {
- return FALSE;
- }
-
- LLVOVolume* vo_volume = (LLVOVolume*) volumep;
-
- vo_volume->updateRelativeXform();
- LLMatrix4 mat = vo_volume->getRelativeXform();
-
- LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));
-
- LLMatrix4a render_mata;
- render_mata.loadu(render_mat);
- LLMatrix4a mata;
- mata.loadu(mat);
-
- num_faces = volume->getNumVolumeFaces();
- for (i = 0; i < num_faces; i++)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
-
- for (U32 v = 0; v < face.mNumVertices; v++)
- {
- const LLVector4a& src_vec = face.mPositions[v];
- LLVector4a vec;
- mata.affineTransform(src_vec, vec);
-
- if (drawablep->isActive())
- {
- LLVector4a t = vec;
- render_mata.affineTransform(t, vec);
- }
-
- BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0;
-
- if (( !in_frustum && all_verts) ||
- (in_frustum && !all_verts))
- {
- return !all_verts;
- }
- }
- }
- return all_verts;
+ S32 i, num_faces;
+ LLDrawable* drawablep = volumep->mDrawable;
+
+ if (!drawablep)
+ {
+ return FALSE;
+ }
+
+ LLVolume* volume = volumep->getVolume();
+ if (!volume)
+ {
+ return FALSE;
+ }
+
+ LLVOVolume* vo_volume = (LLVOVolume*) volumep;
+
+ vo_volume->updateRelativeXform();
+ LLMatrix4 mat = vo_volume->getRelativeXform();
+
+ LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));
+
+ LLMatrix4a render_mata;
+ render_mata.loadu(render_mat);
+ LLMatrix4a mata;
+ mata.loadu(mat);
+
+ num_faces = volume->getNumVolumeFaces();
+ for (i = 0; i < num_faces; i++)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+
+ for (U32 v = 0; v < face.mNumVertices; v++)
+ {
+ const LLVector4a& src_vec = face.mPositions[v];
+ LLVector4a vec;
+ mata.affineTransform(src_vec, vec);
+
+ if (drawablep->isActive())
+ {
+ LLVector4a t = vec;
+ render_mata.affineTransform(t, vec);
+ }
+
+ BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0;
+
+ if (( !in_frustum && all_verts) ||
+ (in_frustum && !all_verts))
+ {
+ return !all_verts;
+ }
+ }
+ }
+ return all_verts;
}
extern BOOL gCubeSnapshot;
@@ -841,29 +847,29 @@ extern BOOL gCubeSnapshot;
{
llassert(!gCubeSnapshot);
- F32 old_fov = LLViewerCamera::getInstance()->getView();
+ F32 old_fov = LLViewerCamera::getInstance()->getView();
- // cap the FoV
- vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
+ // cap the FoV
+ vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
- if (vertical_fov_rads == old_fov) return;
+ if (vertical_fov_rads == old_fov) return;
- // send the new value to the simulator
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_AgentFOV);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
+ // send the new value to the simulator
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_AgentFOV);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
- msg->nextBlockFast(_PREHASH_FOVBlock);
- msg->addU32Fast(_PREHASH_GenCounter, 0);
- msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads);
+ msg->nextBlockFast(_PREHASH_FOVBlock);
+ msg->addU32Fast(_PREHASH_GenCounter, 0);
+ msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads);
- gAgent.sendReliableMessage();
+ gAgent.sendReliableMessage();
- // sync the camera with the new value
- LLCamera::setView(vertical_fov_rads); // call base implementation
+ // sync the camera with the new value
+ LLCamera::setView(vertical_fov_rads); // call base implementation
}
void LLViewerCamera::setViewNoBroadcast(F32 vertical_fov_rads)
@@ -871,28 +877,28 @@ void LLViewerCamera::setViewNoBroadcast(F32 vertical_fov_rads)
LLCamera::setView(vertical_fov_rads);
}
-void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
+void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
{
- vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
- setView(vertical_fov_rads);
- mCameraFOVDefault = vertical_fov_rads;
- mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
+ vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
+ setView(vertical_fov_rads);
+ mCameraFOVDefault = vertical_fov_rads;
+ mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
}
BOOL LLViewerCamera::isDefaultFOVChanged()
{
- if(mPrevCameraFOVDefault != mCameraFOVDefault)
- {
- mPrevCameraFOVDefault = mCameraFOVDefault;
- return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs");
- }
- return FALSE;
+ if(mPrevCameraFOVDefault != mCameraFOVDefault)
+ {
+ mPrevCameraFOVDefault = mCameraFOVDefault;
+ return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs");
+ }
+ return FALSE;
}
// static
void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value)
{
- LLViewerCamera* self=(LLViewerCamera*)user_data;
- self->setDefaultFOV(value.asReal());
+ LLViewerCamera* self=(LLViewerCamera*)user_data;
+ self->setDefaultFOV(value.asReal());
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 377110cd94..1fc51ac23c 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llviewercontrol.cpp
* @brief Viewer configuration
* @author Richard Nelson
@@ -6,21 +6,21 @@
* $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$
*/
@@ -30,7 +30,7 @@
#include "llviewercontrol.h"
// Library includes
-#include "llwindow.h" // getGamma()
+#include "llwindow.h" // getGamma()
// For Listeners
#include "llaudioengine.h"
@@ -54,6 +54,7 @@
#include "llvotree.h"
#include "llvovolume.h"
#include "llworld.h"
+#include "llvlcomposition.h"
#include "pipeline.h"
#include "llviewerjoystick.h"
#include "llviewerobjectlist.h"
@@ -80,15 +81,15 @@
#include <boost/algorithm/string.hpp>
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
-BOOL gHackGodmode = FALSE;
+BOOL gHackGodmode = FALSE;
#endif
// Should you contemplate changing the name "Global", please first grep for
// that string literal. There are at least a couple other places in the C++
// code that assume the LLControlGroup named "Global" is gSavedSettings.
-LLControlGroup gSavedSettings("Global"); // saved at end of session
+LLControlGroup gSavedSettings("Global"); // saved at end of session
LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
-LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session
+LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session
LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings
std::string gLastRunVersion;
@@ -101,8 +102,8 @@ extern BOOL gDebugGL;
static bool handleRenderAvatarMouselookChanged(const LLSD& newvalue)
{
- LLVOAvatar::sVisibleInFirstPerson = newvalue.asBoolean();
- return true;
+ LLVOAvatar::sVisibleInFirstPerson = newvalue.asBoolean();
+ return true;
}
static bool handleRenderFarClipChanged(const LLSD& newvalue)
@@ -110,19 +111,32 @@ static bool handleRenderFarClipChanged(const LLSD& newvalue)
if (LLStartUp::getStartupState() >= STATE_STARTED)
{
F32 draw_distance = (F32)newvalue.asReal();
- gAgentCamera.mDrawDistance = draw_distance;
- LLWorld::getInstance()->setLandFarClip(draw_distance);
- return true;
+ gAgentCamera.mDrawDistance = draw_distance;
+ LLWorld::getInstance()->setLandFarClip(draw_distance);
+ return true;
}
return false;
}
-static bool handleTerrainDetailChanged(const LLSD& newvalue)
+static bool handleTerrainScaleChanged(const LLSD& newvalue)
{
- LLDrawPoolTerrain::sDetailMode = newvalue.asInteger();
- return true;
+ F64 scale = newvalue.asReal();
+ if (scale != 0.0)
+ {
+ LLDrawPoolTerrain::sDetailScale = F32(1.0 / scale);
+ }
+ return true;
}
+static bool handlePBRTerrainScaleChanged(const LLSD& newvalue)
+{
+ F64 scale = newvalue.asReal();
+ if (scale != 0.0)
+ {
+ LLDrawPoolTerrain::sPBRDetailScale = F32(1.0 / scale);
+ }
+ return true;
+}
static bool handleDebugAvatarJointsChanged(const LLSD& newvalue)
{
@@ -133,19 +147,19 @@ static bool handleDebugAvatarJointsChanged(const LLSD& newvalue)
static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue)
{
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->setHoverIfRegionEnabled();
- }
- return true;
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->setHoverIfRegionEnabled();
+ }
+ return true;
}
static bool handleSetShaderChanged(const LLSD& newvalue)
{
- // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache
- gBumpImageList.destroyGL();
- gBumpImageList.restoreGL();
+ // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache
+ gBumpImageList.destroyGL();
+ gBumpImageList.restoreGL();
if (gPipeline.isInit())
{
@@ -153,9 +167,9 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
LLPipeline::refreshCachedSettings();
}
- // else, leave terrain detail as is
- LLViewerShaderMgr::instance()->setShaders();
- return true;
+ // else, leave terrain detail as is
+ LLViewerShaderMgr::instance()->setShaders();
+ return true;
}
static bool handleRenderPerfTestChanged(const LLSD& newvalue)
@@ -172,10 +186,10 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
LLPipeline::RENDER_TYPE_HUD,
LLPipeline::RENDER_TYPE_CLOUDS,
LLPipeline::RENDER_TYPE_HUD_PARTICLES,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::END_RENDER_TYPES);
gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, false);
}
- else
+ else
{
gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY,
LLPipeline::RENDER_TYPE_TERRAIN,
@@ -195,55 +209,55 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
- if (gPipeline.isInit())
- {
- gPipeline.updateRenderTransparentWater();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- LLViewerShaderMgr::instance()->setShaders();
- }
- LLWorld::getInstance()->updateWaterObjects();
- return true;
+ if (gPipeline.isInit())
+ {
+ gPipeline.updateRenderTransparentWater();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+ LLWorld::getInstance()->updateWaterObjects();
+ return true;
}
static bool handleShadowsResized(const LLSD& newvalue)
{
- gPipeline.requestResizeShadowTexture();
- return true;
+ gPipeline.requestResizeShadowTexture();
+ return true;
}
static bool handleWindowResized(const LLSD& newvalue)
{
- gPipeline.requestResizeScreenTexture();
- return true;
+ gPipeline.requestResizeScreenTexture();
+ return true;
}
static bool handleReleaseGLBufferChanged(const LLSD& newvalue)
{
- if (gPipeline.isInit())
- {
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- }
- return true;
+ if (gPipeline.isInit())
+ {
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ }
+ return true;
}
static bool handleLUTBufferChanged(const LLSD& newvalue)
{
- if (gPipeline.isInit())
- {
- gPipeline.releaseLUTBuffers();
- gPipeline.createLUTBuffers();
- }
- return true;
+ if (gPipeline.isInit())
+ {
+ gPipeline.releaseLUTBuffers();
+ gPipeline.createLUTBuffers();
+ }
+ return true;
}
static bool handleAnisotropicChanged(const LLSD& newvalue)
{
- LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean();
- LLImageGL::dirtyTexOptions();
- return true;
+ LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean();
+ LLImageGL::dirtyTexOptions();
+ return true;
}
static bool handleVSyncChanged(const LLSD& newvalue)
@@ -262,62 +276,62 @@ static bool handleVSyncChanged(const LLSD& newvalue)
static bool handleVolumeLODChanged(const LLSD& newvalue)
{
- LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
- LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
- return true;
+ LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
+ LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
+ return true;
}
static bool handleAvatarLODChanged(const LLSD& newvalue)
{
- LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
- return true;
+ LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
+ return true;
}
static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
{
- LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
- return true;
+ LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
+ return true;
}
static bool handleTerrainLODChanged(const LLSD& newvalue)
{
- LLVOSurfacePatch::sLODFactor = (F32)newvalue.asReal();
- //sqaure lod factor to get exponential range of [0,4] and keep
- //a value of 1 in the middle of the detail slider for consistency
- //with other detail sliders (see panel_preferences_graphics1.xml)
- LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor;
- return true;
+ LLVOSurfacePatch::sLODFactor = (F32)newvalue.asReal();
+ //sqaure lod factor to get exponential range of [0,4] and keep
+ //a value of 1 in the middle of the detail slider for consistency
+ //with other detail sliders (see panel_preferences_graphics1.xml)
+ LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor;
+ return true;
}
static bool handleTreeLODChanged(const LLSD& newvalue)
{
- LLVOTree::sTreeFactor = (F32) newvalue.asReal();
- return true;
+ LLVOTree::sTreeFactor = (F32) newvalue.asReal();
+ return true;
}
static bool handleFlexLODChanged(const LLSD& newvalue)
{
- LLVolumeImplFlexible::sUpdateFactor = (F32) newvalue.asReal();
- return true;
+ LLVolumeImplFlexible::sUpdateFactor = (F32) newvalue.asReal();
+ return true;
}
static bool handleGammaChanged(const LLSD& newvalue)
{
- F32 gamma = (F32) newvalue.asReal();
- if (gamma == 0.0f)
- {
- gamma = 1.0f; // restore normal gamma
- }
- if (gViewerWindow && gViewerWindow->getWindow() && gamma != gViewerWindow->getWindow()->getGamma())
- {
- // Only save it if it's changed
- if (!gViewerWindow->getWindow()->setGamma(gamma))
- {
- LL_WARNS() << "setGamma failed!" << LL_ENDL;
- }
- }
+ F32 gamma = (F32) newvalue.asReal();
+ if (gamma == 0.0f)
+ {
+ gamma = 1.0f; // restore normal gamma
+ }
+ if (gViewerWindow && gViewerWindow->getWindow() && gamma != gViewerWindow->getWindow()->getGamma())
+ {
+ // Only save it if it's changed
+ if (!gViewerWindow->getWindow()->setGamma(gamma))
+ {
+ LL_WARNS() << "setGamma failed!" << LL_ENDL;
+ }
+ }
- return true;
+ return true;
}
const F32 MAX_USER_FOG_RATIO = 10.f;
@@ -325,93 +339,93 @@ const F32 MIN_USER_FOG_RATIO = 0.5f;
static bool handleFogRatioChanged(const LLSD& newvalue)
{
- F32 fog_ratio = llmax(MIN_USER_FOG_RATIO, llmin((F32) newvalue.asReal(), MAX_USER_FOG_RATIO));
- gSky.setFogRatio(fog_ratio);
- return true;
+ F32 fog_ratio = llmax(MIN_USER_FOG_RATIO, llmin((F32) newvalue.asReal(), MAX_USER_FOG_RATIO));
+ gSky.setFogRatio(fog_ratio);
+ return true;
}
static bool handleMaxPartCountChanged(const LLSD& newvalue)
{
- LLViewerPartSim::setMaxPartCount(newvalue.asInteger());
- return true;
+ LLViewerPartSim::setMaxPartCount(newvalue.asInteger());
+ return true;
}
static bool handleChatFontSizeChanged(const LLSD& newvalue)
{
- if(gConsole)
- {
- gConsole->setFontSize(newvalue.asInteger());
- }
- return true;
+ if(gConsole)
+ {
+ gConsole->setFontSize(newvalue.asInteger());
+ }
+ return true;
}
static bool handleChatPersistTimeChanged(const LLSD& newvalue)
{
- if(gConsole)
- {
- gConsole->setLinePersistTime((F32) newvalue.asReal());
- }
- return true;
+ if(gConsole)
+ {
+ gConsole->setLinePersistTime((F32) newvalue.asReal());
+ }
+ return true;
}
static bool handleConsoleMaxLinesChanged(const LLSD& newvalue)
{
- if(gConsole)
- {
- gConsole->setMaxLines(newvalue.asInteger());
- }
- return true;
+ if(gConsole)
+ {
+ gConsole->setMaxLines(newvalue.asInteger());
+ }
+ return true;
}
static void handleAudioVolumeChanged(const LLSD& newvalue)
{
- audio_update_volume(true);
+ audio_update_volume(true);
}
static bool handleJoystickChanged(const LLSD& newvalue)
{
- LLViewerJoystick::getInstance()->setCameraNeedsUpdate(TRUE);
- return true;
+ LLViewerJoystick::getInstance()->setCameraNeedsUpdate(TRUE);
+ return true;
}
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean()
- && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
- return true;
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean()
+ && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
+ return true;
}
static bool handleUploadBakedTexOldChanged(const LLSD& newvalue)
{
- LLPipeline::sForceOldBakedUpload = newvalue.asBoolean();
- return true;
+ LLPipeline::sForceOldBakedUpload = newvalue.asBoolean();
+ return true;
}
static bool handleWLSkyDetailChanged(const LLSD&)
{
- if (gSky.mVOWLSkyp.notNull())
- {
- gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable);
- }
- return true;
+ if (gSky.mVOWLSkyp.notNull())
+ {
+ gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable);
+ }
+ return true;
}
static bool handleRepartition(const LLSD&)
{
- if (gPipeline.isInit())
- {
- gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
- gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
- gObjectList.repartitionObjects();
- }
- return true;
+ if (gPipeline.isInit())
+ {
+ gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
+ gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
+ gObjectList.repartitionObjects();
+ }
+ return true;
}
static bool handleRenderDynamicLODChanged(const LLSD& newvalue)
{
- LLPipeline::sDynamicLOD = newvalue.asBoolean();
- return true;
+ LLPipeline::sDynamicLOD = newvalue.asBoolean();
+ return true;
}
static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
@@ -423,167 +437,180 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
gPipeline.createGLBuffers();
LLViewerShaderMgr::instance()->setShaders();
gPipeline.mReflectionMapManager.reset();
+ gPipeline.mHeroProbeManager.reset();
}
return true;
}
-static bool handleRenderDebugPipelineChanged(const LLSD& newvalue)
+static bool handleHeroProbeResolutionChanged(const LLSD &newvalue)
{
- gDebugPipeline = newvalue.asBoolean();
+ if (gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ gPipeline.mHeroProbeManager.reset();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ }
return true;
}
+static bool handleRenderDebugPipelineChanged(const LLSD& newvalue)
+{
+ gDebugPipeline = newvalue.asBoolean();
+ return true;
+}
+
static bool handleRenderResolutionDivisorChanged(const LLSD&)
{
- gResizeScreenTexture = TRUE;
- return true;
+ gResizeScreenTexture = TRUE;
+ return true;
}
static bool handleDebugViewsChanged(const LLSD& newvalue)
{
- LLView::sDebugRects = newvalue.asBoolean();
- return true;
+ LLView::sDebugRects = newvalue.asBoolean();
+ return true;
}
static bool handleLogFileChanged(const LLSD& newvalue)
{
- std::string log_filename = newvalue.asString();
- LLFile::remove(log_filename);
- LLError::logToFile(log_filename);
- return true;
+ std::string log_filename = newvalue.asString();
+ LLFile::remove(log_filename);
+ LLError::logToFile(log_filename);
+ return true;
}
bool handleHideGroupTitleChanged(const LLSD& newvalue)
{
- gAgent.setHideGroupTitle(newvalue);
- return true;
+ gAgent.setHideGroupTitle(newvalue);
+ return true;
}
bool handleEffectColorChanged(const LLSD& newvalue)
{
- gAgent.setEffectColor(LLColor4(newvalue));
- return true;
+ gAgent.setEffectColor(LLColor4(newvalue));
+ return true;
}
bool handleHighResSnapshotChanged(const LLSD& newvalue)
{
- // High Res Snapshot active, must uncheck RenderUIInSnapshot
- if (newvalue.asBoolean())
- {
- gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
- }
- return true;
+ // High Res Snapshot active, must uncheck RenderUIInSnapshot
+ if (newvalue.asBoolean())
+ {
+ gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
+ }
+ return true;
}
bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
{
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->updateSettings();
- }
- return true;
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->updateSettings();
+ }
+ return true;
}
bool handleVelocityInterpolate(const LLSD& newvalue)
{
- LLMessageSystem* msg = gMessageSystem;
- if ( newvalue.asBoolean() )
- {
- msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- LL_INFOS() << "Velocity Interpolation On" << LL_ENDL;
- }
- else
- {
- msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- LL_INFOS() << "Velocity Interpolation Off" << LL_ENDL;
- }
- return true;
+ LLMessageSystem* msg = gMessageSystem;
+ if ( newvalue.asBoolean() )
+ {
+ msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+ LL_INFOS() << "Velocity Interpolation On" << LL_ENDL;
+ }
+ else
+ {
+ msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+ LL_INFOS() << "Velocity Interpolation Off" << LL_ENDL;
+ }
+ return true;
}
bool handleForceShowGrid(const LLSD& newvalue)
{
- LLPanelLogin::updateLocationSelectorsVisibility();
- return true;
+ LLPanelLogin::updateLocationSelectorsVisibility();
+ return true;
}
bool handleLoginLocationChanged()
{
- /*
- * This connects the default preference setting to the state of the login
- * panel if it is displayed; if you open the preferences panel before
- * logging in, and change the default login location there, the login
- * panel immediately changes to match your new preference.
- */
- std::string new_login_location = gSavedSettings.getString("LoginLocation");
- LL_DEBUGS("AppInit")<<new_login_location<<LL_ENDL;
- LLStartUp::setStartSLURL(LLSLURL(new_login_location));
- return true;
+ /*
+ * This connects the default preference setting to the state of the login
+ * panel if it is displayed; if you open the preferences panel before
+ * logging in, and change the default login location there, the login
+ * panel immediately changes to match your new preference.
+ */
+ std::string new_login_location = gSavedSettings.getString("LoginLocation");
+ LL_DEBUGS("AppInit")<<new_login_location<<LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(new_login_location));
+ return true;
}
bool handleSpellCheckChanged()
{
- if (gSavedSettings.getBOOL("SpellCheck"))
- {
- std::list<std::string> dict_list;
- std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
- boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
- if (!dict_list.empty())
- {
- LLSpellChecker::setUseSpellCheck(dict_list.front());
- dict_list.pop_front();
- LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
- return true;
- }
- }
- LLSpellChecker::setUseSpellCheck(LLStringUtil::null);
- return true;
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ return true;
+ }
+ }
+ LLSpellChecker::setUseSpellCheck(LLStringUtil::null);
+ return true;
}
bool toggle_agent_pause(const LLSD& newvalue)
{
- if ( newvalue.asBoolean() )
- {
- send_agent_pause();
- }
- else
- {
- send_agent_resume();
- }
- return true;
+ if ( newvalue.asBoolean() )
+ {
+ send_agent_pause();
+ }
+ else
+ {
+ send_agent_resume();
+ }
+ return true;
}
bool toggle_show_navigation_panel(const LLSD& newvalue)
{
- bool value = newvalue.asBoolean();
+ bool value = newvalue.asBoolean();
- LLNavigationBar::getInstance()->setVisible(value);
- gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
+ LLNavigationBar::getInstance()->setVisible(value);
+ gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
gViewerWindow->reshapeStatusBarContainer();
- return true;
+ return true;
}
bool toggle_show_mini_location_panel(const LLSD& newvalue)
{
- bool value = newvalue.asBoolean();
+ bool value = newvalue.asBoolean();
- LLPanelTopInfoBar::getInstance()->setVisible(value);
- gSavedSettings.setBOOL("ShowNavbarNavigationPanel", !value);
+ LLPanelTopInfoBar::getInstance()->setVisible(value);
+ gSavedSettings.setBOOL("ShowNavbarNavigationPanel", !value);
- return true;
+ return true;
}
bool toggle_show_object_render_cost(const LLSD& newvalue)
{
- LLFloaterTools::sShowObjectCost = newvalue.asBoolean();
- return true;
+ LLFloaterTools::sShowObjectCost = newvalue.asBoolean();
+ return true;
}
void handleTargetFPSChanged(const LLSD& newValue)
@@ -650,6 +677,16 @@ void handleFPSTuningStrategyChanged(const LLSD& newValue)
const auto newval = gSavedSettings.getU32("TuningFPSStrategy");
LLPerfStats::tunables.userFPSTuningStrategy = newval;
}
+
+void handleLocalTerrainChanged(const LLSD& newValue)
+{
+ for (U32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)
+ {
+ const auto setting = gSavedSettings.getString(std::string("LocalTerrainAsset") + std::to_string(i + 1));
+ const LLUUID materialID(setting);
+ gLocalTerrainMaterials.setDetailAssetID(i, materialID);
+ }
+}
////////////////////////////////////////////////////////////////////////////
LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
@@ -684,7 +721,11 @@ void settings_setup_listeners()
{
setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRPlanarSampleCount", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRTriplanarBlendFactor", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
@@ -716,7 +757,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
@@ -724,6 +765,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHeroProbeResolution", handleHeroProbeResolutionChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
@@ -806,7 +848,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
- setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
@@ -830,6 +872,10 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset1", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset2", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset3", handleLocalTerrainChanged);
+ setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset4", handleLocalTerrainChanged);
setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
@@ -858,21 +904,21 @@ static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hah
void test_cached_control()
{
#define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL; } while(0)
- TEST_LLCC(U32, 666);
- TEST_LLCC(S32, (S32)-666);
- TEST_LLCC(F32, (F32)-666.666);
- TEST_LLCC(bool, true);
- TEST_LLCC(BOOL, FALSE);
- if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL;
- TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
- TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
- TEST_LLCC(LLRect, LLRect(0, 0, 100, 500));
- TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
- TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
- TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
-//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);
-
- if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL;
+ TEST_LLCC(U32, 666);
+ TEST_LLCC(S32, (S32)-666);
+ TEST_LLCC(F32, (F32)-666.666);
+ TEST_LLCC(bool, true);
+ TEST_LLCC(BOOL, FALSE);
+ if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL;
+ TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
+ TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
+ TEST_LLCC(LLRect, LLRect(0, 0, 100, 500));
+ TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
+ TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
+ TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
+//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);
+
+ if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL;
}
#endif // TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index f1538d0abc..2a77146101 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerdisplay.cpp
* @brief LLViewerDisplay class implementation
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -87,10 +87,10 @@ extern bool gShiftFrame;
LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
// used to toggle renderer back on after teleport
-BOOL gTeleportDisplay = FALSE;
+BOOL gTeleportDisplay = FALSE;
LLFrameTimer gTeleportDisplayTimer;
LLFrameTimer gTeleportArrivalTimer;
-const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain
+const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain
BOOL gForceRenderLandFence = FALSE;
BOOL gDisplaySwapBuffers = FALSE;
@@ -125,84 +125,84 @@ void render_disconnected_background();
void display_startup()
{
- if ( !gViewerWindow
- || !gViewerWindow->getActive()
- || !gViewerWindow->getWindow()->getVisible()
- || gViewerWindow->getWindow()->getMinimized()
- || gNonInteractive)
- {
- return;
- }
-
- gPipeline.updateGL();
-
- // Written as branch to appease GCC which doesn't like different
- // pointer types across ternary ops
- //
- if (!LLViewerFetchedTexture::sWhiteImagep.isNull())
- {
- LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
- }
-
- LLGLSDefault gls_default;
-
- // Required for HTML update in login screen
- static S32 frame_count = 0;
-
- LLGLState::checkStates();
-
- if (frame_count++ > 1) // make sure we have rendered a frame first
- {
- LLViewerDynamicTexture::updateAllInstances();
- }
+ if ( !gViewerWindow
+ || !gViewerWindow->getActive()
+ || !gViewerWindow->getWindow()->getVisible()
+ || gViewerWindow->getWindow()->getMinimized()
+ || gNonInteractive)
+ {
+ return;
+ }
+
+ gPipeline.updateGL();
+
+ // Written as branch to appease GCC which doesn't like different
+ // pointer types across ternary ops
+ //
+ if (!LLViewerFetchedTexture::sWhiteImagep.isNull())
+ {
+ LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+ }
+
+ LLGLSDefault gls_default;
+
+ // Required for HTML update in login screen
+ static S32 frame_count = 0;
+
+ LLGLState::checkStates();
+
+ if (frame_count++ > 1) // make sure we have rendered a frame first
+ {
+ LLViewerDynamicTexture::updateAllInstances();
+ }
else
{
LL_DEBUGS("Window") << "First display_startup frame" << LL_ENDL;
}
- LLGLState::checkStates();
+ LLGLState::checkStates();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
- LLGLSUIDefault gls_ui;
- gPipeline.disableLights();
+ LLGLSUIDefault gls_ui;
+ gPipeline.disableLights();
- if (gViewerWindow)
- gViewerWindow->setup2DRender();
- if (gViewerWindow)
- gViewerWindow->draw();
- gGL.flush();
+ if (gViewerWindow)
+ gViewerWindow->setup2DRender();
+ if (gViewerWindow)
+ gViewerWindow->draw();
+ gGL.flush();
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- LLGLState::checkStates();
+ LLGLState::checkStates();
- if (gViewerWindow && gViewerWindow->getWindow())
- gViewerWindow->getWindow()->swapBuffers();
+ if (gViewerWindow && gViewerWindow->getWindow())
+ gViewerWindow->getWindow()->swapBuffers();
- glClear(GL_DEPTH_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT);
}
void display_update_camera()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Camera");
- // TODO: cut draw distance down if customizing avatar?
- // TODO: cut draw distance on per-parcel basis?
+ // TODO: cut draw distance down if customizing avatar?
+ // TODO: cut draw distance on per-parcel basis?
- // Cut draw distance in half when customizing avatar,
- // but on the viewer only.
- F32 final_far = gAgentCamera.mDrawDistance;
+ // Cut draw distance in half when customizing avatar,
+ // but on the viewer only.
+ F32 final_far = gAgentCamera.mDrawDistance;
if (gCubeSnapshot)
{
final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");
}
else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
-
- {
- final_far *= 0.5f;
- }
- LLViewerCamera::getInstance()->setFar(final_far);
- gViewerWindow->setup3DRender();
-
+
+ {
+ final_far *= 0.5f;
+ }
+ LLViewerCamera::getInstance()->setFar(final_far);
+ gViewerWindow->setup3DRender();
+
if (!gCubeSnapshot)
{
// Update land visibility too
@@ -213,30 +213,30 @@ void display_update_camera()
// Write some stats to LL_INFOS()
void display_stats()
{
- LL_PROFILE_ZONE_SCOPED
- F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency");
- if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
- F32 fps = gRecentFrameCount / fps_log_freq;
- LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
- gRecentFrameCount = 0;
- gRecentFPSTime.reset();
- }
- F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
- if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory");
- gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS());
- U32Megabytes memory = gMemoryAllocated;
- LL_INFOS() << "MEMORY: " << memory << LL_ENDL;
- LLMemory::logMemoryInfo(TRUE) ;
- gRecentMemoryTime.reset();
- }
+ LL_PROFILE_ZONE_SCOPED
+ F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency");
+ if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
+ F32 fps = gRecentFrameCount / fps_log_freq;
+ LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
+ gRecentFrameCount = 0;
+ gRecentFPSTime.reset();
+ }
+ F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
+ if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory");
+ gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS());
+ U32Megabytes memory = gMemoryAllocated;
+ LL_INFOS() << "MEMORY: " << memory << LL_ENDL;
+ LLMemory::logMemoryInfo(TRUE) ;
+ gRecentMemoryTime.reset();
+ }
F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency");
if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage");
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage");
gAssetStorageLogTime.reset();
gAssetStorage->logAssetStorageInfo();
}
@@ -244,144 +244,144 @@ void display_stats()
static void update_tp_display(bool minimized)
{
- static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay");
- static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");
-
- S32 attach_count = 0;
- if (isAgentAvatarValid())
- {
- attach_count = gAgentAvatarp->getAttachmentCount();
- }
- F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
- F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
- F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
- if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f)
- {
- // Give up. Don't keep the UI locked forever.
- LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
- gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
- gAgent.setTeleportMessage(std::string());
- }
-
- // Make sure the TP progress panel gets hidden in case the viewer window
- // is minimized *during* a TP. HB
- if (minimized)
- {
- gViewerWindow->setShowProgress(FALSE);
- }
-
- const std::string& message = gAgent.getTeleportMessage();
- switch (gAgent.getTeleportState())
- {
- case LLAgent::TELEPORT_PENDING:
- {
- gTeleportDisplayTimer.reset();
- const std::string& msg = LLAgent::sTeleportProgressMessages["pending"];
- if (!minimized)
- {
- gViewerWindow->setShowProgress(TRUE);
- gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
- gViewerWindow->setProgressString(msg);
- }
- gAgent.setTeleportMessage(msg);
- break;
- }
-
- case LLAgent::TELEPORT_START:
- {
- // Transition to REQUESTED. Viewer has sent some kind
- // of TeleportRequest to the source simulator
- gTeleportDisplayTimer.reset();
- const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"];
- LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
- gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
- gAgent.setTeleportMessage(msg);
- if (!minimized)
- {
- gViewerWindow->setShowProgress(TRUE);
- gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
- gViewerWindow->setProgressString(msg);
- gViewerWindow->setProgressMessage(gAgent.mMOTD);
- }
- break;
- }
-
- case LLAgent::TELEPORT_REQUESTED:
- // Waiting for source simulator to respond
- if (!minimized)
- {
- gViewerWindow->setProgressPercent(llmin(teleport_percent, 37.5f));
- gViewerWindow->setProgressString(message);
- }
- break;
-
- case LLAgent::TELEPORT_MOVING:
- // Viewer has received destination location from source simulator
- if (!minimized)
- {
- gViewerWindow->setProgressPercent(llmin(teleport_percent, 75.f));
- gViewerWindow->setProgressString(message);
- }
- break;
-
- case LLAgent::TELEPORT_START_ARRIVAL:
- // Transition to ARRIVING. Viewer has received avatar update, etc.,
- // from destination simulator
- gTeleportArrivalTimer.reset();
- LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
- gAgent.setTeleportState(LLAgent::TELEPORT_ARRIVING);
- gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["arriving"]);
- gAgent.sheduleTeleportIM();
- gTextureList.mForceResetTextureStats = TRUE;
- gAgentCamera.resetView(TRUE, TRUE);
- if (!minimized)
- {
- gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
- gViewerWindow->setProgressPercent(75.f);
- }
- break;
-
- case LLAgent::TELEPORT_ARRIVING:
- // Make the user wait while content "pre-caches"
- {
- F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());
- if (arrival_fraction > 1.f)
- {
- arrival_fraction = 1.f;
- //LLFirstUse::useTeleport();
- LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
- gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
- }
- if (!minimized)
- {
- gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
- gViewerWindow->setProgressPercent(arrival_fraction * 25.f + 75.f);
- gViewerWindow->setProgressString(message);
- }
- break;
- }
-
- case LLAgent::TELEPORT_LOCAL:
- // Short delay when teleporting in the same sim (progress screen active but not shown - did not
- // fall-through from TELEPORT_START)
- {
- if (gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay())
- {
- //LLFirstUse::useTeleport();
- LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
- << " exceeds teleport_local_delete " << teleport_local_delay
- << "; setting state to TELEPORT_NONE"
- << LL_ENDL;
- gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
- }
- break;
- }
-
- case LLAgent::TELEPORT_NONE:
- // No teleport in progress
- gViewerWindow->setShowProgress(FALSE);
- gTeleportDisplay = FALSE;
- }
+ static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay");
+ static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");
+
+ S32 attach_count = 0;
+ if (isAgentAvatarValid())
+ {
+ attach_count = gAgentAvatarp->getAttachmentCount();
+ }
+ F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
+ F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
+ F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
+ if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f)
+ {
+ // Give up. Don't keep the UI locked forever.
+ LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
+ gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+ gAgent.setTeleportMessage(std::string());
+ }
+
+ // Make sure the TP progress panel gets hidden in case the viewer window
+ // is minimized *during* a TP. HB
+ if (minimized)
+ {
+ gViewerWindow->setShowProgress(FALSE);
+ }
+
+ const std::string& message = gAgent.getTeleportMessage();
+ switch (gAgent.getTeleportState())
+ {
+ case LLAgent::TELEPORT_PENDING:
+ {
+ gTeleportDisplayTimer.reset();
+ const std::string& msg = LLAgent::sTeleportProgressMessages["pending"];
+ if (!minimized)
+ {
+ gViewerWindow->setShowProgress(TRUE);
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+ gViewerWindow->setProgressString(msg);
+ }
+ gAgent.setTeleportMessage(msg);
+ break;
+ }
+
+ case LLAgent::TELEPORT_START:
+ {
+ // Transition to REQUESTED. Viewer has sent some kind
+ // of TeleportRequest to the source simulator
+ gTeleportDisplayTimer.reset();
+ const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"];
+ LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
+ gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
+ gAgent.setTeleportMessage(msg);
+ if (!minimized)
+ {
+ gViewerWindow->setShowProgress(TRUE);
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+ gViewerWindow->setProgressString(msg);
+ gViewerWindow->setProgressMessage(gAgent.mMOTD);
+ }
+ break;
+ }
+
+ case LLAgent::TELEPORT_REQUESTED:
+ // Waiting for source simulator to respond
+ if (!minimized)
+ {
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 37.5f));
+ gViewerWindow->setProgressString(message);
+ }
+ break;
+
+ case LLAgent::TELEPORT_MOVING:
+ // Viewer has received destination location from source simulator
+ if (!minimized)
+ {
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 75.f));
+ gViewerWindow->setProgressString(message);
+ }
+ break;
+
+ case LLAgent::TELEPORT_START_ARRIVAL:
+ // Transition to ARRIVING. Viewer has received avatar update, etc.,
+ // from destination simulator
+ gTeleportArrivalTimer.reset();
+ LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
+ gAgent.setTeleportState(LLAgent::TELEPORT_ARRIVING);
+ gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["arriving"]);
+ gAgent.sheduleTeleportIM();
+ gTextureList.mForceResetTextureStats = TRUE;
+ gAgentCamera.resetView(TRUE, TRUE);
+ if (!minimized)
+ {
+ gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
+ gViewerWindow->setProgressPercent(75.f);
+ }
+ break;
+
+ case LLAgent::TELEPORT_ARRIVING:
+ // Make the user wait while content "pre-caches"
+ {
+ F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());
+ if (arrival_fraction > 1.f)
+ {
+ arrival_fraction = 1.f;
+ //LLFirstUse::useTeleport();
+ LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
+ gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+ }
+ if (!minimized)
+ {
+ gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
+ gViewerWindow->setProgressPercent(arrival_fraction * 25.f + 75.f);
+ gViewerWindow->setProgressString(message);
+ }
+ break;
+ }
+
+ case LLAgent::TELEPORT_LOCAL:
+ // Short delay when teleporting in the same sim (progress screen active but not shown - did not
+ // fall-through from TELEPORT_START)
+ {
+ if (gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay())
+ {
+ //LLFirstUse::useTeleport();
+ LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
+ << " exceeds teleport_local_delete " << teleport_local_delay
+ << "; setting state to TELEPORT_NONE"
+ << LL_ENDL;
+ gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+ }
+ break;
+ }
+
+ case LLAgent::TELEPORT_NONE:
+ // No teleport in progress
+ gViewerWindow->setShowProgress(FALSE);
+ gTeleportDisplay = FALSE;
+ }
}
// Paint the display!
@@ -390,513 +390,521 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Render");
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering.
-
- if (gWindowResized)
- { //skip render on frames where window has been resized
- LL_DEBUGS("Window") << "Resizing window" << LL_ENDL;
+
+ if (gWindowResized)
+ { //skip render on frames where window has been resized
+ LL_DEBUGS("Window") << "Resizing window" << LL_ENDL;
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Resize Window");
- gGL.flush();
- glClear(GL_COLOR_BUFFER_BIT);
- gViewerWindow->getWindow()->swapBuffers();
- LLPipeline::refreshCachedSettings();
- gPipeline.resizeScreenTexture();
- gResizeScreenTexture = FALSE;
- gWindowResized = FALSE;
- return;
- }
+ gGL.flush();
+ glClear(GL_COLOR_BUFFER_BIT);
+ gViewerWindow->getWindow()->swapBuffers();
+ LLPipeline::refreshCachedSettings();
+ gPipeline.resizeScreenTexture();
+ gResizeScreenTexture = FALSE;
+ gWindowResized = FALSE;
+ return;
+ }
if (gResizeShadowTexture)
- { //skip render on frames where window has been resized
- gPipeline.resizeShadowTexture();
- gResizeShadowTexture = FALSE;
- }
-
- gSnapshot = for_snapshot;
-
- if (LLPipeline::sRenderDeferred)
- { //hack to make sky show up in deferred snapshots
- for_snapshot = FALSE;
- }
-
- LLGLSDefault gls_default;
- LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
-
- LLVertexBuffer::unbind();
-
- LLGLState::checkStates();
-
- gPipeline.disableLights();
-
- // Don't draw if the window is hidden or minimized.
- // In fact, must explicitly check the minimized state before drawing.
- // Attempting to draw into a minimized window causes a GL error. JC
- if ( !gViewerWindow->getActive()
- || !gViewerWindow->getWindow()->getVisible()
- || gViewerWindow->getWindow()->getMinimized()
- || gNonInteractive)
- {
- // Clean up memory the pools may have allocated
- if (rebuild)
- {
- stop_glerror();
- gPipeline.rebuildPools();
- stop_glerror();
- }
-
- stop_glerror();
- gViewerWindow->returnEmptyPicks();
- stop_glerror();
-
- // We still need to update the teleport progress (to get changes done
- // in TP states, else the sim does not get the messages signaling the
- // agent's arrival). This fixes BUG-230616. HB
- if (gTeleportDisplay)
- {
- // true = minimized, do not show/update the TP screen. HB
- update_tp_display(true);
- }
- return;
- }
-
- gViewerWindow->checkSettings();
-
- {
+ { //skip render on frames where window has been resized
+ gPipeline.resizeShadowTexture();
+ gResizeShadowTexture = FALSE;
+ }
+
+ gSnapshot = for_snapshot;
+
+ if (LLPipeline::sRenderDeferred)
+ { //hack to make sky show up in deferred snapshots
+ for_snapshot = FALSE;
+ }
+
+ LLGLSDefault gls_default;
+ LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
+
+ LLVertexBuffer::unbind();
+
+ LLGLState::checkStates();
+
+ gPipeline.disableLights();
+
+ // Don't draw if the window is hidden or minimized.
+ // In fact, must explicitly check the minimized state before drawing.
+ // Attempting to draw into a minimized window causes a GL error. JC
+ if ( !gViewerWindow->getActive()
+ || !gViewerWindow->getWindow()->getVisible()
+ || gViewerWindow->getWindow()->getMinimized()
+ || gNonInteractive)
+ {
+ // Clean up memory the pools may have allocated
+ if (rebuild)
+ {
+ stop_glerror();
+ gPipeline.rebuildPools();
+ stop_glerror();
+ }
+
+ stop_glerror();
+ gViewerWindow->returnEmptyPicks();
+ stop_glerror();
+
+ // We still need to update the teleport progress (to get changes done
+ // in TP states, else the sim does not get the messages signaling the
+ // agent's arrival). This fixes BUG-230616. HB
+ if (gTeleportDisplay)
+ {
+ // true = minimized, do not show/update the TP screen. HB
+ update_tp_display(true);
+ }
+ return;
+ }
+
+ gViewerWindow->checkSettings();
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Picking");
- gViewerWindow->performPick();
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
- LLGLState::checkStates();
-
- //////////////////////////////////////////////////////////
- //
- // Logic for forcing window updates if we're in drone mode.
- //
-
- // *TODO: Investigate running display() during gHeadlessClient. See if this early exit is needed DK 2011-02-18
- if (gHeadlessClient)
- {
+ gViewerWindow->performPick();
+ }
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
+ LLGLState::checkStates();
+
+ //////////////////////////////////////////////////////////
+ //
+ // Logic for forcing window updates if we're in drone mode.
+ //
+
+ // *TODO: Investigate running display() during gHeadlessClient. See if this early exit is needed DK 2011-02-18
+ if (gHeadlessClient)
+ {
#if LL_WINDOWS
- static F32 last_update_time = 0.f;
- if ((gFrameTimeSeconds - last_update_time) > 1.f)
- {
- InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
- last_update_time = gFrameTimeSeconds;
- }
+ static F32 last_update_time = 0.f;
+ if ((gFrameTimeSeconds - last_update_time) > 1.f)
+ {
+ InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
+ last_update_time = gFrameTimeSeconds;
+ }
#elif LL_DARWIN
- // MBW -- Do something clever here.
+ // MBW -- Do something clever here.
#endif
- // Not actually rendering, don't bother.
- return;
- }
-
-
- //
- // Bail out if we're in the startup state and don't want to try to
- // render the world.
- //
- if (LLStartUp::getStartupState() < STATE_PRECACHE)
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:Startup");
- display_startup();
- return;
- }
-
-
- if (gShaderProfileFrame)
- {
- LLGLSLShader::initProfile();
- }
-
- //LLGLState::verify(FALSE);
-
- /////////////////////////////////////////////////
- //
- // Update GL Texture statistics (used for discard logic?)
- //
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
- stop_glerror();
-
- LLImageGL::updateStats(gFrameTimeSeconds);
-
- LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode");
- LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode"));
-
- gPipeline.mBackfaceCull = TRUE;
- gFrameCount++;
- gRecentFrameCount++;
- if (gFocusMgr.getAppHasFocus())
- {
- gForegroundFrameCount++;
- }
-
- //////////////////////////////////////////////////////////
- //
- // Display start screen if we're teleporting, and skip render
- //
-
- if (gTeleportDisplay)
- {
+ // Not actually rendering, don't bother.
+ return;
+ }
+
+
+ //
+ // Bail out if we're in the startup state and don't want to try to
+ // render the world.
+ //
+ if (LLStartUp::getStartupState() < STATE_PRECACHE)
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Startup");
+ display_startup();
+ return;
+ }
+
+
+ if (gShaderProfileFrame)
+ {
+ LLGLSLShader::initProfile();
+ }
+
+ //LLGLState::verify(FALSE);
+
+ /////////////////////////////////////////////////
+ //
+ // Update GL Texture statistics (used for discard logic?)
+ //
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
+ stop_glerror();
+
+ LLImageGL::updateStats(gFrameTimeSeconds);
+
+ LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode");
+ LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode"));
+
+ gPipeline.mBackfaceCull = TRUE;
+ gFrameCount++;
+ gRecentFrameCount++;
+ if (gFocusMgr.getAppHasFocus())
+ {
+ gForegroundFrameCount++;
+ }
+
+ //////////////////////////////////////////////////////////
+ //
+ // Display start screen if we're teleporting, and skip render
+ //
+
+ if (gTeleportDisplay)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Teleport Display");
- LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
- // Note: false = not minimized, do update the TP screen. HB
- update_tp_display(false);
- }
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
+ // Note: false = not minimized, do update the TP screen. HB
+ update_tp_display(false);
+ }
else if(LLAppViewer::instance()->logoutRequestSent())
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:Logout");
- F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
- if (percent_done > 100.f)
- {
- percent_done = 100.f;
- }
-
- if( LLApp::isExiting() )
- {
- percent_done = 100.f;
- }
-
- gViewerWindow->setProgressPercent( percent_done );
- gViewerWindow->setProgressMessage(std::string());
- }
- else
- if (gRestoreGL)
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL");
- F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
- if( percent_done > 100.f )
- {
- gViewerWindow->setShowProgress(FALSE);
- gRestoreGL = FALSE;
- }
- else
- {
-
- if( LLApp::isExiting() )
- {
- percent_done = 100.f;
- }
-
- gViewerWindow->setProgressPercent( percent_done );
- }
- gViewerWindow->setProgressMessage(std::string());
- }
-
- //////////////////////////
- //
- // Prepare for the next frame
- //
-
- /////////////////////////////
- //
- // Update the camera
- //
- //
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Logout");
+ F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
+ if (percent_done > 100.f)
+ {
+ percent_done = 100.f;
+ }
+
+ if( LLApp::isExiting() )
+ {
+ percent_done = 100.f;
+ }
+
+ gViewerWindow->setProgressPercent( percent_done );
+ gViewerWindow->setProgressMessage(std::string());
+ }
+ else
+ if (gRestoreGL)
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL");
+ F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
+ if( percent_done > 100.f )
+ {
+ gViewerWindow->setShowProgress(FALSE);
+ gRestoreGL = FALSE;
+ }
+ else
+ {
+
+ if( LLApp::isExiting() )
+ {
+ percent_done = 100.f;
+ }
+
+ gViewerWindow->setProgressPercent( percent_done );
+ }
+ gViewerWindow->setProgressMessage(std::string());
+ }
+
+ //////////////////////////
+ //
+ // Prepare for the next frame
+ //
+
+ /////////////////////////////
+ //
+ // Update the camera
+ //
+ //
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
if (LLViewerCamera::instanceExists())
{
LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);
}
- //////////////////////////
- //
- // clear the next buffer
- // (must follow dynamic texture writing since that uses the frame buffer)
- //
-
- if (gDisconnected)
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
- render_ui();
- swap();
- }
-
- //////////////////////////
- //
- // Set rendering options
- //
- //
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup");
- stop_glerror();
-
- ///////////////////////////////////////
- //
- // Slam lighting parameters back to our defaults.
- // Note that these are not the same as GL defaults...
-
- stop_glerror();
- gGL.setAmbientLightColor(LLColor4::white);
- stop_glerror();
-
- /////////////////////////////////////
- //
- // Render
- //
- // Actually push all of our triangles to the screen.
- //
-
- // do render-to-texture stuff here
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
+ //////////////////////////
+ //
+ // clear the next buffer
+ // (must follow dynamic texture writing since that uses the frame buffer)
+ //
+
+ if (gDisconnected)
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
+ render_ui();
+ swap();
+ }
+
+ //////////////////////////
+ //
+ // Set rendering options
+ //
+ //
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup");
+ stop_glerror();
+
+ ///////////////////////////////////////
+ //
+ // Slam lighting parameters back to our defaults.
+ // Note that these are not the same as GL defaults...
+
+ stop_glerror();
+ gGL.setAmbientLightColor(LLColor4::white);
+ stop_glerror();
+
+ /////////////////////////////////////
+ //
+ // Render
+ //
+ // Actually push all of our triangles to the screen.
+ //
+
+ // do render-to-texture stuff here
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Dynamic Textures");
- if (LLViewerDynamicTexture::updateAllInstances())
+ if (LLViewerDynamicTexture::updateAllInstances())
+ {
+ gGL.setColorMask(true, true);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ }
+
+ gViewerWindow->setup3DViewport();
+
+ gPipeline.resetFrameStats(); // Reset per-frame statistics.
+
+ if (!gDisconnected)
+ {
+ // Render mirrors and associated hero probes before we render the rest of the scene.
+ // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it.
+ if (gPipeline.RenderMirrors && !gSnapshot && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0))
{
- gGL.setColorMask(true, true);
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- }
-
- gViewerWindow->setup3DViewport();
-
- gPipeline.resetFrameStats(); // Reset per-frame statistics.
-
- if (!gDisconnected)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1");
- LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
- if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- { //don't draw hud objects in this frame
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- }
-
- if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
- { //don't draw hud particles in this frame
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes");
+ gPipeline.mHeroProbeManager.update();
}
- stop_glerror();
- display_update_camera();
- stop_glerror();
-
- {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1");
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ { //don't draw hud objects in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
+ { //don't draw hud particles in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ }
+
+ stop_glerror();
+ display_update_camera();
+ stop_glerror();
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Env Update");
// update all the sky/atmospheric/water settings
LLEnvironment::instance().update(LLViewerCamera::getInstance());
- }
+ }
- // *TODO: merge these two methods
- {
+ // *TODO: merge these two methods
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("HUD Update");
- LLHUDManager::getInstance()->updateEffects();
- LLHUDObject::updateAll();
- stop_glerror();
- }
+ LLHUDManager::getInstance()->updateEffects();
+ LLHUDObject::updateAll();
+ stop_glerror();
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Geom");
- const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time
- gPipeline.createObjects(max_geom_update_time);
- gPipeline.processPartitionQ();
- gPipeline.updateGeom(max_geom_update_time);
- stop_glerror();
- }
-
- gPipeline.updateGL();
-
- stop_glerror();
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
-
- //Increment drawable frame counter
- LLDrawable::incrementVisible();
-
- LLSpatialGroup::sNoDelete = TRUE;
- LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
-
- S32 occlusion = LLPipeline::sUseOcclusion;
- if (gDepthDirty)
- { //depth buffer is invalid, don't overwrite occlusion state
- LLPipeline::sUseOcclusion = llmin(occlusion, 1);
- }
- gDepthDirty = FALSE;
-
- LLGLState::checkStates();
-
- static LLCullResult result;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
- gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
- stop_glerror();
-
- LLGLState::checkStates();
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2")
- if (gResizeScreenTexture)
- {
- gPipeline.resizeScreenTexture();
+ const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time
+ gPipeline.createObjects(max_geom_update_time);
+ gPipeline.processPartitionQ();
+ gPipeline.updateGeom(max_geom_update_time);
+ stop_glerror();
+ }
+
+ gPipeline.updateGL();
+
+ stop_glerror();
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
+
+ //Increment drawable frame counter
+ LLDrawable::incrementVisible();
+
+ LLSpatialGroup::sNoDelete = TRUE;
+ LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+
+ S32 occlusion = LLPipeline::sUseOcclusion;
+ if (gDepthDirty)
+ { //depth buffer is invalid, don't overwrite occlusion state
+ LLPipeline::sUseOcclusion = llmin(occlusion, 1);
+ }
+ gDepthDirty = FALSE;
+
+ LLGLState::checkStates();
+
+ static LLCullResult result;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
+ gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
+ stop_glerror();
+
+ LLGLState::checkStates();
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2")
+ if (gResizeScreenTexture)
+ {
+ gPipeline.resizeScreenTexture();
gResizeScreenTexture = FALSE;
- }
+ }
- gGL.setColorMask(true, true);
- glClearColor(0,0,0,0);
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
- LLGLState::checkStates();
+ LLGLState::checkStates();
- if (!for_snapshot)
- {
+ if (!for_snapshot)
+ {
if (gFrameCount > 1 && !for_snapshot)
- { //for some reason, ATI 4800 series will error out if you
+ { //for some reason, ATI 4800 series will error out if you
//try to generate a shadow before the first frame is through
gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
}
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- LLGLState::checkStates();
+ LLGLState::checkStates();
- glh::matrix4f proj = get_current_projection();
- glh::matrix4f mod = get_current_modelview();
- glViewport(0,0,512,512);
+ glh::matrix4f proj = get_current_projection();
+ glh::matrix4f mod = get_current_modelview();
+ glViewport(0,0,512,512);
- LLVOAvatar::updateImpostors();
+ LLVOAvatar::updateImpostors();
- set_current_projection(proj);
- set_current_modelview(mod);
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadMatrix(proj.m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(mod.m);
- gViewerWindow->setup3DViewport();
+ set_current_projection(proj);
+ set_current_modelview(mod);
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadMatrix(proj.m);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(mod.m);
+ gViewerWindow->setup3DViewport();
- LLGLState::checkStates();
- }
+ LLGLState::checkStates();
+ }
glClear(GL_DEPTH_BUFFER_BIT);
- }
-
- //////////////////////////////////////
- //
- // Update images, using the image stats generated during object update/culling
- //
- // Can put objects onto the retextured list.
- //
- // Doing this here gives hardware occlusion queries extra time to complete
- LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
-
- {
+ }
+
+ //////////////////////////////////////
+ //
+ // Update images, using the image stats generated during object update/culling
+ //
+ // Can put objects onto the retextured list.
+ //
+ // Doing this here gives hardware occlusion queries extra time to complete
+ LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
+
+ {
LL_PROFILE_ZONE_NAMED("Update Images");
-
- {
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Class");
- LLViewerTexture::updateClass();
- }
+ LLViewerTexture::updateClass();
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Image Update Bump");
- gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
- }
+ gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("List");
- F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time
- max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
- gTextureList.updateImages(max_image_decode_time);
- }
+ F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time
+ max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
+ gTextureList.updateImages(max_image_decode_time);
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("GLTF Materials Cleanup");
- //remove dead gltf materials
+ //remove dead gltf materials
gGLTFMaterialList.flushMaterials();
- }
- }
-
- LLGLState::checkStates();
-
- ///////////////////////////////////
- //
- // StateSort
- //
- // Responsible for taking visible objects, and adding them to the appropriate draw orders.
- // In the case of alpha objects, z-sorts them first.
- // Also creates special lists for outlines and selected face rendering.
- //
- LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 4")
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
- stop_glerror();
-
- if (rebuild)
- {
- //////////////////////////////////////
- //
- // rebuildPools
- //
- //
- gPipeline.rebuildPools();
- stop_glerror();
- }
- }
-
- LLSceneMonitor::getInstance()->fetchQueryResult();
-
- LLGLState::checkStates();
-
- LLPipeline::sUseOcclusion = occlusion;
-
- {
- LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
- LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT("update sky"); //LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY);
- gSky.updateSky();
- }
-
- if(gUseWireframe)
- {
- glClearColor(0.5f, 0.5f, 0.5f, 0.f);
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
-
- //// render frontmost floater opaque for occlusion culling purposes
- //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
- //// assumes frontmost floater with focus is opaque
- //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
- //{
- // gGL.matrixMode(LLRender::MM_MODELVIEW);
- // gGL.pushMatrix();
- // {
- // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
- // gGL.loadIdentity();
-
- // LLRect floater_rect = frontmost_floaterp->calcScreenRect();
- // // deflate by one pixel so rounding errors don't occlude outside of floater extents
- // floater_rect.stretch(-1);
- // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(),
- // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(),
- // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(),
- // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled());
- // floater_3d_rect.translate(-0.5f, -0.5f);
- // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
- // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
- // gGL.color4fv(LLColor4::white.mV);
- // gGL.begin(LLVertexBuffer::QUADS);
- // {
- // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
- // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
- // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
- // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
- // }
- // gGL.end();
- // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- // }
- // gGL.popMatrix();
- //}
-
- LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
-
- LLGLState::checkStates();
-
- stop_glerror();
+ }
+ }
+
+ LLGLState::checkStates();
+
+ ///////////////////////////////////
+ //
+ // StateSort
+ //
+ // Responsible for taking visible objects, and adding them to the appropriate draw orders.
+ // In the case of alpha objects, z-sorts them first.
+ // Also creates special lists for outlines and selected face rendering.
+ //
+ LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 4")
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
+ stop_glerror();
+
+ if (rebuild)
+ {
+ //////////////////////////////////////
+ //
+ // rebuildPools
+ //
+ //
+ gPipeline.rebuildPools();
+ stop_glerror();
+ }
+ }
+
+ LLSceneMonitor::getInstance()->fetchQueryResult();
+
+ LLGLState::checkStates();
+
+ LLPipeline::sUseOcclusion = occlusion;
+
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
+ LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT("update sky"); //LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY);
+ gSky.updateSky();
+ }
+
+ if(gUseWireframe)
+ {
+ glClearColor(0.5f, 0.5f, 0.5f, 0.f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
+
+ //// render frontmost floater opaque for occlusion culling purposes
+ //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
+ //// assumes frontmost floater with focus is opaque
+ //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
+ //{
+ // gGL.matrixMode(LLRender::MM_MODELVIEW);
+ // gGL.pushMatrix();
+ // {
+ // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
+ // gGL.loadIdentity();
+
+ // LLRect floater_rect = frontmost_floaterp->calcScreenRect();
+ // // deflate by one pixel so rounding errors don't occlude outside of floater extents
+ // floater_rect.stretch(-1);
+ // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(),
+ // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(),
+ // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(),
+ // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled());
+ // floater_3d_rect.translate(-0.5f, -0.5f);
+ // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
+ // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
+ // gGL.color4fv(LLColor4::white.mV);
+ // gGL.begin(LLVertexBuffer::QUADS);
+ // {
+ // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
+ // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
+ // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
+ // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
+ // }
+ // gGL.end();
+ // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ // }
+ // gGL.popMatrix();
+ //}
+
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
+
+ LLGLState::checkStates();
+
+ stop_glerror();
gGL.setColorMask(true, true);
@@ -928,94 +936,94 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, false);
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
-
- if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
- && !gRestoreGL)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5")
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- if (gSavedSettings.getBOOL("RenderDepthPrePass"))
- {
- gGL.setColorMask(false, false);
-
- static const U32 types[] = {
- LLRenderPass::PASS_SIMPLE,
- LLRenderPass::PASS_FULLBRIGHT,
- LLRenderPass::PASS_SHINY
- };
-
- U32 num_types = LL_ARRAY_SIZE(types);
- gOcclusionProgram.bind();
- for (U32 i = 0; i < num_types; i++)
- {
- gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
- }
-
- gOcclusionProgram.unbind();
-
- }
-
- gGL.setColorMask(true, true);
- gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
- }
-
- {
+
+ if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
+ && !gRestoreGL)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5")
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+
+ if (gSavedSettings.getBOOL("RenderDepthPrePass"))
+ {
+ gGL.setColorMask(false, false);
+
+ static const U32 types[] = {
+ LLRenderPass::PASS_SIMPLE,
+ LLRenderPass::PASS_FULLBRIGHT,
+ LLRenderPass::PASS_SHINY
+ };
+
+ U32 num_types = LL_ARRAY_SIZE(types);
+ gOcclusionProgram.bind();
+ for (U32 i = 0; i < num_types; i++)
+ {
+ gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+ }
+
+ gOcclusionProgram.unbind();
+
+ }
+
+ gGL.setColorMask(true, true);
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
+ }
+
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Texture Unbind");
- for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
- }
- }
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
+ for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
+ { //dummy cleanup of any currently bound textures
+ if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
+ {
+ gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
+ gGL.getTexUnit(i)->disable();
+ }
+ }
+ }
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderDeferredLighting();
- }
-
- LLPipeline::sUnderWaterRender = FALSE;
-
- {
- //capture the frame buffer.
- LLSceneMonitor::getInstance()->capture();
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
- if (!for_snapshot)
- {
- render_ui();
- swap();
- }
-
-
- LLSpatialGroup::sNoDelete = FALSE;
- gPipeline.clearReferences();
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
-
- stop_glerror();
-
- display_stats();
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
-
- gShiftFrame = false;
-
- if (gShaderProfileFrame)
- {
- gShaderProfileFrame = FALSE;
- LLGLSLShader::finishProfile();
- }
+ gPipeline.renderDeferredLighting();
+ }
+
+ LLPipeline::sUnderWaterRender = FALSE;
+
+ {
+ //capture the frame buffer.
+ LLSceneMonitor::getInstance()->capture();
+ }
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
+ if (!for_snapshot)
+ {
+ render_ui();
+ swap();
+ }
+
+
+ LLSpatialGroup::sNoDelete = FALSE;
+ gPipeline.clearReferences();
+ }
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
+
+ stop_glerror();
+
+ display_stats();
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
+
+ gShiftFrame = false;
+
+ if (gShaderProfileFrame)
+ {
+ gShaderProfileFrame = FALSE;
+ LLGLSLShader::finishProfile();
+ }
}
// WIP simplified copy of display() that does minimal work
@@ -1062,9 +1070,9 @@ void display_cube_face()
}
LLSpatialGroup::sNoDelete = TRUE;
-
+
S32 occlusion = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots
+ LLPipeline::sUseOcclusion = 1; // occlusion data is from main camera point of view, don't read or write it during cube snapshots
//gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data
static LLCullResult result;
@@ -1076,7 +1084,7 @@ void display_cube_face()
glClearColor(0, 0, 0, 0);
gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
-
+
glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
{
@@ -1094,7 +1102,7 @@ void display_cube_face()
stop_glerror();
}
}
-
+
LLPipeline::sUseOcclusion = occlusion;
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
@@ -1113,13 +1121,13 @@ void display_cube_face()
glClearColor(1, 0, 1, 1);
}
gPipeline.mRT->deferredScreen.clear();
-
+
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
gPipeline.mRT->deferredScreen.flush();
-
+
gPipeline.renderDeferredLighting();
LLPipeline::sUnderWaterRender = FALSE;
@@ -1135,200 +1143,200 @@ void render_hud_attachments()
{
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches)
gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- 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);
- // smoothly interpolate current zoom level
- gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f));
-
- if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
- {
- LLPipeline::sRenderingHUDs = TRUE;
- LLCamera hud_cam = *LLViewerCamera::getInstance();
- hud_cam.setOrigin(-1.f,0,0);
- hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
- LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
-
- bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");
-
- //only render hud objects
- gPipeline.pushRenderTypeMask();
-
- // turn off everything
- gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
- // turn on HUD
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- // turn on HUD particles
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
-
- // if particles are off, turn off hud-particles as well
- if (!render_particles)
- {
- // turn back off HUD particles
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
- }
-
- bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- if (has_ui)
- {
- gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- S32 use_occlusion = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0;
-
- //cull, sort, and render hud objects
- static LLCullResult result;
- LLSpatialGroup::sNoDelete = TRUE;
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- gPipeline.updateCull(hud_cam, result);
+ gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+
+ 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);
+ // smoothly interpolate current zoom level
+ gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f));
+
+ if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
+ {
+ LLPipeline::sRenderingHUDs = TRUE;
+ LLCamera hud_cam = *LLViewerCamera::getInstance();
+ hud_cam.setOrigin(-1.f,0,0);
+ hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
+ LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
+
+ bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");
+
+ //only render hud objects
+ gPipeline.pushRenderTypeMask();
+
+ // turn off everything
+ gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
+ // turn on HUD
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ // turn on HUD particles
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+
+ // if particles are off, turn off hud-particles as well
+ if (!render_particles)
+ {
+ // turn back off HUD particles
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ }
+
+ bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ if (has_ui)
+ {
+ gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ S32 use_occlusion = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0;
+
+ //cull, sort, and render hud objects
+ static LLCullResult result;
+ LLSpatialGroup::sNoDelete = TRUE;
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ gPipeline.updateCull(hud_cam, result);
// Toggle render types
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR_ALPHA_MASK);
// Toggle render passes
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE);
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK);
-
- gPipeline.stateSort(hud_cam, result);
-
- gPipeline.renderGeomPostDeferred(hud_cam);
-
- LLSpatialGroup::sNoDelete = FALSE;
- //gPipeline.clearReferences();
-
- render_hud_elements();
-
- //restore type mask
- gPipeline.popRenderTypeMask();
-
- if (has_ui)
- {
- gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
- LLPipeline::sUseOcclusion = use_occlusion;
- LLPipeline::sRenderingHUDs = FALSE;
- }
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- set_current_projection(current_proj);
- set_current_modelview(current_mod);
+
+ gPipeline.stateSort(hud_cam, result);
+
+ gPipeline.renderGeomPostDeferred(hud_cam);
+
+ LLSpatialGroup::sNoDelete = FALSE;
+ //gPipeline.clearReferences();
+
+ render_hud_elements();
+
+ //restore type mask
+ gPipeline.popRenderTypeMask();
+
+ if (has_ui)
+ {
+ gPipeline.toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+ LLPipeline::sUseOcclusion = use_occlusion;
+ LLPipeline::sRenderingHUDs = FALSE;
+ }
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ set_current_projection(current_proj);
+ set_current_modelview(current_mod);
}
LLRect get_whole_screen_region()
{
- LLRect whole_screen = gViewerWindow->getWorldViewRectScaled();
-
- // apply camera zoom transform (for high res screenshots)
- F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
- S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
- if (zoom_factor > 1.f)
- {
- S32 num_horizontal_tiles = llceil(zoom_factor);
- S32 tile_width = ll_round((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor);
- S32 tile_height = ll_round((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor);
- int tile_y = sub_region / num_horizontal_tiles;
- int tile_x = sub_region - (tile_y * num_horizontal_tiles);
-
- whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height);
- }
- return whole_screen;
+ LLRect whole_screen = gViewerWindow->getWorldViewRectScaled();
+
+ // apply camera zoom transform (for high res screenshots)
+ F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
+ S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
+ if (zoom_factor > 1.f)
+ {
+ S32 num_horizontal_tiles = llceil(zoom_factor);
+ S32 tile_width = ll_round((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor);
+ S32 tile_height = ll_round((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor);
+ int tile_y = sub_region / num_horizontal_tiles;
+ int tile_x = sub_region - (tile_y * num_horizontal_tiles);
+
+ whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height);
+ }
+ return whole_screen;
}
bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::matrix4f &model)
{
- if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment())
- {
- F32 zoom_level = gAgentCamera.mHUDCurZoom;
- LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
-
- F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
- proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth);
- proj.element(2,2) = -0.01f;
-
- F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect();
-
- glh::matrix4f mat;
- F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth();
- F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight();
- mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f));
- mat.set_translate(
- glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio),
- clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y),
- 0.f));
- proj *= mat;
-
- glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION);
-
- mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level));
- mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f));
-
- tmp_model *= mat;
- model = tmp_model;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment())
+ {
+ F32 zoom_level = gAgentCamera.mHUDCurZoom;
+ LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
+
+ F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
+ proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth);
+ proj.element(2,2) = -0.01f;
+
+ F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect();
+
+ glh::matrix4f mat;
+ F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth();
+ F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight();
+ mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f));
+ mat.set_translate(
+ glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio),
+ clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y),
+ 0.f));
+ proj *= mat;
+
+ glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION);
+
+ mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level));
+ mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f));
+
+ tmp_model *= mat;
+ model = tmp_model;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model)
{
- LLRect whole_screen = get_whole_screen_region();
- return get_hud_matrices(whole_screen, proj, model);
+ LLRect whole_screen = get_whole_screen_region();
+ return get_hud_matrices(whole_screen, proj, model);
}
bool setup_hud_matrices()
{
- LLRect whole_screen = get_whole_screen_region();
- return setup_hud_matrices(whole_screen);
+ LLRect whole_screen = get_whole_screen_region();
+ return setup_hud_matrices(whole_screen);
}
bool setup_hud_matrices(const LLRect& screen_region)
{
- glh::matrix4f proj, model;
- bool result = get_hud_matrices(screen_region, proj, model);
- if (!result) return result;
-
- // set up transform to keep HUD objects in front of camera
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadMatrix(proj.m);
- set_current_projection(proj);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(model.m);
- set_current_modelview(model);
- return TRUE;
+ glh::matrix4f proj, model;
+ bool result = get_hud_matrices(screen_region, proj, model);
+ if (!result) return result;
+
+ // set up transform to keep HUD objects in front of camera
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadMatrix(proj.m);
+ set_current_projection(proj);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(model.m);
+ set_current_modelview(model);
+ return TRUE;
}
void render_ui(F32 zoom_factor, int subfield)
@@ -1336,45 +1344,45 @@ void render_ui(F32 zoom_factor, int subfield)
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO)
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
LL_PROFILE_GPU_ZONE("ui");
- LLGLState::checkStates();
-
- glh::matrix4f saved_view = get_current_modelview();
-
- if (!gSnapshot)
- {
- gGL.pushMatrix();
- gGL.loadMatrix(gGLLastModelView);
- set_current_modelview(copy_matrix(gGLLastModelView));
- }
-
- if(LLSceneMonitor::getInstance()->needsUpdate())
- {
- gGL.pushMatrix();
- gViewerWindow->setup2DRender();
- LLSceneMonitor::getInstance()->compare();
- gViewerWindow->setup3DRender();
- gGL.popMatrix();
- }
+ LLGLState::checkStates();
+
+ glh::matrix4f saved_view = get_current_modelview();
+
+ if (!gSnapshot)
+ {
+ gGL.pushMatrix();
+ gGL.loadMatrix(gGLLastModelView);
+ set_current_modelview(copy_matrix(gGLLastModelView));
+ }
+
+ if(LLSceneMonitor::getInstance()->needsUpdate())
+ {
+ gGL.pushMatrix();
+ gViewerWindow->setup2DRender();
+ LLSceneMonitor::getInstance()->compare();
+ gViewerWindow->setup3DRender();
+ gGL.popMatrix();
+ }
// apply gamma correction and post effects
gPipeline.renderFinalize();
- {
+ {
LLGLState::checkStates();
LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD");
- render_hud_elements();
+ render_hud_elements();
LLGLState::checkStates();
- render_hud_attachments();
+ render_hud_attachments();
LLGLState::checkStates();
- LLGLSDefault gls_default;
- LLGLSUIDefault gls_ui;
- {
- gPipeline.disableLights();
- }
+ LLGLSDefault gls_default;
+ LLGLSUIDefault gls_ui;
+ {
+ gPipeline.disableLights();
+ }
bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
if (render_ui)
@@ -1402,13 +1410,13 @@ void render_ui(F32 zoom_factor, int subfield)
gViewerWindow->setup2DRender();
gViewerWindow->updateDebugText();
gViewerWindow->drawDebugText();
- }
+ }
- if (!gSnapshot)
- {
- set_current_modelview(saved_view);
- gGL.popMatrix();
- }
+ if (!gSnapshot)
+ {
+ set_current_modelview(saved_view);
+ gGL.popMatrix();
+ }
}
void swap()
@@ -1416,112 +1424,112 @@ void swap()
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Swap");
LL_PROFILE_GPU_ZONE("swap");
- if (gDisplaySwapBuffers)
- {
- gViewerWindow->getWindow()->swapBuffers();
- }
- gDisplaySwapBuffers = TRUE;
+ if (gDisplaySwapBuffers)
+ {
+ gViewerWindow->getWindow()->swapBuffers();
+ }
+ gDisplaySwapBuffers = TRUE;
}
void renderCoordinateAxes()
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.begin(LLRender::LINES);
- gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(2.0f, 0.0f, 0.0f);
- gGL.vertex3f(3.0f, 0.0f, 0.0f);
- gGL.vertex3f(5.0f, 0.0f, 0.0f);
- gGL.vertex3f(6.0f, 0.0f, 0.0f);
- gGL.vertex3f(8.0f, 0.0f, 0.0f);
- // Make an X
- gGL.vertex3f(11.0f, 1.0f, 1.0f);
- gGL.vertex3f(11.0f, -1.0f, -1.0f);
- gGL.vertex3f(11.0f, 1.0f, -1.0f);
- gGL.vertex3f(11.0f, -1.0f, 1.0f);
-
- gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(0.0f, 2.0f, 0.0f);
- gGL.vertex3f(0.0f, 3.0f, 0.0f);
- gGL.vertex3f(0.0f, 5.0f, 0.0f);
- gGL.vertex3f(0.0f, 6.0f, 0.0f);
- gGL.vertex3f(0.0f, 8.0f, 0.0f);
- // Make a Y
- gGL.vertex3f(1.0f, 11.0f, 1.0f);
- gGL.vertex3f(0.0f, 11.0f, 0.0f);
- gGL.vertex3f(-1.0f, 11.0f, 1.0f);
- gGL.vertex3f(0.0f, 11.0f, 0.0f);
- gGL.vertex3f(0.0f, 11.0f, 0.0f);
- gGL.vertex3f(0.0f, 11.0f, -1.0f);
-
- gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(0.0f, 0.0f, 2.0f);
- gGL.vertex3f(0.0f, 0.0f, 3.0f);
- gGL.vertex3f(0.0f, 0.0f, 5.0f);
- gGL.vertex3f(0.0f, 0.0f, 6.0f);
- gGL.vertex3f(0.0f, 0.0f, 8.0f);
- // Make a Z
- gGL.vertex3f(-1.0f, 1.0f, 11.0f);
- gGL.vertex3f(1.0f, 1.0f, 11.0f);
- gGL.vertex3f(1.0f, 1.0f, 11.0f);
- gGL.vertex3f(-1.0f, -1.0f, 11.0f);
- gGL.vertex3f(-1.0f, -1.0f, 11.0f);
- gGL.vertex3f(1.0f, -1.0f, 11.0f);
- gGL.end();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.begin(LLRender::LINES);
+ gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red
+ gGL.vertex3f(0.0f, 0.0f, 0.0f);
+ gGL.vertex3f(2.0f, 0.0f, 0.0f);
+ gGL.vertex3f(3.0f, 0.0f, 0.0f);
+ gGL.vertex3f(5.0f, 0.0f, 0.0f);
+ gGL.vertex3f(6.0f, 0.0f, 0.0f);
+ gGL.vertex3f(8.0f, 0.0f, 0.0f);
+ // Make an X
+ gGL.vertex3f(11.0f, 1.0f, 1.0f);
+ gGL.vertex3f(11.0f, -1.0f, -1.0f);
+ gGL.vertex3f(11.0f, 1.0f, -1.0f);
+ gGL.vertex3f(11.0f, -1.0f, 1.0f);
+
+ gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green
+ gGL.vertex3f(0.0f, 0.0f, 0.0f);
+ gGL.vertex3f(0.0f, 2.0f, 0.0f);
+ gGL.vertex3f(0.0f, 3.0f, 0.0f);
+ gGL.vertex3f(0.0f, 5.0f, 0.0f);
+ gGL.vertex3f(0.0f, 6.0f, 0.0f);
+ gGL.vertex3f(0.0f, 8.0f, 0.0f);
+ // Make a Y
+ gGL.vertex3f(1.0f, 11.0f, 1.0f);
+ gGL.vertex3f(0.0f, 11.0f, 0.0f);
+ gGL.vertex3f(-1.0f, 11.0f, 1.0f);
+ gGL.vertex3f(0.0f, 11.0f, 0.0f);
+ gGL.vertex3f(0.0f, 11.0f, 0.0f);
+ gGL.vertex3f(0.0f, 11.0f, -1.0f);
+
+ gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue
+ gGL.vertex3f(0.0f, 0.0f, 0.0f);
+ gGL.vertex3f(0.0f, 0.0f, 2.0f);
+ gGL.vertex3f(0.0f, 0.0f, 3.0f);
+ gGL.vertex3f(0.0f, 0.0f, 5.0f);
+ gGL.vertex3f(0.0f, 0.0f, 6.0f);
+ gGL.vertex3f(0.0f, 0.0f, 8.0f);
+ // Make a Z
+ gGL.vertex3f(-1.0f, 1.0f, 11.0f);
+ gGL.vertex3f(1.0f, 1.0f, 11.0f);
+ gGL.vertex3f(1.0f, 1.0f, 11.0f);
+ gGL.vertex3f(-1.0f, -1.0f, 11.0f);
+ gGL.vertex3f(-1.0f, -1.0f, 11.0f);
+ gGL.vertex3f(1.0f, -1.0f, 11.0f);
+ gGL.end();
}
-void draw_axes()
+void draw_axes()
{
- LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // A vertical white line at origin
- LLVector3 v = gAgent.getPositionAgent();
- gGL.begin(LLRender::LINES);
- gGL.color3f(1.0f, 1.0f, 1.0f);
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(0.0f, 0.0f, 40.0f);
- gGL.end();
- // Some coordinate axes
- gGL.pushMatrix();
- gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
- renderCoordinateAxes();
- gGL.popMatrix();
+ LLGLSUIDefault gls_ui;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ // A vertical white line at origin
+ LLVector3 v = gAgent.getPositionAgent();
+ gGL.begin(LLRender::LINES);
+ gGL.color3f(1.0f, 1.0f, 1.0f);
+ gGL.vertex3f(0.0f, 0.0f, 0.0f);
+ gGL.vertex3f(0.0f, 0.0f, 40.0f);
+ gGL.end();
+ // Some coordinate axes
+ gGL.pushMatrix();
+ gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
+ renderCoordinateAxes();
+ gGL.popMatrix();
}
void render_ui_3d()
{
- LLGLSPipeline gls_pipeline;
-
- //////////////////////////////////////
- //
- // Render 3D UI elements
- // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD,
- // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD
- //
-
- /////////////////////////////////////////////////////////////
- //
- // Render 2.5D elements (2D elements in the world)
- // Stuff without z writes
- //
-
- // Debugging stuff goes before the UI.
-
- stop_glerror();
-
- gUIProgram.bind();
+ LLGLSPipeline gls_pipeline;
+
+ //////////////////////////////////////
+ //
+ // Render 3D UI elements
+ // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD,
+ // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD
+ //
+
+ /////////////////////////////////////////////////////////////
+ //
+ // Render 2.5D elements (2D elements in the world)
+ // Stuff without z writes
+ //
+
+ // Debugging stuff goes before the UI.
+
+ stop_glerror();
+
+ gUIProgram.bind();
gGL.color4f(1, 1, 1, 1);
- // Coordinate axes
- if (gSavedSettings.getBOOL("ShowAxes"))
- {
- draw_axes();
- }
+ // Coordinate axes
+ if (gSavedSettings.getBOOL("ShowAxes"))
+ {
+ draw_axes();
+ }
- gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
+ gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
@@ -1531,205 +1539,205 @@ void render_ui_3d()
gSky.addSunMoonBeacons();
}
- stop_glerror();
+ stop_glerror();
}
void render_ui_2d()
{
- LLGLSUIDefault gls_ui;
+ LLGLSUIDefault gls_ui;
- /////////////////////////////////////////////////////////////
- //
- // Render 2D UI elements that overlay the world (no z compare)
+ /////////////////////////////////////////////////////////////
+ //
+ // Render 2D UI elements that overlay the world (no z compare)
- // Disable wireframe mode below here, as this is HUD/menus
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ // Disable wireframe mode below here, as this is HUD/menus
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- // Menu overlays, HUD, etc
- gViewerWindow->setup2DRender();
+ // Menu overlays, HUD, etc
+ gViewerWindow->setup2DRender();
- F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
- S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
+ F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
+ S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
- if (zoom_factor > 1.f)
- {
- //decompose subregion number to x and y values
- int pos_y = sub_region / llceil(zoom_factor);
- int pos_x = sub_region - (pos_y*llceil(zoom_factor));
- // offset for this tile
- LLFontGL::sCurOrigin.mX -= ll_round((F32)gViewerWindow->getWindowWidthScaled() * (F32)pos_x / zoom_factor);
- LLFontGL::sCurOrigin.mY -= ll_round((F32)gViewerWindow->getWindowHeightScaled() * (F32)pos_y / zoom_factor);
- }
+ if (zoom_factor > 1.f)
+ {
+ //decompose subregion number to x and y values
+ int pos_y = sub_region / llceil(zoom_factor);
+ int pos_x = sub_region - (pos_y*llceil(zoom_factor));
+ // offset for this tile
+ LLFontGL::sCurOrigin.mX -= ll_round((F32)gViewerWindow->getWindowWidthScaled() * (F32)pos_x / zoom_factor);
+ LLFontGL::sCurOrigin.mY -= ll_round((F32)gViewerWindow->getWindowHeightScaled() * (F32)pos_y / zoom_factor);
+ }
- stop_glerror();
+ stop_glerror();
- // render outline for HUD
- if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f)
- {
+ // render outline for HUD
+ if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f)
+ {
gUIProgram.bind();
- gGL.pushMatrix();
- S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
- S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
- gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
- gGL.translatef((F32)half_width, (F32)half_height, 0.f);
- F32 zoom = gAgentCamera.mHUDCurZoom;
- gGL.scalef(zoom,zoom,1.f);
- gGL.color4fv(LLColor4::white.mV);
- gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
- gGL.popMatrix();
+ gGL.pushMatrix();
+ S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
+ S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
+ gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
+ gGL.translatef((F32)half_width, (F32)half_height, 0.f);
+ F32 zoom = gAgentCamera.mHUDCurZoom;
+ gGL.scalef(zoom,zoom,1.f);
+ gGL.color4fv(LLColor4::white.mV);
+ gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
+ gGL.popMatrix();
gUIProgram.unbind();
- stop_glerror();
- }
-
-
- if (gSavedSettings.getBOOL("RenderUIBuffer"))
- {
- if (LLView::sIsRectDirty)
- {
+ stop_glerror();
+ }
+
+
+ if (gSavedSettings.getBOOL("RenderUIBuffer"))
+ {
+ if (LLView::sIsRectDirty)
+ {
LLView::sIsRectDirty = false;
- LLRect t_rect;
+ LLRect t_rect;
- gPipeline.mRT->uiScreen.bindTarget();
- gGL.setColorMask(true, true);
- {
- static const S32 pad = 8;
+ gPipeline.mRT->uiScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ {
+ static const S32 pad = 8;
LLView::sDirtyRect.mLeft -= pad;
LLView::sDirtyRect.mRight += pad;
LLView::sDirtyRect.mBottom -= pad;
LLView::sDirtyRect.mTop += pad;
- LLGLEnable scissor(GL_SCISSOR_TEST);
- static LLRect last_rect = LLView::sDirtyRect;
-
- //union with last rect to avoid mouse poop
- last_rect.unionWith(LLView::sDirtyRect);
+ LLGLEnable scissor(GL_SCISSOR_TEST);
+ static LLRect last_rect = LLView::sDirtyRect;
- t_rect = LLView::sDirtyRect;
+ //union with last rect to avoid mouse poop
+ last_rect.unionWith(LLView::sDirtyRect);
+
+ t_rect = LLView::sDirtyRect;
LLView::sDirtyRect = last_rect;
- last_rect = t_rect;
-
- last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
- last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
- last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
- last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
+ last_rect = t_rect;
- LLRect clip_rect(last_rect);
+ last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+ last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+ last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+ last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
- glClear(GL_COLOR_BUFFER_BIT);
+ LLRect clip_rect(last_rect);
+
+ glClear(GL_COLOR_BUFFER_BIT);
- gViewerWindow->draw();
- }
+ gViewerWindow->draw();
+ }
- gPipeline.mRT->uiScreen.flush();
- gGL.setColorMask(true, false);
+ gPipeline.mRT->uiScreen.flush();
+ gGL.setColorMask(true, false);
LLView::sDirtyRect = t_rect;
- }
-
- LLGLDisable cull(GL_CULL_FACE);
- LLGLDisable blend(GL_BLEND);
- S32 width = gViewerWindow->getWindowWidthScaled();
- S32 height = gViewerWindow->getWindowHeightScaled();
- gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.color4f(1,1,1,1);
- gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
- gGL.texCoord2f(width, 0); gGL.vertex2i(width, 0);
- gGL.texCoord2f(0, height); gGL.vertex2i(0, height);
- gGL.texCoord2f(width, height); gGL.vertex2i(width, height);
- gGL.end();
- }
- else
- {
- gViewerWindow->draw();
- }
-
-
-
- // reset current origin for font rendering, in case of tiling render
- LLFontGL::sCurOrigin.set(0, 0);
+ }
+
+ LLGLDisable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+ S32 width = gViewerWindow->getWindowWidthScaled();
+ S32 height = gViewerWindow->getWindowHeightScaled();
+ gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.color4f(1,1,1,1);
+ gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
+ gGL.texCoord2f(width, 0); gGL.vertex2i(width, 0);
+ gGL.texCoord2f(0, height); gGL.vertex2i(0, height);
+ gGL.texCoord2f(width, height); gGL.vertex2i(width, height);
+ gGL.end();
+ }
+ else
+ {
+ gViewerWindow->draw();
+ }
+
+
+
+ // reset current origin for font rendering, in case of tiling render
+ LLFontGL::sCurOrigin.set(0, 0);
}
void render_disconnected_background()
{
- gUIProgram.bind();
-
- gGL.color4f(1,1,1,1);
- if (!gDisconnectedImagep && gDisconnected)
- {
- LL_INFOS() << "Loading last bitmap..." << LL_ENDL;
-
- std::string temp_str;
- temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getScreenLastFilename();
-
- LLPointer<LLImagePNG> image_png = new LLImagePNG;
- if( !image_png->load(temp_str) )
- {
- //LL_INFOS() << "Bitmap load failed" << LL_ENDL;
- return;
- }
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
- if (!image_png->decode(raw, 0.0f))
- {
- LL_INFOS() << "Bitmap decode failed" << LL_ENDL;
- gDisconnectedImagep = NULL;
- return;
- }
-
- U8 *rawp = raw->getData();
- S32 npixels = (S32)image_png->getWidth()*(S32)image_png->getHeight();
- for (S32 i = 0; i < npixels; i++)
- {
- S32 sum = 0;
- sum = *rawp + *(rawp+1) + *(rawp+2);
- sum /= 3;
- *rawp = ((S32)sum*6 + *rawp)/7;
- rawp++;
- *rawp = ((S32)sum*6 + *rawp)/7;
- rawp++;
- *rawp = ((S32)sum*6 + *rawp)/7;
- rawp++;
- }
-
-
- raw->expandToPowerOfTwo();
- gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE );
- gStartTexture = gDisconnectedImagep;
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
-
- // Make sure the progress view always fills the entire window.
- S32 width = gViewerWindow->getWindowWidthScaled();
- S32 height = gViewerWindow->getWindowHeightScaled();
-
- if (gDisconnectedImagep)
- {
- LLGLSUIDefault gls_ui;
- gViewerWindow->setup2DRender();
- gGL.pushMatrix();
- {
- // scale ui to reflect UIScaleFactor
- // this can't be done in setup2DRender because it requires a
- // pushMatrix/popMatrix pair
- const LLVector2& display_scale = gViewerWindow->getDisplayScale();
- gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
-
- gGL.getTexUnit(0)->bind(gDisconnectedImagep);
- gGL.color4f(1.f, 1.f, 1.f, 1.f);
- gl_rect_2d_simple_tex(width, height);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- gGL.popMatrix();
- }
- gGL.flush();
-
- gUIProgram.unbind();
+ gUIProgram.bind();
+
+ gGL.color4f(1,1,1,1);
+ if (!gDisconnectedImagep && gDisconnected)
+ {
+ LL_INFOS() << "Loading last bitmap..." << LL_ENDL;
+
+ std::string temp_str;
+ temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getScreenLastFilename();
+
+ LLPointer<LLImagePNG> image_png = new LLImagePNG;
+ if( !image_png->load(temp_str) )
+ {
+ //LL_INFOS() << "Bitmap load failed" << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+ if (!image_png->decode(raw, 0.0f))
+ {
+ LL_INFOS() << "Bitmap decode failed" << LL_ENDL;
+ gDisconnectedImagep = NULL;
+ return;
+ }
+
+ U8 *rawp = raw->getData();
+ S32 npixels = (S32)image_png->getWidth()*(S32)image_png->getHeight();
+ for (S32 i = 0; i < npixels; i++)
+ {
+ S32 sum = 0;
+ sum = *rawp + *(rawp+1) + *(rawp+2);
+ sum /= 3;
+ *rawp = ((S32)sum*6 + *rawp)/7;
+ rawp++;
+ *rawp = ((S32)sum*6 + *rawp)/7;
+ rawp++;
+ *rawp = ((S32)sum*6 + *rawp)/7;
+ rawp++;
+ }
+
+
+ raw->expandToPowerOfTwo();
+ gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE );
+ gStartTexture = gDisconnectedImagep;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+
+ // Make sure the progress view always fills the entire window.
+ S32 width = gViewerWindow->getWindowWidthScaled();
+ S32 height = gViewerWindow->getWindowHeightScaled();
+
+ if (gDisconnectedImagep)
+ {
+ LLGLSUIDefault gls_ui;
+ gViewerWindow->setup2DRender();
+ gGL.pushMatrix();
+ {
+ // scale ui to reflect UIScaleFactor
+ // this can't be done in setup2DRender because it requires a
+ // pushMatrix/popMatrix pair
+ const LLVector2& display_scale = gViewerWindow->getDisplayScale();
+ gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
+
+ gGL.getTexUnit(0)->bind(gDisconnectedImagep);
+ gGL.color4f(1.f, 1.f, 1.f, 1.f);
+ gl_rect_2d_simple_tex(width, height);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ gGL.popMatrix();
+ }
+ gGL.flush();
+
+ gUIProgram.unbind();
}
void display_cleanup()
{
- gDisconnectedImagep = NULL;
+ gDisconnectedImagep = NULL;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 37f23f9cca..c1a8c5df9e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewermenu.cpp
* @brief Builds menus out of items.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2014, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -30,7 +30,7 @@
#include "vld.h"
#endif
-#include "llviewermenu.h"
+#include "llviewermenu.h"
// linden library includes
#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
@@ -115,7 +115,7 @@
#include "llviewerdisplay.h" //for gWindowResized
#include "llviewergenericmessage.h"
#include "llviewerhelp.h"
-#include "llviewermenufile.h" // init_menu_file()
+#include "llviewermenufile.h" // init_menu_file()
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
@@ -141,6 +141,7 @@
#include <boost/algorithm/string.hpp>
#include "llcleanup.h"
#include "llviewershadermgr.h"
+#include "gltfscenemanager.h"
using namespace LLAvatarAppearanceDefines;
@@ -159,7 +160,7 @@ void handle_test_load_url(void*);
//
// Evil hackish imported globals
-//extern BOOL gHideSelectedObjects;
+//extern BOOL gHideSelectedObjects;
//extern BOOL gAllowSelectAvatar;
//extern BOOL gDebugAvatarRotation;
extern BOOL gDebugClicks;
@@ -173,20 +174,20 @@ extern BOOL gShaderProfileFrame;
// Globals
//
-LLMenuBarGL *gMenuBarView = NULL;
-LLViewerMenuHolderGL *gMenuHolder = NULL;
-LLMenuGL *gPopupMenuView = NULL;
-LLMenuGL *gEditMenu = NULL;
-LLMenuBarGL *gLoginMenuBarView = NULL;
+LLMenuBarGL *gMenuBarView = NULL;
+LLViewerMenuHolderGL *gMenuHolder = NULL;
+LLMenuGL *gPopupMenuView = NULL;
+LLMenuGL *gEditMenu = NULL;
+LLMenuBarGL *gLoginMenuBarView = NULL;
// Pie menus
-LLContextMenu *gMenuAvatarSelf = NULL;
-LLContextMenu *gMenuAvatarOther = NULL;
-LLContextMenu *gMenuObject = NULL;
-LLContextMenu *gMenuAttachmentSelf = NULL;
-LLContextMenu *gMenuAttachmentOther = NULL;
-LLContextMenu *gMenuLand = NULL;
-LLContextMenu *gMenuMuteParticle = NULL;
+LLContextMenu *gMenuAvatarSelf = NULL;
+LLContextMenu *gMenuAvatarOther = NULL;
+LLContextMenu *gMenuObject = NULL;
+LLContextMenu *gMenuAttachmentSelf = NULL;
+LLContextMenu *gMenuAttachmentOther = NULL;
+LLContextMenu *gMenuLand = NULL;
+LLContextMenu *gMenuMuteParticle = NULL;
const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
@@ -284,7 +285,7 @@ void handle_force_parcel_owner_to_me(void*);
void handle_force_parcel_to_content(void*);
void handle_claim_public_land(void*);
-void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry
+void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry
void reload_vertex_shader(void *);
void handle_disconnect_viewer(void *);
@@ -344,9 +345,9 @@ void menu_toggle_attached_particles(void* user_data);
class LLMenuParcelObserver : public LLParcelObserver
{
public:
- LLMenuParcelObserver();
- ~LLMenuParcelObserver();
- virtual void changed();
+ LLMenuParcelObserver();
+ ~LLMenuParcelObserver();
+ virtual void changed();
};
static LLMenuParcelObserver* gMenuParcelObserver = NULL;
@@ -355,17 +356,17 @@ static LLUIListener sUIListener;
LLMenuParcelObserver::LLMenuParcelObserver()
{
- LLViewerParcelMgr::getInstance()->addObserver(this);
+ LLViewerParcelMgr::getInstance()->addObserver(this);
}
LLMenuParcelObserver::~LLMenuParcelObserver()
{
- LLViewerParcelMgr::getInstance()->removeObserver(this);
+ LLViewerParcelMgr::getInstance()->removeObserver(this);
}
void LLMenuParcelObserver::changed()
{
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
if (gMenuLand && parcel)
{
LLView* child = gMenuLand->findChild<LLView>("Land Buy Pass");
@@ -438,131 +439,129 @@ void check_merchant_status(bool force)
void init_menus()
{
- // Initialize actions
- initialize_menus();
-
- ///
- /// Popup menu
- ///
- /// The popup menu is now populated by the show_context_menu()
- /// method.
-
- LLMenuGL::Params menu_params;
- menu_params.name = "Popup";
- menu_params.visible = false;
- gPopupMenuView = LLUICtrlFactory::create<LLMenuGL>(menu_params);
- gMenuHolder->addChild( gPopupMenuView );
-
- ///
- /// Context menus
- ///
-
- const widget_registry_t& registry =
- LLViewerMenuHolderGL::child_registry_t::instance();
- gEditMenu = LLUICtrlFactory::createFromFile<LLMenuGL>("menu_edit.xml", gMenuHolder, registry);
- gMenuAvatarSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_avatar_self.xml", gMenuHolder, registry);
- gMenuAvatarOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_avatar_other.xml", gMenuHolder, registry);
-
- gDetachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach HUD", true);
- gDetachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach", true);
-
- gMenuObject = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_object.xml", gMenuHolder, registry);
-
- gAttachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach HUD");
- gAttachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach");
-
- gMenuAttachmentSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_attachment_self.xml", gMenuHolder, registry);
- gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_attachment_other.xml", gMenuHolder, registry);
-
- gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true);
- gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true);
-
- gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_land.xml", gMenuHolder, registry);
-
- gMenuMuteParticle = LLUICtrlFactory::createFromFile<LLContextMenu>(
- "menu_mute_particle.xml", gMenuHolder, registry);
-
- ///
- /// set up the colors
- ///
- LLColor4 color;
-
- LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor");
-
- gMenuAvatarSelf->setBackgroundColor( context_menu_color );
- gMenuAvatarOther->setBackgroundColor( context_menu_color );
- gMenuObject->setBackgroundColor( context_menu_color );
- gMenuAttachmentSelf->setBackgroundColor( context_menu_color );
- gMenuAttachmentOther->setBackgroundColor( context_menu_color );
-
- gMenuLand->setBackgroundColor( context_menu_color );
-
- color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" );
- gPopupMenuView->setBackgroundColor( color );
-
- // If we are not in production, use a different color to make it apparent.
- if (LLGridManager::getInstance()->isInProductionGrid())
- {
- color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
- }
- else
- {
- color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
- }
-
- LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder");
-
- gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT));
- gMenuBarView->setBackgroundColor( color );
-
- menu_bar_holder->addChild(gMenuBarView);
-
- gViewerWindow->setMenuBackgroundColor(false,
+ // Initialize actions
+ initialize_menus();
+
+ ///
+ /// Popup menu
+ ///
+ /// The popup menu is now populated by the show_context_menu()
+ /// method.
+
+ LLMenuGL::Params menu_params;
+ menu_params.name = "Popup";
+ menu_params.visible = false;
+ gPopupMenuView = LLUICtrlFactory::create<LLMenuGL>(menu_params);
+ gMenuHolder->addChild( gPopupMenuView );
+
+ ///
+ /// Context menus
+ ///
+
+ const widget_registry_t& registry =
+ LLViewerMenuHolderGL::child_registry_t::instance();
+ gEditMenu = LLUICtrlFactory::createFromFile<LLMenuGL>("menu_edit.xml", gMenuHolder, registry);
+ gMenuAvatarSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_avatar_self.xml", gMenuHolder, registry);
+ gMenuAvatarOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_avatar_other.xml", gMenuHolder, registry);
+
+ gDetachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach HUD", true);
+ gDetachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach", true);
+
+ gMenuObject = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_object.xml", gMenuHolder, registry);
+
+ gAttachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach HUD");
+ gAttachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach");
+
+ gMenuAttachmentSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_attachment_self.xml", gMenuHolder, registry);
+ gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_attachment_other.xml", gMenuHolder, registry);
+
+ gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true);
+ gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true);
+
+ gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_land.xml", gMenuHolder, registry);
+
+ gMenuMuteParticle = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_mute_particle.xml", gMenuHolder, registry);
+
+ ///
+ /// set up the colors
+ ///
+ LLColor4 color;
+
+ LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor");
+
+ gMenuAvatarSelf->setBackgroundColor( context_menu_color );
+ gMenuAvatarOther->setBackgroundColor( context_menu_color );
+ gMenuObject->setBackgroundColor( context_menu_color );
+ gMenuAttachmentSelf->setBackgroundColor( context_menu_color );
+ gMenuAttachmentOther->setBackgroundColor( context_menu_color );
+
+ gMenuLand->setBackgroundColor( context_menu_color );
+
+ color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" );
+ gPopupMenuView->setBackgroundColor( color );
+
+ // If we are not in production, use a different color to make it apparent.
+ if (LLGridManager::getInstance()->isInProductionGrid())
+ {
+ color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
+ }
+ else
+ {
+ color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
+ }
+
+ LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder");
+
+ gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT));
+ gMenuBarView->setBackgroundColor( color );
+
+ menu_bar_holder->addChild(gMenuBarView);
+
+ gViewerWindow->setMenuBackgroundColor(false,
LLGridManager::getInstance()->isInProductionGrid());
- // *TODO:Also fix cost in llfolderview.cpp for Inventory menus
- const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
- const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
- const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- gMenuHolder->childSetLabelArg("Upload Image", "[COST]", texture_upload_cost_str);
- gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
- gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
-
- gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
- gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
-
- gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
- gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
-
- // Don't display the Memory console menu if the feature is turned off
- LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE);
- if (memoryMenu)
- {
- memoryMenu->setVisible(FALSE);
- }
-
- gMenuBarView->createJumpKeys();
-
- // Let land based option enable when parcel changes
- gMenuParcelObserver = new LLMenuParcelObserver();
-
- gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gLoginMenuBarView->arrangeAndClear();
- LLRect menuBarRect = gLoginMenuBarView->getRect();
- menuBarRect.setLeftTopAndSize(0, menu_bar_holder->getRect().getHeight(), menuBarRect.getWidth(), menuBarRect.getHeight());
- gLoginMenuBarView->setRect(menuBarRect);
- gLoginMenuBarView->setBackgroundColor( color );
- menu_bar_holder->addChild(gLoginMenuBarView);
-
- // tooltips are on top of EVERYTHING, including menus
- gViewerWindow->getRootView()->sendChildToFront(gToolTipView);
+ // *TODO:Also fix cost in llfolderview.cpp for Inventory menus
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
+ gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
+ gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
+
+ gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
+ gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
+
+ gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
+ gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
+
+ // Don't display the Memory console menu if the feature is turned off
+ LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE);
+ if (memoryMenu)
+ {
+ memoryMenu->setVisible(FALSE);
+ }
+
+ gMenuBarView->createJumpKeys();
+
+ // Let land based option enable when parcel changes
+ gMenuParcelObserver = new LLMenuParcelObserver();
+
+ gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gLoginMenuBarView->arrangeAndClear();
+ LLRect menuBarRect = gLoginMenuBarView->getRect();
+ menuBarRect.setLeftTopAndSize(0, menu_bar_holder->getRect().getHeight(), menuBarRect.getWidth(), menuBarRect.getHeight());
+ gLoginMenuBarView->setRect(menuBarRect);
+ gLoginMenuBarView->setBackgroundColor( color );
+ menu_bar_holder->addChild(gLoginMenuBarView);
+
+ // tooltips are on top of EVERYTHING, including menus
+ gViewerWindow->getRootView()->sendChildToFront(gToolTipView);
}
///////////////////
@@ -572,62 +571,62 @@ void init_menus()
class LLAdvancedToggleConsole : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string console_type = userdata.asString();
- if ("texture" == console_type)
- {
- toggle_visibility( (void*)gTextureView );
- }
- else if ("debug" == console_type)
- {
- toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep));
- }
- else if ("fast timers" == console_type)
- {
- LLFloaterReg::toggleInstance("block_timers");
- }
- else if ("scene view" == console_type)
- {
- toggle_visibility( (void*)gSceneView);
- }
- else if ("scene monitor" == console_type)
- {
- toggle_visibility( (void*)gSceneMonitorView);
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string console_type = userdata.asString();
+ if ("texture" == console_type)
+ {
+ toggle_visibility( (void*)gTextureView );
+ }
+ else if ("debug" == console_type)
+ {
+ toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep));
+ }
+ else if ("fast timers" == console_type)
+ {
+ LLFloaterReg::toggleInstance("block_timers");
+ }
+ else if ("scene view" == console_type)
+ {
+ toggle_visibility( (void*)gSceneView);
+ }
+ else if ("scene monitor" == console_type)
+ {
+ toggle_visibility( (void*)gSceneMonitorView);
+ }
+
+ return true;
+ }
};
class LLAdvancedCheckConsole : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string console_type = userdata.asString();
- bool new_value = false;
- if ("texture" == console_type)
- {
- new_value = get_visibility( (void*)gTextureView );
- }
- else if ("debug" == console_type)
- {
- new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
- }
- else if ("fast timers" == console_type)
- {
- new_value = LLFloaterReg::instanceVisible("block_timers");
- }
- else if ("scene view" == console_type)
- {
- new_value = get_visibility( (void*) gSceneView);
- }
- else if ("scene monitor" == console_type)
- {
- new_value = get_visibility( (void*) gSceneMonitorView);
- }
-
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string console_type = userdata.asString();
+ bool new_value = false;
+ if ("texture" == console_type)
+ {
+ new_value = get_visibility( (void*)gTextureView );
+ }
+ else if ("debug" == console_type)
+ {
+ new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
+ }
+ else if ("fast timers" == console_type)
+ {
+ new_value = LLFloaterReg::instanceVisible("block_timers");
+ }
+ else if ("scene view" == console_type)
+ {
+ new_value = get_visibility( (void*) gSceneView);
+ }
+ else if ("scene monitor" == console_type)
+ {
+ new_value = get_visibility( (void*) gSceneMonitorView);
+ }
+
+ return new_value;
+ }
};
@@ -638,24 +637,24 @@ class LLAdvancedCheckConsole : public view_listener_t
class LLAdvancedDumpInfoToConsole : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gDebugView->mDebugConsolep->setVisible(TRUE);
- std::string info_type = userdata.asString();
- if ("region" == info_type)
- {
- handle_region_dump_settings(NULL);
- }
- else if ("group" == info_type)
- {
- handle_dump_group_info(NULL);
- }
- else if ("capabilities" == info_type)
- {
- handle_dump_capabilities_info(NULL);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gDebugView->mDebugConsolep->setVisible(TRUE);
+ std::string info_type = userdata.asString();
+ if ("region" == info_type)
+ {
+ handle_region_dump_settings(NULL);
+ }
+ else if ("group" == info_type)
+ {
+ handle_dump_group_info(NULL);
+ }
+ else if ("capabilities" == info_type)
+ {
+ handle_dump_capabilities_info(NULL);
+ }
+ return true;
+ }
};
@@ -666,54 +665,54 @@ class LLAdvancedDumpInfoToConsole : public view_listener_t
class LLAdvancedToggleHUDInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string info_type = userdata.asString();
-
- if ("camera" == info_type)
- {
- gDisplayCameraPos = !(gDisplayCameraPos);
- }
- else if ("wind" == info_type)
- {
- gDisplayWindInfo = !(gDisplayWindInfo);
- }
- else if ("fov" == info_type)
- {
- gDisplayFOV = !(gDisplayFOV);
- }
- else if ("badge" == info_type)
- {
- gDisplayBadge = !(gDisplayBadge);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string info_type = userdata.asString();
+
+ if ("camera" == info_type)
+ {
+ gDisplayCameraPos = !(gDisplayCameraPos);
+ }
+ else if ("wind" == info_type)
+ {
+ gDisplayWindInfo = !(gDisplayWindInfo);
+ }
+ else if ("fov" == info_type)
+ {
+ gDisplayFOV = !(gDisplayFOV);
+ }
+ else if ("badge" == info_type)
+ {
+ gDisplayBadge = !(gDisplayBadge);
+ }
+ return true;
+ }
};
class LLAdvancedCheckHUDInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string info_type = userdata.asString();
- bool new_value = false;
- if ("camera" == info_type)
- {
- new_value = gDisplayCameraPos;
- }
- else if ("wind" == info_type)
- {
- new_value = gDisplayWindInfo;
- }
- else if ("fov" == info_type)
- {
- new_value = gDisplayFOV;
- }
- else if ("badge" == info_type)
- {
- new_value = gDisplayBadge;
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string info_type = userdata.asString();
+ bool new_value = false;
+ if ("camera" == info_type)
+ {
+ new_value = gDisplayCameraPos;
+ }
+ else if ("wind" == info_type)
+ {
+ new_value = gDisplayWindInfo;
+ }
+ else if ("fov" == info_type)
+ {
+ new_value = gDisplayFOV;
+ }
+ else if ("badge" == info_type)
+ {
+ new_value = gDisplayBadge;
+ }
+ return new_value;
+ }
};
@@ -723,11 +722,11 @@ class LLAdvancedCheckHUDInfo : public view_listener_t
class LLAdvancedClearGroupCache : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLGroupMgr::debugClearAllGroups(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLGroupMgr::debugClearAllGroups(NULL);
+ return true;
+ }
};
@@ -738,97 +737,117 @@ class LLAdvancedClearGroupCache : public view_listener_t
/////////////////
U32 render_type_from_string(std::string render_type)
{
- if ("simple" == render_type)
- {
- return LLPipeline::RENDER_TYPE_SIMPLE;
- }
- else if ("alpha" == render_type)
- {
- return LLPipeline::RENDER_TYPE_ALPHA;
- }
- else if ("tree" == render_type)
- {
- return LLPipeline::RENDER_TYPE_TREE;
- }
- else if ("character" == render_type)
- {
- return LLPipeline::RENDER_TYPE_AVATAR;
- }
- else if ("controlAV" == render_type) // Animesh
- {
- return LLPipeline::RENDER_TYPE_CONTROL_AV;
- }
- else if ("surfacePatch" == render_type)
- {
- return LLPipeline::RENDER_TYPE_TERRAIN;
- }
- else if ("sky" == render_type)
- {
- return LLPipeline::RENDER_TYPE_SKY;
- }
- else if ("water" == render_type)
- {
- return LLPipeline::RENDER_TYPE_WATER;
- }
- else if ("volume" == render_type)
- {
- return LLPipeline::RENDER_TYPE_VOLUME;
- }
- else if ("grass" == render_type)
- {
- return LLPipeline::RENDER_TYPE_GRASS;
- }
- else if ("clouds" == render_type)
- {
- return LLPipeline::RENDER_TYPE_CLOUDS;
- }
- else if ("particles" == render_type)
- {
- return LLPipeline::RENDER_TYPE_PARTICLES;
- }
- else if ("bump" == render_type)
- {
- return LLPipeline::RENDER_TYPE_BUMP;
- }
- else if ("pbr" == render_type)
+ if ("simple" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_SIMPLE;
+ }
+ if ("materials" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_MATERIALS;
+ }
+ else if ("alpha" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_ALPHA;
+ }
+ else if ("alpha_mask" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_ALPHA_MASK;
+ }
+ else if ("fullbright_alpha_mask" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK;
+ }
+ else if ("fullbright" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_FULLBRIGHT;
+ }
+ else if ("glow" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_GLOW;
+ }
+ else if ("tree" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_TREE;
+ }
+ else if ("character" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_AVATAR;
+ }
+ else if ("controlAV" == render_type) // Animesh
+ {
+ return LLPipeline::RENDER_TYPE_CONTROL_AV;
+ }
+ else if ("surfacePatch" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_TERRAIN;
+ }
+ else if ("sky" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_SKY;
+ }
+ else if ("water" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_WATER;
+ }
+ else if ("volume" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_VOLUME;
+ }
+ else if ("grass" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_GRASS;
+ }
+ else if ("clouds" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_CLOUDS;
+ }
+ else if ("particles" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_PARTICLES;
+ }
+ else if ("bump" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_BUMP;
+ }
+ else if ("pbr" == render_type)
{
return LLPipeline::RENDER_TYPE_GLTF_PBR;
}
- else
- {
- return 0;
- }
+ else
+ {
+ return 0;
+ }
}
class LLAdvancedToggleRenderType : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U32 render_type = render_type_from_string( userdata.asString() );
- if ( render_type != 0 )
- {
- LLPipeline::toggleRenderTypeControl( render_type );
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 render_type = render_type_from_string( userdata.asString() );
+ if ( render_type != 0 )
+ {
+ LLPipeline::toggleRenderTypeControl( render_type );
+ }
+ return true;
+ }
};
class LLAdvancedCheckRenderType : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U32 render_type = render_type_from_string( userdata.asString() );
- bool new_value = false;
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 render_type = render_type_from_string( userdata.asString() );
+ bool new_value = false;
- if ( render_type != 0 )
- {
- new_value = LLPipeline::hasRenderTypeControl( render_type );
- }
+ if ( render_type != 0 )
+ {
+ new_value = LLPipeline::hasRenderTypeControl( render_type );
+ }
- return new_value;
- }
+ return new_value;
+ }
};
@@ -836,140 +855,140 @@ class LLAdvancedCheckRenderType : public view_listener_t
// FEATURE //
/////////////
U32 feature_from_string(std::string feature)
-{
- if ("ui" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_UI;
- }
- else if ("selected" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED;
- }
- else if ("highlighted" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED;
- }
- else if ("dynamic textures" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES;
- }
- else if ("foot shadows" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS;
- }
- else if ("fog" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_FOG;
- }
- else if ("fr info" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO;
- }
- else if ("flexible" == feature)
- {
- return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE;
- }
- else
- {
- return 0;
- }
+{
+ if ("ui" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_UI;
+ }
+ else if ("selected" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED;
+ }
+ else if ("highlighted" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED;
+ }
+ else if ("dynamic textures" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES;
+ }
+ else if ("foot shadows" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS;
+ }
+ else if ("fog" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FOG;
+ }
+ else if ("fr info" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO;
+ }
+ else if ("flexible" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE;
+ }
+ else
+ {
+ return 0;
+ }
};
class LLAdvancedToggleFeature : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U32 feature = feature_from_string( userdata.asString() );
- if ( feature != 0 )
- {
- LLPipeline::toggleRenderDebugFeature( feature );
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 feature = feature_from_string( userdata.asString() );
+ if ( feature != 0 )
+ {
+ LLPipeline::toggleRenderDebugFeature( feature );
+ }
+ return true;
+ }
};
class LLAdvancedCheckFeature : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- U32 feature = feature_from_string( userdata.asString() );
- bool new_value = false;
+ U32 feature = feature_from_string( userdata.asString() );
+ bool new_value = false;
- if ( feature != 0 )
- {
- new_value = LLPipeline::toggleRenderDebugFeatureControl( feature );
- }
+ if ( feature != 0 )
+ {
+ new_value = LLPipeline::toggleRenderDebugFeatureControl( feature );
+ }
- return new_value;
+ return new_value;
}
};
class LLAdvancedCheckDisplayTextureDensity : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string mode = userdata.asString();
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
- {
- return mode == "none";
- }
- if (mode == "current")
- {
- return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT;
- }
- else if (mode == "desired")
- {
- return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED;
- }
- else if (mode == "full")
- {
- return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL;
- }
- return false;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string mode = userdata.asString();
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ {
+ return mode == "none";
+ }
+ if (mode == "current")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT;
+ }
+ else if (mode == "desired")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED;
+ }
+ else if (mode == "full")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL;
+ }
+ return false;
+ }
};
class LLAdvancedSetDisplayTextureDensity : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string mode = userdata.asString();
- if (mode == "none")
- {
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE)
- {
- gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
- }
- LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
- }
- else if (mode == "current")
- {
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
- {
- gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
- }
- LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT;
- }
- else if (mode == "desired")
- {
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
- {
- gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
- }
- gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true);
- LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED;
- }
- else if (mode == "full")
- {
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
- {
- gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
- }
- LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL;
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string mode = userdata.asString();
+ if (mode == "none")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE)
+ {
+ gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
+ }
+ else if (mode == "current")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT;
+ }
+ else if (mode == "desired")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true);
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED;
+ }
+ else if (mode == "full")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL;
+ }
+ return true;
+ }
};
@@ -978,122 +997,126 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t
//////////////////
U64 info_display_from_string(std::string info_display)
{
- if ("verify" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_VERIFY;
- }
- else if ("bboxes" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_BBOXES;
- }
- else if ("normals" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_NORMALS;
- }
- else if ("points" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_POINTS;
- }
- else if ("octree" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_OCTREE;
- }
- else if ("shadow frusta" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA;
- }
- else if ("physics shapes" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES;
- }
- else if ("occlusion" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_OCCLUSION;
- }
- else if ("render batches" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_BATCH_SIZE;
- }
- else if ("update type" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_UPDATE_TYPE;
- }
- else if ("texture anim" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM;
- }
- else if ("texture priority" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY;
- }
- else if ("texture area" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_TEXTURE_AREA;
- }
- else if ("face area" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_FACE_AREA;
- }
- else if ("lod info" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_LOD_INFO;
- }
- else if ("lights" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_LIGHTS;
- }
- else if ("particles" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_PARTICLES;
- }
- else if ("composition" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_COMPOSITION;
- }
- else if ("avatardrawinfo" == info_display)
- {
- return (LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO);
- }
- else if ("glow" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_GLOW;
- }
- else if ("collision skeleton" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME;
- }
- else if ("joints" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_AVATAR_JOINTS;
- }
- else if ("raycast" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_RAYCAST;
- }
- else if ("agent target" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_AGENT_TARGET;
- }
- else if ("sculpt" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_SCULPTED;
- }
- else if ("wind vectors" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_WIND_VECTORS;
- }
- else if ("texel density" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
- }
- else if ("triangle count" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT;
- }
- else if ("impostors" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_IMPOSTORS;
- }
+ if ("verify" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_VERIFY;
+ }
+ else if ("bboxes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_BBOXES;
+ }
+ else if ("normals" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_NORMALS;
+ }
+ else if ("points" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_POINTS;
+ }
+ else if ("octree" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_OCTREE;
+ }
+ else if ("nodes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_NODES;
+ }
+ else if ("shadow frusta" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA;
+ }
+ else if ("physics shapes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES;
+ }
+ else if ("occlusion" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_OCCLUSION;
+ }
+ else if ("render batches" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_BATCH_SIZE;
+ }
+ else if ("update type" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_UPDATE_TYPE;
+ }
+ else if ("texture anim" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM;
+ }
+ else if ("texture priority" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY;
+ }
+ else if ("texture area" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_AREA;
+ }
+ else if ("face area" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_FACE_AREA;
+ }
+ else if ("lod info" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_LOD_INFO;
+ }
+ else if ("lights" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_LIGHTS;
+ }
+ else if ("particles" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_PARTICLES;
+ }
+ else if ("composition" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_COMPOSITION;
+ }
+ else if ("avatardrawinfo" == info_display)
+ {
+ return (LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO);
+ }
+ else if ("glow" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_GLOW;
+ }
+ else if ("collision skeleton" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME;
+ }
+ else if ("joints" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_AVATAR_JOINTS;
+ }
+ else if ("raycast" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_RAYCAST;
+ }
+ else if ("agent target" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_AGENT_TARGET;
+ }
+ else if ("sculpt" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_SCULPTED;
+ }
+ else if ("wind vectors" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_WIND_VECTORS;
+ }
+ else if ("texel density" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
+ }
+ else if ("triangle count" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT;
+ }
+ else if ("impostors" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_IMPOSTORS;
+ }
else if ("reflection probes" == info_display)
{
return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
@@ -1102,45 +1125,45 @@ U64 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_PROBE_UPDATES;
}
- else
- {
- LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
- return 0;
- }
+ else
+ {
+ LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
+ return 0;
+ }
};
class LLAdvancedToggleInfoDisplay : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U64 info_display = info_display_from_string( userdata.asString() );
-
- LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL;
+ bool handleEvent(const LLSD& userdata)
+ {
+ U64 info_display = info_display_from_string( userdata.asString() );
- if ( info_display != 0 )
- {
- LLPipeline::toggleRenderDebug( info_display );
- }
+ LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL;
+
+ if ( info_display != 0 )
+ {
+ LLPipeline::toggleRenderDebug( info_display );
+ }
- return true;
- }
+ return true;
+ }
};
class LLAdvancedCheckInfoDisplay : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U64 info_display = info_display_from_string( userdata.asString() );
- bool new_value = false;
+ bool handleEvent(const LLSD& userdata)
+ {
+ U64 info_display = info_display_from_string( userdata.asString() );
+ bool new_value = false;
- if ( info_display != 0 )
- {
- new_value = LLPipeline::toggleRenderDebugControl( info_display );
- }
+ if ( info_display != 0 )
+ {
+ new_value = LLPipeline::toggleRenderDebugControl( info_display );
+ }
- return new_value;
- }
+ return new_value;
+ }
};
@@ -1151,20 +1174,20 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t
class LLAdvancedToggleRandomizeFramerate : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gRandomizeFramerate = !(gRandomizeFramerate);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gRandomizeFramerate = !(gRandomizeFramerate);
+ return true;
+ }
};
class LLAdvancedCheckRandomizeFramerate : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gRandomizeFramerate;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gRandomizeFramerate;
+ return new_value;
+ }
};
///////////////////////////
@@ -1174,36 +1197,36 @@ class LLAdvancedCheckRandomizeFramerate : public view_listener_t
class LLAdvancedTogglePeriodicSlowFrame : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gPeriodicSlowFrame = !(gPeriodicSlowFrame);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gPeriodicSlowFrame = !(gPeriodicSlowFrame);
+ return true;
+ }
};
class LLAdvancedCheckPeriodicSlowFrame : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gPeriodicSlowFrame;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gPeriodicSlowFrame;
+ return new_value;
+ }
};
///////////////////////////
// SELECTED TEXTURE INFO //
-//
+//
///////////////////////////
class LLAdvancedSelectedTextureInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_selected_texture_info(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_selected_texture_info(NULL);
+ return true;
+ }
};
//////////////////////
@@ -1212,33 +1235,33 @@ class LLAdvancedSelectedTextureInfo : public view_listener_t
class LLAdvancedToggleWireframe : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gUseWireframe = !(gUseWireframe);
+ bool handleEvent(const LLSD& userdata)
+ {
+ gUseWireframe = !(gUseWireframe);
- return true;
- }
+ return true;
+ }
};
class LLAdvancedCheckWireframe : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gUseWireframe;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gUseWireframe;
+ }
};
-
+
//////////////////////////
// DUMP SCRIPTED CAMERA //
//////////////////////////
-
+
class LLAdvancedDumpScriptedCamera : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_dump_followcam(NULL);
- return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_followcam(NULL);
+ return true;
}
};
@@ -1251,11 +1274,11 @@ class LLAdvancedDumpScriptedCamera : public view_listener_t
class LLAdvancedDumpRegionObjectCache : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_dump_region_object_cache(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_region_object_cache(NULL);
+ return true;
+ }
};
class LLAdvancedToggleInterestList360Mode : public view_listener_t
@@ -1266,22 +1289,22 @@ public:
// Toggle the mode - regions will get updated
if (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360)
{
- gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_DEFAULT);
- }
- else
- {
- gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360);
- }
+ gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_DEFAULT);
+ }
+ else
+ {
+ gAgent.changeInterestListMode(LLViewerRegion::IL_MODE_360);
+ }
return true;
}
};
class LLAdvancedCheckInterestList360Mode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360);
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (gAgent.getInterestListMode() == LLViewerRegion::IL_MODE_360);
+ }
};
class LLAdvancedToggleStatsRecorder : public view_listener_t
@@ -1289,13 +1312,13 @@ class LLAdvancedToggleStatsRecorder : public view_listener_t
bool handleEvent(const LLSD &userdata)
{
if (LLViewerStatsRecorder::instance().isEnabled())
- { // Turn off both recording and logging
- LLViewerStatsRecorder::instance().enableObjectStatsRecording(false);
- }
- else
- { // Turn on both recording and logging
- LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true);
- }
+ { // Turn off both recording and logging
+ LLViewerStatsRecorder::instance().enableObjectStatsRecording(false);
+ }
+ else
+ { // Turn on both recording and logging
+ LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true);
+ }
return true;
}
};
@@ -1303,7 +1326,7 @@ class LLAdvancedToggleStatsRecorder : public view_listener_t
class LLAdvancedCheckStatsRecorder : public view_listener_t
{
bool handleEvent(const LLSD &userdata)
- { // Use the logging state as the indicator of whether the stats recorder is on
+ { // Use the logging state as the indicator of whether the stats recorder is on
return LLViewerStatsRecorder::instance().isLogging();
}
};
@@ -1311,7 +1334,7 @@ class LLAdvancedCheckStatsRecorder : public view_listener_t
class LLAdvancedResetInterestLists : public view_listener_t
{
bool handleEvent(const LLSD &userdata)
- { // Reset all region interest lists
+ { // Reset all region interest lists
handle_reset_interest_lists(NULL);
return true;
}
@@ -1319,12 +1342,12 @@ class LLAdvancedResetInterestLists : public view_listener_t
class LLAdvancedBuyCurrencyTest : public view_listener_t
- {
- bool handleEvent(const LLSD& userdata)
- {
- handle_buy_currency_test(NULL);
- return true;
- }
+ {
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_buy_currency_test(NULL);
+ return true;
+ }
};
@@ -1335,11 +1358,11 @@ class LLAdvancedBuyCurrencyTest : public view_listener_t
class LLAdvancedDumpSelectMgr : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- dump_select_mgr(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ dump_select_mgr(NULL);
+ return true;
+ }
};
@@ -1351,11 +1374,11 @@ class LLAdvancedDumpSelectMgr : public view_listener_t
class LLAdvancedDumpInventory : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- dump_inventory(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ dump_inventory(NULL);
+ return true;
+ }
};
@@ -1367,11 +1390,11 @@ class LLAdvancedDumpInventory : public view_listener_t
class LLAdvancedPrintSelectedObjectInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- print_object_info(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ print_object_info(NULL);
+ return true;
+ }
};
@@ -1383,11 +1406,11 @@ class LLAdvancedPrintSelectedObjectInfo : public view_listener_t
class LLAdvancedPrintAgentInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- print_agent_nvpairs(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ print_agent_nvpairs(NULL);
+ return true;
+ }
};
//////////////////
@@ -1397,20 +1420,20 @@ class LLAdvancedPrintAgentInfo : public view_listener_t
class LLAdvancedToggleDebugClicks : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gDebugClicks = !(gDebugClicks);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gDebugClicks = !(gDebugClicks);
+ return true;
+ }
};
class LLAdvancedCheckDebugClicks : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gDebugClicks;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gDebugClicks;
+ return new_value;
+ }
};
@@ -1422,20 +1445,20 @@ class LLAdvancedCheckDebugClicks : public view_listener_t
class LLAdvancedToggleDebugViews : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLView::sDebugRects = !(LLView::sDebugRects);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugRects = !(LLView::sDebugRects);
+ return true;
+ }
};
class LLAdvancedCheckDebugViews : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLView::sDebugRects;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugRects;
+ return new_value;
+ }
};
@@ -1447,19 +1470,19 @@ class LLAdvancedCheckDebugViews : public view_listener_t
class LLAdvancedToggleDebugUnicode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLView::sDebugUnicode = !(LLView::sDebugUnicode);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugUnicode = !(LLView::sDebugUnicode);
+ return true;
+ }
};
class LLAdvancedCheckDebugUnicode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return LLView::sDebugUnicode;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return LLView::sDebugUnicode;
+ }
};
@@ -1471,20 +1494,20 @@ class LLAdvancedCheckDebugUnicode : public view_listener_t
class LLAdvancedToggleDebugCamera : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLView::sDebugCamera = !(LLView::sDebugCamera);
- LLFloaterCamera::onDebugCameraToggled();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugCamera = !(LLView::sDebugCamera);
+ LLFloaterCamera::onDebugCameraToggled();
+ return true;
+ }
};
class LLAdvancedCheckDebugCamera : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return LLView::sDebugCamera;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return LLView::sDebugCamera;
+ }
};
@@ -1496,20 +1519,20 @@ class LLAdvancedCheckDebugCamera : public view_listener_t
class LLAdvancedToggleXUINameTooltips : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- toggle_show_xui_names(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ toggle_show_xui_names(NULL);
+ return true;
+ }
};
class LLAdvancedCheckXUINameTooltips : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = check_show_xui_names(NULL);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = check_show_xui_names(NULL);
+ return new_value;
+ }
};
@@ -1521,20 +1544,20 @@ class LLAdvancedCheckXUINameTooltips : public view_listener_t
class LLAdvancedToggleDebugMouseEvents : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling);
+ return true;
+ }
};
class LLAdvancedCheckDebugMouseEvents : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLView::sDebugMouseHandling;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugMouseHandling;
+ return new_value;
+ }
};
@@ -1546,22 +1569,22 @@ class LLAdvancedCheckDebugMouseEvents : public view_listener_t
class LLAdvancedToggleDebugKeys : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLView::sDebugKeys = !(LLView::sDebugKeys);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugKeys = !(LLView::sDebugKeys);
+ return true;
+ }
};
-
+
class LLAdvancedCheckDebugKeys : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLView::sDebugKeys;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugKeys;
+ return new_value;
+ }
};
-
+
///////////////////////
@@ -1571,30 +1594,30 @@ class LLAdvancedCheckDebugKeys : public view_listener_t
class LLAdvancedToggleDebugWindowProc : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gDebugWindowProc = !(gDebugWindowProc);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gDebugWindowProc = !(gDebugWindowProc);
+ return true;
+ }
};
class LLAdvancedCheckDebugWindowProc : public view_listener_t
- {
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gDebugWindowProc;
- return new_value;
- }
+ {
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gDebugWindowProc;
+ return new_value;
+ }
};
// ------------------------------XUI MENU ---------------------------
class LLAdvancedSendTestIms : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLIMModel::instance().testMessages();
- return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLIMModel::instance().testMessages();
+ return true;
}
};
@@ -1606,20 +1629,20 @@ class LLAdvancedSendTestIms : public view_listener_t
class LLAdvancedToggleXUINames : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- toggle_show_xui_names(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ toggle_show_xui_names(NULL);
+ return true;
+ }
};
class LLAdvancedCheckXUINames : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = check_show_xui_names(NULL);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = check_show_xui_names(NULL);
+ return new_value;
+ }
};
@@ -1630,71 +1653,71 @@ class LLAdvancedCheckXUINames : public view_listener_t
class LLAdvancedGrabBakedTexture : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string texture_type = userdata.asString();
- if ("iris" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_EYES );
- }
- else if ("head" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_HEAD );
- }
- else if ("upper" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_UPPER );
- }
- else if ("lower" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_LOWER );
- }
- else if ("skirt" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_SKIRT );
- }
- else if ("hair" == texture_type)
- {
- handle_grab_baked_texture( (void*)BAKED_HAIR );
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string texture_type = userdata.asString();
+ if ("iris" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_EYES );
+ }
+ else if ("head" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_HEAD );
+ }
+ else if ("upper" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_UPPER );
+ }
+ else if ("lower" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_LOWER );
+ }
+ else if ("skirt" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_SKIRT );
+ }
+ else if ("hair" == texture_type)
+ {
+ handle_grab_baked_texture( (void*)BAKED_HAIR );
+ }
+
+ return true;
+ }
};
class LLAdvancedEnableGrabBakedTexture : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
-{
- std::string texture_type = userdata.asString();
- bool new_value = false;
-
- if ("iris" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_EYES );
- }
- else if ("head" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_HEAD );
- }
- else if ("upper" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_UPPER );
- }
- else if ("lower" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_LOWER );
- }
- else if ("skirt" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_SKIRT );
- }
- else if ("hair" == texture_type)
- {
- new_value = enable_grab_baked_texture( (void*)BAKED_HAIR );
- }
-
- return new_value;
+ bool handleEvent(const LLSD& userdata)
+{
+ std::string texture_type = userdata.asString();
+ bool new_value = false;
+
+ if ("iris" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_EYES );
+ }
+ else if ("head" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_HEAD );
+ }
+ else if ("upper" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_UPPER );
+ }
+ else if ("lower" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_LOWER );
+ }
+ else if ("skirt" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_SKIRT );
+ }
+ else if ("hair" == texture_type)
+ {
+ new_value = enable_grab_baked_texture( (void*)BAKED_HAIR );
+ }
+
+ return new_value;
}
};
@@ -1705,8 +1728,8 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t
class LLAdvancedEnableAppearanceToXML : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (obj && obj->isAnimatedObject() && obj->getControlAvatar())
{
@@ -1721,18 +1744,18 @@ class LLAdvancedEnableAppearanceToXML : public view_listener_t
// This has to be a non-control avatar, because control avs are invisible and unclickable.
return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
}
- else
- {
- return false;
- }
- }
+ else
+ {
+ return false;
+ }
+ }
};
class LLAdvancedAppearanceToXML : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string emptyname;
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string emptyname;
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
LLVOAvatar *avatar = NULL;
if (obj)
@@ -1755,14 +1778,14 @@ class LLAdvancedAppearanceToXML : public view_listener_t
else
{
// If no selection, use the self avatar.
- avatar = gAgentAvatarp;
+ avatar = gAgentAvatarp;
}
if (avatar)
{
avatar->dumpArchetypeXML(emptyname);
}
- return true;
- }
+ return true;
+ }
};
@@ -1774,44 +1797,44 @@ class LLAdvancedAppearanceToXML : public view_listener_t
class LLAdvancedToggleCharacterGeometry : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_god_request_avatar_geometry(NULL);
- return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_god_request_avatar_geometry(NULL);
+ return true;
}
};
- /////////////////////////////
+ /////////////////////////////
// TEST MALE / TEST FEMALE //
/////////////////////////////
class LLAdvancedTestMale : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_test_male(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_test_male(NULL);
+ return true;
+ }
};
class LLAdvancedTestFemale : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_test_female(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_test_female(NULL);
+ return true;
+ }
};
class LLAdvancedForceParamsToDefault : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLAgent::clearVisualParams(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAgent::clearVisualParams(NULL);
+ return true;
+ }
};
@@ -1820,47 +1843,47 @@ class LLAdvancedForceParamsToDefault : public view_listener_t
//////////////////////////
// Utility function to set all AV time factors to the same global value
-static void set_all_animation_time_factors(F32 time_factor)
+static void set_all_animation_time_factors(F32 time_factor)
{
- LLMotionController::setCurrentTimeFactor(time_factor);
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- (*iter)->setAnimTimeFactor(time_factor);
- }
+ LLMotionController::setCurrentTimeFactor(time_factor);
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ (*iter)->setAnimTimeFactor(time_factor);
+ }
}
class LLAdvancedAnimTenFaster : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- //LL_INFOS() << "LLAdvancedAnimTenFaster" << LL_ENDL;
- F32 time_factor = LLMotionController::getCurrentTimeFactor();
- time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed
- set_all_animation_time_factors(time_factor);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ //LL_INFOS() << "LLAdvancedAnimTenFaster" << LL_ENDL;
+ F32 time_factor = LLMotionController::getCurrentTimeFactor();
+ time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed
+ set_all_animation_time_factors(time_factor);
+ return true;
+ }
};
class LLAdvancedAnimTenSlower : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- //LL_INFOS() << "LLAdvancedAnimTenSlower" << LL_ENDL;
- F32 time_factor = LLMotionController::getCurrentTimeFactor();
- time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed
- set_all_animation_time_factors(time_factor);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ //LL_INFOS() << "LLAdvancedAnimTenSlower" << LL_ENDL;
+ F32 time_factor = LLMotionController::getCurrentTimeFactor();
+ time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed
+ set_all_animation_time_factors(time_factor);
+ return true;
+ }
};
class LLAdvancedAnimResetAll : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- set_all_animation_time_factors(1.f);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ set_all_animation_time_factors(1.f);
+ return true;
+ }
};
@@ -1871,11 +1894,11 @@ class LLAdvancedAnimResetAll : public view_listener_t
class LLAdvancedReloadVertexShader : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- reload_vertex_shader(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ reload_vertex_shader(NULL);
+ return true;
+ }
};
@@ -1887,20 +1910,20 @@ class LLAdvancedReloadVertexShader : public view_listener_t
class LLAdvancedToggleAnimationInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug);
+ return true;
+ }
};
class LLAdvancedCheckAnimationInfo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLVOAvatar::sShowAnimationDebug;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sShowAnimationDebug;
+ return new_value;
+ }
};
@@ -1911,20 +1934,20 @@ class LLAdvancedCheckAnimationInfo : public view_listener_t
class LLAdvancedToggleShowLookAt : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt);
+ return true;
+ }
};
class LLAdvancedCheckShowLookAt : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLHUDEffectLookAt::sDebugLookAt;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLHUDEffectLookAt::sDebugLookAt;
+ return new_value;
+ }
};
@@ -1936,20 +1959,20 @@ class LLAdvancedCheckShowLookAt : public view_listener_t
class LLAdvancedToggleShowPointAt : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt);
+ return true;
+ }
};
class LLAdvancedCheckShowPointAt : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLHUDEffectPointAt::sDebugPointAt;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLHUDEffectPointAt::sDebugPointAt;
+ return new_value;
+ }
};
@@ -1961,20 +1984,20 @@ class LLAdvancedCheckShowPointAt : public view_listener_t
class LLAdvancedToggleDebugJointUpdates : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug);
+ return true;
+ }
};
class LLAdvancedCheckDebugJointUpdates : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLVOAvatar::sJointDebug;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sJointDebug;
+ return new_value;
+ }
};
@@ -1986,20 +2009,20 @@ class LLAdvancedCheckDebugJointUpdates : public view_listener_t
class LLAdvancedToggleDisableLOD : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD);
+ return true;
+ }
};
-
+
class LLAdvancedCheckDisableLOD : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerJoint::sDisableLOD;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLViewerJoint::sDisableLOD;
+ return new_value;
+ }
};
@@ -2011,20 +2034,20 @@ class LLAdvancedCheckDisableLOD : public view_listener_t
class LLAdvancedToggleDebugCharacterVis : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible);
+ return true;
+ }
};
class LLAdvancedCheckDebugCharacterVis : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLVOAvatar::sDebugInvisible;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sDebugInvisible;
+ return new_value;
+ }
};
@@ -2032,33 +2055,33 @@ class LLAdvancedCheckDebugCharacterVis : public view_listener_t
// DUMP ATTACHMENTS //
//////////////////////
-
+
class LLAdvancedDumpAttachments : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_dump_attachments(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_attachments(NULL);
+ return true;
+ }
};
-
+
/////////////////////
// REBAKE TEXTURES //
/////////////////////
-
-
+
+
class LLAdvancedRebakeTextures : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_rebake_textures(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_rebake_textures(NULL);
+ return true;
+ }
};
-
-
+
+
#if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
///////////////////////////
// DEBUG AVATAR TEXTURES //
@@ -2067,14 +2090,14 @@ class LLAdvancedRebakeTextures : public view_listener_t
class LLAdvancedDebugAvatarTextures : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgent.isGodlike())
- {
- handle_debug_avatar_textures(NULL);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.isGodlike())
+ {
+ handle_debug_avatar_textures(NULL);
+ }
+ return true;
+ }
};
////////////////////////////////
@@ -2084,17 +2107,17 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t
class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
#ifndef LL_RELEASE_FOR_DOWNLOAD
- handle_dump_avatar_local_textures(NULL);
+ handle_dump_avatar_local_textures(NULL);
#endif
- return true;
- }
+ return true;
+ }
};
#endif
-
+
/////////////////
// MESSAGE LOG //
/////////////////
@@ -2102,20 +2125,20 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
class LLAdvancedEnableMessageLog : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_viewer_enable_message_log(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_viewer_enable_message_log(NULL);
+ return true;
+ }
};
class LLAdvancedDisableMessageLog : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_viewer_disable_message_log(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_viewer_disable_message_log(NULL);
+ return true;
+ }
};
/////////////////
@@ -2125,11 +2148,11 @@ class LLAdvancedDisableMessageLog : public view_listener_t
class LLAdvancedDropPacket : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gMessageSystem->mPacketRing.dropPackets(1);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gMessageSystem->mPacketRing.dropPackets(1);
+ return true;
+ }
};
//////////////////////
@@ -2139,8 +2162,8 @@ class LLAdvancedDropPacket : public view_listener_t
class LLAdvancedPurgeDiskCache : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
llassert_always(main_queue);
@@ -2154,8 +2177,8 @@ class LLAdvancedPurgeDiskCache : public view_listener_t
},
[](){}); // Callback to main thread is empty as there is nothing left to do
- return true;
- }
+ return true;
+ }
};
@@ -2166,12 +2189,26 @@ class LLAdvancedPurgeDiskCache : public view_listener_t
class LLAdvancedPurgeShaderCache : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerShaderMgr::instance()->clearShaderCache();
- LLViewerShaderMgr::instance()->setShaders();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerShaderMgr::instance()->clearShaderCache();
+ LLViewerShaderMgr::instance()->setShaders();
+ return true;
+ }
+};
+
+/////////////////////
+// REBUILD TERRAIN //
+/////////////////////
+
+
+class LLAdvancedRebuildTerrain : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gPipeline.rebuildTerrain();
+ return true;
+ }
};
////////////////////
@@ -2181,32 +2218,32 @@ class LLAdvancedPurgeShaderCache : public view_listener_t
class LLAdvancedViewerEventRecorder : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string command = userdata.asString();
- if ("start playback" == command)
- {
- LL_INFOS() << "Event Playback starting" << LL_ENDL;
- LLViewerEventRecorder::instance().playbackRecording();
- LL_INFOS() << "Event Playback completed" << LL_ENDL;
- }
- else if ("stop playback" == command)
- {
- // Future
- }
- else if ("start recording" == command)
- {
- LLViewerEventRecorder::instance().setEventLoggingOn();
- LL_INFOS() << "Event recording started" << LL_ENDL;
- }
- else if ("stop recording" == command)
- {
- LLViewerEventRecorder::instance().setEventLoggingOff();
- LL_INFOS() << "Event recording stopped" << LL_ENDL;
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string command = userdata.asString();
+ if ("start playback" == command)
+ {
+ LL_INFOS() << "Event Playback starting" << LL_ENDL;
+ LLViewerEventRecorder::instance().playbackRecording();
+ LL_INFOS() << "Event Playback completed" << LL_ENDL;
+ }
+ else if ("stop playback" == command)
+ {
+ // Future
+ }
+ else if ("start recording" == command)
+ {
+ LLViewerEventRecorder::instance().setEventLoggingOn();
+ LL_INFOS() << "Event recording started" << LL_ENDL;
+ }
+ else if ("stop recording" == command)
+ {
+ LLViewerEventRecorder::instance().setEventLoggingOff();
+ LL_INFOS() << "Event recording stopped" << LL_ENDL;
+ }
+
+ return true;
+ }
};
@@ -2219,29 +2256,29 @@ class LLAdvancedViewerEventRecorder : public view_listener_t
class LLAdvancedAgentPilot : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string command = userdata.asString();
- if ("start playback" == command)
- {
- gAgentPilot.setNumRuns(-1);
- gAgentPilot.startPlayback();
- }
- else if ("stop playback" == command)
- {
- gAgentPilot.stopPlayback();
- }
- else if ("start record" == command)
- {
- gAgentPilot.startRecord();
- }
- else if ("stop record" == command)
- {
- gAgentPilot.stopRecord();
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string command = userdata.asString();
+ if ("start playback" == command)
+ {
+ gAgentPilot.setNumRuns(-1);
+ gAgentPilot.startPlayback();
+ }
+ else if ("stop playback" == command)
+ {
+ gAgentPilot.stopPlayback();
+ }
+ else if ("start record" == command)
+ {
+ gAgentPilot.startRecord();
+ }
+ else if ("stop record" == command)
+ {
+ gAgentPilot.stopRecord();
+ }
+
+ return true;
+ }
};
@@ -2253,20 +2290,20 @@ class LLAdvancedAgentPilot : public view_listener_t
class LLAdvancedToggleAgentPilotLoop : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgentPilot.setLoop(!gAgentPilot.getLoop());
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgentPilot.setLoop(!gAgentPilot.getLoop());
+ return true;
+ }
};
class LLAdvancedCheckAgentPilotLoop : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gAgentPilot.getLoop();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAgentPilot.getLoop();
+ return new_value;
+ }
};
@@ -2277,20 +2314,20 @@ class LLAdvancedCheckAgentPilotLoop : public view_listener_t
class LLAdvancedToggleShowObjectUpdates : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gShowObjectUpdates = !(gShowObjectUpdates);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gShowObjectUpdates = !(gShowObjectUpdates);
+ return true;
+ }
};
class LLAdvancedCheckShowObjectUpdates : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gShowObjectUpdates;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gShowObjectUpdates;
+ return new_value;
+ }
};
@@ -2302,11 +2339,11 @@ class LLAdvancedCheckShowObjectUpdates : public view_listener_t
class LLAdvancedCompressImage : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_compress_image(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_compress_image(NULL);
+ return true;
+ }
};
@@ -2332,11 +2369,11 @@ class LLAdvancedCompressFileTest : public view_listener_t
class LLAdvancedShowDebugSettings : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterReg::showInstance("settings_debug",userdata);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterReg::showInstance("settings_debug",userdata);
+ return true;
+ }
};
@@ -2347,40 +2384,40 @@ class LLAdvancedShowDebugSettings : public view_listener_t
class LLAdvancedEnableViewAdminOptions : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // Don't enable in god mode since the admin menu is shown anyway.
- // Only enable if the user has set the appropriate debug setting.
- bool new_value = !gAgent.getAgentAccess().isGodlikeWithoutAdminMenuFakery() && gSavedSettings.getBOOL("AdminMenu");
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // Don't enable in god mode since the admin menu is shown anyway.
+ // Only enable if the user has set the appropriate debug setting.
+ bool new_value = !gAgent.getAgentAccess().isGodlikeWithoutAdminMenuFakery() && gSavedSettings.getBOOL("AdminMenu");
+ return new_value;
+ }
};
class LLAdvancedToggleViewAdminOptions : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_admin_override_toggle(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_admin_override_toggle(NULL);
+ return true;
+ }
};
class LLAdvancedToggleVisualLeakDetector : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_visual_leak_detector_toggle(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_visual_leak_detector_toggle(NULL);
+ return true;
+ }
};
class LLAdvancedCheckViewAdminOptions : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = check_admin_override(NULL) || gAgent.isGodlike();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = check_admin_override(NULL) || gAgent.isGodlike();
+ return new_value;
+ }
};
//////////////////
@@ -2390,20 +2427,20 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t
class LLAdvancedRequestAdminStatus : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_god_mode(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_god_mode(NULL);
+ return true;
+ }
};
class LLAdvancedLeaveAdminStatus : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_leave_god_mode(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_leave_god_mode(NULL);
+ return true;
+ }
};
//////////////////////////
@@ -2412,20 +2449,20 @@ class LLAdvancedLeaveAdminStatus : public view_listener_t
class LLAdvancedForceErrorBreakpoint : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_breakpoint(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_breakpoint(NULL);
+ return true;
+ }
};
class LLAdvancedForceErrorLlerror : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_llerror(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_llerror(NULL);
+ return true;
+ }
};
class LLAdvancedForceErrorLlerrorMsg: public view_listener_t
@@ -2439,11 +2476,11 @@ class LLAdvancedForceErrorLlerrorMsg: public view_listener_t
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_bad_memory_access(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_bad_memory_access(NULL);
+ return true;
+ }
};
class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
@@ -2464,20 +2501,20 @@ class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_infinite_loop(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_infinite_loop(NULL);
+ return true;
+ }
};
class LLAdvancedForceErrorSoftwareException : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_software_exception(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_software_exception(NULL);
+ return true;
+ }
};
class LLAdvancedForceOSException: public view_listener_t
@@ -2507,11 +2544,11 @@ class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_error_driver_crash(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_driver_crash(NULL);
+ return true;
+ }
};
class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
@@ -2534,10 +2571,10 @@ class LLAdvancedForceErrorThreadCrash : public view_listener_t
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_disconnect_viewer(NULL);
- return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_disconnect_viewer(NULL);
+ return true;
}
};
@@ -2546,29 +2583,29 @@ class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
class LLAdvancedHandleToggleHackedGodmode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_toggle_hacked_godmode(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_toggle_hacked_godmode(NULL);
+ return true;
+ }
};
class LLAdvancedCheckToggleHackedGodmode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- check_toggle_hacked_godmode(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ check_toggle_hacked_godmode(NULL);
+ return true;
+ }
};
class LLAdvancedEnableToggleHackedGodmode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = enable_toggle_hacked_godmode(NULL);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = enable_toggle_hacked_godmode(NULL);
+ return new_value;
+ }
};
#endif
@@ -2585,21 +2622,21 @@ class LLAdvancedEnableToggleHackedGodmode : public view_listener_t
class LLDevelopCheckLoggingLevel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U32 level = userdata.asInteger();
- return (static_cast<LLError::ELevel>(level) == LLError::getDefaultLevel());
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 level = userdata.asInteger();
+ return (static_cast<LLError::ELevel>(level) == LLError::getDefaultLevel());
+ }
};
class LLDevelopSetLoggingLevel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- U32 level = userdata.asInteger();
- LLError::setDefaultLevel(static_cast<LLError::ELevel>(level));
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 level = userdata.asInteger();
+ LLError::setDefaultLevel(static_cast<LLError::ELevel>(level));
+ return true;
+ }
};
//////////////////
@@ -2609,100 +2646,100 @@ class LLDevelopSetLoggingLevel : public view_listener_t
// Admin > Object
class LLAdminForceTakeCopy : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- force_take_copy(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_take_copy(NULL);
+ return true;
+ }
};
class LLAdminHandleObjectOwnerSelf : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_object_owner_self(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_owner_self(NULL);
+ return true;
+ }
};
class LLAdminHandleObjectOwnerPermissive : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_object_owner_permissive(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_owner_permissive(NULL);
+ return true;
+ }
};
class LLAdminHandleForceDelete : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_force_delete(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_delete(NULL);
+ return true;
+ }
};
class LLAdminHandleObjectLock : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_object_lock(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_lock(NULL);
+ return true;
+ }
};
class LLAdminHandleObjectAssetIDs: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_object_asset_ids(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_asset_ids(NULL);
+ return true;
+ }
};
//Admin >Parcel
class LLAdminHandleForceParcelOwnerToMe: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_force_parcel_owner_to_me(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_parcel_owner_to_me(NULL);
+ return true;
+ }
};
class LLAdminHandleForceParcelToContent: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_force_parcel_to_content(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_parcel_to_content(NULL);
+ return true;
+ }
};
class LLAdminHandleClaimPublicLand: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_claim_public_land(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_claim_public_land(NULL);
+ return true;
+ }
};
// Admin > Region
class LLAdminHandleRegionDumpTempAssetData: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_region_dump_temp_asset_data(NULL);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_region_dump_temp_asset_data(NULL);
+ return true;
+ }
};
//Admin (Top Level)
class LLAdminOnSaveState: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLPanelRegionTools::onSaveState(NULL);
- return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPanelRegionTools::onSaveState(NULL);
+ return true;
}
};
@@ -2712,38 +2749,38 @@ class LLAdminOnSaveState: public view_listener_t
//-----------------------------------------------------------------------------
void cleanup_menus()
{
- delete gMenuParcelObserver;
- gMenuParcelObserver = NULL;
+ delete gMenuParcelObserver;
+ gMenuParcelObserver = NULL;
- delete gMenuAvatarSelf;
- gMenuAvatarSelf = NULL;
+ delete gMenuAvatarSelf;
+ gMenuAvatarSelf = NULL;
- delete gMenuAvatarOther;
- gMenuAvatarOther = NULL;
+ delete gMenuAvatarOther;
+ gMenuAvatarOther = NULL;
- delete gMenuObject;
- gMenuObject = NULL;
+ delete gMenuObject;
+ gMenuObject = NULL;
- delete gMenuAttachmentSelf;
- gMenuAttachmentSelf = NULL;
+ delete gMenuAttachmentSelf;
+ gMenuAttachmentSelf = NULL;
- delete gMenuAttachmentOther;
- gMenuAttachmentSelf = NULL;
+ delete gMenuAttachmentOther;
+ gMenuAttachmentSelf = NULL;
- delete gMenuLand;
- gMenuLand = NULL;
+ delete gMenuLand;
+ gMenuLand = NULL;
- delete gMenuMuteParticle;
- gMenuMuteParticle = NULL;
+ delete gMenuMuteParticle;
+ gMenuMuteParticle = NULL;
- delete gMenuBarView;
- gMenuBarView = NULL;
+ delete gMenuBarView;
+ gMenuBarView = NULL;
- delete gPopupMenuView;
- gPopupMenuView = NULL;
+ delete gPopupMenuView;
+ gPopupMenuView = NULL;
- delete gMenuHolder;
- gMenuHolder = NULL;
+ delete gMenuHolder;
+ gMenuHolder = NULL;
}
//-----------------------------------------------------------------------------
@@ -2752,40 +2789,40 @@ void cleanup_menus()
class LLObjectReportAbuse : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (objectp)
- {
- LLFloaterReporter::showFromObject(objectp->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (objectp)
+ {
+ LLFloaterReporter::showFromObject(objectp->getID());
+ }
+ return true;
+ }
};
// Enabled it you clicked an object
class LLObjectEnableReportAbuse : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;
+ return new_value;
+ }
};
void handle_object_touch()
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return;
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return;
- LLPickInfo pick = LLToolPie::getInstance()->getPick();
+ LLPickInfo pick = LLToolPie::getInstance()->getPick();
- // *NOTE: Hope the packets arrive safely and in order or else
- // there will be some problems.
- // *TODO: Just fix this bad assumption.
- send_ObjectGrab_message(object, pick, LLVector3::zero);
- send_ObjectDeGrab_message(object, pick);
+ // *NOTE: Hope the packets arrive safely and in order or else
+ // there will be some problems.
+ // *TODO: Just fix this bad assumption.
+ send_ObjectGrab_message(object, pick, LLVector3::zero);
+ send_ObjectDeGrab_message(object, pick);
}
void handle_object_show_original()
@@ -2818,75 +2855,75 @@ void handle_object_show_original()
static void init_default_item_label(LLUICtrl* ctrl)
{
- const std::string& item_name = ctrl->getName();
- boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
- if (it == sDefaultItemLabels.end())
- {
- // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value
- // (doesn't seem to matter much ATM).
- LLStringExplicit default_label = ctrl->getValue().asString();
- if (!default_label.empty())
- {
- sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
- }
- }
+ const std::string& item_name = ctrl->getName();
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it == sDefaultItemLabels.end())
+ {
+ // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value
+ // (doesn't seem to matter much ATM).
+ LLStringExplicit default_label = ctrl->getValue().asString();
+ if (!default_label.empty())
+ {
+ sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
+ }
+ }
}
static LLStringExplicit get_default_item_label(const std::string& item_name)
{
- LLStringExplicit res("");
- boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
- if (it != sDefaultItemLabels.end())
- {
- res = it->second;
- }
+ LLStringExplicit res("");
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it != sDefaultItemLabels.end())
+ {
+ res = it->second;
+ }
- return res;
+ return res;
}
bool enable_object_touch(LLUICtrl* ctrl)
{
- bool new_value = false;
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (obj)
- {
- LLViewerObject* parent = (LLViewerObject*)obj->getParent();
- new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch());
- }
+ bool new_value = false;
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (obj)
+ {
+ LLViewerObject* parent = (LLViewerObject*)obj->getParent();
+ new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch());
+ }
- init_default_item_label(ctrl);
+ init_default_item_label(ctrl);
- // Update label based on the node touch name if available.
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mTouchName.empty())
- {
- ctrl->setValue(node->mTouchName);
- }
- else
- {
- ctrl->setValue(get_default_item_label(ctrl->getName()));
- }
+ // Update label based on the node touch name if available.
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid && !node->mTouchName.empty())
+ {
+ ctrl->setValue(node->mTouchName);
+ }
+ else
+ {
+ ctrl->setValue(get_default_item_label(ctrl->getName()));
+ }
- return new_value;
+ return new_value;
};
//void label_touch(std::string& label, void*)
//{
-// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
-// if (node && node->mValid && !node->mTouchName.empty())
-// {
-// label.assign(node->mTouchName);
-// }
-// else
-// {
-// label.assign("Touch");
-// }
+// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+// if (node && node->mValid && !node->mTouchName.empty())
+// {
+// label.assign(node->mTouchName);
+// }
+// else
+// {
+// label.assign("Touch");
+// }
//}
void handle_object_open()
{
- LLFloaterReg::showInstance("openobject");
+ LLFloaterReg::showInstance("openobject");
}
bool enable_object_inspect()
@@ -2941,67 +2978,67 @@ bool enable_object_edit_gltf_material()
bool enable_object_open()
{
- // Look for contents in root object, which is all the LLFloaterOpenObject
- // understands.
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!obj) return false;
+ // Look for contents in root object, which is all the LLFloaterOpenObject
+ // understands.
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!obj) return false;
- LLViewerObject* root = obj->getRootEdit();
- if (!root) return false;
+ LLViewerObject* root = obj->getRootEdit();
+ if (!root) return false;
- return root->allowOpen();
+ return root->allowOpen();
}
class LLViewJoystickFlycam : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_toggle_flycam();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_toggle_flycam();
+ return true;
+ }
};
class LLViewCheckJoystickFlycam : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera();
+ return new_value;
+ }
};
void handle_toggle_flycam()
{
- LLViewerJoystick::getInstance()->toggleFlycam();
+ LLViewerJoystick::getInstance()->toggleFlycam();
}
class LLObjectBuild : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
- {
- // zoom in if we're looking at the avatar
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- else if ( gSavedSettings.getBOOL("EditCameraMovement") )
- {
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gViewerWindow->moveCursorToCenter();
- }
-
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
-
- // Could be first use
- //LLFirstUse::useBuild();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ // zoom in if we're looking at the avatar
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
+ gViewerWindow->moveCursorToCenter();
+ }
+ else if ( gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ gViewerWindow->moveCursorToCenter();
+ }
+
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
+
+ // Could be first use
+ //LLFirstUse::useBuild();
+ return true;
+ }
};
void update_camera()
@@ -3040,17 +3077,17 @@ void handle_object_edit()
{
update_camera();
- LLFloaterReg::showInstance("build");
-
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
-
- LLViewerJoystick::getInstance()->moveObjects(true);
- LLViewerJoystick::getInstance()->setNeedsReset(true);
-
- // Could be first use
- //LLFirstUse::useBuild();
- return;
+ LLFloaterReg::showInstance("build");
+
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
+
+ LLViewerJoystick::getInstance()->moveObjects(true);
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+
+ // Could be first use
+ //LLFirstUse::useBuild();
+ return;
}
void handle_object_edit_gltf_material()
@@ -3072,68 +3109,68 @@ void handle_object_edit_gltf_material()
void handle_attachment_edit(const LLUUID& inv_item_id)
{
- if (isAgentAvatarValid())
- {
- if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id))
- {
- LLSelectMgr::getInstance()->deselectAll();
- LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj);
+ if (isAgentAvatarValid())
+ {
+ if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id))
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj);
- handle_object_edit();
- }
- }
+ handle_object_edit();
+ }
+ }
}
void handle_attachment_touch(const LLUUID& inv_item_id)
{
- if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) )
- {
- if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)))
- {
- LLSelectMgr::getInstance()->deselectAll();
-
- LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj);
- if (!LLToolMgr::getInstance()->inBuildMode())
- {
- struct SetTransient : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- node->setTransient(TRUE);
- return true;
- }
- } f;
- sel->applyToNodes(&f);
- }
-
- handle_object_touch();
- }
- }
+ if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) )
+ {
+ if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)))
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+
+ LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj);
+ if (!LLToolMgr::getInstance()->inBuildMode())
+ {
+ struct SetTransient : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ node->setTransient(TRUE);
+ return true;
+ }
+ } f;
+ sel->applyToNodes(&f);
+ }
+
+ handle_object_touch();
+ }
+ }
}
bool enable_attachment_touch(const LLUUID& inv_item_id)
{
- if (isAgentAvatarValid())
- {
- const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
- return (attach_obj) && (attach_obj->flagHandleTouch());
- }
- return false;
+ if (isAgentAvatarValid())
+ {
+ const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
+ return (attach_obj) && (attach_obj->flagHandleTouch());
+ }
+ return false;
}
void handle_object_inspect()
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* selected_objectp = selection->getFirstRootObject();
- if (selected_objectp)
- {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* selected_objectp = selection->getFirstRootObject();
+ if (selected_objectp)
+ {
LLFloaterReg::showInstance("task_properties");
- }
-
- /*
- // Old floater properties
- LLFloaterReg::showInstance("inspect", LLSD());
- */
+ }
+
+ /*
+ // Old floater properties
+ LLFloaterReg::showInstance("inspect", LLSD());
+ */
}
//---------------------------------------------------------------------------
@@ -3141,133 +3178,133 @@ void handle_object_inspect()
//---------------------------------------------------------------------------
class LLLandBuild : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerParcelMgr::getInstance()->deselectLand();
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerParcelMgr::getInstance()->deselectLand();
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
- {
- // zoom in if we're looking at the avatar
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- else if ( gSavedSettings.getBOOL("EditCameraMovement") )
- {
- // otherwise just move focus
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gViewerWindow->moveCursorToCenter();
- }
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ // zoom in if we're looking at the avatar
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
+ gViewerWindow->moveCursorToCenter();
+ }
+ else if ( gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ // otherwise just move focus
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ gViewerWindow->moveCursorToCenter();
+ }
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
- // Could be first use
- //LLFirstUse::useBuild();
- return true;
- }
+ // Could be first use
+ //LLFirstUse::useBuild();
+ return true;
+ }
};
class LLLandBuyPass : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLPanelLandGeneral::onClickBuyPass((void *)FALSE);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPanelLandGeneral::onClickBuyPass((void *)FALSE);
+ return true;
+ }
};
class LLLandEnableBuyPass : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLPanelLandGeneral::enableBuyPass(NULL);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLPanelLandGeneral::enableBuyPass(NULL);
+ return new_value;
+ }
};
// BUG: Should really check if CLICK POINT is in a parcel where you can build.
BOOL enable_land_build(void*)
{
- if (gAgent.isGodlike()) return TRUE;
- if (gAgent.inPrelude()) return FALSE;
+ if (gAgent.isGodlike()) return TRUE;
+ if (gAgent.inPrelude()) return FALSE;
- BOOL can_build = FALSE;
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (agent_parcel)
- {
- can_build = agent_parcel->getAllowModify();
- }
- return can_build;
+ BOOL can_build = FALSE;
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (agent_parcel)
+ {
+ can_build = agent_parcel->getAllowModify();
+ }
+ return can_build;
}
// BUG: Should really check if OBJECT is in a parcel where you can build.
BOOL enable_object_build(void*)
{
- if (gAgent.isGodlike()) return TRUE;
- if (gAgent.inPrelude()) return FALSE;
+ if (gAgent.isGodlike()) return TRUE;
+ if (gAgent.inPrelude()) return FALSE;
- BOOL can_build = FALSE;
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (agent_parcel)
- {
- can_build = agent_parcel->getAllowModify();
- }
- return can_build;
+ BOOL can_build = FALSE;
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (agent_parcel)
+ {
+ can_build = agent_parcel->getAllowModify();
+ }
+ return can_build;
}
bool enable_object_edit()
{
- if (!isAgentAvatarValid()) return false;
-
- // *HACK: The new "prelude" Help Islands have a build sandbox area,
- // so users need the Edit and Create pie menu options when they are
- // there. Eventually this needs to be replaced with code that only
- // lets you edit objects if you have permission to do so (edit perms,
- // group edit, god). See also lltoolbar.cpp. JC
- bool enable = false;
- if (gAgent.inPrelude())
- {
- enable = LLViewerParcelMgr::getInstance()->allowAgentBuild()
- || LLSelectMgr::getInstance()->getSelection()->isAttachment();
- }
- else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound())
- {
- enable = true;
- }
-
- return enable;
+ if (!isAgentAvatarValid()) return false;
+
+ // *HACK: The new "prelude" Help Islands have a build sandbox area,
+ // so users need the Edit and Create pie menu options when they are
+ // there. Eventually this needs to be replaced with code that only
+ // lets you edit objects if you have permission to do so (edit perms,
+ // group edit, god). See also lltoolbar.cpp. JC
+ bool enable = false;
+ if (gAgent.inPrelude())
+ {
+ enable = LLViewerParcelMgr::getInstance()->allowAgentBuild()
+ || LLSelectMgr::getInstance()->getSelection()->isAttachment();
+ }
+ else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound())
+ {
+ enable = true;
+ }
+
+ return enable;
}
bool enable_mute_particle()
{
- const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
+ const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
- return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID();
+ return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID();
}
// mutually exclusive - show either edit option or build in menu
bool enable_object_build()
{
- return !enable_object_edit();
+ return !enable_object_edit();
}
bool enable_object_select_in_pathfinding_linksets()
{
- return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets();
+ return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets();
}
bool visible_object_select_in_pathfinding_linksets()
{
- return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
+ return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
}
bool enable_object_select_in_pathfinding_characters()
{
- return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters();
+ return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters();
}
bool enable_os_exception()
@@ -3281,40 +3318,40 @@ bool enable_os_exception()
class LLSelfRemoveAllAttachments : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
+ return true;
+ }
};
class LLSelfEnableRemoveAllAttachments : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = false;
- if (isAgentAvatarValid())
- {
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getNumObjects() > 0)
- {
- new_value = true;
- break;
- }
- }
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = false;
+ if (isAgentAvatarValid())
+ {
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getNumObjects() > 0)
+ {
+ new_value = true;
+ break;
+ }
+ }
+ }
+ return new_value;
+ }
};
BOOL enable_has_attachments(void*)
{
- return FALSE;
+ return FALSE;
}
//---------------------------------------------------------------------------
@@ -3322,229 +3359,229 @@ BOOL enable_has_attachments(void*)
//---------------------------------------------------------------------------
//void handle_follow(void *userdata)
//{
-// // follow a given avatar by ID
-// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
-// if (objectp)
-// {
-// gAgent.startFollowPilot(objectp->getID());
-// }
+// // follow a given avatar by ID
+// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+// if (objectp)
+// {
+// gAgent.startFollowPilot(objectp->getID());
+// }
//}
bool enable_object_mute()
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return false;
-
- LLVOAvatar* avatar = find_avatar_from_object(object);
- if (avatar)
- {
- // It's an avatar
- LLNameValue *lastname = avatar->getNVPair("LastName");
- bool is_linden =
- lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
- bool is_self = avatar->isSelf();
- return !is_linden && !is_self;
- }
- else
- {
- // Just a regular object
- return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
- !LLMuteList::getInstance()->isMuted(object->getID());
- }
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (avatar)
+ {
+ // It's an avatar
+ LLNameValue *lastname = avatar->getNVPair("LastName");
+ bool is_linden =
+ lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
+ bool is_self = avatar->isSelf();
+ return !is_linden && !is_self;
+ }
+ else
+ {
+ // Just a regular object
+ return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
+ !LLMuteList::getInstance()->isMuted(object->getID());
+ }
}
bool enable_object_unmute()
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return false;
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
- LLVOAvatar* avatar = find_avatar_from_object(object);
- if (avatar)
- {
- // It's an avatar
- LLNameValue *lastname = avatar->getNVPair("LastName");
- bool is_linden =
- lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
- bool is_self = avatar->isSelf();
- return !is_linden && !is_self;
- }
- else
- {
- // Just a regular object
- return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
- LLMuteList::getInstance()->isMuted(object->getID());;
- }
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (avatar)
+ {
+ // It's an avatar
+ LLNameValue *lastname = avatar->getNVPair("LastName");
+ bool is_linden =
+ lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
+ bool is_self = avatar->isSelf();
+ return !is_linden && !is_self;
+ }
+ else
+ {
+ // Just a regular object
+ return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
+ LLMuteList::getInstance()->isMuted(object->getID());;
+ }
}
// 0 = normal, 1 = always, 2 = never
class LLAvatarCheckImpostorMode : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return false;
-
- LLVOAvatar* avatar = find_avatar_from_object(object);
- if (!avatar) return false;
-
- U32 mode = userdata.asInteger();
- switch (mode)
- {
- case 0:
- return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
- case 1:
- return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
- case 2:
- return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (!avatar) return false;
+
+ U32 mode = userdata.asInteger();
+ switch (mode)
+ {
+ case 0:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
+ case 1:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
+ case 2:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
case 4:
return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY);
- default:
- return false;
- }
- } // handleEvent()
+ default:
+ return false;
+ }
+ } // handleEvent()
};
// 0 = normal, 1 = always, 2 = never
class LLAvatarSetImpostorMode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return false;
-
- LLVOAvatar* avatar = find_avatar_from_object(object);
- if (!avatar) return false;
-
- U32 mode = userdata.asInteger();
- switch (mode)
- {
- case 0:
- avatar->setVisualMuteSettings(LLVOAvatar::AV_RENDER_NORMALLY);
- break;
- case 1:
- avatar->setVisualMuteSettings(LLVOAvatar::AV_DO_NOT_RENDER);
- break;
- case 2:
- avatar->setVisualMuteSettings(LLVOAvatar::AV_ALWAYS_RENDER);
- break;
- default:
- return false;
- }
-
- LLVOAvatar::cullAvatarsByPixelArea();
- return true;
- } // handleEvent()
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (!avatar) return false;
+
+ U32 mode = userdata.asInteger();
+ switch (mode)
+ {
+ case 0:
+ avatar->setVisualMuteSettings(LLVOAvatar::AV_RENDER_NORMALLY);
+ break;
+ case 1:
+ avatar->setVisualMuteSettings(LLVOAvatar::AV_DO_NOT_RENDER);
+ break;
+ case 2:
+ avatar->setVisualMuteSettings(LLVOAvatar::AV_ALWAYS_RENDER);
+ break;
+ default:
+ return false;
+ }
+
+ LLVOAvatar::cullAvatarsByPixelArea();
+ return true;
+ } // handleEvent()
};
class LLObjectMute : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return true;
-
- LLUUID id;
- std::string name;
- LLMute::EType type;
- LLVOAvatar* avatar = find_avatar_from_object(object);
- if (avatar)
- {
- avatar->mNeedsImpostorUpdate = TRUE;
- avatar->mLastImpostorUpdateReason = 9;
-
- id = avatar->getID();
-
- LLNameValue *firstname = avatar->getNVPair("FirstName");
- LLNameValue *lastname = avatar->getNVPair("LastName");
- if (firstname && lastname)
- {
- name = LLCacheName::buildFullName(
- firstname->getString(), lastname->getString());
- }
-
- type = LLMute::AGENT;
- }
- else
- {
- // it's an object
- id = object->getID();
-
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node)
- {
- name = node->mName;
- }
-
- type = LLMute::OBJECT;
- }
-
- LLMute mute(id, name, type);
- if (LLMuteList::getInstance()->isMuted(mute.mID))
- {
- LLMuteList::getInstance()->remove(mute);
- }
- else
- {
- LLMuteList::getInstance()->add(mute);
- LLPanelBlockedList::showPanelAndSelect(mute.mID);
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return true;
+
+ LLUUID id;
+ std::string name;
+ LLMute::EType type;
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (avatar)
+ {
+ avatar->mNeedsImpostorUpdate = TRUE;
+ avatar->mLastImpostorUpdateReason = 9;
+
+ id = avatar->getID();
+
+ LLNameValue *firstname = avatar->getNVPair("FirstName");
+ LLNameValue *lastname = avatar->getNVPair("LastName");
+ if (firstname && lastname)
+ {
+ name = LLCacheName::buildFullName(
+ firstname->getString(), lastname->getString());
+ }
+
+ type = LLMute::AGENT;
+ }
+ else
+ {
+ // it's an object
+ id = object->getID();
+
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node)
+ {
+ name = node->mName;
+ }
+
+ type = LLMute::OBJECT;
+ }
+
+ LLMute mute(id, name, type);
+ if (LLMuteList::getInstance()->isMuted(mute.mID))
+ {
+ LLMuteList::getInstance()->remove(mute);
+ }
+ else
+ {
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ }
+
+ return true;
+ }
};
bool handle_go_to()
{
- // try simulator autopilot
- std::vector<std::string> strings;
- std::string val;
- LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
- val = llformat("%g", pos.mdV[VX]);
- strings.push_back(val);
- val = llformat("%g", pos.mdV[VY]);
- strings.push_back(val);
- val = llformat("%g", pos.mdV[VZ]);
- strings.push_back(val);
- send_generic_message("autopilot", strings);
-
- LLViewerParcelMgr::getInstance()->deselectLand();
-
- if (isAgentAvatarValid() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
- {
- gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgentAvatarp->getID());
- }
- else
- {
- // Snap camera back to behind avatar
- gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
- }
-
- // Could be first use
- //LLFirstUse::useGoTo();
- return true;
+ // try simulator autopilot
+ std::vector<std::string> strings;
+ std::string val;
+ LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
+ val = llformat("%g", pos.mdV[VX]);
+ strings.push_back(val);
+ val = llformat("%g", pos.mdV[VY]);
+ strings.push_back(val);
+ val = llformat("%g", pos.mdV[VZ]);
+ strings.push_back(val);
+ send_generic_message("autopilot", strings);
+
+ LLViewerParcelMgr::getInstance()->deselectLand();
+
+ if (isAgentAvatarValid() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
+ {
+ gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgentAvatarp->getID());
+ }
+ else
+ {
+ // Snap camera back to behind avatar
+ gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
+ }
+
+ // Could be first use
+ //LLFirstUse::useGoTo();
+ return true;
}
class LLGoToObject : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return handle_go_to();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return handle_go_to();
+ }
};
class LLAvatarReportAbuse : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLFloaterReporter::showFromObject(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLFloaterReporter::showFromObject(avatar->getID());
+ }
+ return true;
+ }
};
@@ -3553,230 +3590,230 @@ class LLAvatarReportAbuse : public view_listener_t
//---------------------------------------------------------------------------
bool callback_freeze(const LLSD& notification, const LLSD& response)
{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (0 == option || 1 == option)
- {
- U32 flags = 0x0;
- if (1 == option)
- {
- // unfreeze
- flags |= 0x1;
- }
-
- LLMessageSystem* msg = gMessageSystem;
- LLViewerObject* avatar = gObjectList.findObject(avatar_id);
-
- if (avatar)
- {
- msg->newMessage("FreezeUser");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("TargetID", avatar_id );
- msg->addU32("Flags", flags );
- msg->sendReliable( avatar->getRegion()->getHost() );
- }
- }
- return false;
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option || 1 == option)
+ {
+ U32 flags = 0x0;
+ if (1 == option)
+ {
+ // unfreeze
+ flags |= 0x1;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ LLViewerObject* avatar = gObjectList.findObject(avatar_id);
+
+ if (avatar)
+ {
+ msg->newMessage("FreezeUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ msg->sendReliable( avatar->getRegion()->getHost() );
+ }
+ }
+ return false;
}
void handle_avatar_freeze(const LLSD& avatar_id)
{
- // Use avatar_id if available, otherwise default to right-click avatar
- LLVOAvatar* avatar = NULL;
- if (avatar_id.asUUID().notNull())
- {
- avatar = find_avatar_from_object(avatar_id.asUUID());
- }
- else
- {
- avatar = find_avatar_from_object(
- LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- }
-
- if( avatar )
- {
- std::string fullname = avatar->getFullname();
- LLSD payload;
- payload["avatar_id"] = avatar->getID();
-
- if (!fullname.empty())
- {
- LLSD args;
- args["AVATAR_NAME"] = fullname;
- LLNotificationsUtil::add("FreezeAvatarFullname",
- args,
- payload,
- callback_freeze);
- }
- else
- {
- LLNotificationsUtil::add("FreezeAvatar",
- LLSD(),
- payload,
- callback_freeze);
- }
- }
+ // Use avatar_id if available, otherwise default to right-click avatar
+ LLVOAvatar* avatar = NULL;
+ if (avatar_id.asUUID().notNull())
+ {
+ avatar = find_avatar_from_object(avatar_id.asUUID());
+ }
+ else
+ {
+ avatar = find_avatar_from_object(
+ LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ }
+
+ if( avatar )
+ {
+ std::string fullname = avatar->getFullname();
+ LLSD payload;
+ payload["avatar_id"] = avatar->getID();
+
+ if (!fullname.empty())
+ {
+ LLSD args;
+ args["AVATAR_NAME"] = fullname;
+ LLNotificationsUtil::add("FreezeAvatarFullname",
+ args,
+ payload,
+ callback_freeze);
+ }
+ else
+ {
+ LLNotificationsUtil::add("FreezeAvatar",
+ LLSD(),
+ payload,
+ callback_freeze);
+ }
+ }
}
class LLAvatarVisibleDebug : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gAgent.isGodlike();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.isGodlike();
+ }
};
class LLAvatarDebug : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if( avatar )
- {
- if (avatar->isSelf())
- {
- ((LLVOAvatarSelf *)avatar)->dumpLocalTextures();
- }
- LL_INFOS() << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << LL_ENDL;
- std::vector<std::string> strings;
- strings.push_back(avatar->getID().asString());
- LLUUID invoice;
- send_generic_message("dumptempassetdata", strings, invoice);
- LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) );
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if( avatar )
+ {
+ if (avatar->isSelf())
+ {
+ ((LLVOAvatarSelf *)avatar)->dumpLocalTextures();
+ }
+ LL_INFOS() << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << LL_ENDL;
+ std::vector<std::string> strings;
+ strings.push_back(avatar->getID().asString());
+ LLUUID invoice;
+ send_generic_message("dumptempassetdata", strings, invoice);
+ LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) );
+ }
+ return true;
+ }
};
bool callback_eject(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (2 == option)
- {
- // Cancel button.
- return false;
- }
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean();
-
- if (0 == option)
- {
- // Eject button
- LLMessageSystem* msg = gMessageSystem;
- LLViewerObject* avatar = gObjectList.findObject(avatar_id);
-
- if (avatar)
- {
- U32 flags = 0x0;
- msg->newMessage("EjectUser");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID() );
- msg->addUUID("SessionID", gAgent.getSessionID() );
- msg->nextBlock("Data");
- msg->addUUID("TargetID", avatar_id );
- msg->addU32("Flags", flags );
- msg->sendReliable( avatar->getRegion()->getHost() );
- }
- }
- else if (ban_enabled)
- {
- // This is tricky. It is similar to say if it is not an 'Eject' button,
- // and it is also not an 'Cancle' button, and ban_enabled==ture,
- // it should be the 'Eject and Ban' button.
- LLMessageSystem* msg = gMessageSystem;
- LLViewerObject* avatar = gObjectList.findObject(avatar_id);
-
- if (avatar)
- {
- U32 flags = 0x1;
- msg->newMessage("EjectUser");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID() );
- msg->addUUID("SessionID", gAgent.getSessionID() );
- msg->nextBlock("Data");
- msg->addUUID("TargetID", avatar_id );
- msg->addU32("Flags", flags );
- msg->sendReliable( avatar->getRegion()->getHost() );
- }
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (2 == option)
+ {
+ // Cancel button.
+ return false;
+ }
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean();
+
+ if (0 == option)
+ {
+ // Eject button
+ LLMessageSystem* msg = gMessageSystem;
+ LLViewerObject* avatar = gObjectList.findObject(avatar_id);
+
+ if (avatar)
+ {
+ U32 flags = 0x0;
+ msg->newMessage("EjectUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID() );
+ msg->addUUID("SessionID", gAgent.getSessionID() );
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ msg->sendReliable( avatar->getRegion()->getHost() );
+ }
+ }
+ else if (ban_enabled)
+ {
+ // This is tricky. It is similar to say if it is not an 'Eject' button,
+ // and it is also not an 'Cancle' button, and ban_enabled==ture,
+ // it should be the 'Eject and Ban' button.
+ LLMessageSystem* msg = gMessageSystem;
+ LLViewerObject* avatar = gObjectList.findObject(avatar_id);
+
+ if (avatar)
+ {
+ U32 flags = 0x1;
+ msg->newMessage("EjectUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID() );
+ msg->addUUID("SessionID", gAgent.getSessionID() );
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ msg->sendReliable( avatar->getRegion()->getHost() );
+ }
+ }
+ return false;
}
void handle_avatar_eject(const LLSD& avatar_id)
{
- // Use avatar_id if available, otherwise default to right-click avatar
- LLVOAvatar* avatar = NULL;
- if (avatar_id.asUUID().notNull())
- {
- avatar = find_avatar_from_object(avatar_id.asUUID());
- }
- else
- {
- avatar = find_avatar_from_object(
- LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- }
-
- if( avatar )
- {
- LLSD payload;
- payload["avatar_id"] = avatar->getID();
- std::string fullname = avatar->getFullname();
-
- const LLVector3d& pos = avatar->getPositionGlobal();
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel();
-
- if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED))
- {
+ // Use avatar_id if available, otherwise default to right-click avatar
+ LLVOAvatar* avatar = NULL;
+ if (avatar_id.asUUID().notNull())
+ {
+ avatar = find_avatar_from_object(avatar_id.asUUID());
+ }
+ else
+ {
+ avatar = find_avatar_from_object(
+ LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ }
+
+ if( avatar )
+ {
+ LLSD payload;
+ payload["avatar_id"] = avatar->getID();
+ std::string fullname = avatar->getFullname();
+
+ const LLVector3d& pos = avatar->getPositionGlobal();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel();
+
+ if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED))
+ {
payload["ban_enabled"] = true;
- if (!fullname.empty())
- {
- LLSD args;
- args["AVATAR_NAME"] = fullname;
- LLNotificationsUtil::add("EjectAvatarFullname",
- args,
- payload,
- callback_eject);
- }
- else
- {
- LLNotificationsUtil::add("EjectAvatarFullname",
- LLSD(),
- payload,
- callback_eject);
- }
- }
- else
- {
+ if (!fullname.empty())
+ {
+ LLSD args;
+ args["AVATAR_NAME"] = fullname;
+ LLNotificationsUtil::add("EjectAvatarFullname",
+ args,
+ payload,
+ callback_eject);
+ }
+ else
+ {
+ LLNotificationsUtil::add("EjectAvatarFullname",
+ LLSD(),
+ payload,
+ callback_eject);
+ }
+ }
+ else
+ {
payload["ban_enabled"] = false;
- if (!fullname.empty())
- {
- LLSD args;
- args["AVATAR_NAME"] = fullname;
- LLNotificationsUtil::add("EjectAvatarFullnameNoBan",
- args,
- payload,
- callback_eject);
- }
- else
- {
- LLNotificationsUtil::add("EjectAvatarNoBan",
- LLSD(),
- payload,
- callback_eject);
- }
- }
- }
+ if (!fullname.empty())
+ {
+ LLSD args;
+ args["AVATAR_NAME"] = fullname;
+ LLNotificationsUtil::add("EjectAvatarFullnameNoBan",
+ args,
+ payload,
+ callback_eject);
+ }
+ else
+ {
+ LLNotificationsUtil::add("EjectAvatarNoBan",
+ LLSD(),
+ payload,
+ callback_eject);
+ }
+ }
+ }
}
bool my_profile_visible()
{
- LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID);
- return floaterp && floaterp->isInVisibleChain();
+ LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID);
+ return floaterp && floaterp->isInVisibleChain();
}
bool picks_tab_visible()
@@ -3786,192 +3823,192 @@ bool picks_tab_visible()
bool enable_freeze_eject(const LLSD& avatar_id)
{
- // Use avatar_id if available, otherwise default to right-click avatar
- LLVOAvatar* avatar = NULL;
- if (avatar_id.asUUID().notNull())
- {
- avatar = find_avatar_from_object(avatar_id.asUUID());
- }
- else
- {
- avatar = find_avatar_from_object(
- LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- }
- if (!avatar) return false;
-
- // Gods can always freeze
- if (gAgent.isGodlike()) return true;
-
- // Estate owners / managers can freeze
- // Parcel owners can also freeze
- const LLVector3& pos = avatar->getPositionRegion();
- const LLVector3d& pos_global = avatar->getPositionGlobal();
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
- LLViewerRegion* region = avatar->getRegion();
- if (!region) return false;
-
- bool new_value = region->isOwnedSelf(pos);
- if (!new_value || region->isOwnedGroup(pos))
- {
- new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
- }
- return new_value;
+ // Use avatar_id if available, otherwise default to right-click avatar
+ LLVOAvatar* avatar = NULL;
+ if (avatar_id.asUUID().notNull())
+ {
+ avatar = find_avatar_from_object(avatar_id.asUUID());
+ }
+ else
+ {
+ avatar = find_avatar_from_object(
+ LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ }
+ if (!avatar) return false;
+
+ // Gods can always freeze
+ if (gAgent.isGodlike()) return true;
+
+ // Estate owners / managers can freeze
+ // Parcel owners can also freeze
+ const LLVector3& pos = avatar->getPositionRegion();
+ const LLVector3d& pos_global = avatar->getPositionGlobal();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
+ LLViewerRegion* region = avatar->getRegion();
+ if (!region) return false;
+
+ bool new_value = region->isOwnedSelf(pos);
+ if (!new_value || region->isOwnedGroup(pos))
+ {
+ new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
+ }
+ return new_value;
}
bool callback_leave_group(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_LeaveGroupRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_GroupData);
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
- gAgent.sendReliableMessage();
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_LeaveGroupRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_GroupData);
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
+ gAgent.sendReliableMessage();
+ }
+ return false;
}
void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt)
{
- LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
- std::string buffer;
- switch(val)
- {
- case LLAggregatePermissions::AP_NONE:
- buffer = llformat( "* %s None\n", txt);
- break;
- case LLAggregatePermissions::AP_SOME:
- buffer = llformat( "* %s Some\n", txt);
- break;
- case LLAggregatePermissions::AP_ALL:
- buffer = llformat( "* %s All\n", txt);
- break;
- case LLAggregatePermissions::AP_EMPTY:
- default:
- break;
- }
- string.append(buffer);
+ LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
+ std::string buffer;
+ switch(val)
+ {
+ case LLAggregatePermissions::AP_NONE:
+ buffer = llformat( "* %s None\n", txt);
+ break;
+ case LLAggregatePermissions::AP_SOME:
+ buffer = llformat( "* %s Some\n", txt);
+ break;
+ case LLAggregatePermissions::AP_ALL:
+ buffer = llformat( "* %s All\n", txt);
+ break;
+ case LLAggregatePermissions::AP_EMPTY:
+ default:
+ break;
+ }
+ string.append(buffer);
}
bool enable_buy_object()
{
// In order to buy, there must only be 1 purchaseable object in
// the selection manager.
- if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false;
+ if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false;
LLViewerObject* obj = NULL;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if(node)
+ if(node)
{
obj = node->getObject();
if(!obj) return false;
- if( for_sale_selection(node) )
- {
- // *NOTE: Is this needed? This checks to see if anyone owns the
- // object, dating back to when we had "public" objects owned by
- // no one. JC
- if(obj->permAnyOwner()) return true;
- }
+ if( for_sale_selection(node) )
+ {
+ // *NOTE: Is this needed? This checks to see if anyone owns the
+ // object, dating back to when we had "public" objects owned by
+ // no one. JC
+ if(obj->permAnyOwner()) return true;
+ }
}
- return false;
+ return false;
}
// Note: This will only work if the selected object's data has been
// received by the viewer and cached in the selection manager.
void handle_buy_object(LLSaleInfo sale_info)
{
- if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
- {
- LLNotificationsUtil::add("UnableToBuyWhileDownloading");
- return;
- }
+ if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
+ {
+ LLNotificationsUtil::add("UnableToBuyWhileDownloading");
+ return;
+ }
- LLUUID owner_id;
- std::string owner_name;
- BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
- if (!owners_identical)
- {
- LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners");
- return;
- }
+ LLUUID owner_id;
+ std::string owner_name;
+ BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+ if (!owners_identical)
+ {
+ LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners");
+ return;
+ }
- LLPermissions perm;
- BOOL valid = LLSelectMgr::getInstance()->selectGetPermissions(perm);
- LLAggregatePermissions ag_perm;
- valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm);
- if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
- {
- LLNotificationsUtil::add("ObjectNotForSale");
- return;
- }
+ LLPermissions perm;
+ BOOL valid = LLSelectMgr::getInstance()->selectGetPermissions(perm);
+ LLAggregatePermissions ag_perm;
+ valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm);
+ if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
+ {
+ LLNotificationsUtil::add("ObjectNotForSale");
+ return;
+ }
- LLFloaterBuy::show(sale_info);
+ LLFloaterBuy::show(sale_info);
}
void handle_buy_contents(LLSaleInfo sale_info)
{
- LLFloaterBuyContents::show(sale_info);
+ LLFloaterBuyContents::show(sale_info);
}
void handle_region_dump_temp_asset_data(void*)
{
- LL_INFOS() << "Dumping temporary asset data to simulator logs" << LL_ENDL;
- std::vector<std::string> strings;
- LLUUID invoice;
- send_generic_message("dumptempassetdata", strings, invoice);
+ LL_INFOS() << "Dumping temporary asset data to simulator logs" << LL_ENDL;
+ std::vector<std::string> strings;
+ LLUUID invoice;
+ send_generic_message("dumptempassetdata", strings, invoice);
}
void handle_region_clear_temp_asset_data(void*)
{
- LL_INFOS() << "Clearing temporary asset data" << LL_ENDL;
- std::vector<std::string> strings;
- LLUUID invoice;
- send_generic_message("cleartempassetdata", strings, invoice);
+ LL_INFOS() << "Clearing temporary asset data" << LL_ENDL;
+ std::vector<std::string> strings;
+ LLUUID invoice;
+ send_generic_message("cleartempassetdata", strings, invoice);
}
void handle_region_dump_settings(void*)
{
- LLViewerRegion* regionp = gAgent.getRegion();
- if (regionp)
- {
- LL_INFOS() << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << LL_ENDL;
- LL_INFOS() << "Water: " << (regionp->getWaterHeight()) << LL_ENDL;
- }
+ LLViewerRegion* regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ LL_INFOS() << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << LL_ENDL;
+ LL_INFOS() << "Water: " << (regionp->getWaterHeight()) << LL_ENDL;
+ }
}
void handle_dump_group_info(void *)
{
- gAgent.dumpGroupInfo();
+ gAgent.dumpGroupInfo();
}
void handle_dump_capabilities_info(void *)
{
- LLViewerRegion* regionp = gAgent.getRegion();
- if (regionp)
- {
- regionp->logActiveCapabilities();
- }
+ LLViewerRegion* regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ regionp->logActiveCapabilities();
+ }
}
void handle_dump_region_object_cache(void*)
{
- LLViewerRegion* regionp = gAgent.getRegion();
- if (regionp)
- {
- regionp->dumpCache();
- }
+ LLViewerRegion* regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ regionp->dumpCache();
+ }
}
void handle_reset_interest_lists(void *)
@@ -3992,18 +4029,18 @@ void handle_reset_interest_lists(void *)
void handle_dump_focus()
{
- LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- LL_INFOS() << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << LL_ENDL;
+ LL_INFOS() << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << LL_ENDL;
}
class LLSelfStandUp : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.standUp();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgent.standUp();
+ return true;
+ }
};
bool enable_standup_self()
@@ -4024,202 +4061,202 @@ class LLSelfSitDown : public view_listener_t
bool show_sitdown_self()
{
- return isAgentAvatarValid() && !gAgentAvatarp->isSitting();
+ return isAgentAvatarValid() && !gAgentAvatarp->isSitting();
}
bool enable_sitdown_self()
{
- return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
+ return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
}
class LLSelfToggleSitStand : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (isAgentAvatarValid())
- {
- if (gAgentAvatarp->isSitting())
- {
- gAgent.standUp();
- }
- else
- {
- gAgent.sitDown();
- }
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (isAgentAvatarValid())
+ {
+ if (gAgentAvatarp->isSitting())
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ gAgent.sitDown();
+ }
+ }
+ return true;
+ }
};
bool enable_sit_stand()
{
- return enable_sitdown_self() || enable_standup_self();
+ return enable_sitdown_self() || enable_standup_self();
}
bool enable_fly_land()
{
- return gAgent.getFlying() || LLAgent::enableFlying();
+ return gAgent.getFlying() || LLAgent::enableFlying();
}
class LLCheckPanelPeopleTab : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string panel_name = userdata.asString();
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string panel_name = userdata.asString();
- LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
- if(panel && panel->isInVisibleChain())
- {
- return true;
- }
- return false;
- }
+ LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
+ if(panel && panel->isInVisibleChain())
+ {
+ return true;
+ }
+ return false;
+ }
};
// Toggle one of "People" panel tabs in side tray.
class LLTogglePanelPeopleTab : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string panel_name = userdata.asString();
-
- LLSD param;
- param["people_panel_tab_name"] = panel_name;
-
- if ( panel_name == "friends_panel"
- || panel_name == "groups_panel"
- || panel_name == "nearby_panel"
- || panel_name == "blocked_panel")
- {
- return togglePeoplePanel(panel_name, param);
- }
- else
- {
- return false;
- }
- }
-
- static bool togglePeoplePanel(const std::string& panel_name, const LLSD& param)
- {
- LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
- if(!panel)
- return false;
-
- if (panel->isInVisibleChain())
- {
- LLFloaterReg::hideInstance("people");
- }
- else
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_people", param) ;
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string panel_name = userdata.asString();
+
+ LLSD param;
+ param["people_panel_tab_name"] = panel_name;
+
+ if ( panel_name == "friends_panel"
+ || panel_name == "groups_panel"
+ || panel_name == "nearby_panel"
+ || panel_name == "blocked_panel")
+ {
+ return togglePeoplePanel(panel_name, param);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ static bool togglePeoplePanel(const std::string& panel_name, const LLSD& param)
+ {
+ LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
+ if(!panel)
+ return false;
+
+ if (panel->isInVisibleChain())
+ {
+ LLFloaterReg::hideInstance("people");
+ }
+ else
+ {
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people", param) ;
+ }
+
+ return true;
+ }
};
BOOL check_admin_override(void*)
{
- return gAgent.getAdminOverride();
+ return gAgent.getAdminOverride();
}
void handle_admin_override_toggle(void*)
{
- gAgent.setAdminOverride(!gAgent.getAdminOverride());
+ gAgent.setAdminOverride(!gAgent.getAdminOverride());
- // The above may have affected which debug menus are visible
- show_debug_menus();
+ // The above may have affected which debug menus are visible
+ show_debug_menus();
}
void handle_visual_leak_detector_toggle(void*)
{
- static bool vld_enabled = false;
+ static bool vld_enabled = false;
- if ( vld_enabled )
- {
+ if ( vld_enabled )
+ {
#ifdef INCLUDE_VLD
- // only works for debug builds (hard coded into vld.h)
+ // only works for debug builds (hard coded into vld.h)
#ifdef _DEBUG
- // start with Visual Leak Detector turned off
- VLDDisable();
+ // start with Visual Leak Detector turned off
+ VLDDisable();
#endif // _DEBUG
#endif // INCLUDE_VLD
- vld_enabled = false;
- }
- else
- {
+ vld_enabled = false;
+ }
+ else
+ {
#ifdef INCLUDE_VLD
- // only works for debug builds (hard coded into vld.h)
- #ifdef _DEBUG
- // start with Visual Leak Detector turned off
- VLDEnable();
- #endif // _DEBUG
+ // only works for debug builds (hard coded into vld.h)
+ #ifdef _DEBUG
+ // start with Visual Leak Detector turned off
+ VLDEnable();
+ #endif // _DEBUG
#endif // INCLUDE_VLD
- vld_enabled = true;
- };
+ vld_enabled = true;
+ };
}
void handle_god_mode(void*)
{
- gAgent.requestEnterGodMode();
+ gAgent.requestEnterGodMode();
}
void handle_leave_god_mode(void*)
{
- gAgent.requestLeaveGodMode();
+ gAgent.requestLeaveGodMode();
}
void set_god_level(U8 god_level)
{
- U8 old_god_level = gAgent.getGodLevel();
- gAgent.setGodLevel( god_level );
- LLViewerParcelMgr::getInstance()->notifyObservers();
+ U8 old_god_level = gAgent.getGodLevel();
+ gAgent.setGodLevel( god_level );
+ LLViewerParcelMgr::getInstance()->notifyObservers();
- // God mode changes region visibility
- LLWorldMap::getInstance()->reloadItems(true);
+ // God mode changes region visibility
+ LLWorldMap::getInstance()->reloadItems(true);
- // inventory in items may change in god mode
- gObjectList.dirtyAllObjectInventory();
+ // inventory in items may change in god mode
+ gObjectList.dirtyAllObjectInventory();
if(gViewerWindow)
{
gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
LLGridManager::getInstance()->isInProductionGrid());
}
-
+
LLSD args;
- if(god_level > GOD_NOT)
- {
- args["LEVEL"] = llformat("%d",(S32)god_level);
- LLNotificationsUtil::add("EnteringGodMode", args);
- }
- else
- {
- args["LEVEL"] = llformat("%d",(S32)old_god_level);
- LLNotificationsUtil::add("LeavingGodMode", args);
- }
-
- // changing god-level can affect which menus we see
- show_debug_menus();
-
- // changing god-level can invalidate search results
- LLFloaterSearch *search = dynamic_cast<LLFloaterSearch*>(LLFloaterReg::getInstance("search"));
- if (search)
- {
- search->godLevelChanged(god_level);
- }
+ if(god_level > GOD_NOT)
+ {
+ args["LEVEL"] = llformat("%d",(S32)god_level);
+ LLNotificationsUtil::add("EnteringGodMode", args);
+ }
+ else
+ {
+ args["LEVEL"] = llformat("%d",(S32)old_god_level);
+ LLNotificationsUtil::add("LeavingGodMode", args);
+ }
+
+ // changing god-level can affect which menus we see
+ show_debug_menus();
+
+ // changing god-level can invalidate search results
+ LLFloaterSearch *search = dynamic_cast<LLFloaterSearch*>(LLFloaterReg::getInstance("search"));
+ if (search)
+ {
+ search->godLevelChanged(god_level);
+ }
}
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
void handle_toggle_hacked_godmode(void*)
{
- gHackGodmode = !gHackGodmode;
- set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT);
+ gHackGodmode = !gHackGodmode;
+ set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT);
}
BOOL check_toggle_hacked_godmode(void*)
{
- return gHackGodmode;
+ return gHackGodmode;
}
bool enable_toggle_hacked_godmode(void*)
@@ -4230,174 +4267,174 @@ bool enable_toggle_hacked_godmode(void*)
void process_grant_godlike_powers(LLMessageSystem* msg, void**)
{
- LLUUID agent_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- LLUUID session_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
- if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID()))
- {
- U8 god_level;
- msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level);
- set_god_level(god_level);
- }
- else
- {
- LL_WARNS() << "Grant godlike for wrong agent " << agent_id << LL_ENDL;
- }
+ LLUUID agent_id;
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+ LLUUID session_id;
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
+ if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID()))
+ {
+ U8 god_level;
+ msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level);
+ set_god_level(god_level);
+ }
+ else
+ {
+ LL_WARNS() << "Grant godlike for wrong agent " << agent_id << LL_ENDL;
+ }
}
/*
class LLHaveCallingcard : public LLInventoryCollectFunctor
{
public:
- LLHaveCallingcard(const LLUUID& agent_id);
- virtual ~LLHaveCallingcard() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item);
- BOOL isThere() const { return mIsThere;}
+ LLHaveCallingcard(const LLUUID& agent_id);
+ virtual ~LLHaveCallingcard() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+ BOOL isThere() const { return mIsThere;}
protected:
- LLUUID mID;
- BOOL mIsThere;
+ LLUUID mID;
+ BOOL mIsThere;
};
LLHaveCallingcard::LLHaveCallingcard(const LLUUID& agent_id) :
- mID(agent_id),
- mIsThere(FALSE)
+ mID(agent_id),
+ mIsThere(FALSE)
{
}
bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
-{
- if(item)
- {
- if((item->getType() == LLAssetType::AT_CALLINGCARD)
- && (item->getCreatorUUID() == mID))
- {
- mIsThere = TRUE;
- }
- }
- return FALSE;
+ LLInventoryItem* item)
+{
+ if(item)
+ {
+ if((item->getType() == LLAssetType::AT_CALLINGCARD)
+ && (item->getCreatorUUID() == mID))
+ {
+ mIsThere = TRUE;
+ }
+ }
+ return FALSE;
}
*/
BOOL is_agent_mappable(const LLUUID& agent_id)
{
- const LLRelationship* buddy_info = NULL;
- bool is_friend = LLAvatarActions::isFriend(agent_id);
+ const LLRelationship* buddy_info = NULL;
+ bool is_friend = LLAvatarActions::isFriend(agent_id);
- if (is_friend)
- buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
+ if (is_friend)
+ buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
- return (buddy_info &&
- buddy_info->isOnline() &&
- buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
- );
+ return (buddy_info &&
+ buddy_info->isOnline() &&
+ buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
+ );
}
// Enable a menu item when you don't have someone's card.
class LLAvatarEnableAddFriend : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
+ return new_value;
+ }
};
void request_friendship(const LLUUID& dest_id)
{
- LLViewerObject* dest = gObjectList.findObject(dest_id);
- if(dest && dest->isAvatar())
- {
- std::string full_name;
- LLNameValue* nvfirst = dest->getNVPair("FirstName");
- LLNameValue* nvlast = dest->getNVPair("LastName");
- if(nvfirst && nvlast)
- {
- full_name = LLCacheName::buildFullName(
- nvfirst->getString(), nvlast->getString());
- }
- if (!full_name.empty())
- {
- LLAvatarActions::requestFriendshipDialog(dest_id, full_name);
- }
- else
- {
- LLNotificationsUtil::add("CantOfferFriendship");
- }
- }
+ LLViewerObject* dest = gObjectList.findObject(dest_id);
+ if(dest && dest->isAvatar())
+ {
+ std::string full_name;
+ LLNameValue* nvfirst = dest->getNVPair("FirstName");
+ LLNameValue* nvlast = dest->getNVPair("LastName");
+ if(nvfirst && nvlast)
+ {
+ full_name = LLCacheName::buildFullName(
+ nvfirst->getString(), nvlast->getString());
+ }
+ if (!full_name.empty())
+ {
+ LLAvatarActions::requestFriendshipDialog(dest_id, full_name);
+ }
+ else
+ {
+ LLNotificationsUtil::add("CantOfferFriendship");
+ }
+ }
}
class LLEditEnableCustomizeAvatar : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gAgentWearables.areWearablesLoaded();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAgentWearables.areWearablesLoaded();
+ return new_value;
+ }
};
class LLEnableEditShape : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
+ }
};
class LLEnableHoverHeight : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
+ }
};
class LLEnableEditPhysics : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- //return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
- return TRUE;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ //return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
+ return TRUE;
+ }
};
bool is_object_sittable()
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (object && object->getPCode() == LL_PCODE_VOLUME)
- {
- return true;
- }
- else
- {
- return false;
- }
+ if (object && object->getPCode() == LL_PCODE_VOLUME)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
// only works on pie menu
void handle_object_sit(LLViewerObject *object, const LLVector3 &offset)
{
- // get object selection offset
+ // get object selection offset
- if (object && object->getPCode() == LL_PCODE_VOLUME)
- {
+ if (object && object->getPCode() == LL_PCODE_VOLUME)
+ {
- gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
- gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
+ gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
+ gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
- object->getRegion()->sendReliableMessage();
- }
+ object->getRegion()->sendReliableMessage();
+ }
}
void handle_object_sit_or_stand()
@@ -4432,12 +4469,12 @@ void handle_object_sit(const LLUUID& object_id)
void near_sit_down_point(BOOL success, void *)
{
- if (success)
- {
- gAgent.setFlying(FALSE);
- gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
- gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
- }
+ if (success)
+ {
+ gAgent.setFlying(FALSE);
+ gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
+ gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
+ }
}
class LLLandSit : public view_listener_t
@@ -4484,120 +4521,120 @@ void reset_view_final( BOOL proceed );
void handle_reset_view()
{
- if (gAgentCamera.cameraCustomizeAvatar())
- {
- // switching to outfit selector should automagically save any currently edited wearable
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
- }
- gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE);
- reset_view_final( TRUE );
- LLFloaterCamera::resetCameraMode();
+ if (gAgentCamera.cameraCustomizeAvatar())
+ {
+ // switching to outfit selector should automagically save any currently edited wearable
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
+ }
+ gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE);
+ reset_view_final( TRUE );
+ LLFloaterCamera::resetCameraMode();
}
class LLViewResetView : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- handle_reset_view();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_reset_view();
+ return true;
+ }
};
// Note: extra parameters allow this function to be called from dialog.
-void reset_view_final( BOOL proceed )
+void reset_view_final( BOOL proceed )
{
- if( !proceed )
- {
- return;
- }
+ if( !proceed )
+ {
+ return;
+ }
- gAgentCamera.resetView(TRUE, TRUE);
- gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
+ gAgentCamera.resetView(TRUE, TRUE);
+ gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
}
class LLViewLookAtLastChatter : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgentCamera.lookAtLastChat();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgentCamera.lookAtLastChat();
+ return true;
+ }
};
class LLViewMouselook : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (!gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToMouselook();
- }
- else
- {
- gAgentCamera.changeCameraToDefault();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (!gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToMouselook();
+ }
+ else
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+ return true;
+ }
};
class LLViewDefaultUISize : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gSavedSettings.setF32("UIScaleFactor", 1.0f);
- gSavedSettings.setBOOL("UIAutoScale", FALSE);
- gViewerWindow->reshape(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gSavedSettings.setF32("UIScaleFactor", 1.0f);
+ gSavedSettings.setBOOL("UIAutoScale", FALSE);
+ gViewerWindow->reshape(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+ return true;
+ }
};
class LLViewToggleUI : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
- {
- LLNotification::Params params("ConfirmHideUI");
- params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
- LLSD substitutions;
+ bool handleEvent(const LLSD& userdata)
+ {
+ if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+ {
+ LLNotification::Params params("ConfirmHideUI");
+ params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
+ LLSD substitutions;
#if LL_DARWIN
- substitutions["SHORTCUT"] = "Cmd+Shift+U";
+ substitutions["SHORTCUT"] = "Cmd+Shift+U";
#else
- substitutions["SHORTCUT"] = "Ctrl+Shift+U";
+ substitutions["SHORTCUT"] = "Ctrl+Shift+U";
#endif
- params.substitutions = substitutions;
- if (!gSavedSettings.getBOOL("HideUIControls"))
- {
- // hiding, so show notification
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
- }
- return true;
- }
-
- void confirm(const LLSD& notification, const LLSD& response)
- {
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (option == 0) // OK
- {
- gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls"));
- LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls"));
- gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls"));
- }
- }
+ params.substitutions = substitutions;
+ if (!gSavedSettings.getBOOL("HideUIControls"))
+ {
+ // hiding, so show notification
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ }
+ return true;
+ }
+
+ void confirm(const LLSD& notification, const LLSD& response)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (option == 0) // OK
+ {
+ gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls"));
+ LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls"));
+ gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls"));
+ }
+ }
};
void handle_duplicate_in_place(void*)
{
- LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL;
+ LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL;
- LLVector3 offset(0.f, 0.f, 0.f);
- LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);
+ LLVector3 offset(0.f, 0.f, 0.f);
+ LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);
}
@@ -4606,121 +4643,121 @@ void handle_duplicate_in_place(void*)
* No longer able to support viewer side manipulations in this way
*
void god_force_inv_owner_permissive(LLViewerObject* object,
- LLInventoryObject::object_list_t* inventory,
- S32 serial_num,
- void*)
-{
- typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
- item_array_t items;
-
- LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin();
- LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end();
- for ( ; inv_it != inv_end; ++inv_it)
- {
- if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY))
- {
- LLInventoryObject* obj = *inv_it;
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj);
- LLPermissions perm(new_item->getPermissions());
- perm.setMaskBase(PERM_ALL);
- perm.setMaskOwner(PERM_ALL);
- new_item->setPermissions(perm);
- items.push_back(new_item);
- }
- }
- item_array_t::iterator end = items.end();
- item_array_t::iterator it;
- for(it = items.begin(); it != end; ++it)
- {
- // since we have the inventory item in the callback, it should not
- // invalidate iteration through the selection manager.
- object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false);
- }
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void*)
+{
+ typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
+ item_array_t items;
+
+ LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin();
+ LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end();
+ for ( ; inv_it != inv_end; ++inv_it)
+ {
+ if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY))
+ {
+ LLInventoryObject* obj = *inv_it;
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj);
+ LLPermissions perm(new_item->getPermissions());
+ perm.setMaskBase(PERM_ALL);
+ perm.setMaskOwner(PERM_ALL);
+ new_item->setPermissions(perm);
+ items.push_back(new_item);
+ }
+ }
+ item_array_t::iterator end = items.end();
+ item_array_t::iterator it;
+ for(it = items.begin(); it != end; ++it)
+ {
+ // since we have the inventory item in the callback, it should not
+ // invalidate iteration through the selection manager.
+ object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false);
+ }
}
*/
void handle_object_owner_permissive(void*)
{
- // only send this if they're a god.
- if(gAgent.isGodlike())
- {
- // do the objects.
- LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE);
- LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE);
- }
+ // only send this if they're a god.
+ if(gAgent.isGodlike())
+ {
+ // do the objects.
+ LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE);
+ LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE);
+ }
}
void handle_object_owner_self(void*)
{
- // only send this if they're a god.
- if(gAgent.isGodlike())
- {
- LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE);
- }
+ // only send this if they're a god.
+ if(gAgent.isGodlike())
+ {
+ LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE);
+ }
}
// Shortcut to set owner permissions to not editable.
void handle_object_lock(void*)
{
- LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY);
+ LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY);
}
void handle_object_asset_ids(void*)
{
- // only send this if they're a god.
- if (gAgent.isGodlike())
- {
- LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids");
- }
+ // only send this if they're a god.
+ if (gAgent.isGodlike())
+ {
+ LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids");
+ }
}
void handle_force_parcel_owner_to_me(void*)
{
- LLViewerParcelMgr::getInstance()->sendParcelGodForceOwner( gAgent.getID() );
+ LLViewerParcelMgr::getInstance()->sendParcelGodForceOwner( gAgent.getID() );
}
void handle_force_parcel_to_content(void*)
{
- LLViewerParcelMgr::getInstance()->sendParcelGodForceToContent();
+ LLViewerParcelMgr::getInstance()->sendParcelGodForceToContent();
}
void handle_claim_public_land(void*)
{
- if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion())
- {
- LLNotificationsUtil::add("ClaimPublicLand");
- return;
- }
-
- LLVector3d west_south_global;
- LLVector3d east_north_global;
- LLViewerParcelMgr::getInstance()->getSelection(west_south_global, east_north_global);
- LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global);
- LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("GodlikeMessage");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
- msg->nextBlock("MethodData");
- msg->addString("Method", "claimpublicland");
- msg->addUUID("Invoice", LLUUID::null);
- std::string buffer;
- buffer = llformat( "%f", west_south.mV[VX]);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buffer);
- buffer = llformat( "%f", west_south.mV[VY]);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buffer);
- buffer = llformat( "%f", east_north.mV[VX]);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buffer);
- buffer = llformat( "%f", east_north.mV[VY]);
- msg->nextBlock("ParamList");
- msg->addString("Parameter", buffer);
- gAgent.sendReliableMessage();
+ if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion())
+ {
+ LLNotificationsUtil::add("ClaimPublicLand");
+ return;
+ }
+
+ LLVector3d west_south_global;
+ LLVector3d east_north_global;
+ LLViewerParcelMgr::getInstance()->getSelection(west_south_global, east_north_global);
+ LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global);
+ LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("GodlikeMessage");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+ msg->nextBlock("MethodData");
+ msg->addString("Method", "claimpublicland");
+ msg->addUUID("Invoice", LLUUID::null);
+ std::string buffer;
+ buffer = llformat( "%f", west_south.mV[VX]);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buffer);
+ buffer = llformat( "%f", west_south.mV[VY]);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buffer);
+ buffer = llformat( "%f", east_north.mV[VX]);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buffer);
+ buffer = llformat( "%f", east_north.mV[VY]);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buffer);
+ gAgent.sendReliableMessage();
}
@@ -4728,286 +4765,286 @@ void handle_claim_public_land(void*)
// HACK for easily testing new avatar geometry
void handle_god_request_avatar_geometry(void *)
{
- if (gAgent.isGodlike())
- {
- LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", "");
- }
+ if (gAgent.isGodlike())
+ {
+ LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", "");
+ }
}
static bool get_derezzable_objects(
- EDeRezDestination dest,
- std::string& error,
- LLViewerRegion*& first_region,
- std::vector<LLViewerObjectPtr>* derez_objectsp,
- bool only_check = false)
-{
- bool found = false;
-
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- if (derez_objectsp)
- derez_objectsp->reserve(selection->getRootObjectCount());
-
- // Check conditions that we can't deal with, building a list of
- // everything that we'll actually be derezzing.
- for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
- iter != selection->valid_root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- LLViewerRegion* region = object->getRegion();
- if (!first_region)
- {
- first_region = region;
- }
- else
- {
- if(region != first_region)
- {
- // Derez doesn't work at all if the some of the objects
- // are in regions besides the first object selected.
-
- // ...crosses region boundaries
- error = "AcquireErrorObjectSpan";
- break;
- }
- }
- if (object->isAvatar())
- {
- // ...don't acquire avatars
- continue;
- }
-
- // If AssetContainers are being sent back, they will appear as
- // boxes in the owner's inventory.
- if (object->getNVPair("AssetContainer")
- && dest != DRD_RETURN_TO_OWNER)
- {
- // this object is an asset container, derez its contents, not it
- LL_WARNS() << "Attempt to derez deprecated AssetContainer object type not supported." << LL_ENDL;
- /*
- object->requestInventory(container_inventory_arrived,
- (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest));
- */
- continue;
- }
- BOOL can_derez_current = FALSE;
- switch(dest)
- {
- case DRD_TAKE_INTO_AGENT_INVENTORY:
- case DRD_TRASH:
- if (!object->isPermanentEnforced() &&
- ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
- || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE))))
- {
- can_derez_current = TRUE;
- }
- break;
-
- case DRD_RETURN_TO_OWNER:
- if(!object->isAttachment())
- {
- can_derez_current = TRUE;
- }
- break;
-
- default:
- if((node->mPermissions->allowTransferTo(gAgent.getID())
- && object->permCopy())
- || gAgent.isGodlike())
- {
- can_derez_current = TRUE;
- }
- break;
- }
- if(can_derez_current)
- {
- found = true;
-
- if (only_check)
- // one found, no need to traverse to the end
- break;
-
- if (derez_objectsp)
- derez_objectsp->push_back(object);
-
- }
- }
-
- return found;
+ EDeRezDestination dest,
+ std::string& error,
+ LLViewerRegion*& first_region,
+ std::vector<LLViewerObjectPtr>* derez_objectsp,
+ bool only_check = false)
+{
+ bool found = false;
+
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (derez_objectsp)
+ derez_objectsp->reserve(selection->getRootObjectCount());
+
+ // Check conditions that we can't deal with, building a list of
+ // everything that we'll actually be derezzing.
+ for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
+ iter != selection->valid_root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ LLViewerRegion* region = object->getRegion();
+ if (!first_region)
+ {
+ first_region = region;
+ }
+ else
+ {
+ if(region != first_region)
+ {
+ // Derez doesn't work at all if the some of the objects
+ // are in regions besides the first object selected.
+
+ // ...crosses region boundaries
+ error = "AcquireErrorObjectSpan";
+ break;
+ }
+ }
+ if (object->isAvatar())
+ {
+ // ...don't acquire avatars
+ continue;
+ }
+
+ // If AssetContainers are being sent back, they will appear as
+ // boxes in the owner's inventory.
+ if (object->getNVPair("AssetContainer")
+ && dest != DRD_RETURN_TO_OWNER)
+ {
+ // this object is an asset container, derez its contents, not it
+ LL_WARNS() << "Attempt to derez deprecated AssetContainer object type not supported." << LL_ENDL;
+ /*
+ object->requestInventory(container_inventory_arrived,
+ (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest));
+ */
+ continue;
+ }
+ BOOL can_derez_current = FALSE;
+ switch(dest)
+ {
+ case DRD_TAKE_INTO_AGENT_INVENTORY:
+ case DRD_TRASH:
+ if (!object->isPermanentEnforced() &&
+ ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
+ || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE))))
+ {
+ can_derez_current = TRUE;
+ }
+ break;
+
+ case DRD_RETURN_TO_OWNER:
+ if(!object->isAttachment())
+ {
+ can_derez_current = TRUE;
+ }
+ break;
+
+ default:
+ if((node->mPermissions->allowTransferTo(gAgent.getID())
+ && object->permCopy())
+ || gAgent.isGodlike())
+ {
+ can_derez_current = TRUE;
+ }
+ break;
+ }
+ if(can_derez_current)
+ {
+ found = true;
+
+ if (only_check)
+ // one found, no need to traverse to the end
+ break;
+
+ if (derez_objectsp)
+ derez_objectsp->push_back(object);
+
+ }
+ }
+
+ return found;
}
static bool can_derez(EDeRezDestination dest)
{
- LLViewerRegion* first_region = NULL;
- std::string error;
- return get_derezzable_objects(dest, error, first_region, NULL, true);
+ LLViewerRegion* first_region = NULL;
+ std::string error;
+ return get_derezzable_objects(dest, error, first_region, NULL, true);
}
static void derez_objects(
- EDeRezDestination dest,
- const LLUUID& dest_id,
- LLViewerRegion*& first_region,
- std::string& error,
- std::vector<LLViewerObjectPtr>* objectsp)
-{
- std::vector<LLViewerObjectPtr> derez_objects;
-
- if (!objectsp) // if objects to derez not specified
- {
- // get them from selection
- if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false))
- {
- LL_WARNS() << "No objects to derez" << LL_ENDL;
- return;
- }
-
- objectsp = &derez_objects;
- }
-
-
- if(gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToDefault();
- }
-
- // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
- // root. I lopped off a few (33) to provide a bit
- // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
- // This gives us a maximum of 63500 root objects - which should
- // satisfy anybody.
- const S32 MAX_ROOTS_PER_PACKET = 250;
- const S32 MAX_PACKET_COUNT = 254;
- F32 packets = ceil((F32)objectsp->size() / (F32)MAX_ROOTS_PER_PACKET);
- if(packets > (F32)MAX_PACKET_COUNT)
- {
- error = "AcquireErrorTooManyObjects";
- }
-
- if(error.empty() && objectsp->size() > 0)
- {
- U8 d = (U8)dest;
- LLUUID tid;
- tid.generate();
- U8 packet_count = (U8)packets;
- S32 object_index = 0;
- S32 objects_in_packet = 0;
- LLMessageSystem* msg = gMessageSystem;
- for(U8 packet_number = 0;
- packet_number < packet_count;
- ++packet_number)
- {
- msg->newMessageFast(_PREHASH_DeRezObject);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_AgentBlock);
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- msg->addU8Fast(_PREHASH_Destination, d);
- msg->addUUIDFast(_PREHASH_DestinationID, dest_id);
- msg->addUUIDFast(_PREHASH_TransactionID, tid);
- msg->addU8Fast(_PREHASH_PacketCount, packet_count);
- msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
- objects_in_packet = 0;
- while((object_index < objectsp->size())
- && (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
-
- {
- LLViewerObject* object = objectsp->at(object_index++);
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
- // VEFFECT: DerezObject
- LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
- effectp->setPositionGlobal(object->getPositionGlobal());
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- }
- msg->sendReliable(first_region->getHost());
- }
- make_ui_sound("UISndObjectRezOut");
-
- // Busy count decremented by inventory update, so only increment
- // if will be causing an update.
- if (dest != DRD_RETURN_TO_OWNER)
- {
- gViewerWindow->getWindow()->incBusyCount();
- }
- }
- else if(!error.empty())
- {
- LLNotificationsUtil::add(error);
- }
+ EDeRezDestination dest,
+ const LLUUID& dest_id,
+ LLViewerRegion*& first_region,
+ std::string& error,
+ std::vector<LLViewerObjectPtr>* objectsp)
+{
+ std::vector<LLViewerObjectPtr> derez_objects;
+
+ if (!objectsp) // if objects to derez not specified
+ {
+ // get them from selection
+ if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false))
+ {
+ LL_WARNS() << "No objects to derez" << LL_ENDL;
+ return;
+ }
+
+ objectsp = &derez_objects;
+ }
+
+
+ if(gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+
+ // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
+ // root. I lopped off a few (33) to provide a bit
+ // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
+ // This gives us a maximum of 63500 root objects - which should
+ // satisfy anybody.
+ const S32 MAX_ROOTS_PER_PACKET = 250;
+ const S32 MAX_PACKET_COUNT = 254;
+ F32 packets = ceil((F32)objectsp->size() / (F32)MAX_ROOTS_PER_PACKET);
+ if(packets > (F32)MAX_PACKET_COUNT)
+ {
+ error = "AcquireErrorTooManyObjects";
+ }
+
+ if(error.empty() && objectsp->size() > 0)
+ {
+ U8 d = (U8)dest;
+ LLUUID tid;
+ tid.generate();
+ U8 packet_count = (U8)packets;
+ S32 object_index = 0;
+ S32 objects_in_packet = 0;
+ LLMessageSystem* msg = gMessageSystem;
+ for(U8 packet_number = 0;
+ packet_number < packet_count;
+ ++packet_number)
+ {
+ msg->newMessageFast(_PREHASH_DeRezObject);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_AgentBlock);
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+ msg->addU8Fast(_PREHASH_Destination, d);
+ msg->addUUIDFast(_PREHASH_DestinationID, dest_id);
+ msg->addUUIDFast(_PREHASH_TransactionID, tid);
+ msg->addU8Fast(_PREHASH_PacketCount, packet_count);
+ msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
+ objects_in_packet = 0;
+ while((object_index < objectsp->size())
+ && (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
+
+ {
+ LLViewerObject* object = objectsp->at(object_index++);
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
+ // VEFFECT: DerezObject
+ LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
+ effectp->setPositionGlobal(object->getPositionGlobal());
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
+ msg->sendReliable(first_region->getHost());
+ }
+ make_ui_sound("UISndObjectRezOut");
+
+ // Busy count decremented by inventory update, so only increment
+ // if will be causing an update.
+ if (dest != DRD_RETURN_TO_OWNER)
+ {
+ gViewerWindow->getWindow()->incBusyCount();
+ }
+ }
+ else if(!error.empty())
+ {
+ LLNotificationsUtil::add(error);
+ }
}
static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
{
- LLViewerRegion* first_region = NULL;
- std::string error;
- derez_objects(dest, dest_id, first_region, error, NULL);
+ LLViewerRegion* first_region = NULL;
+ std::string error;
+ derez_objects(dest, dest_id, first_region, error, NULL);
}
void handle_take_copy()
{
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
- const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
- derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
+ const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
+ derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
}
void handle_link_objects()
{
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- LLFloaterReg::toggleInstanceOrBringToFront("places");
- }
- else
- {
- LLSelectMgr::getInstance()->linkObjects();
- }
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("places");
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->linkObjects();
+ }
}
// You can return an object to its owner if it is on your land.
class LLObjectReturn : public view_listener_t
{
public:
- LLObjectReturn() : mFirstRegion(NULL) {}
+ LLObjectReturn() : mFirstRegion(NULL) {}
private:
- bool handleEvent(const LLSD& userdata)
- {
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
+
+ mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
- mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+ // Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
+ get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects);
- // Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
- get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects);
+ LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2));
+ return true;
+ }
- LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2));
- return true;
- }
+ bool onReturnToOwner(const LLSD& notification, const LLSD& response)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ // Ignore category ID for this derez destination.
+ derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects);
+ }
- bool onReturnToOwner(const LLSD& notification, const LLSD& response)
- {
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (0 == option)
- {
- // Ignore category ID for this derez destination.
- derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects);
- }
+ mReturnableObjects.clear();
+ mError.clear();
+ mFirstRegion = NULL;
- mReturnableObjects.clear();
- mError.clear();
- mFirstRegion = NULL;
+ // drop reference to current selection
+ mObjectSelection = NULL;
+ return false;
+ }
- // drop reference to current selection
- mObjectSelection = NULL;
- return false;
- }
-
- LLObjectSelectionHandle mObjectSelection;
+ LLObjectSelectionHandle mObjectSelection;
- std::vector<LLViewerObjectPtr> mReturnableObjects;
- std::string mError;
- LLViewerRegion* mFirstRegion;
+ std::vector<LLViewerObjectPtr> mReturnableObjects;
+ std::string mError;
+ LLViewerRegion* mFirstRegion;
};
@@ -5015,187 +5052,187 @@ private:
// over land you own.
class LLObjectEnableReturn : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- // Do not enable if nothing selected
- return false;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ // Do not enable if nothing selected
+ return false;
+ }
#ifdef HACKED_GODLIKE_VIEWER
- bool new_value = true;
+ bool new_value = true;
#else
- bool new_value = false;
- if (gAgent.isGodlike())
- {
- new_value = true;
- }
- else
- {
- new_value = can_derez(DRD_RETURN_TO_OWNER);
- }
+ bool new_value = false;
+ if (gAgent.isGodlike())
+ {
+ new_value = true;
+ }
+ else
+ {
+ new_value = can_derez(DRD_RETURN_TO_OWNER);
+ }
#endif
- return new_value;
- }
+ return new_value;
+ }
};
void force_take_copy(void*)
{
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
- const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
- derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
+ const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
+ derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
}
void handle_take()
{
- // we want to use the folder this was derezzed from if it's
- // available. Otherwise, derez to the normal place.
- if(LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- return;
- }
-
- BOOL you_own_everything = TRUE;
- BOOL locked_but_takeable_object = FALSE;
- LLUUID category_id;
-
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if(object)
- {
- if(!object->permYouOwner())
- {
- you_own_everything = FALSE;
- }
-
- if(!object->permMove())
- {
- locked_but_takeable_object = TRUE;
- }
- }
- if(node->mFolderID.notNull())
- {
- if(category_id.isNull())
- {
- category_id = node->mFolderID;
- }
- else if(category_id != node->mFolderID)
- {
- // we have found two potential destinations. break out
- // now and send to the default location.
- category_id.setNull();
- break;
- }
- }
- }
- if(category_id.notNull())
- {
- // there is an unambiguous destination. See if this agent has
- // such a location and it is not in the trash or library
- if(!gInventory.getCategory(category_id))
- {
- // nope, set to NULL.
- category_id.setNull();
- }
- if(category_id.notNull())
- {
- // check trash
- const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
- {
- category_id.setNull();
- }
-
- // check library
- if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID()))
- {
- category_id.setNull();
- }
-
- // check inbox
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
- if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id))
- {
- category_id.setNull();
- }
- }
- }
- if(category_id.isNull())
- {
- category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
- }
- LLSD payload;
- payload["folder_id"] = category_id;
-
- LLNotification::Params params("ConfirmObjectTakeLock");
- params.payload(payload);
- // MAINT-290
- // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
- // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
- params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection()));
-
- if(locked_but_takeable_object ||
- !you_own_everything)
- {
- if(locked_but_takeable_object && you_own_everything)
- {
- params.name("ConfirmObjectTakeLock");
- }
- else if(!locked_but_takeable_object && !you_own_everything)
- {
- params.name("ConfirmObjectTakeNoOwn");
- }
- else
- {
- params.name("ConfirmObjectTakeLockNoOwn");
- }
-
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 0);
- }
+ // we want to use the folder this was derezzed from if it's
+ // available. Otherwise, derez to the normal place.
+ if(LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ return;
+ }
+
+ BOOL you_own_everything = TRUE;
+ BOOL locked_but_takeable_object = FALSE;
+ LLUUID category_id;
+
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if(object)
+ {
+ if(!object->permYouOwner())
+ {
+ you_own_everything = FALSE;
+ }
+
+ if(!object->permMove())
+ {
+ locked_but_takeable_object = TRUE;
+ }
+ }
+ if(node->mFolderID.notNull())
+ {
+ if(category_id.isNull())
+ {
+ category_id = node->mFolderID;
+ }
+ else if(category_id != node->mFolderID)
+ {
+ // we have found two potential destinations. break out
+ // now and send to the default location.
+ category_id.setNull();
+ break;
+ }
+ }
+ }
+ if(category_id.notNull())
+ {
+ // there is an unambiguous destination. See if this agent has
+ // such a location and it is not in the trash or library
+ if(!gInventory.getCategory(category_id))
+ {
+ // nope, set to NULL.
+ category_id.setNull();
+ }
+ if(category_id.notNull())
+ {
+ // check trash
+ const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
+ {
+ category_id.setNull();
+ }
+
+ // check library
+ if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID()))
+ {
+ category_id.setNull();
+ }
+
+ // check inbox
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+ if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id))
+ {
+ category_id.setNull();
+ }
+ }
+ }
+ if(category_id.isNull())
+ {
+ category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
+ }
+ LLSD payload;
+ payload["folder_id"] = category_id;
+
+ LLNotification::Params params("ConfirmObjectTakeLock");
+ params.payload(payload);
+ // MAINT-290
+ // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
+ // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
+ params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection()));
+
+ if(locked_but_takeable_object ||
+ !you_own_everything)
+ {
+ if(locked_but_takeable_object && you_own_everything)
+ {
+ params.name("ConfirmObjectTakeLock");
+ }
+ else if(!locked_but_takeable_object && !you_own_everything)
+ {
+ params.name("ConfirmObjectTakeNoOwn");
+ }
+ else
+ {
+ params.name("ConfirmObjectTakeLockNoOwn");
+ }
+
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
void handle_object_show_inspector()
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* objectp = selection->getFirstRootObject(TRUE);
- if (!objectp)
- {
- return;
- }
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* objectp = selection->getFirstRootObject(TRUE);
+ if (!objectp)
+ {
+ return;
+ }
- LLSD params;
- params["object_id"] = objectp->getID();
- LLFloaterReg::showInstance("inspect_object", params);
+ LLSD params;
+ params["object_id"] = objectp->getID();
+ LLFloaterReg::showInstance("inspect_object", params);
}
void handle_avatar_show_inspector()
{
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLSD params;
- params["avatar_id"] = avatar->getID();
- LLFloaterReg::showInstance("inspect_avatar", params);
- }
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLSD params;
+ params["avatar_id"] = avatar->getID();
+ LLFloaterReg::showInstance("inspect_avatar", params);
+ }
}
bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if(enable_take() && (option == 0))
- {
- derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if(enable_take() && (option == 0))
+ {
+ derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
+ }
+ return false;
}
// You can take an item when it is public and transferrable, or when
@@ -5203,101 +5240,101 @@ bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelect
// one item selected can be copied to inventory.
BOOL enable_take()
{
- if (sitting_on_selection())
- {
- return FALSE;
- }
-
- for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (object->isAvatar())
- {
- // ...don't acquire avatars
- continue;
- }
+ if (sitting_on_selection())
+ {
+ return FALSE;
+ }
+
+ for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if (object->isAvatar())
+ {
+ // ...don't acquire avatars
+ continue;
+ }
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike())
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- if(!object->isPermanentEnforced() &&
- ((node->mPermissions->allowTransferTo(gAgent.getID())
- && object->permModify())
- || (node->mPermissions->getOwner() == gAgent.getID())))
- {
- return !object->isAttachment();
- }
+ if(!object->isPermanentEnforced() &&
+ ((node->mPermissions->allowTransferTo(gAgent.getID())
+ && object->permModify())
+ || (node->mPermissions->getOwner() == gAgent.getID())))
+ {
+ return !object->isAttachment();
+ }
#endif
- }
- return FALSE;
+ }
+ return FALSE;
}
void handle_buy_or_take()
{
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- return;
- }
-
- if (is_selection_buy_not_take())
- {
- S32 total_price = selection_price();
-
- if (total_price <= gStatusBar->getBalance() || total_price == 0)
- {
- handle_buy();
- }
- else
- {
- LLStringUtil::format_map_t args;
- args["AMOUNT"] = llformat("%d", total_price);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );
- }
- }
- else
- {
- handle_take();
- }
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ return;
+ }
+
+ if (is_selection_buy_not_take())
+ {
+ S32 total_price = selection_price();
+
+ if (total_price <= gStatusBar->getBalance() || total_price == 0)
+ {
+ handle_buy();
+ }
+ else
+ {
+ LLStringUtil::format_map_t args;
+ args["AMOUNT"] = llformat("%d", total_price);
+ LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );
+ }
+ }
+ else
+ {
+ handle_take();
+ }
}
bool visible_buy_object()
{
- return is_selection_buy_not_take() && enable_buy_object();
+ return is_selection_buy_not_take() && enable_buy_object();
}
bool visible_take_object()
{
- return !is_selection_buy_not_take() && enable_take();
+ return !is_selection_buy_not_take() && enable_take();
}
bool tools_visible_buy_object()
{
- return is_selection_buy_not_take();
+ return is_selection_buy_not_take();
}
bool tools_visible_take_object()
{
- return !is_selection_buy_not_take();
+ return !is_selection_buy_not_take();
}
class LLToolsEnableBuyOrTake : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool is_buy = is_selection_buy_not_take();
- bool new_value = is_buy ? enable_buy_object() : enable_take();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool is_buy = is_selection_buy_not_take();
+ bool new_value = is_buy ? enable_buy_object() : enable_take();
+ return new_value;
+ }
};
// This is a small helper function to determine if we have a buy or a
@@ -5318,255 +5355,255 @@ class LLToolsEnableBuyOrTake : public view_listener_t
// FALSE if selection is a 'take'
BOOL is_selection_buy_not_take()
{
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
- {
- // you do not own the object and it is for sale, thus,
- // it's a buy
- return TRUE;
- }
- }
- return FALSE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
+ {
+ // you do not own the object and it is for sale, thus,
+ // it's a buy
+ return TRUE;
+ }
+ }
+ return FALSE;
}
S32 selection_price()
{
- S32 total_price = 0;
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
- {
- // you do not own the object and it is for sale.
- // Add its price.
- total_price += node->mSaleInfo.getSalePrice();
- }
- }
-
- return total_price;
+ S32 total_price = 0;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
+ {
+ // you do not own the object and it is for sale.
+ // Add its price.
+ total_price += node->mSaleInfo.getSalePrice();
+ }
+ }
+
+ return total_price;
}
/*
bool callback_show_buy_currency(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (0 == option)
- {
- LL_INFOS() << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << LL_ENDL;
- LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL"));
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LL_INFOS() << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << LL_ENDL;
+ LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL"));
+ }
+ return false;
}
*/
void show_buy_currency(const char* extra)
{
- // Don't show currency web page for branded clients.
+ // Don't show currency web page for branded clients.
/*
- std::ostringstream mesg;
- if (extra != NULL)
- {
- mesg << extra << "\n \n";
- }
- mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?";
+ std::ostringstream mesg;
+ if (extra != NULL)
+ {
+ mesg << extra << "\n \n";
+ }
+ mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?";
*/
- LLSD args;
- if (extra != NULL)
- {
- args["EXTRA"] = extra;
- }
- LLNotificationsUtil::add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency);
+ LLSD args;
+ if (extra != NULL)
+ {
+ args["EXTRA"] = extra;
+ }
+ LLNotificationsUtil::add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency);
}
void handle_buy()
{
- if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
- LLSaleInfo sale_info;
- BOOL valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
- if (!valid) return;
+ LLSaleInfo sale_info;
+ BOOL valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
+ if (!valid) return;
- S32 price = sale_info.getSalePrice();
+ S32 price = sale_info.getSalePrice();
+
+ if (price > 0 && price > gStatusBar->getBalance())
+ {
+ LLStringUtil::format_map_t args;
+ args["AMOUNT"] = llformat("%d", price);
+ LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price );
+ return;
+ }
- if (price > 0 && price > gStatusBar->getBalance())
- {
- LLStringUtil::format_map_t args;
- args["AMOUNT"] = llformat("%d", price);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price );
- return;
- }
-
- if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS)
- {
- handle_buy_contents(sale_info);
- }
- else
- {
- handle_buy_object(sale_info);
- }
+ if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS)
+ {
+ handle_buy_contents(sale_info);
+ }
+ else
+ {
+ handle_buy_object(sale_info);
+ }
}
bool anyone_copy_selection(LLSelectNode* nodep)
{
- bool perm_copy = (bool)(nodep->getObject()->permCopy());
- bool all_copy = (bool)(nodep->mPermissions->getMaskEveryone() & PERM_COPY);
- return perm_copy && all_copy;
+ bool perm_copy = (bool)(nodep->getObject()->permCopy());
+ bool all_copy = (bool)(nodep->mPermissions->getMaskEveryone() & PERM_COPY);
+ return perm_copy && all_copy;
}
bool for_sale_selection(LLSelectNode* nodep)
{
- return nodep->mSaleInfo.isForSale()
- && nodep->mPermissions->getMaskOwner() & PERM_TRANSFER
- && (nodep->mPermissions->getMaskOwner() & PERM_COPY
- || nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY);
+ return nodep->mSaleInfo.isForSale()
+ && nodep->mPermissions->getMaskOwner() & PERM_TRANSFER
+ && (nodep->mPermissions->getMaskOwner() & PERM_COPY
+ || nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY);
}
BOOL sitting_on_selection()
{
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (!node)
- {
- return FALSE;
- }
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (!node)
+ {
+ return FALSE;
+ }
- if (!node->mValid)
- {
- return FALSE;
- }
+ if (!node->mValid)
+ {
+ return FALSE;
+ }
- LLViewerObject* root_object = node->getObject();
- if (!root_object)
- {
- return FALSE;
- }
+ LLViewerObject* root_object = node->getObject();
+ if (!root_object)
+ {
+ return FALSE;
+ }
- // Need to determine if avatar is sitting on this object
- if (!isAgentAvatarValid()) return FALSE;
+ // Need to determine if avatar is sitting on this object
+ if (!isAgentAvatarValid()) return FALSE;
- return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object);
+ return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object);
}
class LLToolsSaveToObjectInventory : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
- {
- // *TODO: check to see if the fromtaskid object exists.
- derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
+ {
+ // *TODO: check to see if the fromtaskid object exists.
+ derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
+ }
+ return true;
+ }
};
class LLToolsEnablePathfinding : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
+ }
};
class LLToolsEnablePathfindingView : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled();
+ }
};
class LLToolsDoPathfindingRebakeRegion : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL);
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL);
- if (hasPathfinding)
- {
- LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
- }
+ if (hasPathfinding)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
+ }
- return hasPathfinding;
- }
+ return hasPathfinding;
+ }
};
class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool returnValue = false;
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool returnValue = false;
if (LLNavigationBar::instanceExists())
{
returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
}
- return returnValue;
- }
+ return returnValue;
+ }
};
// Round the position of all root objects to the grid
class LLToolsSnapObjectXY : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
-
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if (obj->permModify())
- {
- LLVector3d pos_global = obj->getPositionGlobal();
- F64 round_x = fmod(pos_global.mdV[VX], snap_size);
- if (round_x < snap_size * 0.5)
- {
- // closer to round down
- pos_global.mdV[VX] -= round_x;
- }
- else
- {
- // closer to round up
- pos_global.mdV[VX] -= round_x;
- pos_global.mdV[VX] += snap_size;
- }
-
- F64 round_y = fmod(pos_global.mdV[VY], snap_size);
- if (round_y < snap_size * 0.5)
- {
- pos_global.mdV[VY] -= round_y;
- }
- else
- {
- pos_global.mdV[VY] -= round_y;
- pos_global.mdV[VY] += snap_size;
- }
-
- obj->setPositionGlobal(pos_global, FALSE);
- }
- }
- LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
+
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (obj->permModify())
+ {
+ LLVector3d pos_global = obj->getPositionGlobal();
+ F64 round_x = fmod(pos_global.mdV[VX], snap_size);
+ if (round_x < snap_size * 0.5)
+ {
+ // closer to round down
+ pos_global.mdV[VX] -= round_x;
+ }
+ else
+ {
+ // closer to round up
+ pos_global.mdV[VX] -= round_x;
+ pos_global.mdV[VX] += snap_size;
+ }
+
+ F64 round_y = fmod(pos_global.mdV[VY], snap_size);
+ if (round_y < snap_size * 0.5)
+ {
+ pos_global.mdV[VY] -= round_y;
+ }
+ else
+ {
+ pos_global.mdV[VY] -= round_y;
+ pos_global.mdV[VY] += snap_size;
+ }
+
+ obj->setPositionGlobal(pos_global, FALSE);
+ }
+ }
+ LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
+ return true;
+ }
};
// Determine if the option to cycle between linked prims is shown
class LLToolsEnableSelectNextPart : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
bool new_value = (!LLSelectMgr::getInstance()->getSelection()->isEmpty()
&& (gSavedSettings.getBOOL("EditLinkedParts")
|| LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()));
- return new_value;
- }
+ return new_value;
+ }
};
// Cycle selection through linked children or/and faces in selected object.
@@ -5641,61 +5678,61 @@ class LLToolsSelectNextPartFace : public view_listener_t
}
}
- S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
- if (cycle_linked && object_count && restart_face_on_part)
- {
- LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if (selected && selected->getRootEdit())
- {
- LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren();
- children.push_front(selected->getRootEdit()); // need root in the list too
-
- for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter)
- {
- if ((*iter)->isSelected())
- {
- if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include
- {
- to_select = *iter;
- if (fwd)
- {
- // stop searching if going forward; repeat to get last hit if backward
- break;
- }
- }
- else if ((object_count == 1) || (ifwd || iprev)) // single selection or include
- {
- if (fwd || ifwd)
- {
- ++iter;
- while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected())))
- {
- ++iter; // skip sitting avatars and selected if include
- }
- }
- else // backward
- {
- iter = (iter == children.begin() ? children.end() : iter);
- --iter;
- while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected())))
- {
- --iter; // skip sitting avatars and selected if include
- }
- }
- iter = (iter == children.end() ? children.begin() : iter);
- to_select = *iter;
- break;
- }
- }
- }
- }
- }
+ S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (cycle_linked && object_count && restart_face_on_part)
+ {
+ LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ if (selected && selected->getRootEdit())
+ {
+ LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren();
+ children.push_front(selected->getRootEdit()); // need root in the list too
+
+ for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter)
+ {
+ if ((*iter)->isSelected())
+ {
+ if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include
+ {
+ to_select = *iter;
+ if (fwd)
+ {
+ // stop searching if going forward; repeat to get last hit if backward
+ break;
+ }
+ }
+ else if ((object_count == 1) || (ifwd || iprev)) // single selection or include
+ {
+ if (fwd || ifwd)
+ {
+ ++iter;
+ while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected())))
+ {
+ ++iter; // skip sitting avatars and selected if include
+ }
+ }
+ else // backward
+ {
+ iter = (iter == children.begin() ? children.end() : iter);
+ --iter;
+ while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected())))
+ {
+ --iter; // skip sitting avatars and selected if include
+ }
+ }
+ iter = (iter == children.end() ? children.begin() : iter);
+ to_select = *iter;
+ break;
+ }
+ }
+ }
+ }
+ }
if (to_select)
{
if (gFocusMgr.childHasKeyboardFocus(gFloaterTools))
{
- gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes
+ gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes
}
if (fwd || prev)
{
@@ -5723,455 +5760,455 @@ class LLToolsSelectNextPartFace : public view_listener_t
}
return true;
}
- return true;
- }
+ return true;
+ }
};
class LLToolsStopAllAnimations : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.stopCurrentAnimations();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgent.stopCurrentAnimations();
+ return true;
+ }
};
class LLToolsReleaseKeys : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.forceReleaseControls();
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgent.forceReleaseControls();
- return true;
- }
+ return true;
+ }
};
class LLToolsEnableReleaseKeys : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gAgent.anyControlGrabbed();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.anyControlGrabbed();
+ }
};
class LLEditEnableCut : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut();
+ return new_value;
+ }
};
class LLEditCut : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler )
- {
- LLEditMenuHandler::gEditMenuHandler->cut();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler )
+ {
+ LLEditMenuHandler::gEditMenuHandler->cut();
+ }
+ return true;
+ }
};
class LLEditEnableCopy : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy();
+ return new_value;
+ }
};
class LLEditCopy : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler )
- {
- LLEditMenuHandler::gEditMenuHandler->copy();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler )
+ {
+ LLEditMenuHandler::gEditMenuHandler->copy();
+ }
+ return true;
+ }
};
class LLEditEnablePaste : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste();
+ return new_value;
+ }
};
class LLEditPaste : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler )
- {
- LLEditMenuHandler::gEditMenuHandler->paste();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler )
+ {
+ LLEditMenuHandler::gEditMenuHandler->paste();
+ }
+ return true;
+ }
};
class LLEditEnableDelete : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete();
+ return new_value;
+ }
};
class LLEditDelete : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // If a text field can do a deletion, it gets precedence over deleting
- // an object in the world.
- if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete())
- {
- LLEditMenuHandler::gEditMenuHandler->doDelete();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // If a text field can do a deletion, it gets precedence over deleting
+ // an object in the world.
+ if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete())
+ {
+ LLEditMenuHandler::gEditMenuHandler->doDelete();
+ }
- // and close any pie/context menus when done
- gMenuHolder->hideMenus();
+ // and close any pie/context menus when done
+ gMenuHolder->hideMenus();
- // When deleting an object we may not actually be done
- // Keep selection so we know what to delete when confirmation is needed about the delete
- gMenuObject->hide();
- return true;
- }
+ // When deleting an object we may not actually be done
+ // Keep selection so we know what to delete when confirmation is needed about the delete
+ gMenuObject->hide();
+ return true;
+ }
};
void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param)
{
- const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
- LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
- {
- return;
- }
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return;
+ }
- U32 index = 0;
- if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
- {
- return;
- }
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return;
+ }
- spellcheck_handler->replaceWithSuggestion(index);
+ spellcheck_handler->replaceWithSuggestion(index);
}
bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param)
{
- LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
- const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
- const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
- {
- return false;
- }
+ LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
+ const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return false;
+ }
- U32 index = 0;
- if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
- {
- return false;
- }
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return false;
+ }
- item->setLabel(spellcheck_handler->getSuggestion(index));
- return true;
+ item->setLabel(spellcheck_handler->getSuggestion(index));
+ return true;
}
void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
{
- const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
- LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
- {
- spellcheck_handler->addToDictionary();
- }
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
+ {
+ spellcheck_handler->addToDictionary();
+ }
}
bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
{
- const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
- const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
}
void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
{
- const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
- LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
- {
- spellcheck_handler->addToIgnore();
- }
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
+ {
+ spellcheck_handler->addToIgnore();
+ }
}
bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
{
- const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
- const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
- return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
}
bool enable_object_return()
{
- return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() &&
- (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER)));
+ return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() &&
+ (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER)));
}
bool enable_object_delete()
{
- bool new_value =
+ bool new_value =
#ifdef HACKED_GODLIKE_VIEWER
- TRUE;
+ TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- (!LLGridManager::getInstance()->isInProductionGrid()
+ (!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike()) ||
# endif
- LLSelectMgr::getInstance()->canDoDelete();
+ LLSelectMgr::getInstance()->canDoDelete();
#endif
- return new_value;
+ return new_value;
}
class LLObjectsReturnPackage
{
public:
- LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {};
- ~LLObjectsReturnPackage()
- {
- mObjectSelection.clear();
- mReturnableObjects.clear();
- mError.clear();
- mFirstRegion = NULL;
- };
+ LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {};
+ ~LLObjectsReturnPackage()
+ {
+ mObjectSelection.clear();
+ mReturnableObjects.clear();
+ mError.clear();
+ mFirstRegion = NULL;
+ };
- LLObjectSelectionHandle mObjectSelection;
- std::vector<LLViewerObjectPtr> mReturnableObjects;
- std::string mError;
- LLViewerRegion *mFirstRegion;
+ LLObjectSelectionHandle mObjectSelection;
+ std::vector<LLViewerObjectPtr> mReturnableObjects;
+ std::string mError;
+ LLViewerRegion *mFirstRegion;
};
static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response)
{
- if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
- {
- // Ignore category ID for this derez destination.
- derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects);
- }
+ if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
+ {
+ // Ignore category ID for this derez destination.
+ derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects);
+ }
- delete objectsReturnPackage;
+ delete objectsReturnPackage;
}
void handle_object_return()
{
- if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage();
- objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+ if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage();
+ objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
- // Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
- get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects);
+ // Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
+ get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects);
- LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2));
- }
+ LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2));
+ }
}
void handle_object_delete()
{
- if (LLSelectMgr::getInstance())
- {
- LLSelectMgr::getInstance()->doDelete();
- }
+ if (LLSelectMgr::getInstance())
+ {
+ LLSelectMgr::getInstance()->doDelete();
+ }
- // and close any pie/context menus when done
- gMenuHolder->hideMenus();
+ // and close any pie/context menus when done
+ gMenuHolder->hideMenus();
- // When deleting an object we may not actually be done
- // Keep selection so we know what to delete when confirmation is needed about the delete
- gMenuObject->hide();
- return;
+ // When deleting an object we may not actually be done
+ // Keep selection so we know what to delete when confirmation is needed about the delete
+ gMenuObject->hide();
+ return;
}
void handle_force_delete(void*)
{
- LLSelectMgr::getInstance()->selectForceDelete();
+ LLSelectMgr::getInstance()->selectForceDelete();
}
class LLViewEnableJoystickFlycam : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled"));
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled"));
+ return new_value;
+ }
};
class LLViewEnableLastChatter : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // *TODO: add check that last chatter is in range
- bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull());
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // *TODO: add check that last chatter is in range
+ bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull());
+ return new_value;
+ }
};
class LLEditEnableDeselect : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect();
+ return new_value;
+ }
};
class LLEditDeselect : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler )
- {
- LLEditMenuHandler::gEditMenuHandler->deselect();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler )
+ {
+ LLEditMenuHandler::gEditMenuHandler->deselect();
+ }
+ return true;
+ }
};
class LLEditEnableSelectAll : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll();
+ return new_value;
+ }
};
class LLEditSelectAll : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler )
- {
- LLEditMenuHandler::gEditMenuHandler->selectAll();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler )
+ {
+ LLEditMenuHandler::gEditMenuHandler->selectAll();
+ }
+ return true;
+ }
};
class LLEditEnableUndo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo();
+ return new_value;
+ }
};
class LLEditUndo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() )
- {
- LLEditMenuHandler::gEditMenuHandler->undo();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() )
+ {
+ LLEditMenuHandler::gEditMenuHandler->undo();
+ }
+ return true;
+ }
};
class LLEditEnableRedo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo();
+ return new_value;
+ }
};
class LLEditRedo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() )
- {
- LLEditMenuHandler::gEditMenuHandler->redo();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() )
+ {
+ LLEditMenuHandler::gEditMenuHandler->redo();
+ }
+ return true;
+ }
};
void print_object_info(void*)
{
- LLSelectMgr::getInstance()->selectionDump();
+ LLSelectMgr::getInstance()->selectionDump();
}
void print_agent_nvpairs(void*)
{
- LLViewerObject *objectp;
+ LLViewerObject *objectp;
- LL_INFOS() << "Agent Name Value Pairs" << LL_ENDL;
+ LL_INFOS() << "Agent Name Value Pairs" << LL_ENDL;
- objectp = gObjectList.findObject(gAgentID);
- if (objectp)
- {
- objectp->printNameValuePairs();
- }
- else
- {
- LL_INFOS() << "Can't find agent object" << LL_ENDL;
- }
+ objectp = gObjectList.findObject(gAgentID);
+ if (objectp)
+ {
+ objectp->printNameValuePairs();
+ }
+ else
+ {
+ LL_INFOS() << "Can't find agent object" << LL_ENDL;
+ }
- LL_INFOS() << "Camera at " << gAgentCamera.getCameraPositionGlobal() << LL_ENDL;
+ LL_INFOS() << "Camera at " << gAgentCamera.getCameraPositionGlobal() << LL_ENDL;
}
void show_debug_menus()
{
- // this might get called at login screen where there is no menu so only toggle it if one exists
- if ( gMenuBarView )
- {
- BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
- BOOL qamode = gSavedSettings.getBOOL("QAMode");
-
- gMenuBarView->setItemVisible("Advanced", debug);
-// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden
-
- gMenuBarView->setItemVisible("Debug", qamode);
- gMenuBarView->setItemEnabled("Debug", qamode);
-
- gMenuBarView->setItemVisible("Develop", qamode);
- gMenuBarView->setItemEnabled("Develop", qamode);
-
- // Server ('Admin') menu hidden when not in godmode.
- const bool show_server_menu = (gAgent.getGodLevel() > GOD_NOT || (debug && gAgent.getAdminOverride()));
- gMenuBarView->setItemVisible("Admin", show_server_menu);
- gMenuBarView->setItemEnabled("Admin", show_server_menu);
- }
- if (gLoginMenuBarView)
- {
- BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
- gLoginMenuBarView->setItemVisible("Debug", debug);
- gLoginMenuBarView->setItemEnabled("Debug", debug);
- }
+ // this might get called at login screen where there is no menu so only toggle it if one exists
+ if ( gMenuBarView )
+ {
+ BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
+ BOOL qamode = gSavedSettings.getBOOL("QAMode");
+
+ gMenuBarView->setItemVisible("Advanced", debug);
+// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden
+
+ gMenuBarView->setItemVisible("Debug", qamode);
+ gMenuBarView->setItemEnabled("Debug", qamode);
+
+ gMenuBarView->setItemVisible("Develop", qamode);
+ gMenuBarView->setItemEnabled("Develop", qamode);
+
+ // Server ('Admin') menu hidden when not in godmode.
+ const bool show_server_menu = (gAgent.getGodLevel() > GOD_NOT || (debug && gAgent.getAdminOverride()));
+ gMenuBarView->setItemVisible("Admin", show_server_menu);
+ gMenuBarView->setItemEnabled("Admin", show_server_menu);
+ }
+ if (gLoginMenuBarView)
+ {
+ BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
+ gLoginMenuBarView->setItemVisible("Debug", debug);
+ gLoginMenuBarView->setItemEnabled("Debug", debug);
+ }
}
void toggle_debug_menus(void*)
{
- BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus");
- gSavedSettings.setBOOL("UseDebugMenus", visible);
- show_debug_menus();
+ BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus");
+ gSavedSettings.setBOOL("UseDebugMenus", visible);
+ show_debug_menus();
}
@@ -6182,292 +6219,292 @@ void toggle_debug_menus(void*)
// void handle_export_selected( void * )
// {
-// LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-// if (selection->isEmpty())
-// {
-// return;
-// }
-// LL_INFOS() << "Exporting selected objects:" << LL_ENDL;
-
-// gExporterRequestID.generate();
-// gExportDirectory = "";
-
-// LLMessageSystem* msg = gMessageSystem;
-// msg->newMessageFast(_PREHASH_ObjectExportSelected);
-// msg->nextBlockFast(_PREHASH_AgentData);
-// msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-// msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID);
-// msg->addS16Fast(_PREHASH_VolumeDetail, 4);
-
-// for (LLObjectSelection::root_iterator iter = selection->root_begin();
-// iter != selection->root_end(); iter++)
-// {
-// LLSelectNode* node = *iter;
-// LLViewerObject* object = node->getObject();
-// msg->nextBlockFast(_PREHASH_ObjectData);
-// msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
-// LL_INFOS() << "Object: " << object->getID() << LL_ENDL;
-// }
-// msg->sendReliable(gAgent.getRegion()->getHost());
-
-// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
+// LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+// if (selection->isEmpty())
+// {
+// return;
+// }
+// LL_INFOS() << "Exporting selected objects:" << LL_ENDL;
+
+// gExporterRequestID.generate();
+// gExportDirectory = "";
+
+// LLMessageSystem* msg = gMessageSystem;
+// msg->newMessageFast(_PREHASH_ObjectExportSelected);
+// msg->nextBlockFast(_PREHASH_AgentData);
+// msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+// msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID);
+// msg->addS16Fast(_PREHASH_VolumeDetail, 4);
+
+// for (LLObjectSelection::root_iterator iter = selection->root_begin();
+// iter != selection->root_end(); iter++)
+// {
+// LLSelectNode* node = *iter;
+// LLViewerObject* object = node->getObject();
+// msg->nextBlockFast(_PREHASH_ObjectData);
+// msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
+// LL_INFOS() << "Object: " << object->getID() << LL_ENDL;
+// }
+// msg->sendReliable(gAgent.getRegion()->getHost());
+
+// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
// }
//
class LLCommunicateNearbyChat : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
LLFloaterIMNearbyChat* floater_nearby = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
- if (floater_nearby->isInVisibleChain() && !floater_nearby->isTornOff()
+ if (floater_nearby->isInVisibleChain() && !floater_nearby->isTornOff()
&& im_box->getSelectedSession() == LLUUID() && im_box->getConversationListItemSize() > 1)
- {
- im_box->selectNextorPreviousConversation(false);
- }
- else
- {
- LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat");
- }
- return true;
- }
+ {
+ im_box->selectNextorPreviousConversation(false);
+ }
+ else
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat");
+ }
+ return true;
+ }
};
class LLWorldSetHomeLocation : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // we just send the message and let the server check for failure cases
- // server will echo back a "Home position set." alert if it succeeds
- // and the home location screencapture happens when that alert is recieved
- gAgent.setStartPosition(START_LOCATION_ID_HOME);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // we just send the message and let the server check for failure cases
+ // server will echo back a "Home position set." alert if it succeeds
+ // and the home location screencapture happens when that alert is recieved
+ gAgent.setStartPosition(START_LOCATION_ID_HOME);
+ return true;
+ }
};
class LLWorldLindenHome : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url");
- LLWeb::loadURL(url);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url");
+ LLWeb::loadURL(url);
+ return true;
+ }
};
class LLWorldTeleportHome : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.teleportHome();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAgent.teleportHome();
+ return true;
+ }
};
class LLWorldAlwaysRun : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // as well as altering the default walk-vs-run state,
- // we also change the *current* walk-vs-run state.
- if (gAgent.getAlwaysRun())
- {
- gAgent.clearAlwaysRun();
- gAgent.clearRunning();
- }
- else
- {
- gAgent.setAlwaysRun();
- gAgent.setRunning();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // as well as altering the default walk-vs-run state,
+ // we also change the *current* walk-vs-run state.
+ if (gAgent.getAlwaysRun())
+ {
+ gAgent.clearAlwaysRun();
+ gAgent.clearRunning();
+ }
+ else
+ {
+ gAgent.setAlwaysRun();
+ gAgent.setRunning();
+ }
- // tell the simulator.
- gAgent.sendWalkRun(gAgent.getAlwaysRun());
+ // tell the simulator.
+ gAgent.sendWalkRun(gAgent.getAlwaysRun());
- // Update Movement Controls according to AlwaysRun mode
- LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun());
+ // Update Movement Controls according to AlwaysRun mode
+ LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun());
- return true;
- }
+ return true;
+ }
};
class LLWorldCheckAlwaysRun : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gAgent.getAlwaysRun();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAgent.getAlwaysRun();
+ return new_value;
+ }
};
class LLWorldSetAway : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgent.getAFK())
- {
- gAgent.clearAFK();
- }
- else
- {
- gAgent.setAFK();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.getAFK())
+ {
+ gAgent.clearAFK();
+ }
+ else
+ {
+ gAgent.setAFK();
+ }
+ return true;
+ }
};
class LLWorldSetDoNotDisturb : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgent.isDoNotDisturb())
- {
- gAgent.setDoNotDisturb(false);
- }
- else
- {
- gAgent.setDoNotDisturb(true);
- LLNotificationsUtil::add("DoNotDisturbModeSet");
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.isDoNotDisturb())
+ {
+ gAgent.setDoNotDisturb(false);
+ }
+ else
+ {
+ gAgent.setDoNotDisturb(true);
+ LLNotificationsUtil::add("DoNotDisturbModeSet");
+ }
+ return true;
+ }
};
class LLWorldCreateLandmark : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterReg::showInstance("add_landmark");
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterReg::showInstance("add_landmark");
- return true;
- }
+ return true;
+ }
};
class LLWorldPlaceProfile : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent"));
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent"));
- return true;
- }
+ return true;
+ }
};
void handle_look_at_selection(const LLSD& param)
{
- const F32 PADDING_FACTOR = 1.75f;
- BOOL zoom = (param.asString() == "zoom");
- if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
-
- LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
- F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
- F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
-
- LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent();
- obj_to_cam.normVec();
-
- LLUUID object_id;
- if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
- {
- object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID;
- }
- if (zoom)
- {
- // Make sure we are not increasing the distance between the camera and object
- LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
- distance = llmin(distance, (F32) orig_distance.length());
-
- gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance),
- LLSelectMgr::getInstance()->getSelectionCenterGlobal(),
- object_id );
-
- }
- else
- {
- gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id );
- }
- }
+ const F32 PADDING_FACTOR = 1.75f;
+ BOOL zoom = (param.asString() == "zoom");
+ if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+
+ LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
+ F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
+
+ LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent();
+ obj_to_cam.normVec();
+
+ LLUUID object_id;
+ if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
+ {
+ object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID;
+ }
+ if (zoom)
+ {
+ // Make sure we are not increasing the distance between the camera and object
+ LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
+ distance = llmin(distance, (F32) orig_distance.length());
+
+ gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance),
+ LLSelectMgr::getInstance()->getSelectionCenterGlobal(),
+ object_id );
+
+ }
+ else
+ {
+ gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id );
+ }
+ }
}
void handle_zoom_to_object(LLUUID object_id)
{
- const F32 PADDING_FACTOR = 2.f;
+ const F32 PADDING_FACTOR = 2.f;
- LLViewerObject* object = gObjectList.findObject(object_id);
+ LLViewerObject* object = gObjectList.findObject(object_id);
- if (object)
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ if (object)
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- LLBBox bbox = object->getBoundingBoxAgent() ;
- F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
- F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
+ LLBBox bbox = object->getBoundingBoxAgent() ;
+ F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
+ F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
- LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent();
- obj_to_cam.normVec();
+ LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent();
+ obj_to_cam.normVec();
- LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
+ LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
- gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance),
- object_center_global,
- object_id );
- }
+ gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance),
+ object_center_global,
+ object_id );
+ }
}
class LLAvatarInviteToGroup : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLAvatarActions::inviteToGroup(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLAvatarActions::inviteToGroup(avatar->getID());
+ }
+ return true;
+ }
};
class LLAvatarAddFriend : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
- {
- request_friendship(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
+ {
+ request_friendship(avatar->getID());
+ }
+ return true;
+ }
};
class LLAvatarToggleMyProfile : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID());
- if (LLFloater::isMinimized(instance))
- {
- instance->setMinimized(FALSE);
- instance->setFocus(TRUE);
- }
- else if (!LLFloater::isShown(instance))
- {
- LLAvatarActions::showProfile(gAgent.getID());
- }
- else if (!instance->hasFocus() && !instance->getIsChrome())
- {
- instance->setFocus(TRUE);
- }
- else
- {
- instance->closeFloater();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+ if (LLFloater::isMinimized(instance))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ }
+ else if (!LLFloater::isShown(instance))
+ {
+ LLAvatarActions::showProfile(gAgent.getID());
+ }
+ else if (!instance->hasFocus() && !instance->getIsChrome())
+ {
+ instance->setFocus(TRUE);
+ }
+ else
+ {
+ instance->closeFloater();
+ }
+ return true;
+ }
};
class LLAvatarTogglePicks : public view_listener_t
@@ -6495,41 +6532,41 @@ class LLAvatarTogglePicks : public view_listener_t
class LLAvatarToggleSearch : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloater* instance = LLFloaterReg::findInstance("search");
- if (LLFloater::isMinimized(instance))
- {
- instance->setMinimized(FALSE);
- instance->setFocus(TRUE);
- }
- else if (!LLFloater::isShown(instance))
- {
- LLFloaterReg::showInstance("search");
- }
- else if (!instance->hasFocus() && !instance->getIsChrome())
- {
- instance->setFocus(TRUE);
- }
- else
- {
- instance->closeFloater();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater* instance = LLFloaterReg::findInstance("search");
+ if (LLFloater::isMinimized(instance))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ }
+ else if (!LLFloater::isShown(instance))
+ {
+ LLFloaterReg::showInstance("search");
+ }
+ else if (!instance->hasFocus() && !instance->getIsChrome())
+ {
+ instance->setFocus(TRUE);
+ }
+ else
+ {
+ instance->closeFloater();
+ }
+ return true;
+ }
};
class LLAvatarResetSkeleton: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLVOAvatar* avatar = NULL;
+ LLVOAvatar* avatar = NULL;
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (obj)
{
avatar = obj->getAvatar();
}
- if(avatar)
+ if(avatar)
{
avatar->resetSkeleton(false);
}
@@ -6553,184 +6590,184 @@ class LLAvatarEnableResetSkeleton: public view_listener_t
class LLAvatarResetSkeletonAndAnimations : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- if (avatar)
- {
- avatar->resetSkeleton(true);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar)
+ {
+ avatar->resetSkeleton(true);
+ }
+ return true;
+ }
};
class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- if (avatar)
- {
- avatar->resetSkeleton(true);
- }
- else
- {
- gAgentAvatarp->resetSkeleton(true);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar)
+ {
+ avatar->resetSkeleton(true);
+ }
+ else
+ {
+ gAgentAvatarp->resetSkeleton(true);
+ }
+ return true;
+ }
};
class LLAvatarAddContact : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- create_inventory_callingcard(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ create_inventory_callingcard(avatar->getID());
+ }
+ return true;
+ }
};
bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- gAgent.setDoNotDisturb(false);
- }
-
- LLViewerObject* objectp = selection->getPrimaryObject();
-
- // Show avatar's name if paying attachment
- if (objectp && objectp->isAttachment())
- {
- while (objectp && !objectp->isAvatar())
- {
- objectp = (LLViewerObject*)objectp->getParent();
- }
- }
-
- if (objectp)
- {
- if (objectp->isAvatar())
- {
- const bool is_group = false;
- LLFloaterPayUtil::payDirectly(&give_money,
- objectp->getID(),
- is_group);
- }
- else
- {
- LLFloaterPayUtil::payViaObject(&give_money, selection);
- }
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ gAgent.setDoNotDisturb(false);
+ }
+
+ LLViewerObject* objectp = selection->getPrimaryObject();
+
+ // Show avatar's name if paying attachment
+ if (objectp && objectp->isAttachment())
+ {
+ while (objectp && !objectp->isAvatar())
+ {
+ objectp = (LLViewerObject*)objectp->getParent();
+ }
+ }
+
+ if (objectp)
+ {
+ if (objectp->isAvatar())
+ {
+ const bool is_group = false;
+ LLFloaterPayUtil::payDirectly(&give_money,
+ objectp->getID(),
+ is_group);
+ }
+ else
+ {
+ LLFloaterPayUtil::payViaObject(&give_money, selection);
+ }
+ }
+ return false;
}
void handle_give_money_dialog()
{
- LLNotification::Params params("DoNotDisturbModePay");
- params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
+ LLNotification::Params params("DoNotDisturbModePay");
+ params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
- if (gAgent.isDoNotDisturb())
- {
- // warn users of being in do not disturb mode during a transaction
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 1);
- }
+ if (gAgent.isDoNotDisturb())
+ {
+ // warn users of being in do not disturb mode during a transaction
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 1);
+ }
}
bool enable_pay_avatar()
{
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- LLVOAvatar* avatar = find_avatar_from_object(obj);
- return (avatar != NULL);
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLVOAvatar* avatar = find_avatar_from_object(obj);
+ return (avatar != NULL);
}
bool enable_pay_object()
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if( object )
- {
- LLViewerObject *parent = (LLViewerObject *)object->getParent();
- if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney()))
- {
- return true;
- }
- }
- return false;
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if( object )
+ {
+ LLViewerObject *parent = (LLViewerObject *)object->getParent();
+ if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney()))
+ {
+ return true;
+ }
+ }
+ return false;
}
bool enable_object_stand_up()
{
- // 'Object Stand Up' menu item is enabled when agent is sitting on selection
- return sitting_on_selection();
+ // 'Object Stand Up' menu item is enabled when agent is sitting on selection
+ return sitting_on_selection();
}
bool enable_object_sit(LLUICtrl* ctrl)
{
- // 'Object Sit' menu item is enabled when agent is not sitting on selection
- bool sitting_on_sel = sitting_on_selection();
- if (!sitting_on_sel)
- {
- // init default labels
- init_default_item_label(ctrl);
-
- // Update label
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mSitName.empty())
- {
- ctrl->setValue(node->mSitName);
- }
- else
- {
- ctrl->setValue(get_default_item_label(ctrl->getName()));
- }
- }
- return !sitting_on_sel && is_object_sittable();
+ // 'Object Sit' menu item is enabled when agent is not sitting on selection
+ bool sitting_on_sel = sitting_on_selection();
+ if (!sitting_on_sel)
+ {
+ // init default labels
+ init_default_item_label(ctrl);
+
+ // Update label
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid && !node->mSitName.empty())
+ {
+ ctrl->setValue(node->mSitName);
+ }
+ else
+ {
+ ctrl->setValue(get_default_item_label(ctrl->getName()));
+ }
+ }
+ return !sitting_on_sel && is_object_sittable();
}
void dump_select_mgr(void*)
{
- LLSelectMgr::getInstance()->dump();
+ LLSelectMgr::getInstance()->dump();
}
void dump_inventory(void*)
{
- gInventory.dumpInventory();
+ gInventory.dumpInventory();
}
void handle_dump_followcam(void*)
{
- LLFollowCamMgr::getInstance()->dump();
+ LLFollowCamMgr::getInstance()->dump();
}
void handle_viewer_enable_message_log(void*)
{
- gMessageSystem->startLogging();
+ gMessageSystem->startLogging();
}
void handle_viewer_disable_message_log(void*)
{
- gMessageSystem->stopLogging();
+ gMessageSystem->stopLogging();
}
void handle_customize_avatar()
{
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
}
void handle_edit_outfit()
{
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
}
void handle_now_wearing()
@@ -6747,225 +6784,225 @@ void handle_now_wearing()
void handle_edit_shape()
{
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
}
void handle_hover_height()
{
- LLFloaterReg::showInstance("edit_hover_height");
+ LLFloaterReg::showInstance("edit_hover_height");
}
void handle_edit_physics()
{
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics"));
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics"));
}
void handle_report_abuse()
{
- // Prevent menu from appearing in screen shot.
- gMenuHolder->hideMenus();
- LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
+ // Prevent menu from appearing in screen shot.
+ gMenuHolder->hideMenus();
+ LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
}
void handle_buy_currency()
{
- LLBuyCurrencyHTML::openCurrencyFloater();
+ LLBuyCurrencyHTML::openCurrencyFloater();
}
class LLFloaterVisible : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string floater_name = userdata.asString();
- bool new_value = false;
- {
- new_value = LLFloaterReg::instanceVisible(floater_name);
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string floater_name = userdata.asString();
+ bool new_value = false;
+ {
+ new_value = LLFloaterReg::instanceVisible(floater_name);
+ }
+ return new_value;
+ }
};
class LLShowHelp : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string help_topic = userdata.asString();
- LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- vhelp->showTopic(help_topic);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string help_topic = userdata.asString();
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(help_topic);
+ return true;
+ }
};
class LLToggleHelp : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloater* help_browser = (LLFloaterReg::findInstance("help_browser"));
- if (help_browser && help_browser->isInVisibleChain())
- {
- help_browser->closeFloater();
- }
- else
- {
- std::string help_topic = userdata.asString();
- LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- vhelp->showTopic(help_topic);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater* help_browser = (LLFloaterReg::findInstance("help_browser"));
+ if (help_browser && help_browser->isInVisibleChain())
+ {
+ help_browser->closeFloater();
+ }
+ else
+ {
+ std::string help_topic = userdata.asString();
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ vhelp->showTopic(help_topic);
+ }
+ return true;
+ }
};
class LLToggleSpeak : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVoiceClient::getInstance()->toggleUserPTTState();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVoiceClient::getInstance()->toggleUserPTTState();
+ return true;
+ }
};
class LLShowSidetrayPanel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string floater_name = userdata.asString();
-
- LLPanel* panel = LLFloaterSidePanelContainer::getPanel(floater_name);
- if (panel)
- {
- if (panel->isInVisibleChain())
- {
- LLFloaterReg::getInstance(floater_name)->closeFloater();
- }
- else
- {
- LLFloaterReg::getInstance(floater_name)->openFloater();
- }
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string floater_name = userdata.asString();
+
+ LLPanel* panel = LLFloaterSidePanelContainer::getPanel(floater_name);
+ if (panel)
+ {
+ if (panel->isInVisibleChain())
+ {
+ LLFloaterReg::getInstance(floater_name)->closeFloater();
+ }
+ else
+ {
+ LLFloaterReg::getInstance(floater_name)->openFloater();
+ }
+ }
+ return true;
+ }
};
class LLSidetrayPanelVisible : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string floater_name = userdata.asString();
- // Toggle the panel
- if (LLFloaterReg::getInstance(floater_name)->isInVisibleChain())
- {
- return true;
- }
- else
- {
- return false;
- }
-
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string floater_name = userdata.asString();
+ // Toggle the panel
+ if (LLFloaterReg::getInstance(floater_name)->isInVisibleChain())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+ }
};
bool callback_show_url(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (0 == option)
- {
- LLWeb::loadURL(notification["payload"]["url"].asString());
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LLWeb::loadURL(notification["payload"]["url"].asString());
+ }
+ return false;
}
class LLPromptShowURL : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string param = userdata.asString();
- std::string::size_type offset = param.find(",");
- if (offset != param.npos)
- {
- std::string alert = param.substr(0, offset);
- std::string url = param.substr(offset+1);
-
- if (LLWeb::useExternalBrowser(url))
- {
- LLSD payload;
- payload["url"] = url;
- LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url);
- }
- else
- {
- LLWeb::loadURL(url);
- }
- }
- else
- {
- LL_INFOS() << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << LL_ENDL;
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string param = userdata.asString();
+ std::string::size_type offset = param.find(",");
+ if (offset != param.npos)
+ {
+ std::string alert = param.substr(0, offset);
+ std::string url = param.substr(offset+1);
+
+ if (LLWeb::useExternalBrowser(url))
+ {
+ LLSD payload;
+ payload["url"] = url;
+ LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url);
+ }
+ else
+ {
+ LLWeb::loadURL(url);
+ }
+ }
+ else
+ {
+ LL_INFOS() << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << LL_ENDL;
+ }
+ return true;
+ }
};
bool callback_show_file(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (0 == option)
- {
- LLWeb::loadURL(notification["payload"]["url"]);
- }
- return false;
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LLWeb::loadURL(notification["payload"]["url"]);
+ }
+ return false;
}
class LLPromptShowFile : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string param = userdata.asString();
- std::string::size_type offset = param.find(",");
- if (offset != param.npos)
- {
- std::string alert = param.substr(0, offset);
- std::string file = param.substr(offset+1);
-
- LLSD payload;
- payload["url"] = file;
- LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_file);
- }
- else
- {
- LL_INFOS() << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << LL_ENDL;
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string param = userdata.asString();
+ std::string::size_type offset = param.find(",");
+ if (offset != param.npos)
+ {
+ std::string alert = param.substr(0, offset);
+ std::string file = param.substr(offset+1);
+
+ LLSD payload;
+ payload["url"] = file;
+ LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_file);
+ }
+ else
+ {
+ LL_INFOS() << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << LL_ENDL;
+ }
+ return true;
+ }
};
class LLShowAgentProfile : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLUUID agent_id;
- if (userdata.asString() == "agent")
- {
- agent_id = gAgent.getID();
- }
- else if (userdata.asString() == "hit object")
- {
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (objectp)
- {
- agent_id = objectp->getID();
- }
- }
- else
- {
- agent_id = userdata.asUUID();
- }
-
- LLVOAvatar* avatar = find_avatar_from_object(agent_id);
- if (avatar)
- {
- LLAvatarActions::showProfile(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLUUID agent_id;
+ if (userdata.asString() == "agent")
+ {
+ agent_id = gAgent.getID();
+ }
+ else if (userdata.asString() == "hit object")
+ {
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (objectp)
+ {
+ agent_id = objectp->getID();
+ }
+ }
+ else
+ {
+ agent_id = userdata.asUUID();
+ }
+
+ LLVOAvatar* avatar = find_avatar_from_object(agent_id);
+ if (avatar)
+ {
+ LLAvatarActions::showProfile(avatar->getID());
+ }
+ return true;
+ }
};
class LLShowAgentProfilePicks : public view_listener_t
@@ -6979,164 +7016,164 @@ class LLShowAgentProfilePicks : public view_listener_t
class LLToggleAgentProfile : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLUUID agent_id;
- if (userdata.asString() == "agent")
- {
- agent_id = gAgent.getID();
- }
- else if (userdata.asString() == "hit object")
- {
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (objectp)
- {
- agent_id = objectp->getID();
- }
- }
- else
- {
- agent_id = userdata.asUUID();
- }
-
- LLVOAvatar* avatar = find_avatar_from_object(agent_id);
- if (avatar)
- {
- if (!LLAvatarActions::profileVisible(avatar->getID()))
- {
- LLAvatarActions::showProfile(avatar->getID());
- }
- else
- {
- LLAvatarActions::hideProfile(avatar->getID());
- }
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLUUID agent_id;
+ if (userdata.asString() == "agent")
+ {
+ agent_id = gAgent.getID();
+ }
+ else if (userdata.asString() == "hit object")
+ {
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (objectp)
+ {
+ agent_id = objectp->getID();
+ }
+ }
+ else
+ {
+ agent_id = userdata.asUUID();
+ }
+
+ LLVOAvatar* avatar = find_avatar_from_object(agent_id);
+ if (avatar)
+ {
+ if (!LLAvatarActions::profileVisible(avatar->getID()))
+ {
+ LLAvatarActions::showProfile(avatar->getID());
+ }
+ else
+ {
+ LLAvatarActions::hideProfile(avatar->getID());
+ }
+ }
+ return true;
+ }
};
class LLLandEdit : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
- {
- // zoom in if we're looking at the avatar
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ // zoom in if we're looking at the avatar
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gAgentCamera.cameraOrbitOver( F_PI * 0.25f );
- gViewerWindow->moveCursorToCenter();
- }
- else if ( gSavedSettings.getBOOL("EditCameraMovement") )
- {
- gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gViewerWindow->moveCursorToCenter();
- }
+ gAgentCamera.cameraOrbitOver( F_PI * 0.25f );
+ gViewerWindow->moveCursorToCenter();
+ }
+ else if ( gSavedSettings.getBOOL("EditCameraMovement") )
+ {
+ gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+ gViewerWindow->moveCursorToCenter();
+ }
- LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );
+ LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );
- LLFloaterReg::showInstance("build");
+ LLFloaterReg::showInstance("build");
- // Switch to land edit toolset
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() );
- return true;
- }
+ // Switch to land edit toolset
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() );
+ return true;
+ }
};
class LLMuteParticle : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID;
-
- if (id.notNull())
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(id, &av_name);
-
- LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
- if (LLMuteList::getInstance()->isMuted(mute.mID))
- {
- LLMuteList::getInstance()->remove(mute);
- }
- else
- {
- LLMuteList::getInstance()->add(mute);
- LLPanelBlockedList::showPanelAndSelect(mute.mID);
- }
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID;
+
+ if (id.notNull())
+ {
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(id, &av_name);
+
+ LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
+ if (LLMuteList::getInstance()->isMuted(mute.mID))
+ {
+ LLMuteList::getInstance()->remove(mute);
+ }
+ else
+ {
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ }
+ }
+
+ return true;
+ }
};
class LLWorldEnableBuyLand : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
- LLViewerParcelMgr::getInstance()->selectionEmpty()
- ? LLViewerParcelMgr::getInstance()->getAgentParcel()
- : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(),
- false);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
+ LLViewerParcelMgr::getInstance()->selectionEmpty()
+ ? LLViewerParcelMgr::getInstance()->getAgentParcel()
+ : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(),
+ false);
+ return new_value;
+ }
};
BOOL enable_buy_land(void*)
{
- return LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
- LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false);
+ return LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
+ LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false);
}
void handle_buy_land()
{
- LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance();
- if (vpm->selectionEmpty())
- {
- vpm->selectParcelAt(gAgent.getPositionGlobal());
- }
- vpm->startBuyLand();
+ LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance();
+ if (vpm->selectionEmpty())
+ {
+ vpm->selectParcelAt(gAgent.getPositionGlobal());
+ }
+ vpm->startBuyLand();
}
class LLObjectAttachToAvatar : public view_listener_t
{
public:
- LLObjectAttachToAvatar(bool replace) : mReplace(replace) {}
- static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
+ LLObjectAttachToAvatar(bool replace) : mReplace(replace) {}
+ static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
private:
- bool handleEvent(const LLSD& userdata)
- {
- setObjectSelection(LLSelectMgr::getInstance()->getSelection());
- LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject();
- if (selectedObject)
- {
- S32 index = userdata.asInteger();
- LLViewerJointAttachment* attachment_point = NULL;
- if (index > 0)
- attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL);
- confirmReplaceAttachment(0, attachment_point);
- }
- return true;
- }
-
- static void onNearAttachObject(BOOL success, void *user_data);
- void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
- class CallbackData : public LLSelectionCallbackData
- {
- public:
- CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {}
-
- LLViewerJointAttachment* mAttachmentPoint;
- bool mReplace;
- };
+ bool handleEvent(const LLSD& userdata)
+ {
+ setObjectSelection(LLSelectMgr::getInstance()->getSelection());
+ LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject();
+ if (selectedObject)
+ {
+ S32 index = userdata.asInteger();
+ LLViewerJointAttachment* attachment_point = NULL;
+ if (index > 0)
+ attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL);
+ confirmReplaceAttachment(0, attachment_point);
+ }
+ return true;
+ }
+
+ static void onNearAttachObject(BOOL success, void *user_data);
+ void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
+ class CallbackData : public LLSelectionCallbackData
+ {
+ public:
+ CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {}
+
+ LLViewerJointAttachment* mAttachmentPoint;
+ bool mReplace;
+ };
protected:
- static LLObjectSelectionHandle sObjectSelection;
- bool mReplace;
+ static LLObjectSelectionHandle sObjectSelection;
+ bool mReplace;
};
LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
@@ -7144,238 +7181,238 @@ LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
// static
void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
{
- if (!user_data) return;
- CallbackData* cb_data = static_cast<CallbackData*>(user_data);
-
- if (success)
- {
- const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint;
-
- U8 attachment_id = 0;
- if (attachment)
- {
- for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
- {
- if (iter->second == attachment)
- {
- attachment_id = iter->first;
- break;
- }
- }
- }
- else
- {
- // interpret 0 as "default location"
- attachment_id = 0;
- }
- LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace);
- }
- LLObjectAttachToAvatar::setObjectSelection(NULL);
-
- delete cb_data;
+ if (!user_data) return;
+ CallbackData* cb_data = static_cast<CallbackData*>(user_data);
+
+ if (success)
+ {
+ const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint;
+
+ U8 attachment_id = 0;
+ if (attachment)
+ {
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
+ {
+ if (iter->second == attachment)
+ {
+ attachment_id = iter->first;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // interpret 0 as "default location"
+ attachment_id = 0;
+ }
+ LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace);
+ }
+ LLObjectAttachToAvatar::setObjectSelection(NULL);
+
+ delete cb_data;
}
// static
void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point)
{
- if (option == 0/*YES*/)
- {
- LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
- if (selectedObject)
- {
- const F32 MIN_STOP_DISTANCE = 1.f; // meters
- const F32 ARM_LENGTH = 0.5f; // meters
- const F32 SCALE_FUDGE = 1.5f;
-
- F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH;
- if (stop_distance < MIN_STOP_DISTANCE)
- {
- stop_distance = MIN_STOP_DISTANCE;
- }
-
- LLVector3 walkToSpot = selectedObject->getPositionAgent();
-
- // make sure we stop in front of the object
- LLVector3 delta = walkToSpot - gAgent.getPositionAgent();
- delta.normVec();
- delta = delta * 0.5f;
- walkToSpot -= delta;
-
- // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak.
- CallbackData* user_data = new CallbackData(attachment_point, mReplace);
- gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance);
- gAgentCamera.clearFocusObject();
- }
- }
+ if (option == 0/*YES*/)
+ {
+ LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
+ if (selectedObject)
+ {
+ const F32 MIN_STOP_DISTANCE = 1.f; // meters
+ const F32 ARM_LENGTH = 0.5f; // meters
+ const F32 SCALE_FUDGE = 1.5f;
+
+ F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH;
+ if (stop_distance < MIN_STOP_DISTANCE)
+ {
+ stop_distance = MIN_STOP_DISTANCE;
+ }
+
+ LLVector3 walkToSpot = selectedObject->getPositionAgent();
+
+ // make sure we stop in front of the object
+ LLVector3 delta = walkToSpot - gAgent.getPositionAgent();
+ delta.normVec();
+ delta = delta * 0.5f;
+ walkToSpot -= delta;
+
+ // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak.
+ CallbackData* user_data = new CallbackData(attachment_point, mReplace);
+ gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance);
+ gAgentCamera.clearFocusObject();
+ }
+ }
}
void callback_attachment_drop(const LLSD& notification, const LLSD& response)
{
- // Ensure user confirmed the drop
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return;
-
- // Called when the user clicked on an object attached to them
- // and selected "Drop".
- LLUUID object_id = notification["payload"]["object_id"].asUUID();
- LLViewerObject *object = gObjectList.findObject(object_id);
-
- if (!object)
- {
- LL_WARNS() << "handle_drop_attachment() - no object to drop" << LL_ENDL;
- return;
- }
-
- LLViewerObject *parent = (LLViewerObject*)object->getParent();
- while (parent)
- {
- if(parent->isAvatar())
- {
- break;
- }
- object = parent;
- parent = (LLViewerObject*)parent->getParent();
- }
-
- if (!object)
- {
- LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
- return;
- }
-
- if (object->isAvatar())
- {
- LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
- return;
- }
-
- // reselect the object
- LLSelectMgr::getInstance()->selectObjectAndFamily(object);
-
- LLSelectMgr::getInstance()->sendDropAttachment();
-
- return;
+ // Ensure user confirmed the drop
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return;
+
+ // Called when the user clicked on an object attached to them
+ // and selected "Drop".
+ LLUUID object_id = notification["payload"]["object_id"].asUUID();
+ LLViewerObject *object = gObjectList.findObject(object_id);
+
+ if (!object)
+ {
+ LL_WARNS() << "handle_drop_attachment() - no object to drop" << LL_ENDL;
+ return;
+ }
+
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+
+ if (!object)
+ {
+ LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
+ return;
+ }
+
+ if (object->isAvatar())
+ {
+ LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
+ return;
+ }
+
+ // reselect the object
+ LLSelectMgr::getInstance()->selectObjectAndFamily(object);
+
+ LLSelectMgr::getInstance()->sendDropAttachment();
+
+ return;
}
class LLAttachmentDrop : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLSD payload;
- LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLSD payload;
+ LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (object)
- {
- payload["object_id"] = object->getID();
- }
- else
- {
- LL_WARNS() << "Drop object not found" << LL_ENDL;
- return true;
- }
+ if (object)
+ {
+ payload["object_id"] = object->getID();
+ }
+ else
+ {
+ LL_WARNS() << "Drop object not found" << LL_ENDL;
+ return true;
+ }
- LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop);
- return true;
- }
+ LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop);
+ return true;
+ }
};
// called from avatar pie menu
class LLAttachmentDetachFromPoint : public view_listener_t
{
- bool handleEvent(const LLSD& user_data)
- {
- uuid_vec_t ids_to_remove;
- const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
- if (attachment->getNumObjects() > 0)
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
- iter != attachment->mAttachedObjects.end();
- iter++)
- {
- LLViewerObject *attached_object = iter->get();
- ids_to_remove.push_back(attached_object->getAttachmentItemID());
- }
- }
- if (!ids_to_remove.empty())
- {
- LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
- }
- return true;
- }
+ bool handleEvent(const LLSD& user_data)
+ {
+ uuid_vec_t ids_to_remove;
+ const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
+ if (attachment->getNumObjects() > 0)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
+ iter != attachment->mAttachedObjects.end();
+ iter++)
+ {
+ LLViewerObject *attached_object = iter->get();
+ ids_to_remove.push_back(attached_object->getAttachmentItemID());
+ }
+ }
+ if (!ids_to_remove.empty())
+ {
+ LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
+ }
+ return true;
+ }
};
static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
{
- std::string label;
- LLMenuItemGL* menu = dynamic_cast<LLMenuItemGL*>(ctrl);
- if (menu)
- {
- const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL);
- if (attachment)
- {
- label = data["label"].asString();
- for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object)
- {
- LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
- if (itemp)
- {
- label += std::string(" (") + itemp->getName() + std::string(")");
- break;
- }
- }
- }
- }
- menu->setLabel(label);
- }
- return true;
+ std::string label;
+ LLMenuItemGL* menu = dynamic_cast<LLMenuItemGL*>(ctrl);
+ if (menu)
+ {
+ const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL);
+ if (attachment)
+ {
+ label = data["label"].asString();
+ for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ const LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
+ if (itemp)
+ {
+ label += std::string(" (") + itemp->getName() + std::string(")");
+ break;
+ }
+ }
+ }
+ }
+ menu->setLabel(label);
+ }
+ return true;
}
class LLAttachmentDetach : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // Called when the user clicked on an object attached to them
- // and selected "Detach".
- LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object)
- {
- LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
- return true;
- }
-
- LLViewerObject *parent = (LLViewerObject*)object->getParent();
- while (parent)
- {
- if(parent->isAvatar())
- {
- break;
- }
- object = parent;
- parent = (LLViewerObject*)parent->getParent();
- }
-
- if (!object)
- {
- LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
- return true;
- }
-
- if (object->isAvatar())
- {
- LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
- return true;
- }
-
- LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // Called when the user clicked on an object attached to them
+ // and selected "Detach".
+ LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
+ return true;
+ }
+
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+
+ if (!object)
+ {
+ LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
+ return true;
+ }
+
+ if (object->isAvatar())
+ {
+ LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
+ return true;
+ }
+
+ LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+
+ return true;
+ }
};
//Adding an observer for a Jira 2422 and needs to be a fetch observer
@@ -7383,468 +7420,468 @@ class LLAttachmentDetach : public view_listener_t
class LLWornItemFetchedObserver : public LLInventoryFetchItemsObserver
{
public:
- LLWornItemFetchedObserver(const LLUUID& worn_item_id) :
- LLInventoryFetchItemsObserver(worn_item_id)
- {}
- virtual ~LLWornItemFetchedObserver() {}
+ LLWornItemFetchedObserver(const LLUUID& worn_item_id) :
+ LLInventoryFetchItemsObserver(worn_item_id)
+ {}
+ virtual ~LLWornItemFetchedObserver() {}
protected:
- virtual void done()
- {
- gMenuAttachmentSelf->buildDrawLabels();
- gInventory.removeObserver(this);
- delete this;
- }
+ virtual void done()
+ {
+ gMenuAttachmentSelf->buildDrawLabels();
+ gInventory.removeObserver(this);
+ delete this;
+ }
};
// You can only drop items on parcels where you can build.
class LLAttachmentEnableDrop : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- BOOL can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->allowAgentBuild());
-
- //Add an inventory observer to only allow dropping the newly attached item
- //once it exists in your inventory. Look at Jira 2422.
- //-jwolk
-
- // A bug occurs when you wear/drop an item before it actively is added to your inventory
- // if this is the case (you're on a slow sim, etc.) a copy of the object,
- // well, a newly created object with the same properties, is placed
- // in your inventory. Therefore, we disable the drop option until the
- // item is in your inventory
-
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- LLViewerJointAttachment* attachment = NULL;
- LLInventoryItem* item = NULL;
-
- // Do not enable drop if all faces of object are not enabled
- if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
- {
- S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
- attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
-
- if (attachment)
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- // make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
- // so check to see if the item is in the inventory already
- item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID());
- if (!item)
- {
- // Item does not exist, make an observer to enable the pie menu
- // when the item finishes fetching worst case scenario
- // if a fetch is already out there (being sent from a slow sim)
- // we refetch and there are 2 fetches
- LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID());
- worn_item_fetched->startFetch();
- gInventory.addObserver(worn_item_fetched);
- }
- }
- }
- }
-
- //now check to make sure that the item is actually in the inventory before we enable dropping it
- bool new_value = enable_detach() && can_build && item;
-
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->allowAgentBuild());
+
+ //Add an inventory observer to only allow dropping the newly attached item
+ //once it exists in your inventory. Look at Jira 2422.
+ //-jwolk
+
+ // A bug occurs when you wear/drop an item before it actively is added to your inventory
+ // if this is the case (you're on a slow sim, etc.) a copy of the object,
+ // well, a newly created object with the same properties, is placed
+ // in your inventory. Therefore, we disable the drop option until the
+ // item is in your inventory
+
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLViewerJointAttachment* attachment = NULL;
+ LLInventoryItem* item = NULL;
+
+ // Do not enable drop if all faces of object are not enabled
+ if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
+ {
+ S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
+ attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
+
+ if (attachment)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ // make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
+ // so check to see if the item is in the inventory already
+ item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID());
+ if (!item)
+ {
+ // Item does not exist, make an observer to enable the pie menu
+ // when the item finishes fetching worst case scenario
+ // if a fetch is already out there (being sent from a slow sim)
+ // we refetch and there are 2 fetches
+ LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID());
+ worn_item_fetched->startFetch();
+ gInventory.addObserver(worn_item_fetched);
+ }
+ }
+ }
+ }
+
+ //now check to make sure that the item is actually in the inventory before we enable dropping it
+ bool new_value = enable_detach() && can_build && item;
+
+ return new_value;
+ }
};
BOOL enable_detach(const LLSD&)
{
- LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+
+ // Only enable detach if all faces of object are selected
+ if (!object ||
+ !object->isAttachment() ||
+ !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
+ {
+ return FALSE;
+ }
- // Only enable detach if all faces of object are selected
- if (!object ||
- !object->isAttachment() ||
- !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
- {
- return FALSE;
- }
+ // Find the avatar who owns this attachment
+ LLViewerObject* avatar = object;
+ while (avatar)
+ {
+ // ...if it's you, good to detach
+ if (avatar->getID() == gAgent.getID())
+ {
+ return TRUE;
+ }
- // Find the avatar who owns this attachment
- LLViewerObject* avatar = object;
- while (avatar)
- {
- // ...if it's you, good to detach
- if (avatar->getID() == gAgent.getID())
- {
- return TRUE;
- }
-
- avatar = (LLViewerObject*)avatar->getParent();
- }
+ avatar = (LLViewerObject*)avatar->getParent();
+ }
- return FALSE;
+ return FALSE;
}
class LLAttachmentEnableDetach : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = enable_detach();
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = enable_detach();
+ return new_value;
+ }
};
// Used to tell if the selected object can be attached to your avatar.
BOOL object_selected_and_point_valid()
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- for (LLObjectSelection::root_iterator iter = selection->root_begin();
- iter != selection->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- LLViewerObject::const_child_list_t& child_list = object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if (child->isAvatar())
- {
- return FALSE;
- }
- }
- }
-
- return (selection->getRootObjectCount() == 1) &&
- (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) &&
- selection->getFirstRootObject()->permYouOwner() &&
- selection->getFirstRootObject()->flagObjectMove() &&
- !selection->getFirstRootObject()->flagObjectPermanent() &&
- !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() &&
- (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL);
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ for (LLObjectSelection::root_iterator iter = selection->root_begin();
+ iter != selection->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ LLViewerObject::const_child_list_t& child_list = object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if (child->isAvatar())
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ return (selection->getRootObjectCount() == 1) &&
+ (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) &&
+ selection->getFirstRootObject()->permYouOwner() &&
+ selection->getFirstRootObject()->flagObjectMove() &&
+ !selection->getFirstRootObject()->flagObjectPermanent() &&
+ !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() &&
+ (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL);
}
BOOL object_is_wearable()
{
- if (!isAgentAvatarValid())
- {
- return FALSE;
- }
- if (!object_selected_and_point_valid())
- {
- return FALSE;
- }
- if (sitting_on_selection())
- {
- return FALSE;
- }
+ if (!isAgentAvatarValid())
+ {
+ return FALSE;
+ }
+ if (!object_selected_and_point_valid())
+ {
+ return FALSE;
+ }
+ if (sitting_on_selection())
+ {
+ return FALSE;
+ }
if (!gAgentAvatarp->canAttachMoreObjects())
{
return FALSE;
}
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- if (node->mPermissions->getOwner() == gAgent.getID())
- {
- return TRUE;
- }
- }
- return FALSE;
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ if (node->mPermissions->getOwner() == gAgent.getID())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
class LLAttachmentPointFilled : public view_listener_t
{
- bool handleEvent(const LLSD& user_data)
- {
- bool enable = false;
- LLVOAvatar::attachment_map_t::iterator found_it = gAgentAvatarp->mAttachmentPoints.find(user_data.asInteger());
- if (found_it != gAgentAvatarp->mAttachmentPoints.end())
- {
- enable = found_it->second->getNumObjects() > 0;
- }
- return enable;
- }
+ bool handleEvent(const LLSD& user_data)
+ {
+ bool enable = false;
+ LLVOAvatar::attachment_map_t::iterator found_it = gAgentAvatarp->mAttachmentPoints.find(user_data.asInteger());
+ if (found_it != gAgentAvatarp->mAttachmentPoints.end())
+ {
+ enable = found_it->second->getNumObjects() > 0;
+ }
+ return enable;
+ }
};
class LLAvatarSendIM : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLAvatarActions::startIM(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLAvatarActions::startIM(avatar->getID());
+ }
+ return true;
+ }
};
class LLAvatarCall : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLAvatarActions::startCall(avatar->getID());
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLAvatarActions::startCall(avatar->getID());
+ }
+ return true;
+ }
};
namespace
{
- struct QueueObjects : public LLSelectedNodeFunctor
- {
- BOOL scripted;
- BOOL modifiable;
- LLFloaterScriptQueue* mQueue;
- QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
- virtual bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- if (!obj)
- {
- return true;
- }
- scripted = obj->flagScripted();
- modifiable = obj->permModify();
-
- if( scripted && modifiable )
- {
- mQueue->addObject(obj->getID(), node->mName);
- return false;
- }
- else
- {
- return true; // fail: stop applying
- }
- }
- };
+ struct QueueObjects : public LLSelectedNodeFunctor
+ {
+ BOOL scripted;
+ BOOL modifiable;
+ LLFloaterScriptQueue* mQueue;
+ QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ LLViewerObject* obj = node->getObject();
+ if (!obj)
+ {
+ return true;
+ }
+ scripted = obj->flagScripted();
+ modifiable = obj->permModify();
+
+ if( scripted && modifiable )
+ {
+ mQueue->addObject(obj->getID(), node->mName);
+ return false;
+ }
+ else
+ {
+ return true; // fail: stop applying
+ }
+ }
+ };
}
bool queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
{
- QueueObjects func(q);
- LLSelectMgr *mgr = LLSelectMgr::getInstance();
- LLObjectSelectionHandle selectHandle = mgr->getSelection();
- bool fail = selectHandle->applyToNodes(&func);
- if(fail)
- {
- if ( !func.scripted )
- {
- std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts";
- LLNotificationsUtil::add(noscriptmsg);
- }
- else if ( !func.modifiable )
- {
- std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission";
- LLNotificationsUtil::add(nomodmsg);
- }
- else
- {
- LL_ERRS() << "Bad logic." << LL_ENDL;
- }
- q->closeFloater();
- }
- else
- {
- if (!q->start())
- {
- LL_WARNS() << "Unexpected script compile failure." << LL_ENDL;
- }
- }
- return !fail;
+ QueueObjects func(q);
+ LLSelectMgr *mgr = LLSelectMgr::getInstance();
+ LLObjectSelectionHandle selectHandle = mgr->getSelection();
+ bool fail = selectHandle->applyToNodes(&func);
+ if(fail)
+ {
+ if ( !func.scripted )
+ {
+ std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts";
+ LLNotificationsUtil::add(noscriptmsg);
+ }
+ else if ( !func.modifiable )
+ {
+ std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission";
+ LLNotificationsUtil::add(nomodmsg);
+ }
+ else
+ {
+ LL_ERRS() << "Bad logic." << LL_ENDL;
+ }
+ q->closeFloater();
+ }
+ else
+ {
+ if (!q->start())
+ {
+ LL_WARNS() << "Unexpected script compile failure." << LL_ENDL;
+ }
+ }
+ return !fail;
}
class LLToolsSelectedScriptAction : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string action = userdata.asString();
- bool mono = false;
- std::string msg, name;
- std::string title;
- if (action == "compile mono")
- {
- name = "compile_queue";
- mono = true;
- msg = "Recompile";
- title = LLTrans::getString("CompileQueueTitle");
- }
- if (action == "compile lsl")
- {
- name = "compile_queue";
- msg = "Recompile";
- title = LLTrans::getString("CompileQueueTitle");
- }
- else if (action == "reset")
- {
- name = "reset_queue";
- msg = "Reset";
- title = LLTrans::getString("ResetQueueTitle");
- }
- else if (action == "start")
- {
- name = "start_queue";
- msg = "SetRunning";
- title = LLTrans::getString("RunQueueTitle");
- }
- else if (action == "stop")
- {
- name = "stop_queue";
- msg = "SetRunningNot";
- title = LLTrans::getString("NotRunQueueTitle");
- }
- LLUUID id; id.generate();
-
- LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id));
- if (queue)
- {
- queue->setMono(mono);
- if (queue_actions(queue, msg))
- {
- queue->setTitle(title);
- }
- }
- else
- {
- LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL;
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string action = userdata.asString();
+ bool mono = false;
+ std::string msg, name;
+ std::string title;
+ if (action == "compile mono")
+ {
+ name = "compile_queue";
+ mono = true;
+ msg = "Recompile";
+ title = LLTrans::getString("CompileQueueTitle");
+ }
+ if (action == "compile lsl")
+ {
+ name = "compile_queue";
+ msg = "Recompile";
+ title = LLTrans::getString("CompileQueueTitle");
+ }
+ else if (action == "reset")
+ {
+ name = "reset_queue";
+ msg = "Reset";
+ title = LLTrans::getString("ResetQueueTitle");
+ }
+ else if (action == "start")
+ {
+ name = "start_queue";
+ msg = "SetRunning";
+ title = LLTrans::getString("RunQueueTitle");
+ }
+ else if (action == "stop")
+ {
+ name = "stop_queue";
+ msg = "SetRunningNot";
+ title = LLTrans::getString("NotRunQueueTitle");
+ }
+ LLUUID id; id.generate();
+
+ LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id));
+ if (queue)
+ {
+ queue->setMono(mono);
+ if (queue_actions(queue, msg))
+ {
+ queue->setTitle(title);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL;
+ }
+ return true;
+ }
};
void handle_selected_texture_info(void*)
{
- for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
- {
- LLSelectNode* node = *iter;
-
- std::string msg;
- msg.assign("Texture info for: ");
- msg.append(node->mName);
-
- U8 te_count = node->getObject()->getNumTEs();
- // map from texture ID to list of faces using it
- typedef std::map< LLUUID, std::vector<U8> > map_t;
- map_t faces_per_texture;
- for (U8 i = 0; i < te_count; i++)
- {
- if (!node->isTESelected(i)) continue;
-
- LLViewerTexture* img = node->getObject()->getTEImage(i);
- LLUUID image_id = img->getID();
- faces_per_texture[image_id].push_back(i);
- }
- // Per-texture, dump which faces are using it.
- map_t::iterator it;
- for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
- {
- U8 te = it->second[0];
- LLViewerTexture* img = node->getObject()->getTEImage(te);
- S32 height = img->getHeight();
- S32 width = img->getWidth();
- S32 components = img->getComponents();
- msg.append(llformat("\n%dx%d %s on face ",
- width,
- height,
- (components == 4 ? "alpha" : "opaque")));
- for (U8 i = 0; i < it->second.size(); ++i)
- {
- msg.append( llformat("%d ", (S32)(it->second[i])));
- }
- }
- LLSD args;
- args["MESSAGE"] = msg;
- LLNotificationsUtil::add("SystemMessage", args);
- }
+ for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
+ std::string msg;
+ msg.assign("Texture info for: ");
+ msg.append(node->mName);
+
+ U8 te_count = node->getObject()->getNumTEs();
+ // map from texture ID to list of faces using it
+ typedef std::map< LLUUID, std::vector<U8> > map_t;
+ map_t faces_per_texture;
+ for (U8 i = 0; i < te_count; i++)
+ {
+ if (!node->isTESelected(i)) continue;
+
+ LLViewerTexture* img = node->getObject()->getTEImage(i);
+ LLUUID image_id = img->getID();
+ faces_per_texture[image_id].push_back(i);
+ }
+ // Per-texture, dump which faces are using it.
+ map_t::iterator it;
+ for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
+ {
+ U8 te = it->second[0];
+ LLViewerTexture* img = node->getObject()->getTEImage(te);
+ S32 height = img->getHeight();
+ S32 width = img->getWidth();
+ S32 components = img->getComponents();
+ msg.append(llformat("\n%dx%d %s on face ",
+ width,
+ height,
+ (components == 4 ? "alpha" : "opaque")));
+ for (U8 i = 0; i < it->second.size(); ++i)
+ {
+ msg.append( llformat("%d ", (S32)(it->second[i])));
+ }
+ }
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
}
void handle_selected_material_info()
{
- for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
- {
- LLSelectNode* node = *iter;
-
- std::string msg;
- msg.assign("Material info for: \n");
- msg.append(node->mName);
-
- U8 te_count = node->getObject()->getNumTEs();
- // map from material ID to list of faces using it
- typedef std::map<LLMaterialID, std::vector<U8> > map_t;
- map_t faces_per_material;
- for (U8 i = 0; i < te_count; i++)
- {
- if (!node->isTESelected(i)) continue;
-
- const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID();
- faces_per_material[material_id].push_back(i);
- }
- // Per-material, dump which faces are using it.
- map_t::iterator it;
- for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it)
- {
- const LLMaterialID& material_id = it->first;
- msg += llformat("%s on face ", material_id.asString().c_str());
- for (U8 i = 0; i < it->second.size(); ++i)
- {
- msg.append( llformat("%d ", (S32)(it->second[i])));
- }
- msg.append("\n");
- }
-
- LLSD args;
- args["MESSAGE"] = msg;
- LLNotificationsUtil::add("SystemMessage", args);
- }
+ for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
+ std::string msg;
+ msg.assign("Material info for: \n");
+ msg.append(node->mName);
+
+ U8 te_count = node->getObject()->getNumTEs();
+ // map from material ID to list of faces using it
+ typedef std::map<LLMaterialID, std::vector<U8> > map_t;
+ map_t faces_per_material;
+ for (U8 i = 0; i < te_count; i++)
+ {
+ if (!node->isTESelected(i)) continue;
+
+ const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID();
+ faces_per_material[material_id].push_back(i);
+ }
+ // Per-material, dump which faces are using it.
+ map_t::iterator it;
+ for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it)
+ {
+ const LLMaterialID& material_id = it->first;
+ msg += llformat("%s on face ", material_id.asString().c_str());
+ for (U8 i = 0; i < it->second.size(); ++i)
+ {
+ msg.append( llformat("%d ", (S32)(it->second[i])));
+ }
+ msg.append("\n");
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
}
void handle_test_male(void*)
{
- LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
- //gGestureList.requestResetFromServer( TRUE );
+ LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
+ //gGestureList.requestResetFromServer( TRUE );
}
void handle_test_female(void*)
{
- LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit");
- //gGestureList.requestResetFromServer( FALSE );
+ LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit");
+ //gGestureList.requestResetFromServer( FALSE );
}
void handle_dump_attachments(void*)
{
- if(!isAgentAvatarValid()) return;
-
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- S32 key = curiter->first;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = attachment_iter->get();
- BOOL visible = (attached_object != NULL &&
- attached_object->mDrawable.notNull() &&
- !attached_object->mDrawable->isRenderType(0));
- LLVector3 pos;
- if (visible) pos = attached_object->mDrawable->getPosition();
- LL_INFOS() << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID()
- << (attached_object ? " present " : " absent ")
- << (visible ? "visible " : "invisible ")
- << " at " << pos
- << " and " << (visible ? attached_object->getPosition() : LLVector3::zero)
- << LL_ENDL;
- }
- }
+ if(!isAgentAvatarValid()) return;
+
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ S32 key = curiter->first;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = attachment_iter->get();
+ BOOL visible = (attached_object != NULL &&
+ attached_object->mDrawable.notNull() &&
+ !attached_object->mDrawable->isRenderType(0));
+ LLVector3 pos;
+ if (visible) pos = attached_object->mDrawable->getPosition();
+ LL_INFOS() << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID()
+ << (attached_object ? " present " : " absent ")
+ << (visible ? "visible " : "invisible ")
+ << " at " << pos
+ << " and " << (visible ? attached_object->getPosition() : LLVector3::zero)
+ << LL_ENDL;
+ }
+ }
}
@@ -7853,78 +7890,102 @@ class LLToggleControl : public view_listener_t
{
protected:
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
- BOOL checked = gSavedSettings.getBOOL( control_name );
- gSavedSettings.setBOOL( control_name, !checked );
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
+ BOOL checked = gSavedSettings.getBOOL( control_name );
+ gSavedSettings.setBOOL( control_name, !checked );
+ return true;
+ }
};
class LLCheckControl : public view_listener_t
{
- bool handleEvent( const LLSD& userdata)
- {
- std::string callback_data = userdata.asString();
- bool new_value = gSavedSettings.getBOOL(callback_data);
- return new_value;
- }
+ bool handleEvent( const LLSD& userdata)
+ {
+ std::string callback_data = userdata.asString();
+ bool new_value = gSavedSettings.getBOOL(callback_data);
+ return new_value;
+ }
};
// not so generic
class LLAdvancedCheckRenderShadowOption: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
- S32 current_shadow_level = gSavedSettings.getS32(control_name);
- if (current_shadow_level == 0) // is off
- {
- return false;
- }
- else // is on
- {
- return true;
- }
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
+ S32 current_shadow_level = gSavedSettings.getS32(control_name);
+ if (current_shadow_level == 0) // is off
+ {
+ return false;
+ }
+ else // is on
+ {
+ return true;
+ }
+ }
};
class LLAdvancedClickRenderShadowOption: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
- S32 current_shadow_level = gSavedSettings.getS32(control_name);
- if (current_shadow_level == 0) // upgrade to level 2
- {
- gSavedSettings.setS32(control_name, 2);
- }
- else // downgrade to level 0
- {
- gSavedSettings.setS32(control_name, 0);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
+ S32 current_shadow_level = gSavedSettings.getS32(control_name);
+ if (current_shadow_level == 0) // upgrade to level 2
+ {
+ gSavedSettings.setS32(control_name, 2);
+ }
+ else // downgrade to level 0
+ {
+ gSavedSettings.setS32(control_name, 0);
+ }
+ return true;
+ }
};
class LLAdvancedClickRenderProfile: public view_listener_t
{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gShaderProfileFrame = TRUE;
+ return true;
+ }
+};
+
+F32 gpu_benchmark();
+
+class LLAdvancedClickRenderBenchmark: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gpu_benchmark();
+ return true;
+ }
+};
+
+void hdri_preview();
+
+class LLAdvancedClickHDRIPreview: public view_listener_t
+{
bool handleEvent(const LLSD& userdata)
{
- gShaderProfileFrame = TRUE;
+ // open personal lighting floater when previewing an HDRI (keeps HDRI from implicitly unloading when opening build tools)
+ LLFloaterReg::showInstance("env_adjust_snapshot");
+ hdri_preview();
return true;
}
};
-F32 gpu_benchmark();
-class LLAdvancedClickRenderBenchmark: public view_listener_t
+class LLAdvancedClickGLTFScenePreview : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- gpu_benchmark();
+ // open personal lighting floater when previewing an HDRI (keeps HDRI from implicitly unloading when opening build tools)
+ LL::GLTFSceneManager::instance().load();
return true;
}
};
@@ -7932,290 +7993,290 @@ class LLAdvancedClickRenderBenchmark: public view_listener_t
// these are used in the gl menus to set control values that require shader recompilation
class LLToggleShaderControl : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
std::string control_name = userdata.asString();
- BOOL checked = gSavedSettings.getBOOL( control_name );
- gSavedSettings.setBOOL( control_name, !checked );
+ BOOL checked = gSavedSettings.getBOOL( control_name );
+ gSavedSettings.setBOOL( control_name, !checked );
LLPipeline::refreshCachedSettings();
LLViewerShaderMgr::instance()->setShaders();
- return !checked;
- }
+ return !checked;
+ }
};
void menu_toggle_attached_lights(void* user_data)
{
- LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
+ LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
}
void menu_toggle_attached_particles(void* user_data)
{
- LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
+ LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
}
class LLAdvancedHandleAttachedLightParticles: public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
- // toggle the control
- gSavedSettings.setBOOL(control_name,
- !gSavedSettings.getBOOL(control_name));
+ // toggle the control
+ gSavedSettings.setBOOL(control_name,
+ !gSavedSettings.getBOOL(control_name));
- // update internal flags
- if (control_name == "RenderAttachedLights")
- {
- menu_toggle_attached_lights(NULL);
- }
- else if (control_name == "RenderAttachedParticles")
- {
- menu_toggle_attached_particles(NULL);
- }
- return true;
- }
+ // update internal flags
+ if (control_name == "RenderAttachedLights")
+ {
+ menu_toggle_attached_lights(NULL);
+ }
+ else if (control_name == "RenderAttachedParticles")
+ {
+ menu_toggle_attached_particles(NULL);
+ }
+ return true;
+ }
};
class LLSomethingSelected : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty());
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty());
+ return new_value;
+ }
};
class LLSomethingSelectedNoHUD : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD);
+ return new_value;
+ }
};
static bool is_editable_selected()
{
- return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
+ return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
}
class LLEditableSelected : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return is_editable_selected();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return is_editable_selected();
+ }
};
class LLEditableSelectedMono : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = false;
- LLViewerRegion* region = gAgent.getRegion();
- if(region && gMenuHolder)
- {
- bool have_cap = (! region->getCapability("UpdateScriptTask").empty());
- new_value = is_editable_selected() && have_cap;
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = false;
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region && gMenuHolder)
+ {
+ bool have_cap = (! region->getCapability("UpdateScriptTask").empty());
+ new_value = is_editable_selected() && have_cap;
+ }
+ return new_value;
+ }
};
bool enable_object_take_copy()
{
- bool all_valid = false;
- if (LLSelectMgr::getInstance())
- {
- if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 0)
- {
- all_valid = true;
+ bool all_valid = false;
+ if (LLSelectMgr::getInstance())
+ {
+ if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 0)
+ {
+ all_valid = true;
#ifndef HACKED_GODLIKE_VIEWER
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (LLGridManager::getInstance()->isInProductionGrid()
+ if (LLGridManager::getInstance()->isInProductionGrid()
|| !gAgent.isGodlike())
# endif
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* obj)
- {
- return (!obj->permCopy() || obj->isAttachment());
- }
- } func;
- const bool firstonly = true;
- bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- all_valid = !any_invalid;
- }
+ {
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* obj)
+ {
+ return (!obj->permCopy() || obj->isAttachment());
+ }
+ } func;
+ const bool firstonly = true;
+ bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
+ all_valid = !any_invalid;
+ }
#endif // HACKED_GODLIKE_VIEWER
- }
- }
+ }
+ }
- return all_valid;
+ return all_valid;
}
class LLHasAsset : public LLInventoryCollectFunctor
{
public:
- LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {}
- virtual ~LLHasAsset() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item);
- BOOL hasAsset() const { return mHasAsset; }
+ LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {}
+ virtual ~LLHasAsset() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+ BOOL hasAsset() const { return mHasAsset; }
protected:
- LLUUID mAssetID;
- BOOL mHasAsset;
+ LLUUID mAssetID;
+ BOOL mHasAsset;
};
bool LLHasAsset::operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
+ LLInventoryItem* item)
{
- if(item && item->getAssetUUID() == mAssetID)
- {
- mHasAsset = TRUE;
- }
- return FALSE;
+ if(item && item->getAssetUUID() == mAssetID)
+ {
+ mHasAsset = TRUE;
+ }
+ return FALSE;
}
BOOL enable_save_into_task_inventory(void*)
{
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
- {
- // *TODO: check to see if the fromtaskid object exists.
- LLViewerObject* obj = node->getObject();
- if( obj && !obj->isAttachment() )
- {
- return TRUE;
- }
- }
- return FALSE;
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
+ {
+ // *TODO: check to see if the fromtaskid object exists.
+ LLViewerObject* obj = node->getObject();
+ if( obj && !obj->isAttachment() )
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
class LLToolsEnableSaveToObjectInventory : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = enable_save_into_task_inventory(NULL);
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = enable_save_into_task_inventory(NULL);
+ return new_value;
+ }
};
class LLToggleHowTo : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterReg::toggleInstanceOrBringToFront("guidebook");
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("guidebook");
+ return true;
+ }
};
class LLViewEnableMouselook : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // You can't go directly from customize avatar to mouselook.
- // TODO: write code with appropriate dialogs to handle this transition.
- bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ // You can't go directly from customize avatar to mouselook.
+ // TODO: write code with appropriate dialogs to handle this transition.
+ bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
+ return new_value;
+ }
};
class LLToolsEnableToolNotPie : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() );
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() );
+ return new_value;
+ }
};
class LLWorldEnableCreateLandmark : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return !LLLandmarkActions::landmarkAlreadyExists();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return !LLLandmarkActions::landmarkAlreadyExists();
+ }
};
class LLWorldEnableSetHomeLocation : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gAgent.isGodlike() ||
- (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome());
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAgent.isGodlike() ||
+ (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome());
+ return new_value;
+ }
};
class LLWorldEnableTeleportHome : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerRegion* regionp = gAgent.getRegion();
- bool agent_on_prelude = (regionp && regionp->isPrelude());
- bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude;
- return enable_teleport_home;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerRegion* regionp = gAgent.getRegion();
+ bool agent_on_prelude = (regionp && regionp->isPrelude());
+ bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude;
+ return enable_teleport_home;
+ }
};
BOOL enable_god_full(void*)
{
- return gAgent.getGodLevel() >= GOD_FULL;
+ return gAgent.getGodLevel() >= GOD_FULL;
}
BOOL enable_god_liaison(void*)
{
- return gAgent.getGodLevel() >= GOD_LIAISON;
+ return gAgent.getGodLevel() >= GOD_LIAISON;
}
bool is_god_customer_service()
{
- return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE;
+ return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE;
}
BOOL enable_god_basic(void*)
{
- return gAgent.getGodLevel() > GOD_NOT;
+ return gAgent.getGodLevel() > GOD_NOT;
}
void toggle_show_xui_names(void *)
{
- gSavedSettings.setBOOL("DebugShowXUINames", !gSavedSettings.getBOOL("DebugShowXUINames"));
+ gSavedSettings.setBOOL("DebugShowXUINames", !gSavedSettings.getBOOL("DebugShowXUINames"));
}
BOOL check_show_xui_names(void *)
{
- return gSavedSettings.getBOOL("DebugShowXUINames");
+ return gSavedSettings.getBOOL("DebugShowXUINames");
}
class LLToolsSelectOnlyMyObjects : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly");
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly");
- gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val );
+ gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val );
- return true;
- }
+ return true;
+ }
};
class LLToolsSelectOnlyMovableObjects : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly");
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly");
- gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val );
+ gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val );
- return true;
- }
+ return true;
+ }
};
class LLToolsSelectInvisibleObjects : public view_listener_t
@@ -8244,178 +8305,178 @@ class LLToolsSelectReflectionProbes: public view_listener_t
class LLToolsSelectBySurrounding : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive;
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive;
- gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive);
- return true;
- }
+ gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive);
+ return true;
+ }
};
class LLToolsShowHiddenSelection : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // TomY TODO Merge these
- LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections;
+ bool handleEvent(const LLSD& userdata)
+ {
+ // TomY TODO Merge these
+ LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections;
- gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections);
- return true;
- }
+ gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections);
+ return true;
+ }
};
class LLToolsShowSelectionLightRadius : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- // TomY TODO merge these
- LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius;
+ bool handleEvent(const LLSD& userdata)
+ {
+ // TomY TODO merge these
+ LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius;
- gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius);
- return true;
- }
+ gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius);
+ return true;
+ }
};
class LLToolsEditLinkedParts : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- BOOL select_individuals = !gSavedSettings.getBOOL("EditLinkedParts");
- gSavedSettings.setBOOL( "EditLinkedParts", select_individuals );
- if (select_individuals)
- {
- LLSelectMgr::getInstance()->demoteSelectionToIndividuals();
- }
- else
- {
- LLSelectMgr::getInstance()->promoteSelectionToRoot();
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL select_individuals = !gSavedSettings.getBOOL("EditLinkedParts");
+ gSavedSettings.setBOOL( "EditLinkedParts", select_individuals );
+ if (select_individuals)
+ {
+ LLSelectMgr::getInstance()->demoteSelectionToIndividuals();
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->promoteSelectionToRoot();
+ }
+ return true;
+ }
};
void reload_vertex_shader(void *)
{
- //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
+ //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
}
void handle_dump_avatar_local_textures(void*)
{
- gAgentAvatarp->dumpLocalTextures();
+ gAgentAvatarp->dumpLocalTextures();
}
void handle_dump_timers()
{
- LLTrace::BlockTimer::dumpCurTimes();
+ LLTrace::BlockTimer::dumpCurTimes();
}
void handle_debug_avatar_textures(void*)
{
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (objectp)
- {
- LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) );
- }
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (objectp)
+ {
+ LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) );
+ }
}
void handle_grab_baked_texture(void* data)
{
- EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data);
- if (!isAgentAvatarValid()) return;
-
- const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index);
- LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << LL_ENDL;
- LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;
- LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;
- const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type));
- if(folder_id.notNull())
- {
- std::string name;
- name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
-
- LLUUID item_id;
- item_id.generate();
- LLPermissions perm;
- perm.init(gAgentID,
- gAgentID,
- LLUUID::null,
- LLUUID::null);
- U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
- perm.initMasks(PERM_ALL,
- PERM_ALL,
- PERM_NONE,
- PERM_NONE,
- next_owner_perm);
- time_t creation_date_now = time_corrected();
- LLPointer<LLViewerInventoryItem> item
- = new LLViewerInventoryItem(item_id,
- folder_id,
- perm,
- asset_id,
- asset_type,
- inv_type,
- name,
- LLStringUtil::null,
- LLSaleInfo::DEFAULT,
- LLInventoryItemFlags::II_FLAGS_NONE,
- creation_date_now);
-
- item->updateServer(TRUE);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
-
- // Show the preview panel for textures to let
- // user know that the image is now in inventory.
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
- if(active_panel)
- {
- LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
-
- active_panel->setSelection(item_id, TAKE_FOCUS_NO);
- active_panel->openSelected();
- //LLFloaterInventory::dumpSelectionInformation((void*)view);
- // restore keyboard focus
- gFocusMgr.setKeyboardFocus(focus_ctrl);
- }
- }
- else
- {
- LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
- }
+ EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data);
+ if (!isAgentAvatarValid()) return;
+
+ const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index);
+ LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << LL_ENDL;
+ LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;
+ LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;
+ const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type));
+ if(folder_id.notNull())
+ {
+ std::string name;
+ name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+
+ LLUUID item_id;
+ item_id.generate();
+ LLPermissions perm;
+ perm.init(gAgentID,
+ gAgentID,
+ LLUUID::null,
+ LLUUID::null);
+ U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+ perm.initMasks(PERM_ALL,
+ PERM_ALL,
+ PERM_NONE,
+ PERM_NONE,
+ next_owner_perm);
+ time_t creation_date_now = time_corrected();
+ LLPointer<LLViewerInventoryItem> item
+ = new LLViewerInventoryItem(item_id,
+ folder_id,
+ perm,
+ asset_id,
+ asset_type,
+ inv_type,
+ name,
+ LLStringUtil::null,
+ LLSaleInfo::DEFAULT,
+ LLInventoryItemFlags::II_FLAGS_NONE,
+ creation_date_now);
+
+ item->updateServer(TRUE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
+ // Show the preview panel for textures to let
+ // user know that the image is now in inventory.
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+ if(active_panel)
+ {
+ LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
+
+ active_panel->setSelection(item_id, TAKE_FOCUS_NO);
+ active_panel->openSelected();
+ //LLFloaterInventory::dumpSelectionInformation((void*)view);
+ // restore keyboard focus
+ gFocusMgr.setKeyboardFocus(focus_ctrl);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
+ }
}
BOOL enable_grab_baked_texture(void* data)
{
- EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data);
- if (isAgentAvatarValid())
- {
- return gAgentAvatarp->canGrabBakedTexture(index);
- }
- return FALSE;
+ EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data);
+ if (isAgentAvatarValid())
+ {
+ return gAgentAvatarp->canGrabBakedTexture(index);
+ }
+ return FALSE;
}
// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
// Returns NULL on failure.
LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
{
- if (object)
- {
- if( object->isAttachment() )
- {
- do
- {
- object = (LLViewerObject*) object->getParent();
- }
- while( object && !object->isAvatar() );
- }
- else if( !object->isAvatar() )
- {
- object = NULL;
- }
- }
+ if (object)
+ {
+ if( object->isAttachment() )
+ {
+ do
+ {
+ object = (LLViewerObject*) object->getParent();
+ }
+ while( object && !object->isAvatar() );
+ }
+ else if( !object->isAvatar() )
+ {
+ object = NULL;
+ }
+ }
- return (LLVOAvatar*) object;
+ return (LLVOAvatar*) object;
}
@@ -8423,13 +8484,13 @@ LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
// Returns NULL on failure.
LLVOAvatar* find_avatar_from_object( const LLUUID& object_id )
{
- return find_avatar_from_object( gObjectList.findObject(object_id) );
+ return find_avatar_from_object( gObjectList.findObject(object_id) );
}
void handle_disconnect_viewer(void *)
{
- LLAppViewer::instance()->forceDisconnect(LLTrans::getString("TestingDisconnect"));
+ LLAppViewer::instance()->forceDisconnect(LLTrans::getString("TestingDisconnect"));
}
void force_error_breakpoint(void *)
@@ -8484,30 +8545,30 @@ void force_error_thread_crash(void *)
class LLToolsUseSelectionForGrid : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLSelectMgr::getInstance()->clearGridObjects();
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* objectp)
- {
- LLSelectMgr::getInstance()->addGridObject(objectp);
- return true;
- }
- } func;
- LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
- LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT);
- LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLSelectMgr::getInstance()->clearGridObjects();
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ LLSelectMgr::getInstance()->addGridObject(objectp);
+ return true;
+ }
+ } func;
+ LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
+ LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT);
+ LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT);
+ return true;
+ }
};
void handle_test_load_url(void*)
{
- LLWeb::loadURL("");
- LLWeb::loadURL("hacker://www.google.com/");
- LLWeb::loadURL("http");
- LLWeb::loadURL("http://www.google.com/");
+ LLWeb::loadURL("");
+ LLWeb::loadURL("hacker://www.google.com/");
+ LLWeb::loadURL("http");
+ LLWeb::loadURL("http://www.google.com/");
}
//
@@ -8521,86 +8582,86 @@ LLViewerMenuHolderGL::LLViewerMenuHolderGL(const LLViewerMenuHolderGL::Params& p
BOOL LLViewerMenuHolderGL::hideMenus()
{
- BOOL handled = FALSE;
+ BOOL handled = FALSE;
+
+ if (LLMenuHolderGL::hideMenus())
+ {
+ handled = TRUE;
+ }
- if (LLMenuHolderGL::hideMenus())
- {
- handled = TRUE;
- }
+ // drop pie menu selection
+ mParcelSelection = NULL;
+ mObjectSelection = NULL;
- // drop pie menu selection
- mParcelSelection = NULL;
- mObjectSelection = NULL;
+ if (gMenuBarView)
+ {
+ gMenuBarView->clearHoverItem();
+ gMenuBarView->resetMenuTrigger();
+ }
- if (gMenuBarView)
- {
- gMenuBarView->clearHoverItem();
- gMenuBarView->resetMenuTrigger();
- }
-
- return handled;
+ return handled;
}
-void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle<LLParcelSelection> selection)
-{
- mParcelSelection = selection;
+void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle<LLParcelSelection> selection)
+{
+ mParcelSelection = selection;
}
-void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle<LLObjectSelection> selection)
-{
- mObjectSelection = selection;
+void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle<LLObjectSelection> selection)
+{
+ mObjectSelection = selection;
}
const LLRect LLViewerMenuHolderGL::getMenuRect() const
{
- return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT);
+ return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT);
}
void handle_web_browser_test(const LLSD& param)
{
- std::string url = param.asString();
- if (url.empty())
- {
- url = "about:blank";
- }
- LLWeb::loadURLInternal(url);
+ std::string url = param.asString();
+ if (url.empty())
+ {
+ url = "about:blank";
+ }
+ LLWeb::loadURLInternal(url);
}
bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if ( option == 0 ) // YES
- {
- //clear cache
- LLAppViewer::instance()->purgeCacheImmediate();
- }
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if ( option == 0 ) // YES
+ {
+ //clear cache
+ LLAppViewer::instance()->purgeCacheImmediate();
+ }
- return false;
+ return false;
}
void handle_cache_clear_immediately()
{
- LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
+ LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
}
void handle_web_content_test(const LLSD& param)
{
- std::string url = param.asString();
- LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true);
+ std::string url = param.asString();
+ LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true);
}
void handle_show_url(const LLSD& param)
{
- std::string url = param.asString();
- if (LLWeb::useExternalBrowser(url))
- {
- LLWeb::loadURLExternal(url);
- }
- else
- {
- LLWeb::loadURLInternal(url);
- }
+ std::string url = param.asString();
+ if (LLWeb::useExternalBrowser(url))
+ {
+ LLWeb::loadURLExternal(url);
+ }
+ else
+ {
+ LLWeb::loadURLInternal(url);
+ }
}
@@ -8612,383 +8673,383 @@ void handle_report_bug(const LLSD& param)
void handle_buy_currency_test(void*)
{
- std::string url =
- "http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]";
+ std::string url =
+ "http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]";
- LLStringUtil::format_map_t replace;
- replace["[AGENT_ID]"] = gAgent.getID().asString();
- replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString();
- replace["[LANGUAGE]"] = LLUI::getLanguage();
- LLStringUtil::format(url, replace);
+ LLStringUtil::format_map_t replace;
+ replace["[AGENT_ID]"] = gAgent.getID().asString();
+ replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString();
+ replace["[LANGUAGE]"] = LLUI::getLanguage();
+ LLStringUtil::format(url, replace);
- LL_INFOS() << "buy currency url " << url << LL_ENDL;
+ LL_INFOS() << "buy currency url " << url << LL_ENDL;
- LLFloaterReg::showInstance("buy_currency_html", LLSD(url));
+ LLFloaterReg::showInstance("buy_currency_html", LLSD(url));
}
// SUNSHINE CLEANUP - is only the request update at the end needed now?
void handle_rebake_textures(void*)
{
- if (!isAgentAvatarValid()) return;
+ if (!isAgentAvatarValid()) return;
- // Slam pending upload count to "unstick" things
- bool slam_for_debug = true;
- gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
- if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
- {
- LLAppearanceMgr::instance().requestServerAppearanceUpdate();
- }
+ // Slam pending upload count to "unstick" things
+ bool slam_for_debug = true;
+ gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
+ if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+ {
+ LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+ }
}
void toggle_visibility(void* user_data)
{
- LLView* viewp = (LLView*)user_data;
- viewp->setVisible(!viewp->getVisible());
+ LLView* viewp = (LLView*)user_data;
+ viewp->setVisible(!viewp->getVisible());
}
BOOL get_visibility(void* user_data)
{
- LLView* viewp = (LLView*)user_data;
- return viewp->getVisible();
+ LLView* viewp = (LLView*)user_data;
+ return viewp->getVisible();
}
class LLViewShowHoverTips : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gSavedSettings.setBOOL("ShowHoverTips", !gSavedSettings.getBOOL("ShowHoverTips"));
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ gSavedSettings.setBOOL("ShowHoverTips", !gSavedSettings.getBOOL("ShowHoverTips"));
+ return true;
+ }
};
class LLViewCheckShowHoverTips : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gSavedSettings.getBOOL("ShowHoverTips");
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gSavedSettings.getBOOL("ShowHoverTips");
+ return new_value;
+ }
};
class LLViewHighlightTransparent : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
// invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag
- gPipeline.rebuildDrawInfo();
- return true;
- }
+ gPipeline.rebuildDrawInfo();
+ return true;
+ }
};
class LLViewCheckHighlightTransparent : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLDrawPoolAlpha::sShowDebugAlpha;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLDrawPoolAlpha::sShowDebugAlpha;
+ return new_value;
+ }
};
class LLViewBeaconWidth : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string width = userdata.asString();
- if(width == "1")
- {
- gSavedSettings.setS32("DebugBeaconLineWidth", 1);
- }
- else if(width == "4")
- {
- gSavedSettings.setS32("DebugBeaconLineWidth", 4);
- }
- else if(width == "16")
- {
- gSavedSettings.setS32("DebugBeaconLineWidth", 16);
- }
- else if(width == "32")
- {
- gSavedSettings.setS32("DebugBeaconLineWidth", 32);
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string width = userdata.asString();
+ if(width == "1")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 1);
+ }
+ else if(width == "4")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 4);
+ }
+ else if(width == "16")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 16);
+ }
+ else if(width == "32")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 32);
+ }
+
+ return true;
+ }
};
class LLViewToggleBeacon : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string beacon = userdata.asString();
- if (beacon == "scriptsbeacon")
- {
- LLPipeline::toggleRenderScriptedBeacons();
- gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
- // toggle the other one off if it's on
- if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
- {
- LLPipeline::toggleRenderScriptedTouchBeacons();
- gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
- }
- }
- else if (beacon == "physicalbeacon")
- {
- LLPipeline::toggleRenderPhysicalBeacons();
- gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() );
- }
- else if (beacon == "moapbeacon")
- {
- LLPipeline::toggleRenderMOAPBeacons();
- gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() );
- }
- else if (beacon == "soundsbeacon")
- {
- LLPipeline::toggleRenderSoundBeacons();
- gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() );
- }
- else if (beacon == "particlesbeacon")
- {
- LLPipeline::toggleRenderParticleBeacons();
- gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() );
- }
- else if (beacon == "scripttouchbeacon")
- {
- LLPipeline::toggleRenderScriptedTouchBeacons();
- gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
- // toggle the other one off if it's on
- if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
- {
- LLPipeline::toggleRenderScriptedBeacons();
- gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
- }
- }
- else if (beacon == "sunbeacon")
- {
- gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon"));
- }
- else if (beacon == "moonbeacon")
- {
- gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon"));
- }
- else if (beacon == "renderbeacons")
- {
- LLPipeline::toggleRenderBeacons();
- gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
- // toggle the other one on if it's not
- if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
- {
- LLPipeline::toggleRenderHighlights();
- gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
- }
- }
- else if (beacon == "renderhighlights")
- {
- LLPipeline::toggleRenderHighlights();
- gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
- // toggle the other one on if it's not
- if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
- {
- LLPipeline::toggleRenderBeacons();
- gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
- }
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string beacon = userdata.asString();
+ if (beacon == "scriptsbeacon")
+ {
+ LLPipeline::toggleRenderScriptedBeacons();
+ gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
+ // toggle the other one off if it's on
+ if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
+ {
+ LLPipeline::toggleRenderScriptedTouchBeacons();
+ gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
+ }
+ }
+ else if (beacon == "physicalbeacon")
+ {
+ LLPipeline::toggleRenderPhysicalBeacons();
+ gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() );
+ }
+ else if (beacon == "moapbeacon")
+ {
+ LLPipeline::toggleRenderMOAPBeacons();
+ gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() );
+ }
+ else if (beacon == "soundsbeacon")
+ {
+ LLPipeline::toggleRenderSoundBeacons();
+ gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() );
+ }
+ else if (beacon == "particlesbeacon")
+ {
+ LLPipeline::toggleRenderParticleBeacons();
+ gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() );
+ }
+ else if (beacon == "scripttouchbeacon")
+ {
+ LLPipeline::toggleRenderScriptedTouchBeacons();
+ gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
+ // toggle the other one off if it's on
+ if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
+ {
+ LLPipeline::toggleRenderScriptedBeacons();
+ gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
+ }
+ }
+ else if (beacon == "sunbeacon")
+ {
+ gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon"));
+ }
+ else if (beacon == "moonbeacon")
+ {
+ gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon"));
+ }
+ else if (beacon == "renderbeacons")
+ {
+ LLPipeline::toggleRenderBeacons();
+ gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
+ // toggle the other one on if it's not
+ if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
+ {
+ LLPipeline::toggleRenderHighlights();
+ gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
+ }
+ }
+ else if (beacon == "renderhighlights")
+ {
+ LLPipeline::toggleRenderHighlights();
+ gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
+ // toggle the other one on if it's not
+ if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
+ {
+ LLPipeline::toggleRenderBeacons();
+ gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
+ }
+ }
+
+ return true;
+ }
};
class LLViewCheckBeaconEnabled : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string beacon = userdata.asString();
- bool new_value = false;
- if (beacon == "scriptsbeacon")
- {
- new_value = gSavedSettings.getBOOL( "scriptsbeacon");
- LLPipeline::setRenderScriptedBeacons(new_value);
- }
- else if (beacon == "moapbeacon")
- {
- new_value = gSavedSettings.getBOOL( "moapbeacon");
- LLPipeline::setRenderMOAPBeacons(new_value);
- }
- else if (beacon == "physicalbeacon")
- {
- new_value = gSavedSettings.getBOOL( "physicalbeacon");
- LLPipeline::setRenderPhysicalBeacons(new_value);
- }
- else if (beacon == "soundsbeacon")
- {
- new_value = gSavedSettings.getBOOL( "soundsbeacon");
- LLPipeline::setRenderSoundBeacons(new_value);
- }
- else if (beacon == "particlesbeacon")
- {
- new_value = gSavedSettings.getBOOL( "particlesbeacon");
- LLPipeline::setRenderParticleBeacons(new_value);
- }
- else if (beacon == "scripttouchbeacon")
- {
- new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
- LLPipeline::setRenderScriptedTouchBeacons(new_value);
- }
- else if (beacon == "renderbeacons")
- {
- new_value = gSavedSettings.getBOOL( "renderbeacons");
- LLPipeline::setRenderBeacons(new_value);
- }
- else if (beacon == "renderhighlights")
- {
- new_value = gSavedSettings.getBOOL( "renderhighlights");
- LLPipeline::setRenderHighlights(new_value);
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string beacon = userdata.asString();
+ bool new_value = false;
+ if (beacon == "scriptsbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "scriptsbeacon");
+ LLPipeline::setRenderScriptedBeacons(new_value);
+ }
+ else if (beacon == "moapbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "moapbeacon");
+ LLPipeline::setRenderMOAPBeacons(new_value);
+ }
+ else if (beacon == "physicalbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "physicalbeacon");
+ LLPipeline::setRenderPhysicalBeacons(new_value);
+ }
+ else if (beacon == "soundsbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "soundsbeacon");
+ LLPipeline::setRenderSoundBeacons(new_value);
+ }
+ else if (beacon == "particlesbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "particlesbeacon");
+ LLPipeline::setRenderParticleBeacons(new_value);
+ }
+ else if (beacon == "scripttouchbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
+ LLPipeline::setRenderScriptedTouchBeacons(new_value);
+ }
+ else if (beacon == "renderbeacons")
+ {
+ new_value = gSavedSettings.getBOOL( "renderbeacons");
+ LLPipeline::setRenderBeacons(new_value);
+ }
+ else if (beacon == "renderhighlights")
+ {
+ new_value = gSavedSettings.getBOOL( "renderhighlights");
+ LLPipeline::setRenderHighlights(new_value);
+ }
+ return new_value;
+ }
};
class LLViewToggleRenderType : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string type = userdata.asString();
- if (type == "hideparticles")
- {
- LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string type = userdata.asString();
+ if (type == "hideparticles")
+ {
+ LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
+ }
+ return true;
+ }
};
class LLViewCheckRenderType : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string type = userdata.asString();
- bool new_value = false;
- if (type == "hideparticles")
- {
- new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES);
- }
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string type = userdata.asString();
+ bool new_value = false;
+ if (type == "hideparticles")
+ {
+ new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES);
+ }
+ return new_value;
+ }
};
class LLViewStatusAway : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return (gAgent.isInitialized() && gAgent.getAFK());
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (gAgent.isInitialized() && gAgent.getAFK());
+ }
};
class LLViewStatusDoNotDisturb : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
+ }
};
class LLViewShowHUDAttachments : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments;
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments;
+ return true;
+ }
};
class LLViewCheckHUDAttachments : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLPipeline::sShowHUDAttachments;
- return new_value;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLPipeline::sShowHUDAttachments;
+ return new_value;
+ }
};
class LLEditEnableTakeOff : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string clothing = userdata.asString();
- LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
- if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT)
- return LLAgentWearables::selfHasWearable(type);
- return false;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string clothing = userdata.asString();
+ LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
+ if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT)
+ return LLAgentWearables::selfHasWearable(type);
+ return false;
+ }
};
class LLEditTakeOff : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string clothing = userdata.asString();
- if (clothing == "all")
- LLAppearanceMgr::instance().removeAllClothesFromAvatar();
- else
- {
- LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
- if (type >= LLWearableType::WT_SHAPE
- && type < LLWearableType::WT_COUNT
- && (gAgentWearables.getWearableCount(type) > 0))
- {
- // MULTI-WEARABLES: assuming user wanted to remove top shirt.
- U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
- LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
- LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
- }
-
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string clothing = userdata.asString();
+ if (clothing == "all")
+ LLAppearanceMgr::instance().removeAllClothesFromAvatar();
+ else
+ {
+ LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
+ if (type >= LLWearableType::WT_SHAPE
+ && type < LLWearableType::WT_COUNT
+ && (gAgentWearables.getWearableCount(type) > 0))
+ {
+ // MULTI-WEARABLES: assuming user wanted to remove top shirt.
+ U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
+ LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
+ LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
+ }
+
+ }
+ return true;
+ }
};
class LLToolsSelectTool : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string tool_name = userdata.asString();
- if (tool_name == "focus")
- {
- LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1);
- }
- else if (tool_name == "move")
- {
- LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2);
- }
- else if (tool_name == "edit")
- {
- LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3);
- }
- else if (tool_name == "create")
- {
- LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4);
- }
- else if (tool_name == "land")
- {
- LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5);
- }
-
- // Note: if floater is not visible LLViewerWindow::updateLayout() will
- // attempt to open it, but it won't bring it to front or de-minimize.
- if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost()))
- {
- gFloaterTools->setMinimized(FALSE);
- gFloaterTools->openFloater();
- gFloaterTools->setVisibleAndFrontmost(TRUE);
- }
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string tool_name = userdata.asString();
+ if (tool_name == "focus")
+ {
+ LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1);
+ }
+ else if (tool_name == "move")
+ {
+ LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2);
+ }
+ else if (tool_name == "edit")
+ {
+ LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3);
+ }
+ else if (tool_name == "create")
+ {
+ LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4);
+ }
+ else if (tool_name == "land")
+ {
+ LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5);
+ }
+
+ // Note: if floater is not visible LLViewerWindow::updateLayout() will
+ // attempt to open it, but it won't bring it to front or de-minimize.
+ if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost()))
+ {
+ gFloaterTools->setMinimized(FALSE);
+ gFloaterTools->openFloater();
+ gFloaterTools->setVisibleAndFrontmost(TRUE);
+ }
+ return true;
+ }
};
/// WINDLIGHT callbacks
class LLWorldEnvSettings : public view_listener_t
-{
+{
void defocusEnvFloaters()
{
//currently there is only one instance of each floater
@@ -9003,180 +9064,180 @@ class LLWorldEnvSettings : public view_listener_t
}
}
- bool handleEvent(const LLSD& userdata)
- {
- std::string event_name = userdata.asString();
-
- if (event_name == "sunrise")
- {
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string event_name = userdata.asString();
+
+ if (event_name == "sunrise")
+ {
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
- }
- else if (event_name == "noon")
- {
+ }
+ else if (event_name == "noon")
+ {
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
- }
+ }
else if (event_name == "legacy noon")
{
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
}
- else if (event_name == "sunset")
- {
+ else if (event_name == "sunset")
+ {
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
- }
- else if (event_name == "midnight")
- {
+ }
+ else if (event_name == "midnight")
+ {
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
- }
+ }
else if (event_name == "region")
- {
+ {
// reset probe data when reverting back to region sky setting
gPipeline.mReflectionMapManager.reset();
LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
- }
+ }
else if (event_name == "pause_clouds")
{
if (LLEnvironment::instance().isCloudScrollPaused())
LLEnvironment::instance().resumeCloudScroll();
- else
+ else
LLEnvironment::instance().pauseCloudScroll();
}
else if (event_name == "adjust_tool")
- {
+ {
LLFloaterReg::showInstance("env_adjust_snapshot");
}
else if (event_name == "my_environs")
{
LLFloaterReg::showInstance("my_environments");
- }
+ }
- return true;
- }
+ return true;
+ }
};
class LLWorldEnableEnvSettings : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool result = false;
- std::string event_name = userdata.asString();
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool result = false;
+ 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 (!sky)
- {
- return (event_name == "region");
- }
+ if (!sky)
+ {
+ return (event_name == "region");
+ }
std::string skyname = (sky) ? sky->getName() : "";
LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
- if (event_name == "sunrise")
- {
+ if (event_name == "sunrise")
+ {
result = (skyid == LLEnvironment::KNOWN_SKY_SUNRISE);
- }
- else if (event_name == "noon")
- {
+ }
+ else if (event_name == "noon")
+ {
result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY);
- }
+ }
else if (event_name == "legacy noon")
{
result = (skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY);
}
- else if (event_name == "sunset")
- {
+ else if (event_name == "sunset")
+ {
result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET);
- }
- else if (event_name == "midnight")
- {
+ }
+ 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;
- }
+ }
+ else if (event_name == "region")
+ {
+ return false;
+ }
+ else
+ {
+ LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL;
+ }
+ return result;
+ }
};
class LLWorldEnvPreset : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- std::string item = userdata.asString();
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string item = userdata.asString();
- if (item == "new_water")
- {
+ if (item == "new_water")
+ {
LLFloaterReg::showInstance("env_fixed_environmentent_water", "new");
- }
- else if (item == "edit_water")
- {
+ }
+ else if (item == "edit_water")
+ {
LLFloaterReg::showInstance("env_fixed_environmentent_water", "edit");
- }
- else if (item == "new_sky")
- {
+ }
+ else if (item == "new_sky")
+ {
LLFloaterReg::showInstance("env_fixed_environmentent_sky", "new");
- }
- else if (item == "edit_sky")
- {
+ }
+ else if (item == "edit_sky")
+ {
LLFloaterReg::showInstance("env_fixed_environmentent_sky", "edit");
- }
- else if (item == "new_day_cycle")
- {
+ }
+ else if (item == "new_day_cycle")
+ {
LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
- }
- else if (item == "edit_day_cycle")
- {
- LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
- }
- else
- {
- LL_WARNS() << "Unknown item selected" << LL_ENDL;
- }
+ }
+ else if (item == "edit_day_cycle")
+ {
+ LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
+ }
+ else
+ {
+ LL_WARNS() << "Unknown item selected" << LL_ENDL;
+ }
- return true;
- }
+ return true;
+ }
};
class LLWorldEnableEnvPreset : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
- return false;
- }
+ return false;
+ }
};
/// Post-Process callbacks
class LLWorldPostProcess : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterReg::showInstance("env_post_process");
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterReg::showInstance("env_post_process");
+ return true;
+ }
};
class LLWorldCheckBanLines : public view_listener_t
@@ -9200,684 +9261,689 @@ class LLWorldShowBanLines : public view_listener_t
void handle_flush_name_caches()
{
- if (gCacheName) gCacheName->clear();
+ if (gCacheName) gCacheName->clear();
}
class LLUploadCostCalculator : public view_listener_t
{
- std::string mCostStr;
-
- bool handleEvent(const LLSD& userdata)
- {
- std::vector<std::string> fields;
- std::string str = userdata.asString();
- boost::split(fields, str, boost::is_any_of(","));
- if (fields.size()<1)
- {
- return false;
- }
- std::string menu_name = fields[0];
- std::string asset_type_str = "texture";
- if (fields.size()>1)
- {
- asset_type_str = fields[1];
- }
- LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL;
- calculateCost(asset_type_str);
- gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);
-
- return true;
- }
-
- void calculateCost(const std::string& asset_type_str);
+ std::string mCostStr;
+
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::vector<std::string> fields;
+ std::string str = userdata.asString();
+ boost::split(fields, str, boost::is_any_of(","));
+ if (fields.size()<1)
+ {
+ return false;
+ }
+ std::string menu_name = fields[0];
+ std::string asset_type_str = "texture";
+ if (fields.size()>1)
+ {
+ asset_type_str = fields[1];
+ }
+ LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL;
+ calculateCost(asset_type_str);
+ gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);
+
+ return true;
+ }
+
+ void calculateCost(const std::string& asset_type_str);
public:
- LLUploadCostCalculator()
- {
- }
+ LLUploadCostCalculator()
+ {
+ }
};
class LLUpdateMembershipLabel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText");
- gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str);
+ bool handleEvent(const LLSD& userdata)
+ {
+ const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText");
+ gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str);
- return true;
- }
+ return true;
+ }
};
void handle_voice_morphing_subscribe()
{
- LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
+ LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
}
void handle_premium_voice_morphing_subscribe()
{
- LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url"));
+ LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url"));
}
class LLToggleUIHints : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints");
- // toggle
- ui_hints_enabled = !ui_hints_enabled;
- gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints");
+ // toggle
+ ui_hints_enabled = !ui_hints_enabled;
+ gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled);
+ return true;
+ }
};
void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str)
{
- S32 upload_cost = -1;
-
- if (asset_type_str == "texture")
- {
- upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
- }
- else if (asset_type_str == "animation")
- {
- upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
- }
- else if (asset_type_str == "sound")
- {
- upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost();
- }
- if (upload_cost < 0)
- {
- LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL;
- }
- mCostStr = std::to_string(upload_cost);
+ S32 upload_cost = -1;
+
+ if (asset_type_str == "texture")
+ {
+ // This use minimal texture cost to allow bulk and
+ // texture upload menu options to be visible
+ upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ }
+ else if (asset_type_str == "animation")
+ {
+ upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
+ }
+ else if (asset_type_str == "sound")
+ {
+ upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost();
+ }
+ if (upload_cost < 0)
+ {
+ LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL;
+ }
+ mCostStr = std::to_string(upload_cost);
}
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
{
- static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
- gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(gMenuHolder->hasVisibleMenu())
- {
- gMenuHolder->hideMenus();
- }
- show_navbar_context_menu->buildDrawLabels();
- show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
+ static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
+ gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(gMenuHolder->hasVisibleMenu())
+ {
+ gMenuHolder->hideMenus();
+ }
+ show_navbar_context_menu->buildDrawLabels();
+ show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
}
void show_topinfobar_context_menu(LLView* ctrl, S32 x, S32 y)
{
- static LLMenuGL* show_topbarinfo_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_topinfobar.xml",
- gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ static LLMenuGL* show_topbarinfo_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_topinfobar.xml",
+ gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- LLMenuItemGL* landmark_item = show_topbarinfo_context_menu->getChild<LLMenuItemGL>("Landmark");
- if (!LLLandmarkActions::landmarkAlreadyExists())
- {
- landmark_item->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
- }
- else
- {
- landmark_item->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
- }
+ LLMenuItemGL* landmark_item = show_topbarinfo_context_menu->getChild<LLMenuItemGL>("Landmark");
+ if (!LLLandmarkActions::landmarkAlreadyExists())
+ {
+ landmark_item->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
+ }
+ else
+ {
+ landmark_item->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
+ }
- if(gMenuHolder->hasVisibleMenu())
- {
- gMenuHolder->hideMenus();
- }
+ if(gMenuHolder->hasVisibleMenu())
+ {
+ gMenuHolder->hideMenus();
+ }
- show_topbarinfo_context_menu->buildDrawLabels();
- show_topbarinfo_context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(ctrl, show_topbarinfo_context_menu, x, y);
+ show_topbarinfo_context_menu->buildDrawLabels();
+ show_topbarinfo_context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(ctrl, show_topbarinfo_context_menu, x, y);
}
void initialize_edit_menu()
{
- view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo");
- view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo");
- view_listener_t::addMenu(new LLEditCut(), "Edit.Cut");
- view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy");
- view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste");
- view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
- view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
- view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
- view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
- view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
- view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
- view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut");
- view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy");
- view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste");
- view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
- view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
- view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
+ view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo");
+ view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo");
+ view_listener_t::addMenu(new LLEditCut(), "Edit.Cut");
+ view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy");
+ view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste");
+ view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
+ view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
+ view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
+ view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
+ view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
+ view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
+ view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut");
+ view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy");
+ view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste");
+ view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
+ view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
+ view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
}
void initialize_spellcheck_menu()
{
- LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
- LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+ LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
- commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
- enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
- commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
- enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
- commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
- enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
+ commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
+ enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
+ commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
+ enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
+ commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
+ enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
}
void initialize_menus()
{
- // A parameterized event handler used as ctrl-8/9/0 zoom controls below.
- class LLZoomer : public view_listener_t
- {
- public:
- // The "mult" parameter says whether "val" is a multiplier or used to set the value.
- LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {}
- bool handleEvent(const LLSD& userdata)
- {
- F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal;
- LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad);
- gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it.
- return true;
- }
- private:
- F32 mVal;
- bool mMult;
- };
-
- LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
- LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
-
- // Generic enable and visible
- // Don't prepend MenuName.Foo because these can be used in any menu.
- enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
-
- enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
-
- view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
-
- view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel");
-
- enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
-
- // Agent
- commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
- enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));
- commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));
- commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));
- commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
- enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2));
- enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2));
-
- // File menu
- init_menu_file();
-
- view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
- view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
- view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape");
- view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
- view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
- commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
+ // A parameterized event handler used as ctrl-8/9/0 zoom controls below.
+ class LLZoomer : public view_listener_t
+ {
+ public:
+ // The "mult" parameter says whether "val" is a multiplier or used to set the value.
+ LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {}
+ bool handleEvent(const LLSD& userdata)
+ {
+ F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal;
+ LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad);
+ gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it.
+ return true;
+ }
+ private:
+ F32 mVal;
+ bool mMult;
+ };
+
+ LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+
+ // Generic enable and visible
+ // Don't prepend MenuName.Foo because these can be used in any menu.
+ enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
+
+ enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
+
+ view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
+
+ view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel");
+
+ enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
+
+ // Agent
+ commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
+ enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));
+ commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));
+ commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));
+ commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
+ enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2));
+ enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2));
+
+ // File menu
+ init_menu_file();
+
+ view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
+ view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
+ view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape");
+ view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
+ view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
+ commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
commit.add("NowWearing", boost::bind(&handle_now_wearing));
- commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
- commit.add("EditShape", boost::bind(&handle_edit_shape));
- commit.add("HoverHeight", boost::bind(&handle_hover_height));
- commit.add("EditPhysics", boost::bind(&handle_edit_physics));
-
- // View menu
- view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
- view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam");
- view_listener_t::addMenu(new LLViewResetView(), "View.ResetView");
- view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
- view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
- view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
- view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
- view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
- view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut");
- view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
- view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
- view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
- view_listener_t::addMenu(new LLViewToggleUI(), "View.ToggleUI");
-
- view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook");
- view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam");
- view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter");
-
- view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
- view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
- view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
- view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
- view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
- view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
- view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
-
- //Communicate Nearby chat
- view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
-
- // Communicate > Voice morphing > Subscribe...
- commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
- // Communicate > Voice morphing > Premium perk...
- commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe));
- LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
- enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
- , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
- commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
- , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
-
- // World menu
- view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
- view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
- view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile");
- view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
- view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
- view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
- view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
- view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");
-
- view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
- view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
- view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome");
- view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand");
-
- view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun");
-
- view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings");
- view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings");
- view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset");
- view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset");
- view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
+ commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
+ commit.add("EditShape", boost::bind(&handle_edit_shape));
+ commit.add("HoverHeight", boost::bind(&handle_hover_height));
+ commit.add("EditPhysics", boost::bind(&handle_edit_physics));
+
+ // View menu
+ view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
+ view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam");
+ view_listener_t::addMenu(new LLViewResetView(), "View.ResetView");
+ view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
+ view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
+ view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
+ view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
+ view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
+ view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut");
+ view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
+ view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
+ view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
+ view_listener_t::addMenu(new LLViewToggleUI(), "View.ToggleUI");
+
+ view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook");
+ view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam");
+ view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter");
+
+ view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
+ view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
+ view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
+ view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
+ view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
+ view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
+ view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
+
+ //Communicate Nearby chat
+ view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
+
+ // Communicate > Voice morphing > Subscribe...
+ commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+ // Communicate > Voice morphing > Premium perk...
+ commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe));
+ LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
+ enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
+ , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+ commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
+ , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+
+ // World menu
+ view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
+ view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
+ view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile");
+ view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
+ view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
+ view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
+ view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
+ view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");
+
+ view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
+ view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
+ view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome");
+ view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand");
+
+ view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun");
+
+ view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings");
+ view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings");
+ view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset");
+ view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset");
+ view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
view_listener_t::addMenu(new LLWorldCheckBanLines() , "World.CheckBanLines");
view_listener_t::addMenu(new LLWorldShowBanLines() , "World.ShowBanLines");
- // Tools menu
- view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
- view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
- view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
+ // Tools menu
+ view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
+ view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
+ view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes");
- view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
- view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
- view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
- view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts");
- view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
- view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
- view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart");
- commit.add("Tools.Link", boost::bind(&handle_link_objects));
- commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
- view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
- view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
- view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
- commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2));
- commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take));
- commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy));
- view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
- view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
-
- view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
- view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart");
- enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance()));
- enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance()));
- view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
- enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy));
- enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object));
- enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object));
- view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
-
- view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding");
- view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView");
- view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion");
- view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion");
-
- // Help menu
- // most items use the ShowFloater method
- view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
-
- // Advanced menu
- view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
- view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");
- view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole");
-
- // Advanced > HUD Info
- view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo");
- view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo");
-
- // Advanced Other Settings
- view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache");
-
- // Advanced > Render > Types
- view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType");
- view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType");
-
- //// Advanced > Render > Features
- view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
- view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
-
- view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity");
- view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity");
-
- // Advanced > Render > Info Displays
- view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
- view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
- view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
- commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));
- view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
- view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
- // Develop > Render
- view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
- view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
- view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
- view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame");
- view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
- view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
- view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
- view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
- view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
- view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
-
- #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
- view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode");
- view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode");
- #endif
-
- // Advanced > World
- view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera");
- view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
+ view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
+ view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
+ view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
+ view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts");
+ view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
+ view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
+ view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart");
+ commit.add("Tools.Link", boost::bind(&handle_link_objects));
+ commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
+ view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
+ view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
+ view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
+ commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2));
+ commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take));
+ commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy));
+ view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
+ view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
+
+ view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
+ view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart");
+ enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance()));
+ enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance()));
+ view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
+ enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy));
+ enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object));
+ enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object));
+ view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
+
+ view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding");
+ view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView");
+ view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion");
+ view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion");
+
+ // Help menu
+ // most items use the ShowFloater method
+ view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
+
+ // Advanced menu
+ view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
+ view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");
+ view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole");
+
+ // Advanced > HUD Info
+ view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo");
+ view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo");
+
+ // Advanced Other Settings
+ view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache");
+
+ // Advanced > Render > Types
+ view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType");
+ view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType");
+
+ //// Advanced > Render > Features
+ view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
+ view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
+
+ view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity");
+ view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity");
+
+ // Advanced > Render > Info Displays
+ view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
+ view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
+ view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
+ commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));
+ view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
+ view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
+ // Develop > Render
+ view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
+ view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
+ view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
+ view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame");
+ view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
+ view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
+ view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
+ view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
+ view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
+ view_listener_t::addMenu(new LLAdvancedClickHDRIPreview(), "Advanced.ClickHDRIPreview");
+ view_listener_t::addMenu(new LLAdvancedClickGLTFScenePreview(), "Advanced.ClickGLTFScenePreview");
+ view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
+ view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
+
+ #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+ view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
+ view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode");
+ view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode");
+ #endif
+
+ // Advanced > World
+ view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera");
+ view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
view_listener_t::addMenu(new LLAdvancedToggleStatsRecorder(), "Advanced.ToggleStatsRecorder");
view_listener_t::addMenu(new LLAdvancedCheckStatsRecorder(), "Advanced.CheckStatsRecorder");
view_listener_t::addMenu(new LLAdvancedToggleInterestList360Mode(), "Advanced.ToggleInterestList360Mode");
view_listener_t::addMenu(new LLAdvancedCheckInterestList360Mode(), "Advanced.CheckInterestList360Mode");
view_listener_t::addMenu(new LLAdvancedResetInterestLists(), "Advanced.ResetInterestLists");
- // Advanced > UI
- commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
- commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater
- commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
- commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2));
- view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
- view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
- view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
- commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) );
- commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) );
- view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo");
- view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo");
- view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks");
- view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks");
- view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews");
- view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews");
- view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode");
- view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode");
- view_listener_t::addMenu(new LLAdvancedCheckDebugCamera(), "Advanced.CheckDebugCamera");
- view_listener_t::addMenu(new LLAdvancedToggleDebugCamera(), "Advanced.ToggleDebugCamera");
- view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips");
- view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips");
- view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents");
- view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents");
- view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys");
- view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys");
- view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc");
- view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc");
-
- // Advanced > XUI
- commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance()));
- view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames");
- view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames");
- view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs");
- commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches));
-
- // Advanced > Character > Grab Baked Texture
- view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture");
- view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture");
-
- // Advanced > Character > Character Tests
- view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
- view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
- view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
-
- view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
- view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
-
- // Advanced > Character > Animation Speed
- view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster");
- view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower");
- view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll");
-
- // Advanced > Character (toplevel)
- view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
- view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");
- view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo");
- view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo");
- view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt");
- view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt");
- view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt");
- view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt");
- view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates");
- view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates");
- view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD");
- view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD");
- view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis");
- view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
- view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
- view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
- view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
- view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
- // Advanced > Network
- view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
- view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
- view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+ // Advanced > UI
+ commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
+ commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater
+ commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
+ commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2));
+ view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
+ view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
+ view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
+ commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) );
+ commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) );
+ view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo");
+ view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugCamera(), "Advanced.CheckDebugCamera");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugCamera(), "Advanced.ToggleDebugCamera");
+ view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips");
+ view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc");
+
+ // Advanced > XUI
+ commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance()));
+ view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames");
+ view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames");
+ view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs");
+ commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches));
+
+ // Advanced > Character > Grab Baked Texture
+ view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture");
+ view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture");
+
+ // Advanced > Character > Character Tests
+ view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
+ view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
+ view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
+
+ view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
+ view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
+
+ // Advanced > Character > Animation Speed
+ view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster");
+ view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower");
+ view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll");
+
+ // Advanced > Character (toplevel)
+ view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
+ view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");
+ view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo");
+ view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo");
+ view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt");
+ view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt");
+ view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt");
+ view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates");
+ view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD");
+ view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
+ view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
+ view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
+ view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
+ view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
+ // Advanced > Network
+ view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
+ view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
+ view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
// Advanced > Cache
view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
- // Advanced > Recorder
- view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
- view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
- view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
- view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
+ // Advanced > Recorder
+ view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
+ view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
+ view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
+ view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
- // Advanced > Debugging
- view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
- view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
+ // Advanced > Debugging
+ view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
+ view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg");
- view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
- view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
- view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
- view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
+ view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
view_listener_t::addMenu(new LLAdvancedForceOSException(), "Advanced.ForceErrorOSException");
- view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
- view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
+ view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
- view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
+ view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
- // Advanced (toplevel)
- view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
- view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
- view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
+ // Advanced (toplevel)
+ view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
+ view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
+ view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
- view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
- view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
- view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
- view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions");
- view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector");
-
- view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
- view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
-
- // Develop >Set logging level
- view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
- view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
-
- //Develop (clear cache immediately)
- commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
-
- // Develop (Fonts debugging)
- commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts));
- commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures));
-
- // Admin >Object
- view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
- view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
- view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive");
- view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete");
- view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock");
- view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs");
-
- // Admin >Parcel
- view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe");
- view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent");
- view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand");
-
- // Admin >Region
- view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData");
- // Admin top level
- view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
-
- // Self context menu
- view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand");
- enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));
- view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
-
- view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
-
- // we don't use boost::bind directly to delay side tray construction
- view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab");
- view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab");
-
- // Avatar pie menu
- view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode");
- view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode");
- view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
- view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
- view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
- commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD()));
- view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");
- view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
- view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
- commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
- commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector));
- view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
- view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
- enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
- view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
- view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
- view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
- view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
- view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
- view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
- view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
- view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
- enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
+ view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
+ view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector");
+
+ view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
+ view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
+
+ // Develop >Set logging level
+ view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
+ view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
+
+ //Develop (clear cache immediately)
+ commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
+
+ // Develop (Fonts debugging)
+ commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts));
+ commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures));
+
+ // Admin >Object
+ view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
+ view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
+ view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive");
+ view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete");
+ view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock");
+ view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs");
+
+ // Admin >Parcel
+ view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe");
+ view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent");
+ view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand");
+
+ // Admin >Region
+ view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData");
+ // Admin top level
+ view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
+
+ // Self context menu
+ view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand");
+ enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));
+ view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
+
+ view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
+
+ // we don't use boost::bind directly to delay side tray construction
+ view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab");
+ view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab");
+
+ // Avatar pie menu
+ view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode");
+ view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode");
+ view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
+ view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
+ view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
+ commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD()));
+ view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");
+ view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
+ view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
+ commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
+ commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector));
+ view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
+ view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
+ enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
+ view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
+ view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
+ view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
+ view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
+ view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
+ view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
+ view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
+ view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
+ enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
- commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
-
- view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
- enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2));
-
- // Object pie menu
- view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
- commit.add("Object.Touch", boost::bind(&handle_object_touch));
- commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
- commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
- commit.add("Object.Delete", boost::bind(&handle_object_delete));
- view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
- view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
- view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
- commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance()));
- view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
- view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
-
- enable.add("Object.VisibleTake", boost::bind(&visible_take_object));
- enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object));
-
- commit.add("Object.Buy", boost::bind(&handle_buy));
- commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
+
+ view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
+ enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2));
+
+ // Object pie menu
+ view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
+ commit.add("Object.Touch", boost::bind(&handle_object_touch));
+ commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
+ commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
+ commit.add("Object.Delete", boost::bind(&handle_object_delete));
+ view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
+ view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
+ view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
+ commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance()));
+ view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
+ view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
+
+ enable.add("Object.VisibleTake", boost::bind(&visible_take_object));
+ enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object));
+
+ commit.add("Object.Buy", boost::bind(&handle_buy));
+ commit.add("Object.Edit", boost::bind(&handle_object_edit));
commit.add("Object.Edit", boost::bind(&handle_object_edit));
commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
- commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
- commit.add("Object.Open", boost::bind(&handle_object_open));
- commit.add("Object.Take", boost::bind(&handle_take));
- commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
+ commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
+ commit.add("Object.Open", boost::bind(&handle_object_open));
+ commit.add("Object.Take", boost::bind(&handle_take));
+ commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
enable.add("Object.EnableInspect", boost::bind(&enable_object_inspect));
enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
- enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
- enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
- enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
- enable.add("Object.EnableWear", boost::bind(&object_is_wearable));
-
- enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
- enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
-
- view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
- enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
- view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
-
- enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
- enable.add("Object.EnableMute", boost::bind(&enable_object_mute));
- enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute));
- enable.add("Object.EnableBuy", boost::bind(&enable_buy_object));
- commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom"));
-
- // Attachment pie menu
- enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2));
- view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop");
- view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint");
- view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach");
- view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled");
- view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop");
- view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach");
-
- // Land pie menu
- view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
- view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
+ enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
+ enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
+ enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
+ enable.add("Object.EnableWear", boost::bind(&object_is_wearable));
+
+ enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
+ enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
+
+ view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
+ enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
+ view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
+
+ enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
+ enable.add("Object.EnableMute", boost::bind(&enable_object_mute));
+ enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute));
+ enable.add("Object.EnableBuy", boost::bind(&enable_buy_object));
+ commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom"));
+
+ // Attachment pie menu
+ enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2));
+ view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop");
+ view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint");
+ view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach");
+ view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled");
+ view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop");
+ view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach");
+
+ // Land pie menu
+ view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
+ view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit");
- view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
- view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
-
- // Particle muting
- view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute");
-
- view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
- commit.add("Land.Buy", boost::bind(&handle_buy_land));
-
- // Generic actions
- commit.add("ReportAbuse", boost::bind(&handle_report_abuse));
- commit.add("BuyCurrency", boost::bind(&handle_buy_currency));
- view_listener_t::addMenu(new LLShowHelp(), "ShowHelp");
- view_listener_t::addMenu(new LLToggleHelp(), "ToggleHelp");
- view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
- view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
- view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
+ view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
+
+ // Particle muting
+ view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute");
+
+ view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
+ commit.add("Land.Buy", boost::bind(&handle_buy_land));
+
+ // Generic actions
+ commit.add("ReportAbuse", boost::bind(&handle_report_abuse));
+ commit.add("BuyCurrency", boost::bind(&handle_buy_currency));
+ view_listener_t::addMenu(new LLShowHelp(), "ShowHelp");
+ view_listener_t::addMenu(new LLToggleHelp(), "ToggleHelp");
+ view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
+ view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
+ view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
- view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
- view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
+ view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
+ view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
- view_listener_t::addMenu(new LLCheckControl(), "CheckControl");
- view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
- commit.add("PayObject", boost::bind(&handle_give_money_dialog));
-
- commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow));
-
- enable.add("EnablePayObject", boost::bind(&enable_pay_object));
- enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
- enable.add("EnableEdit", boost::bind(&enable_object_edit));
- enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle));
- enable.add("VisibleBuild", boost::bind(&enable_object_build));
- commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects));
- enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets));
- enable.add("VisibleSelectInPathfindingLinksets", boost::bind(&visible_object_select_in_pathfinding_linksets));
- commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects));
- enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters));
+ view_listener_t::addMenu(new LLCheckControl(), "CheckControl");
+ view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
+ commit.add("PayObject", boost::bind(&handle_give_money_dialog));
+
+ commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow));
+
+ enable.add("EnablePayObject", boost::bind(&enable_pay_object));
+ enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
+ enable.add("EnableEdit", boost::bind(&enable_object_edit));
+ enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle));
+ enable.add("VisibleBuild", boost::bind(&enable_object_build));
+ commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects));
+ enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets));
+ enable.add("VisibleSelectInPathfindingLinksets", boost::bind(&visible_object_select_in_pathfinding_linksets));
+ commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects));
+ enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters));
enable.add("Advanced.EnableErrorOSException", boost::bind(&enable_os_exception));
- view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");
- view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel");
- view_listener_t::addMenu(new LLSidetrayPanelVisible(), "SidetrayPanelVisible");
- view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected");
- view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
- view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected");
- view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
- view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints");
+ view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");
+ view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel");
+ view_listener_t::addMenu(new LLSidetrayPanelVisible(), "SidetrayPanelVisible");
+ view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected");
+ view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
+ view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected");
+ view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
+ view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints");
}
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index b746d167ba..240c756411 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewermenufile.cpp
* @brief "File" menu in the main menu bar.
*
* $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$
*/
@@ -47,17 +47,17 @@
#include "llimagej2c.h"
#include "llimagejpeg.h"
#include "llimagetga.h"
-#include "llinventorymodel.h" // gInventory
+#include "llinventorymodel.h" // gInventory
#include "llpluginclassmedia.h"
#include "llresourcedata.h"
#include "llstatusbar.h"
#include "lltinygltfhelper.h"
#include "lltoast.h"
-#include "llviewercontrol.h" // gSavedSettings
+#include "llviewercontrol.h" // gSavedSettings
#include "llviewertexturelist.h"
#include "lluictrlfactory.h"
#include "llviewerinventory.h"
-#include "llviewermenu.h" // gMenuHolder
+#include "llviewermenu.h" // gMenuHolder
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
@@ -83,24 +83,24 @@
class LLFileEnableUpload : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
return true;
- }
+ }
};
class LLFileEnableUploadModel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model");
- if (fmp && fmp->isModelLoading())
- {
- return false;
- }
-
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model");
+ if (fmp && fmp->isModelLoading())
+ {
+ return false;
+ }
+
+ return true;
+ }
};
class LLFileEnableUploadMaterial : public view_listener_t
@@ -118,18 +118,18 @@ class LLFileEnableUploadMaterial : public view_listener_t
class LLMeshEnabled : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gSavedSettings.getBOOL("MeshEnabled");
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gSavedSettings.getBOOL("MeshEnabled");
+ }
};
class LLMeshUploadVisible : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- return gMeshRepo.meshUploadEnabled();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gMeshRepo.meshUploadEnabled();
+ }
};
LLMutex* LLFilePickerThread::sMutex = NULL;
@@ -139,51 +139,51 @@ void LLFilePickerThread::getFile()
{
#if LL_WINDOWS
// Todo: get rid of LLFilePickerThread and make this modeless
- start();
+ start();
#elif LL_DARWIN
runModeless();
#else
- run();
+ run();
#endif
}
-//virtual
+//virtual
void LLFilePickerThread::run()
{
#if LL_WINDOWS
- bool blocking = false;
+ bool blocking = false;
#else
- bool blocking = true; // modal
+ bool blocking = true; // modal
#endif
- LLFilePicker picker;
-
- if (mIsSaveDialog)
- {
- if (picker.getSaveFile(mSaveFilter, mProposedName, blocking))
- {
- mResponses.push_back(picker.getFirstFile());
- }
- }
- else
- {
- bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking);
- if (result)
- {
- std::string filename = picker.getFirstFile(); // consider copying mFiles directly
- do
- {
- mResponses.push_back(filename);
- filename = picker.getNextFile();
- }
- while (mIsGetMultiple && !filename.empty());
- }
- }
-
- {
- LLMutexLock lock(sMutex);
- sDeadQ.push(this);
- }
+ LLFilePicker picker;
+
+ if (mIsSaveDialog)
+ {
+ if (picker.getSaveFile(mSaveFilter, mProposedName, blocking))
+ {
+ mResponses.push_back(picker.getFirstFile());
+ }
+ }
+ else
+ {
+ bool result = mIsGetMultiple ? picker.getMultipleOpenFiles(mLoadFilter, blocking) : picker.getOpenFile(mLoadFilter, blocking);
+ if (result)
+ {
+ std::string filename = picker.getFirstFile(); // consider copying mFiles directly
+ do
+ {
+ mResponses.push_back(filename);
+ filename = picker.getNextFile();
+ }
+ while (mIsGetMultiple && !filename.empty());
+ }
+ }
+
+ {
+ LLMutexLock lock(sMutex);
+ sDeadQ.push(this);
+ }
}
void LLFilePickerThread::runModeless()
@@ -206,7 +206,7 @@ void LLFilePickerThread::runModeless()
{
result = picker.getOpenFileModeless(mLoadFilter, modelessVectorCallback, this);
}
-
+
if (!result)
{
LLMutexLock lock(sMutex);
@@ -223,7 +223,7 @@ void LLFilePickerThread::modelessStringCallback(bool success,
{
picker->mResponses.push_back(response);
}
-
+
{
LLMutexLock lock(sMutex);
sDeadQ.push(picker);
@@ -255,7 +255,7 @@ void LLFilePickerThread::modelessVectorCallback(bool success,
}
}
}
-
+
{
LLMutexLock lock(sMutex);
sDeadQ.push(picker);
@@ -265,66 +265,66 @@ void LLFilePickerThread::modelessVectorCallback(bool success,
//static
void LLFilePickerThread::initClass()
{
- sMutex = new LLMutex();
+ sMutex = new LLMutex();
}
//static
void LLFilePickerThread::cleanupClass()
{
- clearDead();
-
- delete sMutex;
- sMutex = NULL;
+ clearDead();
+
+ delete sMutex;
+ sMutex = NULL;
}
//static
void LLFilePickerThread::clearDead()
{
- if (!sDeadQ.empty())
- {
- LLMutexLock lock(sMutex);
- while (!sDeadQ.empty())
- {
- LLFilePickerThread* thread = sDeadQ.front();
- thread->notify(thread->mResponses);
- delete thread;
- sDeadQ.pop();
- }
- }
+ if (!sDeadQ.empty())
+ {
+ LLMutexLock lock(sMutex);
+ while (!sDeadQ.empty())
+ {
+ LLFilePickerThread* thread = sDeadQ.front();
+ thread->notify(thread->mResponses);
+ delete thread;
+ sDeadQ.pop();
+ }
+ }
}
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb)
- : LLFilePickerThread(filter, get_multiple),
- mLoadFilter(filter),
- mSaveFilter(LLFilePicker::FFSAVE_ALL),
- mFilePickedSignal(NULL),
- mFailureSignal(NULL)
+ : LLFilePickerThread(filter, get_multiple),
+ mLoadFilter(filter),
+ mSaveFilter(LLFilePicker::FFSAVE_ALL),
+ mFilePickedSignal(NULL),
+ mFailureSignal(NULL)
{
- mFilePickedSignal = new file_picked_signal_t();
- mFilePickedSignal->connect(cb);
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
- mFailureSignal = new file_picked_signal_t();
- mFailureSignal->connect(failure_cb);
+ mFailureSignal = new file_picked_signal_t();
+ mFailureSignal->connect(failure_cb);
}
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb)
- : LLFilePickerThread(filter, proposed_name),
- mLoadFilter(LLFilePicker::FFLOAD_ALL),
- mSaveFilter(filter),
- mFilePickedSignal(NULL),
- mFailureSignal(NULL)
+ : LLFilePickerThread(filter, proposed_name),
+ mLoadFilter(LLFilePicker::FFLOAD_ALL),
+ mSaveFilter(filter),
+ mFilePickedSignal(NULL),
+ mFailureSignal(NULL)
{
- mFilePickedSignal = new file_picked_signal_t();
- mFilePickedSignal->connect(cb);
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
- mFailureSignal = new file_picked_signal_t();
- mFailureSignal->connect(failure_cb);
+ mFailureSignal = new file_picked_signal_t();
+ mFailureSignal->connect(failure_cb);
}
LLFilePickerReplyThread::~LLFilePickerReplyThread()
{
- delete mFilePickedSignal;
- delete mFailureSignal;
+ delete mFilePickedSignal;
+ delete mFailureSignal;
}
void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type & failure_cb)
@@ -339,20 +339,20 @@ void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
- if (filenames.empty())
- {
- if (mFailureSignal)
- {
- (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
- }
- }
- else
- {
- if (mFilePickedSignal)
- {
- (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
- }
- }
+ if (filenames.empty())
+ {
+ if (mFailureSignal)
+ {
+ (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+ }
+ else
+ {
+ if (mFilePickedSignal)
+ {
+ (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+ }
}
@@ -389,179 +389,197 @@ static std::string MATERIAL_EXTENSIONS = "gltf glb";
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
{
- switch(filter)
- {
+ switch(filter)
+ {
#if LL_WINDOWS
- case LLFilePicker::FFLOAD_IMAGE:
- return IMAGE_EXTENSIONS;
- case LLFilePicker::FFLOAD_WAV:
- return SOUND_EXTENSIONS;
- case LLFilePicker::FFLOAD_ANIM:
- return ANIM_EXTENSIONS;
- case LLFilePicker::FFLOAD_SLOBJECT:
- return SLOBJECT_EXTENSIONS;
- case LLFilePicker::FFLOAD_MODEL:
- return MODEL_EXTENSIONS;
+ case LLFilePicker::FFLOAD_IMAGE:
+ return IMAGE_EXTENSIONS;
+ case LLFilePicker::FFLOAD_WAV:
+ return SOUND_EXTENSIONS;
+ case LLFilePicker::FFLOAD_ANIM:
+ return ANIM_EXTENSIONS;
+ case LLFilePicker::FFLOAD_SLOBJECT:
+ return SLOBJECT_EXTENSIONS;
+ case LLFilePicker::FFLOAD_MODEL:
+ return MODEL_EXTENSIONS;
case LLFilePicker::FFLOAD_MATERIAL:
return MATERIAL_EXTENSIONS;
- case LLFilePicker::FFLOAD_XML:
- return XML_EXTENSIONS;
+ case LLFilePicker::FFLOAD_XML:
+ return XML_EXTENSIONS;
case LLFilePicker::FFLOAD_ALL:
case LLFilePicker::FFLOAD_EXE:
- return ALL_FILE_EXTENSIONS;
+ return ALL_FILE_EXTENSIONS;
#endif
default:
- return ALL_FILE_EXTENSIONS;
- }
+ return ALL_FILE_EXTENSIONS;
+ }
}
const bool check_file_extension(const std::string& filename, LLFilePicker::ELoadFilter type)
{
- std::string ext = gDirUtilp->getExtension(filename);
-
- //strincmp doesn't like NULL pointers
- if (ext.empty())
- {
- std::string short_name = gDirUtilp->getBaseFileName(filename);
-
- // No extension
- LLSD args;
- args["FILE"] = short_name;
- LLNotificationsUtil::add("NoFileExtension", args);
- return false;
- }
- else
- {
- //so there is an extension
- //loop over the valid extensions and compare to see
- //if the extension is valid
-
- //now grab the set of valid file extensions
- std::string valid_extensions = build_extensions_string(type);
-
- BOOL ext_valid = FALSE;
-
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(" ");
- tokenizer tokens(valid_extensions, sep);
- tokenizer::iterator token_iter;
-
- //now loop over all valid file extensions
- //and compare them to the extension of the file
- //to be uploaded
- for (token_iter = tokens.begin();
- token_iter != tokens.end() && ext_valid != TRUE;
- ++token_iter)
- {
- const std::string& cur_token = *token_iter;
-
- if (cur_token == ext || cur_token == "*.*")
- {
- //valid extension
- //or the acceptable extension is any
- ext_valid = TRUE;
- }
- }//end for (loop over all tokens)
-
- if (ext_valid == FALSE)
- {
- //should only get here if the extension exists
- //but is invalid
- LLSD args;
- args["EXTENSION"] = ext;
- args["VALIDS"] = valid_extensions;
- LLNotificationsUtil::add("InvalidFileExtension", args);
- return false;
- }
- }//end else (non-null extension)
- return true;
+ std::string ext = gDirUtilp->getExtension(filename);
+
+ //strincmp doesn't like NULL pointers
+ if (ext.empty())
+ {
+ std::string short_name = gDirUtilp->getBaseFileName(filename);
+
+ // No extension
+ LLSD args;
+ args["FILE"] = short_name;
+ LLNotificationsUtil::add("NoFileExtension", args);
+ return false;
+ }
+ else
+ {
+ //so there is an extension
+ //loop over the valid extensions and compare to see
+ //if the extension is valid
+
+ //now grab the set of valid file extensions
+ std::string valid_extensions = build_extensions_string(type);
+
+ BOOL ext_valid = FALSE;
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ tokenizer tokens(valid_extensions, sep);
+ tokenizer::iterator token_iter;
+
+ //now loop over all valid file extensions
+ //and compare them to the extension of the file
+ //to be uploaded
+ for (token_iter = tokens.begin();
+ token_iter != tokens.end() && ext_valid != TRUE;
+ ++token_iter)
+ {
+ const std::string& cur_token = *token_iter;
+
+ if (cur_token == ext || cur_token == "*.*")
+ {
+ //valid extension
+ //or the acceptable extension is any
+ ext_valid = TRUE;
+ }
+ }//end for (loop over all tokens)
+
+ if (ext_valid == FALSE)
+ {
+ //should only get here if the extension exists
+ //but is invalid
+ LLSD args;
+ args["EXTENSION"] = ext;
+ args["VALIDS"] = valid_extensions;
+ LLNotificationsUtil::add("InvalidFileExtension", args);
+ return false;
+ }
+ }//end else (non-null extension)
+ return true;
}
const void upload_single_file(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
{
- std::string filename = filenames[0];
- if (!check_file_extension(filename, type)) return;
+ std::string filename = filenames[0];
+ if (!check_file_extension(filename, type)) return;
+
+ if (!filename.empty())
+ {
+ if (type == LLFilePicker::FFLOAD_WAV)
+ {
+ // pre-qualify wavs to make sure the format is acceptable
+ std::string error_msg;
+ if (check_for_invalid_wav_formats(filename, error_msg))
+ {
+ LL_INFOS() << error_msg << ": " << filename << LL_ENDL;
+ LLSD args;
+ args["FILE"] = filename;
+ LLNotificationsUtil::add(error_msg, args);
+ return;
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ }
+ }
+ if (type == LLFilePicker::FFLOAD_IMAGE)
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+ if (type == LLFilePicker::FFLOAD_ANIM)
+ {
+ std::string filename_lc(filename);
+ LLStringUtil::toLower(filename_lc);
+ if (filename_lc.rfind(".anim") != std::string::npos)
+ {
+ LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
+ }
+ }
+ }
+ return;
+}
- if (!filename.empty())
- {
- if (type == LLFilePicker::FFLOAD_WAV)
+void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0)
+ {
+ // Cancel upload
+ return;
+ }
+
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ std::string filename = (*in_iter);
+
+ std::string name = gDirUtilp->getBaseFileName(filename, true);
+ std::string asset_name = name;
+ LLStringUtil::replaceNonstandardASCII(asset_name, '?');
+ LLStringUtil::replaceChar(asset_name, '|', '?');
+ LLStringUtil::stripNonprintable(asset_name);
+ LLStringUtil::trim(asset_name);
+
+ std::string ext = gDirUtilp->getExtension(filename);
+ LLAssetType::EType asset_type;
+ U32 codec;
+ S32 expected_upload_cost = 0;
+
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))
{
- // pre-qualify wavs to make sure the format is acceptable
- std::string error_msg;
- if (check_for_invalid_wav_formats(filename, error_msg))
- {
- LL_INFOS() << error_msg << ": " << filename << LL_ENDL;
- LLSD args;
- args["FILE"] = filename;
- LLNotificationsUtil::add(error_msg, args);
- return;
- }
- else
+ bool resource_upload = false;
+ if (asset_type == LLAssetType::AT_TEXTURE)
{
- LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
+ if (gDirUtilp->fileExists(filename) && image_frmted->load(filename))
+ {
+ expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(image_frmted);
+ resource_upload = true;
+ }
}
- }
- if (type == LLFilePicker::FFLOAD_IMAGE)
- {
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
- }
- if (type == LLFilePicker::FFLOAD_ANIM)
- {
- std::string filename_lc(filename);
- LLStringUtil::toLower(filename_lc);
- if (filename_lc.rfind(".anim") != std::string::npos)
+ else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
{
- LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
+ resource_upload = true;
}
- else
+
+ if (resource_upload)
{
- LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo);
}
}
- }
- return;
-}
-
-void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0)
- {
- // Cancel upload
- return;
- }
-
- for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
- {
- std::string filename = (*in_iter);
-
- std::string name = gDirUtilp->getBaseFileName(filename, true);
- std::string asset_name = name;
- LLStringUtil::replaceNonstandardASCII(asset_name, '?');
- LLStringUtil::replaceChar(asset_name, '|', '?');
- LLStringUtil::stripNonprintable(asset_name);
- LLStringUtil::trim(asset_name);
-
- std::string ext = gDirUtilp->getExtension(filename);
- LLAssetType::EType asset_type;
- U32 codec;
- S32 expected_upload_cost;
- if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
- LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
- {
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
- filename,
- asset_name,
- asset_name, 0,
- LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost));
-
- upload_new_resource(uploadInfo);
- }
// gltf does not use normal upload procedure
if (ext == "gltf" || ext == "glb")
@@ -585,34 +603,43 @@ void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification
bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S32& total_cost, S32& file_count, S32& bvh_count)
{
- total_cost = 0;
- file_count = 0;
- bvh_count = 0;
- for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
- {
- std::string filename = (*in_iter);
- std::string ext = gDirUtilp->getExtension(filename);
-
- if (ext == "bvh")
- {
- bvh_count++;
- }
-
- LLAssetType::EType asset_type;
- U32 codec;
- S32 cost;
-
- if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
- LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost))
- {
- total_cost += cost;
- file_count++;
+ total_cost = 0;
+ file_count = 0;
+ bvh_count = 0;
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ std::string filename = (*in_iter);
+ std::string ext = gDirUtilp->getExtension(filename);
+
+ if (ext == "bvh")
+ {
+ bvh_count++;
+ }
+
+ LLAssetType::EType asset_type;
+ U32 codec;
+ S32 cost;
+
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))
+ {
+ if (asset_type == LLAssetType::AT_TEXTURE)
+ {
+ LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);
+ if (gDirUtilp->fileExists(filename) && image_frmted->load(filename))
+ {
+ total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(image_frmted);
+ file_count++;
+ }
+ }
+ else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost))
+ {
+ total_cost += cost;
+ file_count++;
+ }
}
if (ext == "gltf" || ext == "glb")
{
- S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
-
tinygltf::Model model;
if (LLTinyGLTFHelper::loadModel(filename, model))
@@ -629,110 +656,108 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
{
// Todo: make it account for possibility of same texture in different
// materials and even in scope of same material
- S32 texture_count = 0;
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && material->mBaseColorTexture)
{
- texture_count++;
+ total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(material->mBaseColorTexture);
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && material->mMetallicRoughnessTexture)
{
- texture_count++;
+ total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(material->mMetallicRoughnessTexture);
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && material->mNormalTexture)
{
- texture_count++;
+ total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(material->mNormalTexture);
}
- if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull())
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && material->mEmissiveTexture)
{
- texture_count++;
+ total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(material->mEmissiveTexture);
}
- total_cost += texture_count * texture_upload_cost;
file_count++;
}
}
}
}
- }
-
+ }
+
return file_count > 0;
}
const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
{
- // TODO:
- // Check user balance for entire cost
- // Charge user entire cost
- // Loop, uploading
- // If an upload fails, refund the user for that one
- //
- // Also fix single upload to charge first, then refund
-
- // FIXME PREMIUM what about known types that can't be bulk uploaded
- // (bvh)? These will fail in the item by item upload but won't be
- // mentioned in the notification.
- std::vector<std::string> filtered_filenames;
- for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
- {
- const std::string& filename = *in_iter;
- if (check_file_extension(filename, type))
- {
- filtered_filenames.push_back(filename);
- }
- }
-
- S32 expected_upload_cost;
- S32 expected_upload_count;
- S32 bvh_count;
- if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count))
- {
- LLSD args;
- args["COST"] = expected_upload_cost;
- args["COUNT"] = expected_upload_count;
- LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2));
-
- if (filtered_filenames.size() > expected_upload_count)
- {
- if (bvh_count == filtered_filenames.size() - expected_upload_count)
- {
- LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
- }
- else
- {
- LLNotificationsUtil::add("BulkUploadIncompatibleFiles");
- }
- }
- }
- else if (bvh_count == filtered_filenames.size())
- {
- LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
- }
- else
- {
- LLNotificationsUtil::add("BulkUploadNoCompatibleFiles");
- }
+ // TODO:
+ // Check user balance for entire cost
+ // Charge user entire cost
+ // Loop, uploading
+ // If an upload fails, refund the user for that one
+ //
+ // Also fix single upload to charge first, then refund
+
+ // FIXME PREMIUM what about known types that can't be bulk uploaded
+ // (bvh)? These will fail in the item by item upload but won't be
+ // mentioned in the notification.
+ std::vector<std::string> filtered_filenames;
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ const std::string& filename = *in_iter;
+ if (check_file_extension(filename, type))
+ {
+ filtered_filenames.push_back(filename);
+ }
+ }
+
+ S32 expected_upload_cost;
+ S32 expected_upload_count;
+ S32 bvh_count;
+ if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count))
+ {
+ LLSD args;
+ args["COST"] = expected_upload_cost;
+ args["COUNT"] = expected_upload_count;
+ LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2));
+
+ if (filtered_filenames.size() > expected_upload_count)
+ {
+ if (bvh_count == filtered_filenames.size() - expected_upload_count)
+ {
+ LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
+ }
+ else
+ {
+ LLNotificationsUtil::add("BulkUploadIncompatibleFiles");
+ }
+ }
+ }
+ else if (bvh_count == filtered_filenames.size())
+ {
+ LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
+ }
+ else
+ {
+ LLNotificationsUtil::add("BulkUploadNoCompatibleFiles");
+ }
}
class LLFileUploadImage : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToDefault();
- }
- LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false);
+ return true;
+ }
};
class LLFileUploadModel : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
+ bool handleEvent(const LLSD& userdata)
+ {
LLFloaterModelPreview::showModelPreview();
return TRUE;
- }
+ }
};
class LLFileUploadMaterial : public view_listener_t
@@ -746,213 +771,213 @@ class LLFileUploadMaterial : public view_listener_t
class LLFileUploadSound : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToDefault();
- }
- LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false);
+ return true;
+ }
};
class LLFileUploadAnim : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToDefault();
- }
- LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false);
+ return true;
+ }
};
class LLFileUploadBulk : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- if (gAgentCamera.cameraMouselook())
- {
- gAgentCamera.changeCameraToDefault();
- }
- LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true);
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgentCamera.cameraMouselook())
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true);
+ return true;
+ }
};
-void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args)
+void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args)
{
- LL_WARNS() << error_message << LL_ENDL;
- LLNotificationsUtil::add(label, args);
- if(LLFile::remove(filename) == -1)
- {
- LL_DEBUGS() << "unable to remove temp file" << LL_ENDL;
- }
- LLFilePicker::instance().reset();
+ LL_WARNS() << error_message << LL_ENDL;
+ LLNotificationsUtil::add(label, args);
+ if(LLFile::remove(filename) == -1)
+ {
+ LL_DEBUGS() << "unable to remove temp file" << LL_ENDL;
+ }
+ LLFilePicker::instance().reset();
}
class LLFileEnableCloseWindow : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater());
- bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater());
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater());
+ bool frontmost_snapshot_fl_exists = (NULL != gSnapshotFloaterView->getFrontmostClosableFloater());
- return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists);
- }
+ return !LLNotificationsUI::LLToast::isAlertToastShown() && (frontmost_fl_exists || frontmost_snapshot_fl_exists);
+ }
};
class LLFileCloseWindow : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater());
- LLFloater* snapshot_floater = gSnapshotFloaterView->getFrontmostClosableFloater();
-
- if(snapshot_floater && (!frontmost_fl_exists || snapshot_floater->hasFocus()))
- {
- snapshot_floater->closeFloater();
- if (gFocusMgr.getKeyboardFocus() == NULL)
- {
- gFloaterView->focusFrontFloater();
- }
- }
- else
- {
- LLFloater::closeFrontmostFloater();
- }
- if (gMenuHolder) gMenuHolder->hideMenus();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool frontmost_fl_exists = (NULL != gFloaterView->getFrontmostClosableFloater());
+ LLFloater* snapshot_floater = gSnapshotFloaterView->getFrontmostClosableFloater();
+
+ if(snapshot_floater && (!frontmost_fl_exists || snapshot_floater->hasFocus()))
+ {
+ snapshot_floater->closeFloater();
+ if (gFocusMgr.getKeyboardFocus() == NULL)
+ {
+ gFloaterView->focusFrontFloater();
+ }
+ }
+ else
+ {
+ LLFloater::closeFrontmostFloater();
+ }
+ if (gMenuHolder) gMenuHolder->hideMenus();
+ return true;
+ }
};
class LLFileEnableCloseAllWindows : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
- bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain());
- bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
- return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown();
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
+ bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain());
+ bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
+ return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown();
+ }
};
class LLFileCloseAllWindows : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- bool app_quitting = false;
- gFloaterView->closeAllChildren(app_quitting);
- LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
- if (floater_snapshot)
- floater_snapshot->closeFloater(app_quitting);
- if (gMenuHolder) gMenuHolder->hideMenus();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool app_quitting = false;
+ gFloaterView->closeAllChildren(app_quitting);
+ LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
+ if (floater_snapshot)
+ floater_snapshot->closeFloater(app_quitting);
+ if (gMenuHolder) gMenuHolder->hideMenus();
+ return true;
+ }
};
class LLFileTakeSnapshotToDisk : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLPointer<LLImageRaw> raw = new LLImageRaw;
-
- S32 width = gViewerWindow->getWindowWidthRaw();
- S32 height = gViewerWindow->getWindowHeightRaw();
-
- BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
- BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
- BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost");
-
- BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
- if (high_res)
- {
- width *= 2;
- height *= 2;
- // not compatible with UI/HUD
- render_ui = false;
- render_hud = false;
- }
-
- if (gViewerWindow->rawSnapshot(raw,
- width,
- height,
- TRUE,
- FALSE,
- render_ui,
- render_hud,
- FALSE,
- render_no_post,
- LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
- high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
- {
- LLPointer<LLImageFormatted> formatted;
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+
+ S32 width = gViewerWindow->getWindowWidthRaw();
+ S32 height = gViewerWindow->getWindowHeightRaw();
+
+ BOOL render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
+ BOOL render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+ BOOL render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost");
+
+ BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
+ if (high_res)
+ {
+ width *= 2;
+ height *= 2;
+ // not compatible with UI/HUD
+ render_ui = false;
+ render_hud = false;
+ }
+
+ if (gViewerWindow->rawSnapshot(raw,
+ width,
+ height,
+ TRUE,
+ FALSE,
+ render_ui,
+ render_hud,
+ FALSE,
+ render_no_post,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
+ {
+ LLPointer<LLImageFormatted> formatted;
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
- switch (fmt)
- {
- case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
- formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
- break;
- default:
- LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
- case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
- formatted = new LLImagePNG;
- break;
- case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
- formatted = new LLImageBMP;
- break;
- }
- formatted->enableOverSize() ;
- formatted->encode(raw, 0);
- formatted->disableOverSize() ;
- LLSnapshotLivePreview::saveLocal(formatted);
- }
- return true;
- }
+ switch (fmt)
+ {
+ case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
+ formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
+ break;
+ default:
+ LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
+ case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
+ formatted = new LLImagePNG;
+ break;
+ case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
+ formatted = new LLImageBMP;
+ break;
+ }
+ formatted->enableOverSize() ;
+ formatted->encode(raw, 0);
+ formatted->disableOverSize() ;
+ LLSnapshotLivePreview::saveLocal(formatted);
+ }
+ return true;
+ }
};
class LLFileQuit : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLAppViewer::instance()->userQuit();
- return true;
- }
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAppViewer::instance()->userQuit();
+ return true;
+ }
};
void handle_compress_image(void*)
{
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
- {
- std::string infile = picker.getFirstFile();
- while (!infile.empty())
- {
- std::string outfile = infile + ".j2c";
-
- LL_INFOS() << "Input: " << infile << LL_ENDL;
- LL_INFOS() << "Output: " << outfile << LL_ENDL;
-
- BOOL success;
-
- success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
-
- if (success)
- {
- LL_INFOS() << "Compression complete" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Compression failed: " << LLImage::getLastError() << LL_ENDL;
- }
-
- infile = picker.getNextFile();
- }
- }
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
+ {
+ std::string infile = picker.getFirstFile();
+ while (!infile.empty())
+ {
+ std::string outfile = infile + ".j2c";
+
+ LL_INFOS() << "Input: " << infile << LL_ENDL;
+ LL_INFOS() << "Output: " << outfile << LL_ENDL;
+
+ BOOL success;
+
+ success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
+
+ if (success)
+ {
+ LL_INFOS() << "Compression complete" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Compression failed: " << LLImage::getLastError() << LL_ENDL;
+ }
+
+ infile = picker.getNextFile();
+ }
+ }
}
// No convinient check in LLFile, and correct way would be something
@@ -960,7 +985,7 @@ void handle_compress_image(void*)
// so doing dirty, but OS independent fopen and fseek
size_t get_file_size(std::string &filename)
{
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
@@ -1045,21 +1070,21 @@ void handle_compress_file_test(void*)
LLUUID upload_new_resource(
- const std::string& src_filename,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata,
- bool show_inventory)
-{
+ const std::string& src_filename,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata,
+ bool show_inventory)
+{
LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewFileResourceUploadInfo>(
src_filename,
@@ -1073,127 +1098,127 @@ LLUUID upload_new_resource(
}
void upload_done_callback(
- const LLUUID& uuid,
- void* user_data,
- S32 result,
- LLExtStat ext_status) // StoreAssetData callback (fixed)
+ const LLUUID& uuid,
+ void* user_data,
+ S32 result,
+ LLExtStat ext_status) // StoreAssetData callback (fixed)
{
- LLResourceData* data = (LLResourceData*)user_data;
- S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0;
- //LLAssetType::EType pref_loc = data->mPreferredLocation;
- BOOL is_balance_sufficient = TRUE;
-
- if(data)
- {
- if (result >= 0)
- {
- LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation;
-
- if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
- LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
- LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
- {
- // Charge the user for the upload.
- LLViewerRegion* region = gAgent.getRegion();
-
- if(!(can_afford_transaction(expected_upload_cost)))
- {
- LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost );
- is_balance_sufficient = FALSE;
- }
- else if(region)
- {
- // Charge user for upload
- gStatusBar->debitBalance(expected_upload_cost);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_MoneyTransferRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_MoneyData);
- msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
- msg->addU8("Flags", 0);
- // we tell the sim how much we were expecting to pay so it
- // can respond to any discrepancy
- msg->addS32Fast(_PREHASH_Amount, expected_upload_cost);
- msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
- msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
- msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
- msg->addStringFast(_PREHASH_Description, NULL);
- msg->sendReliable(region->getHost());
- }
- }
-
- if(is_balance_sufficient)
- {
- // Actually add the upload to inventory
- LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL;
- const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc);
- if(folder_id.notNull())
- {
- U32 next_owner_perms = data->mNextOwnerPerm;
- if(PERM_NONE == next_owner_perms)
- {
- next_owner_perms = PERM_MOVE | PERM_TRANSFER;
- }
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
- data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
+ LLResourceData* data = (LLResourceData*)user_data;
+ S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0;
+ //LLAssetType::EType pref_loc = data->mPreferredLocation;
+ BOOL is_balance_sufficient = TRUE;
+
+ if(data)
+ {
+ if (result >= 0)
+ {
+ LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation;
+
+ if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
+ LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
+ LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
+ {
+ // Charge the user for the upload.
+ LLViewerRegion* region = gAgent.getRegion();
+
+ if(!(can_afford_transaction(expected_upload_cost)))
+ {
+ LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost );
+ is_balance_sufficient = FALSE;
+ }
+ else if(region)
+ {
+ // Charge user for upload
+ gStatusBar->debitBalance(expected_upload_cost);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoneyTransferRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_MoneyData);
+ msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
+ msg->addU8("Flags", 0);
+ // we tell the sim how much we were expecting to pay so it
+ // can respond to any discrepancy
+ msg->addS32Fast(_PREHASH_Amount, expected_upload_cost);
+ msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
+ msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
+ msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
+ msg->addStringFast(_PREHASH_Description, NULL);
+ msg->sendReliable(region->getHost());
+ }
+ }
+
+ if(is_balance_sufficient)
+ {
+ // Actually add the upload to inventory
+ LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL;
+ const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc);
+ if(folder_id.notNull())
+ {
+ U32 next_owner_perms = data->mNextOwnerPerm;
+ if(PERM_NONE == next_owner_perms)
+ {
+ next_owner_perms = PERM_MOVE | PERM_TRANSFER;
+ }
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
+ data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
data->mInventoryType, NO_INV_SUBTYPE, next_owner_perms,
- LLPointer<LLInventoryCallback>(NULL));
- }
- else
- {
- LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
- }
- }
- }
- else // if(result >= 0)
- {
- LLSD args;
- args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
- args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
- LLNotificationsUtil::add("CannotUploadReason", args);
- }
-
- delete data;
- data = NULL;
- }
-
- LLUploadDialog::modalUploadFinished();
-
- // *NOTE: This is a pretty big hack. What this does is check the
- // file picker if there are any more pending uploads. If so,
- // upload that file.
- const std::string& next_file = LLFilePicker::instance().getNextFile();
- if(is_balance_sufficient && !next_file.empty())
- {
- std::string asset_name = gDirUtilp->getBaseFileName(next_file, true);
- LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
- LLStringUtil::replaceChar(asset_name, '|', '?');
- LLStringUtil::stripNonprintable(asset_name);
- LLStringUtil::trim(asset_name);
-
- std::string display_name = LLStringUtil::null;
- LLAssetStorage::LLStoreAssetCallback callback;
- void *userdata = NULL;
- upload_new_resource(
- next_file,
- asset_name,
- asset_name, // file
- 0,
- LLFolderType::FT_NONE,
- LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- display_name,
- callback,
- expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
- userdata);
- }
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+ LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
+ }
+ }
+ }
+ else // if(result >= 0)
+ {
+ LLSD args;
+ args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
+ args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
+ LLNotificationsUtil::add("CannotUploadReason", args);
+ }
+
+ delete data;
+ data = NULL;
+ }
+
+ LLUploadDialog::modalUploadFinished();
+
+ // *NOTE: This is a pretty big hack. What this does is check the
+ // file picker if there are any more pending uploads. If so,
+ // upload that file.
+ const std::string& next_file = LLFilePicker::instance().getNextFile();
+ if(is_balance_sufficient && !next_file.empty())
+ {
+ std::string asset_name = gDirUtilp->getBaseFileName(next_file, true);
+ LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
+ LLStringUtil::replaceChar(asset_name, '|', '?');
+ LLStringUtil::stripNonprintable(asset_name);
+ LLStringUtil::trim(asset_name);
+
+ std::string display_name = LLStringUtil::null;
+ LLAssetStorage::LLStoreAssetCallback callback;
+ void *userdata = NULL;
+ upload_new_resource(
+ next_file,
+ asset_name,
+ asset_name, // file
+ 0,
+ LLFolderType::FT_NONE,
+ LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ display_name,
+ callback,
+ expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
+ userdata);
+ }
}
void upload_new_resource(
@@ -1201,90 +1226,90 @@ void upload_new_resource(
LLAssetStorage::LLStoreAssetCallback callback,
void *userdata)
{
- if(gDisconnected)
- {
- return ;
- }
+ if(gDisconnected)
+ {
+ return ;
+ }
// uploadInfo->setAssetType(assetType);
// uploadInfo->setTransactionId(tid);
- std::string url = gAgent.getRegionCapability("NewFileAgentInventory");
+ std::string url = gAgent.getRegionCapability("NewFileAgentInventory");
- if ( !url.empty() )
- {
+ if ( !url.empty() )
+ {
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
- }
- else
- {
+ }
+ else
+ {
uploadInfo->prepareUpload();
uploadInfo->logPreparedUpload();
- LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL;
- // check for adequate funds
- // TODO: do this check on the sim
- if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() ||
+ LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL;
+ // check for adequate funds
+ // TODO: do this check on the sim
+ if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() ||
LLAssetType::AT_TEXTURE == uploadInfo->getAssetType() ||
LLAssetType::AT_ANIMATION == uploadInfo->getAssetType())
- {
- S32 balance = gStatusBar->getBalance();
- if (balance < uploadInfo->getExpectedUploadCost())
- {
- // insufficient funds, bail on this upload
+ {
+ S32 balance = gStatusBar->getBalance();
+ if (balance < uploadInfo->getExpectedUploadCost())
+ {
+ // insufficient funds, bail on this upload
LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost());
- return;
- }
- }
+ return;
+ }
+ }
- LLResourceData* data = new LLResourceData;
- data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId();
- data->mAssetInfo.mUuid = uploadInfo->getAssetId();
+ LLResourceData* data = new LLResourceData;
+ data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId();
+ data->mAssetInfo.mUuid = uploadInfo->getAssetId();
data->mAssetInfo.mType = uploadInfo->getAssetType();
- data->mAssetInfo.mCreatorID = gAgentID;
- data->mInventoryType = uploadInfo->getInventoryType();
- data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms();
- data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost();
- data->mUserData = userdata;
- data->mAssetInfo.setName(uploadInfo->getName());
- data->mAssetInfo.setDescription(uploadInfo->getDescription());
- data->mPreferredLocation = uploadInfo->getDestinationFolderType();
-
- LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
- if (callback)
- {
- asset_callback = callback;
- }
- gAssetStorage->storeAssetData(
- data->mAssetInfo.mTransactionID,
- data->mAssetInfo.mType,
- asset_callback,
- (void*)data,
- FALSE);
- }
+ data->mAssetInfo.mCreatorID = gAgentID;
+ data->mInventoryType = uploadInfo->getInventoryType();
+ data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms();
+ data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost();
+ data->mUserData = userdata;
+ data->mAssetInfo.setName(uploadInfo->getName());
+ data->mAssetInfo.setDescription(uploadInfo->getDescription());
+ data->mPreferredLocation = uploadInfo->getDestinationFolderType();
+
+ LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
+ if (callback)
+ {
+ asset_callback = callback;
+ }
+ gAssetStorage->storeAssetData(
+ data->mAssetInfo.mTransactionID,
+ data->mAssetInfo.mType,
+ asset_callback,
+ (void*)data,
+ FALSE);
+ }
}
void init_menu_file()
{
- view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage");
- view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
- view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
- view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
+ view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage");
+ view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
+ view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
+ view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial");
- view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
- view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
- view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
- view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow");
- view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows");
- view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk");
- view_listener_t::addCommit(new LLFileQuit(), "File.Quit");
-
- view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload");
- view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel");
+ view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
+ view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
+ view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
+ view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow");
+ view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows");
+ view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk");
+ view_listener_t::addCommit(new LLFileQuit(), "File.Quit");
+
+ view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload");
+ view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel");
view_listener_t::addEnable(new LLFileEnableUploadMaterial(), "File.EnableUploadMaterial");
- view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled");
- view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel");
+ view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled");
+ view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel");
- // "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
+ // "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index dd2495342b..b66d4b1dab 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerobject.cpp
* @brief Base class for viewer objects
*
* $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$
*/
@@ -110,24 +110,24 @@
//#define DEBUG_UPDATE_TYPE
-BOOL LLViewerObject::sVelocityInterpolate = TRUE;
-BOOL LLViewerObject::sPingInterpolate = TRUE;
+BOOL LLViewerObject::sVelocityInterpolate = TRUE;
+BOOL LLViewerObject::sPingInterpolate = TRUE;
-U32 LLViewerObject::sNumZombieObjects = 0;
-S32 LLViewerObject::sNumObjects = 0;
-BOOL LLViewerObject::sMapDebug = TRUE;
-LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK
-LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit
-S32 LLViewerObject::sAxisArrowLength(50);
+U32 LLViewerObject::sNumZombieObjects = 0;
+S32 LLViewerObject::sNumObjects = 0;
+BOOL LLViewerObject::sMapDebug = TRUE;
+LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK
+LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit
+S32 LLViewerObject::sAxisArrowLength(50);
-BOOL LLViewerObject::sPulseEnabled(FALSE);
-BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
+BOOL LLViewerObject::sPulseEnabled(FALSE);
+BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
-F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion
-F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction
-F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
+F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion
+F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction
+F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
std::map<std::string, U32> LLViewerObject::sObjectDataMap;
@@ -151,194 +151,194 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL;
dumpStack("ObjectUpdateStack");
-
- LLViewerObject *res = NULL;
-
- if (gNonInteractive
- && pcode != LL_PCODE_LEGACY_AVATAR
- && pcode != LL_VO_SURFACE_PATCH
- && pcode != LL_VO_WATER
- && pcode != LL_VO_VOID_WATER
- && pcode != LL_VO_WL_SKY
- && pcode != LL_VO_SKY
- && pcode != LL_VO_PART_GROUP
- )
- {
- return res;
- }
- switch (pcode)
- {
- case LL_PCODE_VOLUME:
- {
- res = new LLVOVolume(id, pcode, regionp); break;
- break;
- }
- case LL_PCODE_LEGACY_AVATAR:
- {
- if (id == gAgentID)
- {
- if (!gAgentAvatarp)
- {
- gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
- gAgentAvatarp->initInstance();
- gAgentWearables.setAvatarObject(gAgentAvatarp);
- }
- else
- {
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->updateRegion(regionp);
- }
- }
- res = gAgentAvatarp;
- }
- else if (flags & CO_FLAG_CONTROL_AVATAR)
- {
+
+ LLViewerObject *res = NULL;
+
+ if (gNonInteractive
+ && pcode != LL_PCODE_LEGACY_AVATAR
+ && pcode != LL_VO_SURFACE_PATCH
+ && pcode != LL_VO_WATER
+ && pcode != LL_VO_VOID_WATER
+ && pcode != LL_VO_WL_SKY
+ && pcode != LL_VO_SKY
+ && pcode != LL_VO_PART_GROUP
+ )
+ {
+ return res;
+ }
+ switch (pcode)
+ {
+ case LL_PCODE_VOLUME:
+ {
+ res = new LLVOVolume(id, pcode, regionp); break;
+ break;
+ }
+ case LL_PCODE_LEGACY_AVATAR:
+ {
+ if (id == gAgentID)
+ {
+ if (!gAgentAvatarp)
+ {
+ gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
+ gAgentAvatarp->initInstance();
+ gAgentWearables.setAvatarObject(gAgentAvatarp);
+ }
+ else
+ {
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateRegion(regionp);
+ }
+ }
+ res = gAgentAvatarp;
+ }
+ else if (flags & CO_FLAG_CONTROL_AVATAR)
+ {
LLControlAvatar *control_avatar = new LLControlAvatar(id, pcode, regionp);
- control_avatar->initInstance();
- res = control_avatar;
- }
+ control_avatar->initInstance();
+ res = control_avatar;
+ }
else if (flags & CO_FLAG_UI_AVATAR)
{
LLUIAvatar *ui_avatar = new LLUIAvatar(id, pcode, regionp);
ui_avatar->initInstance();
res = ui_avatar;
}
- else
- {
- LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp);
- avatar->initInstance();
- res = avatar;
- }
- break;
- }
- case LL_PCODE_LEGACY_GRASS:
- res = new LLVOGrass(id, pcode, regionp); break;
- case LL_PCODE_LEGACY_PART_SYS:
-// LL_WARNS() << "Creating old part sys!" << LL_ENDL;
-// res = new LLVOPart(id, pcode, regionp); break;
- res = NULL; break;
- case LL_PCODE_LEGACY_TREE:
- res = new LLVOTree(id, pcode, regionp); break;
- case LL_PCODE_TREE_NEW:
-// LL_WARNS() << "Creating new tree!" << LL_ENDL;
-// res = new LLVOTree(id, pcode, regionp); break;
- res = NULL; break;
- case LL_VO_SURFACE_PATCH:
- res = new LLVOSurfacePatch(id, pcode, regionp); break;
- case LL_VO_SKY:
- res = new LLVOSky(id, pcode, regionp); break;
- case LL_VO_VOID_WATER:
- res = new LLVOVoidWater(id, pcode, regionp); break;
- case LL_VO_WATER:
- res = new LLVOWater(id, pcode, regionp); break;
- case LL_VO_PART_GROUP:
- res = new LLVOPartGroup(id, pcode, regionp); break;
- case LL_VO_HUD_PART_GROUP:
- res = new LLVOHUDPartGroup(id, pcode, regionp); break;
- case LL_VO_WL_SKY:
- res = new LLVOWLSky(id, pcode, regionp); break;
- default:
- LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
- res = NULL; break;
- }
-
- return res;
+ else
+ {
+ LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp);
+ avatar->initInstance();
+ res = avatar;
+ }
+ break;
+ }
+ case LL_PCODE_LEGACY_GRASS:
+ res = new LLVOGrass(id, pcode, regionp); break;
+ case LL_PCODE_LEGACY_PART_SYS:
+// LL_WARNS() << "Creating old part sys!" << LL_ENDL;
+// res = new LLVOPart(id, pcode, regionp); break;
+ res = NULL; break;
+ case LL_PCODE_LEGACY_TREE:
+ res = new LLVOTree(id, pcode, regionp); break;
+ case LL_PCODE_TREE_NEW:
+// LL_WARNS() << "Creating new tree!" << LL_ENDL;
+// res = new LLVOTree(id, pcode, regionp); break;
+ res = NULL; break;
+ case LL_VO_SURFACE_PATCH:
+ res = new LLVOSurfacePatch(id, pcode, regionp); break;
+ case LL_VO_SKY:
+ res = new LLVOSky(id, pcode, regionp); break;
+ case LL_VO_VOID_WATER:
+ res = new LLVOVoidWater(id, pcode, regionp); break;
+ case LL_VO_WATER:
+ res = new LLVOWater(id, pcode, regionp); break;
+ case LL_VO_PART_GROUP:
+ res = new LLVOPartGroup(id, pcode, regionp); break;
+ case LL_VO_HUD_PART_GROUP:
+ res = new LLVOHUDPartGroup(id, pcode, regionp); break;
+ case LL_VO_WL_SKY:
+ res = new LLVOWLSky(id, pcode, regionp); break;
+ default:
+ LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
+ res = NULL; break;
+ }
+
+ return res;
}
LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
-: LLPrimitive(),
- mChildList(),
- mID(id),
- mLocalID(0),
- mTotalCRC(0),
- mListIndex(-1),
- mTEImages(NULL),
- mTENormalMaps(NULL),
- mTESpecularMaps(NULL),
- mbCanSelect(TRUE),
- mFlags(0),
- mPhysicsShapeType(0),
- mPhysicsGravity(0),
- mPhysicsFriction(0),
- mPhysicsDensity(0),
- mPhysicsRestitution(0),
- mDrawable(),
- mCreateSelected(FALSE),
- mRenderMedia(FALSE),
- mBestUpdatePrecision(0),
- mText(),
- mHudText(""),
- mHudTextColor(LLColor4::white),
+: LLPrimitive(),
+ mChildList(),
+ mID(id),
+ mLocalID(0),
+ mTotalCRC(0),
+ mListIndex(-1),
+ mTEImages(NULL),
+ mTENormalMaps(NULL),
+ mTESpecularMaps(NULL),
+ mbCanSelect(TRUE),
+ mFlags(0),
+ mPhysicsShapeType(0),
+ mPhysicsGravity(0),
+ mPhysicsFriction(0),
+ mPhysicsDensity(0),
+ mPhysicsRestitution(0),
+ mDrawable(),
+ mCreateSelected(FALSE),
+ mRenderMedia(FALSE),
+ mBestUpdatePrecision(0),
+ mText(),
+ mHudText(""),
+ mHudTextColor(LLColor4::white),
mControlAvatar(NULL),
- mLastInterpUpdateSecs(0.f),
- mLastMessageUpdateSecs(0.f),
- mLatestRecvPacketID(0),
- mRegionCrossExpire(0),
- mData(NULL),
- mAudioSourcep(NULL),
- mAudioGain(1.f),
- mSoundCutOffRadius(0.f),
- mAppAngle(0.f),
- mPixelArea(1024.f),
- mInventory(NULL),
- mInventorySerialNum(0),
- mExpectedInventorySerialNum(0),
- mInvRequestState(INVENTORY_REQUEST_STOPPED),
- mInvRequestXFerId(0),
- mInventoryDirty(FALSE),
- mRegionp(regionp),
- mDead(FALSE),
- mOrphaned(FALSE),
- mUserSelected(FALSE),
- mOnActiveList(FALSE),
- mOnMap(FALSE),
- mStatic(FALSE),
- mSeatCount(0),
- mNumFaces(0),
- mRotTime(0.f),
- mAngularVelocityRot(),
- mPreviousRotation(),
- mAttachmentState(0),
- mMedia(NULL),
- mClickAction(0),
- mObjectCost(0),
- mLinksetCost(0),
- mPhysicsCost(0),
- mLinksetPhysicsCost(0.f),
- mCostStale(true),
- mPhysicsShapeUnknown(true),
- mAttachmentItemID(LLUUID::null),
- mLastUpdateType(OUT_UNKNOWN),
- mLastUpdateCached(FALSE),
- mCachedMuteListUpdateTime(0),
- mCachedOwnerInMuteList(false),
- mRiggedAttachedWarned(false)
-{
- if (!is_global)
- {
- llassert(mRegionp);
- }
-
- LLPrimitive::init_primitive(pcode);
-
- // CP: added 12/2/2005 - this was being initialised to 0, not the current frame time
- mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
-
- mPositionRegion = LLVector3(0.f, 0.f, 0.f);
-
- if (!is_global && mRegionp)
- {
- mPositionAgent = mRegionp->getOriginAgent();
- }
- resetRot();
-
- LLViewerObject::sNumObjects++;
+ mLastInterpUpdateSecs(0.f),
+ mLastMessageUpdateSecs(0.f),
+ mLatestRecvPacketID(0),
+ mRegionCrossExpire(0),
+ mData(NULL),
+ mAudioSourcep(NULL),
+ mAudioGain(1.f),
+ mSoundCutOffRadius(0.f),
+ mAppAngle(0.f),
+ mPixelArea(1024.f),
+ mInventory(NULL),
+ mInventorySerialNum(0),
+ mExpectedInventorySerialNum(0),
+ mInvRequestState(INVENTORY_REQUEST_STOPPED),
+ mInvRequestXFerId(0),
+ mInventoryDirty(FALSE),
+ mRegionp(regionp),
+ mDead(FALSE),
+ mOrphaned(FALSE),
+ mUserSelected(FALSE),
+ mOnActiveList(FALSE),
+ mOnMap(FALSE),
+ mStatic(FALSE),
+ mSeatCount(0),
+ mNumFaces(0),
+ mRotTime(0.f),
+ mAngularVelocityRot(),
+ mPreviousRotation(),
+ mAttachmentState(0),
+ mMedia(NULL),
+ mClickAction(0),
+ mObjectCost(0),
+ mLinksetCost(0),
+ mPhysicsCost(0),
+ mLinksetPhysicsCost(0.f),
+ mCostStale(true),
+ mPhysicsShapeUnknown(true),
+ mAttachmentItemID(LLUUID::null),
+ mLastUpdateType(OUT_UNKNOWN),
+ mLastUpdateCached(FALSE),
+ mCachedMuteListUpdateTime(0),
+ mCachedOwnerInMuteList(false),
+ mRiggedAttachedWarned(false)
+{
+ if (!is_global)
+ {
+ llassert(mRegionp);
+ }
+
+ LLPrimitive::init_primitive(pcode);
+
+ // CP: added 12/2/2005 - this was being initialised to 0, not the current frame time
+ mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
+
+ mPositionRegion = LLVector3(0.f, 0.f, 0.f);
+
+ if (!is_global && mRegionp)
+ {
+ mPositionAgent = mRegionp->getOriginAgent();
+ }
+ resetRot();
+
+ LLViewerObject::sNumObjects++;
}
LLViewerObject::~LLViewerObject()
{
- deleteTEImages();
+ deleteTEImages();
// unhook from reflection probe manager
if (mReflectionProbe.notNull())
@@ -347,18 +347,18 @@ LLViewerObject::~LLViewerObject()
mReflectionProbe = nullptr;
}
- if(mInventory)
- {
- mInventory->clear(); // will deref and delete entries
- delete mInventory;
- mInventory = NULL;
- }
+ if(mInventory)
+ {
+ mInventory->clear(); // will deref and delete entries
+ delete mInventory;
+ mInventory = NULL;
+ }
- if (mPartSourcep)
- {
- mPartSourcep->setDead();
- mPartSourcep = NULL;
- }
+ if (mPartSourcep)
+ {
+ mPartSourcep->setDead();
+ mPartSourcep = NULL;
+ }
if (mText)
{
@@ -367,30 +367,30 @@ LLViewerObject::~LLViewerObject()
mText = NULL;
}
- // Delete memory associated with extra parameters.
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- if(iter->second != NULL)
- {
- delete iter->second->data;
- delete iter->second;
- }
- }
- mExtraParameterList.clear();
-
- for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
- mNameValuePairs.clear();
-
- delete[] mData;
- mData = NULL;
-
- delete mMedia;
- mMedia = NULL;
-
- sNumObjects--;
- sNumZombieObjects--;
- llassert(mChildList.size() == 0);
+ // Delete memory associated with extra parameters.
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
+ for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ {
+ if(iter->second != NULL)
+ {
+ delete iter->second->data;
+ delete iter->second;
+ }
+ }
+ mExtraParameterList.clear();
+
+ for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
+ mNameValuePairs.clear();
+
+ delete[] mData;
+ mData = NULL;
+
+ delete mMedia;
+ mMedia = NULL;
+
+ sNumObjects--;
+ sNumZombieObjects--;
+ llassert(mChildList.size() == 0);
llassert(mControlAvatar.isNull()); // Should have been cleaned by now
if (mControlAvatar.notNull())
{
@@ -399,40 +399,40 @@ LLViewerObject::~LLViewerObject()
LL_WARNS() << "Dead object owned a live control avatar" << LL_ENDL;
}
- clearInventoryListeners();
+ clearInventoryListeners();
}
void LLViewerObject::deleteTEImages()
{
- delete[] mTEImages;
- mTEImages = NULL;
-
- if (mTENormalMaps != NULL)
- {
- delete[] mTENormalMaps;
- mTENormalMaps = NULL;
- }
-
- if (mTESpecularMaps != NULL)
- {
- delete[] mTESpecularMaps;
- mTESpecularMaps = NULL;
- }
+ delete[] mTEImages;
+ mTEImages = NULL;
+
+ if (mTENormalMaps != NULL)
+ {
+ delete[] mTENormalMaps;
+ mTENormalMaps = NULL;
+ }
+
+ if (mTESpecularMaps != NULL)
+ {
+ delete[] mTESpecularMaps;
+ mTESpecularMaps = NULL;
+ }
}
void LLViewerObject::markDead()
{
- if (!mDead)
- {
+ if (!mDead)
+ {
LL_PROFILE_ZONE_SCOPED;
- //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
-
- // Root object of this hierarchy unlinks itself.
- if (getParent())
- {
- ((LLViewerObject *)getParent())->removeChild(this);
- }
- LLUUID mesh_id;
+ //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
+
+ // Root object of this hierarchy unlinks itself.
+ if (getParent())
+ {
+ ((LLViewerObject *)getParent())->removeChild(this);
+ }
+ LLUUID mesh_id;
{
LLVOAvatar *av = getAvatar();
if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
@@ -446,83 +446,83 @@ void LLViewerObject::markDead()
unlinkControlAvatar();
}
- // Mark itself as dead
- mDead = TRUE;
- if(mRegionp)
- {
- mRegionp->removeFromCreatedList(getLocalID());
- }
- gObjectList.cleanupReferences(this);
-
- LLViewerObject *childp;
- while (mChildList.size() > 0)
- {
- childp = mChildList.back();
- if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
- {
- //LL_INFOS() << "Marking child " << childp->getLocalID() << " as dead." << LL_ENDL;
- childp->setParent(NULL); // LLViewerObject::markDead 1
- childp->markDead();
- }
- else
- {
- // make sure avatar is no longer parented,
- // so we can properly set it's position
- childp->setDrawableParent(NULL);
- ((LLVOAvatar*)childp)->getOffObject();
- childp->setParent(NULL); // LLViewerObject::markDead 2
- }
- mChildList.pop_back();
- }
-
- if (mDrawable.notNull())
- {
- // Drawables are reference counted, mark as dead, then nuke the pointer.
- mDrawable->markDead();
- mDrawable = NULL;
- }
-
- if (mText)
- {
- mText->markDead();
- mText = NULL;
- }
-
- if (mIcon)
- {
- mIcon->markDead();
- mIcon = NULL;
- }
-
- if (mPartSourcep)
- {
- mPartSourcep->setDead();
- mPartSourcep = NULL;
- }
-
- if (mAudioSourcep)
- {
- // Do some cleanup
- if (gAudiop)
- {
- gAudiop->cleanupAudioSource(mAudioSourcep);
- }
- mAudioSourcep = NULL;
- }
-
- if (flagAnimSource())
- {
- if (isAgentAvatarValid())
- {
- // stop motions associated with this object
- gAgentAvatarp->stopMotionFromSource(mID);
- }
- }
-
- if (flagCameraSource())
- {
- LLFollowCamMgr::getInstance()->removeFollowCamParams(mID);
- }
+ // Mark itself as dead
+ mDead = TRUE;
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
+ gObjectList.cleanupReferences(this);
+
+ LLViewerObject *childp;
+ while (mChildList.size() > 0)
+ {
+ childp = mChildList.back();
+ if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+ {
+ //LL_INFOS() << "Marking child " << childp->getLocalID() << " as dead." << LL_ENDL;
+ childp->setParent(NULL); // LLViewerObject::markDead 1
+ childp->markDead();
+ }
+ else
+ {
+ // make sure avatar is no longer parented,
+ // so we can properly set it's position
+ childp->setDrawableParent(NULL);
+ ((LLVOAvatar*)childp)->getOffObject();
+ childp->setParent(NULL); // LLViewerObject::markDead 2
+ }
+ mChildList.pop_back();
+ }
+
+ if (mDrawable.notNull())
+ {
+ // Drawables are reference counted, mark as dead, then nuke the pointer.
+ mDrawable->markDead();
+ mDrawable = NULL;
+ }
+
+ if (mText)
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+
+ if (mIcon)
+ {
+ mIcon->markDead();
+ mIcon = NULL;
+ }
+
+ if (mPartSourcep)
+ {
+ mPartSourcep->setDead();
+ mPartSourcep = NULL;
+ }
+
+ if (mAudioSourcep)
+ {
+ // Do some cleanup
+ if (gAudiop)
+ {
+ gAudiop->cleanupAudioSource(mAudioSourcep);
+ }
+ mAudioSourcep = NULL;
+ }
+
+ if (flagAnimSource())
+ {
+ if (isAgentAvatarValid())
+ {
+ // stop motions associated with this object
+ gAgentAvatarp->stopMotionFromSource(mID);
+ }
+ }
+
+ if (flagCameraSource())
+ {
+ LLFollowCamMgr::getInstance()->removeFollowCamParams(mID);
+ }
if (mReflectionProbe.notNull())
{
@@ -530,225 +530,225 @@ void LLViewerObject::markDead()
mReflectionProbe = nullptr;
}
- sNumZombieObjects++;
- }
+ sNumZombieObjects++;
+ }
}
void LLViewerObject::dump() const
{
- LL_INFOS() << "Type: " << pCodeToString(mPrimitiveCode) << LL_ENDL;
- LL_INFOS() << "Drawable: " << (LLDrawable *)mDrawable << LL_ENDL;
- LL_INFOS() << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << LL_ENDL;
-
- LL_INFOS() << "Parent: " << getParent() << LL_ENDL;
- LL_INFOS() << "ID: " << mID << LL_ENDL;
- LL_INFOS() << "LocalID: " << mLocalID << LL_ENDL;
- LL_INFOS() << "PositionRegion: " << getPositionRegion() << LL_ENDL;
- LL_INFOS() << "PositionAgent: " << getPositionAgent() << LL_ENDL;
- LL_INFOS() << "PositionGlobal: " << getPositionGlobal() << LL_ENDL;
- LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL;
- if (mDrawable.notNull() &&
- mDrawable->getNumFaces() &&
- mDrawable->getFace(0))
- {
- LLFacePool *poolp = mDrawable->getFace(0)->getPool();
- if (poolp)
- {
- LL_INFOS() << "Pool: " << poolp << LL_ENDL;
- LL_INFOS() << "Pool reference count: " << poolp->mReferences.size() << LL_ENDL;
- }
- }
- //LL_INFOS() << "BoxTree Min: " << mDrawable->getBox()->getMin() << LL_ENDL;
- //LL_INFOS() << "BoxTree Max: " << mDrawable->getBox()->getMin() << LL_ENDL;
- /*
- LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL;
- LL_INFOS() << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << LL_ENDL;
- LL_INFOS() << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << LL_ENDL;
- LL_INFOS() << "AppAngle: " << mAppAngle << LL_ENDL;
- LL_INFOS() << "PixelArea: " << mPixelArea << LL_ENDL;
-
- char buffer[1000];
- char *key;
- for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() )
- {
- mNameValuePairs[key]->printNameValue(buffer);
- LL_INFOS() << buffer << LL_ENDL;
- }
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- LL_INFOS() << " child " << child->getID() << LL_ENDL;
- }
- */
+ LL_INFOS() << "Type: " << pCodeToString(mPrimitiveCode) << LL_ENDL;
+ LL_INFOS() << "Drawable: " << (LLDrawable *)mDrawable << LL_ENDL;
+ LL_INFOS() << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << LL_ENDL;
+
+ LL_INFOS() << "Parent: " << getParent() << LL_ENDL;
+ LL_INFOS() << "ID: " << mID << LL_ENDL;
+ LL_INFOS() << "LocalID: " << mLocalID << LL_ENDL;
+ LL_INFOS() << "PositionRegion: " << getPositionRegion() << LL_ENDL;
+ LL_INFOS() << "PositionAgent: " << getPositionAgent() << LL_ENDL;
+ LL_INFOS() << "PositionGlobal: " << getPositionGlobal() << LL_ENDL;
+ LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL;
+ if (mDrawable.notNull() &&
+ mDrawable->getNumFaces() &&
+ mDrawable->getFace(0))
+ {
+ LLFacePool *poolp = mDrawable->getFace(0)->getPool();
+ if (poolp)
+ {
+ LL_INFOS() << "Pool: " << poolp << LL_ENDL;
+ LL_INFOS() << "Pool reference count: " << poolp->mReferences.size() << LL_ENDL;
+ }
+ }
+ //LL_INFOS() << "BoxTree Min: " << mDrawable->getBox()->getMin() << LL_ENDL;
+ //LL_INFOS() << "BoxTree Max: " << mDrawable->getBox()->getMin() << LL_ENDL;
+ /*
+ LL_INFOS() << "Velocity: " << getVelocity() << LL_ENDL;
+ LL_INFOS() << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << LL_ENDL;
+ LL_INFOS() << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << LL_ENDL;
+ LL_INFOS() << "AppAngle: " << mAppAngle << LL_ENDL;
+ LL_INFOS() << "PixelArea: " << mPixelArea << LL_ENDL;
+
+ char buffer[1000];
+ char *key;
+ for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() )
+ {
+ mNameValuePairs[key]->printNameValue(buffer);
+ LL_INFOS() << buffer << LL_ENDL;
+ }
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ LL_INFOS() << " child " << child->getID() << LL_ENDL;
+ }
+ */
}
void LLViewerObject::printNameValuePairs() const
{
- for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
- iter != mNameValuePairs.end(); iter++)
- {
- LLNameValue* nv = iter->second;
- LL_INFOS() << nv->printNameValue() << LL_ENDL;
- }
+ for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
+ iter != mNameValuePairs.end(); iter++)
+ {
+ LLNameValue* nv = iter->second;
+ LL_INFOS() << nv->printNameValue() << LL_ENDL;
+ }
}
void LLViewerObject::initVOClasses()
{
- // Initialized shared class stuff first.
- LLVOAvatar::initClass();
- LLVOTree::initClass();
- LL_INFOS() << "Viewer Object size: " << sizeof(LLViewerObject) << LL_ENDL;
- LLVOGrass::initClass();
- LLVOWater::initClass();
- LLVOVolume::initClass();
+ // Initialized shared class stuff first.
+ LLVOAvatar::initClass();
+ LLVOTree::initClass();
+ LL_INFOS() << "Viewer Object size: " << sizeof(LLViewerObject) << LL_ENDL;
+ LLVOGrass::initClass();
+ LLVOWater::initClass();
+ LLVOVolume::initClass();
- initObjectDataMap();
+ initObjectDataMap();
}
void LLViewerObject::cleanupVOClasses()
{
- SUBSYSTEM_CLEANUP(LLVOGrass);
- SUBSYSTEM_CLEANUP(LLVOWater);
- SUBSYSTEM_CLEANUP(LLVOTree);
- SUBSYSTEM_CLEANUP(LLVOAvatar);
- SUBSYSTEM_CLEANUP(LLVOVolume);
+ SUBSYSTEM_CLEANUP(LLVOGrass);
+ SUBSYSTEM_CLEANUP(LLVOWater);
+ SUBSYSTEM_CLEANUP(LLVOTree);
+ SUBSYSTEM_CLEANUP(LLVOAvatar);
+ SUBSYSTEM_CLEANUP(LLVOVolume);
- sObjectDataMap.clear();
+ sObjectDataMap.clear();
}
//object data map for compressed && !OUT_TERSE_IMPROVED
//static
void LLViewerObject::initObjectDataMap()
{
- U32 count = 0;
+ U32 count = 0;
- sObjectDataMap["ID"] = count; //full id //LLUUID
- count += sizeof(LLUUID);
+ sObjectDataMap["ID"] = count; //full id //LLUUID
+ count += sizeof(LLUUID);
- sObjectDataMap["LocalID"] = count; //U32
- count += sizeof(U32);
+ sObjectDataMap["LocalID"] = count; //U32
+ count += sizeof(U32);
- sObjectDataMap["PCode"] = count; //U8
- count += sizeof(U8);
+ sObjectDataMap["PCode"] = count; //U8
+ count += sizeof(U8);
- sObjectDataMap["State"] = count; //U8
- count += sizeof(U8);
+ sObjectDataMap["State"] = count; //U8
+ count += sizeof(U8);
- sObjectDataMap["CRC"] = count; //U32
- count += sizeof(U32);
+ sObjectDataMap["CRC"] = count; //U32
+ count += sizeof(U32);
- sObjectDataMap["Material"] = count; //U8
- count += sizeof(U8);
+ sObjectDataMap["Material"] = count; //U8
+ count += sizeof(U8);
- sObjectDataMap["ClickAction"] = count; //U8
- count += sizeof(U8);
+ sObjectDataMap["ClickAction"] = count; //U8
+ count += sizeof(U8);
- sObjectDataMap["Scale"] = count; //LLVector3
- count += sizeof(LLVector3);
+ sObjectDataMap["Scale"] = count; //LLVector3
+ count += sizeof(LLVector3);
- sObjectDataMap["Pos"] = count; //LLVector3
- count += sizeof(LLVector3);
+ sObjectDataMap["Pos"] = count; //LLVector3
+ count += sizeof(LLVector3);
- sObjectDataMap["Rot"] = count; //LLVector3
- count += sizeof(LLVector3);
+ sObjectDataMap["Rot"] = count; //LLVector3
+ count += sizeof(LLVector3);
- sObjectDataMap["SpecialCode"] = count; //U32
- count += sizeof(U32);
+ sObjectDataMap["SpecialCode"] = count; //U32
+ count += sizeof(U32);
- sObjectDataMap["Owner"] = count; //LLUUID
- count += sizeof(LLUUID);
+ sObjectDataMap["Owner"] = count; //LLUUID
+ count += sizeof(LLUUID);
- sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set
- count += sizeof(LLVector3);
+ sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set
+ count += sizeof(LLVector3);
- //ParentID is after Omega if there is Omega, otherwise is after Owner
- sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set
- count += sizeof(U32);
+ //ParentID is after Omega if there is Omega, otherwise is after Owner
+ sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set
+ count += sizeof(U32);
- //-------
- //The rest items are not included here
- //-------
+ //-------
+ //The rest items are not included here
+ //-------
}
-//static
+//static
void LLViewerObject::unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name)
{
- dp->shift(sObjectDataMap[name]);
- dp->unpackVector3(value, name.c_str());
- dp->reset();
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackVector3(value, name.c_str());
+ dp->reset();
}
-//static
+//static
void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name)
{
- dp->shift(sObjectDataMap[name]);
- dp->unpackUUID(value, name.c_str());
- dp->reset();
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackUUID(value, name.c_str());
+ dp->reset();
}
-
-//static
+
+//static
void LLViewerObject::unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name)
{
- dp->shift(sObjectDataMap[name]);
- dp->unpackU32(value, name.c_str());
- dp->reset();
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackU32(value, name.c_str());
+ dp->reset();
}
-
-//static
+
+//static
void LLViewerObject::unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name)
{
- dp->shift(sObjectDataMap[name]);
- dp->unpackU8(value, name.c_str());
- dp->reset();
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackU8(value, name.c_str());
+ dp->reset();
}
-//static
+//static
U32 LLViewerObject::unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id)
{
- dp->shift(sObjectDataMap["SpecialCode"]);
- U32 value;
- dp->unpackU32(value, "SpecialCode");
+ dp->shift(sObjectDataMap["SpecialCode"]);
+ U32 value;
+ dp->unpackU32(value, "SpecialCode");
- parent_id = 0;
- if(value & 0x20)
- {
- S32 offset = sObjectDataMap["ParentID"];
- if(!(value & 0x80))
- {
- offset -= sizeof(LLVector3);
- }
+ parent_id = 0;
+ if(value & 0x20)
+ {
+ S32 offset = sObjectDataMap["ParentID"];
+ if(!(value & 0x80))
+ {
+ offset -= sizeof(LLVector3);
+ }
- dp->shift(offset);
- dp->unpackU32(parent_id, "ParentID");
- }
- dp->reset();
+ dp->shift(offset);
+ dp->unpackU32(parent_id, "ParentID");
+ }
+ dp->reset();
- return parent_id;
+ return parent_id;
}
// Replaces all name value pairs with data from \n delimited list
// Does not update server
void LLViewerObject::setNameValueList(const std::string& name_value_list)
{
- // Clear out the old
- for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
- mNameValuePairs.clear();
-
- // Bring in the new
- std::string::size_type length = name_value_list.length();
- std::string::size_type start = 0;
- while (start < length)
- {
- std::string::size_type end = name_value_list.find_first_of("\n", start);
- if (end == std::string::npos) end = length;
- if (end > start)
- {
- std::string tok = name_value_list.substr(start, end - start);
- addNVPair(tok);
- }
- start = end+1;
- }
+ // Clear out the old
+ for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
+ mNameValuePairs.clear();
+
+ // Bring in the new
+ std::string::size_type length = name_value_list.length();
+ std::string::size_type start = 0;
+ while (start < length)
+ {
+ std::string::size_type end = name_value_list.find_first_of("\n", start);
+ if (end == std::string::npos) end = length;
+ if (end > start)
+ {
+ std::string tok = name_value_list.substr(start, end - start);
+ addNVPair(tok);
+ }
+ start = end+1;
+ }
}
BOOL LLViewerObject::isAnySelected() const
@@ -765,183 +765,183 @@ BOOL LLViewerObject::isAnySelected() const
void LLViewerObject::setSelected(BOOL sel)
{
- mUserSelected = sel;
- resetRot();
+ mUserSelected = sel;
+ resetRot();
- if (!sel)
- {
- setAllTESelected(false);
- }
+ if (!sel)
+ {
+ setAllTESelected(false);
+ }
}
// This method returns true if the object is over land owned by the
// agent.
bool LLViewerObject::isReturnable()
{
- if (isAttachment())
- {
- return false;
- }
-
- std::vector<LLBBox> boxes;
- boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
- }
-
- bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0;
-
- if ( !result )
- {
- //Get list of neighboring regions relative to this vo's region
- std::vector<LLViewerRegion*> uniqueRegions;
- mRegionp->getNeighboringRegions( uniqueRegions );
-
- //Build aabb's - for root and all children
- std::vector<PotentialReturnableObject> returnables;
- typedef std::vector<LLViewerRegion*>::iterator RegionIt;
- RegionIt regionStart = uniqueRegions.begin();
- RegionIt regionEnd = uniqueRegions.end();
-
- for (; regionStart != regionEnd; ++regionStart )
- {
- LLViewerRegion* pTargetRegion = *regionStart;
- //Add the root vo as there may be no children and we still want
- //to test for any edge overlap
- buildReturnablesForChildrenVO( returnables, this, pTargetRegion );
- //Add it's children
- for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++)
- {
- LLViewerObject* pChild = *iter;
- buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion );
- }
- }
-
- //TBD#Eventually create a region -> box list map
- typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt;
- ReturnablesIt retCurrentIt = returnables.begin();
- ReturnablesIt retEndIt = returnables.end();
-
- for ( ; retCurrentIt !=retEndIt; ++retCurrentIt )
- {
- boxes.clear();
- LLViewerRegion* pRegion = (*retCurrentIt).pRegion;
- boxes.push_back( (*retCurrentIt).box );
- bool retResult = pRegion
- && pRegion->childrenObjectReturnable( boxes )
- && pRegion->canManageEstate();
- if ( retResult )
- {
- result = true;
- break;
- }
- }
- }
- return result;
+ if (isAttachment())
+ {
+ return false;
+ }
+
+ std::vector<LLBBox> boxes;
+ boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
+
+ bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0;
+
+ if ( !result )
+ {
+ //Get list of neighboring regions relative to this vo's region
+ std::vector<LLViewerRegion*> uniqueRegions;
+ mRegionp->getNeighboringRegions( uniqueRegions );
+
+ //Build aabb's - for root and all children
+ std::vector<PotentialReturnableObject> returnables;
+ typedef std::vector<LLViewerRegion*>::iterator RegionIt;
+ RegionIt regionStart = uniqueRegions.begin();
+ RegionIt regionEnd = uniqueRegions.end();
+
+ for (; regionStart != regionEnd; ++regionStart )
+ {
+ LLViewerRegion* pTargetRegion = *regionStart;
+ //Add the root vo as there may be no children and we still want
+ //to test for any edge overlap
+ buildReturnablesForChildrenVO( returnables, this, pTargetRegion );
+ //Add it's children
+ for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* pChild = *iter;
+ buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion );
+ }
+ }
+
+ //TBD#Eventually create a region -> box list map
+ typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt;
+ ReturnablesIt retCurrentIt = returnables.begin();
+ ReturnablesIt retEndIt = returnables.end();
+
+ for ( ; retCurrentIt !=retEndIt; ++retCurrentIt )
+ {
+ boxes.clear();
+ LLViewerRegion* pRegion = (*retCurrentIt).pRegion;
+ boxes.push_back( (*retCurrentIt).box );
+ bool retResult = pRegion
+ && pRegion->childrenObjectReturnable( boxes )
+ && pRegion->canManageEstate();
+ if ( retResult )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
}
void LLViewerObject::buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion )
{
- if ( !pChild )
- {
- LL_ERRS()<<"child viewerobject is NULL "<<LL_ENDL;
- }
-
- constructAndAddReturnable( returnables, pChild, pTargetRegion );
-
- //We want to handle any children VO's as well
- for (child_list_t::iterator iter = pChild->mChildList.begin(); iter != pChild->mChildList.end(); iter++)
- {
- LLViewerObject* pChildofChild = *iter;
- buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion );
- }
+ if ( !pChild )
+ {
+ LL_ERRS()<<"child viewerobject is NULL "<<LL_ENDL;
+ }
+
+ constructAndAddReturnable( returnables, pChild, pTargetRegion );
+
+ //We want to handle any children VO's as well
+ for (child_list_t::iterator iter = pChild->mChildList.begin(); iter != pChild->mChildList.end(); iter++)
+ {
+ LLViewerObject* pChildofChild = *iter;
+ buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion );
+ }
}
void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion )
{
-
- LLVector3 targetRegionPos;
- targetRegionPos.setVec( pChild->getPositionGlobal() );
-
- LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f,
- pChild->getScale() * 0.5f).getAxisAligned();
-
- LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal();
- LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal();
-
- LLVector3d edgeAd, edgeBd;
- edgeAd.setVec(edgeA);
- edgeBd.setVec(edgeB);
-
- //Only add the box when either of the extents are in a neighboring region
- if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) )
- {
- PotentialReturnableObject returnableObj;
- returnableObj.box = childBBox;
- returnableObj.pRegion = pTargetRegion;
- returnables.push_back( returnableObj );
- }
+
+ LLVector3 targetRegionPos;
+ targetRegionPos.setVec( pChild->getPositionGlobal() );
+
+ LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f,
+ pChild->getScale() * 0.5f).getAxisAligned();
+
+ LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal();
+ LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal();
+
+ LLVector3d edgeAd, edgeBd;
+ edgeAd.setVec(edgeA);
+ edgeBd.setVec(edgeB);
+
+ //Only add the box when either of the extents are in a neighboring region
+ if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) )
+ {
+ PotentialReturnableObject returnableObj;
+ returnableObj.box = childBBox;
+ returnableObj.pRegion = pTargetRegion;
+ returnables.push_back( returnableObj );
+ }
}
bool LLViewerObject::crossesParcelBounds()
{
- std::vector<LLBBox> boxes;
- boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
- }
+ std::vector<LLBBox> boxes;
+ boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
- return mRegionp && mRegionp->objectsCrossParcel(boxes);
+ return mRegionp && mRegionp->objectsCrossParcel(boxes);
}
BOOL LLViewerObject::setParent(LLViewerObject* parent)
{
- if(mParent != parent)
- {
- LLViewerObject* old_parent = (LLViewerObject*)mParent ;
- BOOL ret = LLPrimitive::setParent(parent);
- if(ret && old_parent && parent)
- {
- old_parent->removeChild(this) ;
- }
- return ret ;
- }
+ if(mParent != parent)
+ {
+ LLViewerObject* old_parent = (LLViewerObject*)mParent ;
+ BOOL ret = LLPrimitive::setParent(parent);
+ if(ret && old_parent && parent)
+ {
+ old_parent->removeChild(this) ;
+ }
+ return ret ;
+ }
- return FALSE ;
+ return FALSE ;
}
void LLViewerObject::addChild(LLViewerObject *childp)
{
- for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
- {
- if (*i == childp)
- { //already has child
- return;
- }
- }
-
- if (!isAvatar())
- {
- // propagate selection properties
- childp->mbCanSelect = mbCanSelect;
- }
-
- if(childp->setParent(this))
- {
- mChildList.push_back(childp);
- childp->afterReparent();
-
- if (childp->isAvatar())
- {
- mSeatCount++;
- }
- }
+ for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+ {
+ if (*i == childp)
+ { //already has child
+ return;
+ }
+ }
+
+ if (!isAvatar())
+ {
+ // propagate selection properties
+ childp->mbCanSelect = mbCanSelect;
+ }
+
+ if(childp->setParent(this))
+ {
+ mChildList.push_back(childp);
+ childp->afterReparent();
+
+ if (childp->isAvatar())
+ {
+ mSeatCount++;
+ }
+ }
}
void LLViewerObject::onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent)
@@ -954,149 +954,149 @@ void LLViewerObject::afterReparent()
void LLViewerObject::removeChild(LLViewerObject *childp)
{
- for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
- {
- if (*i == childp)
- {
- if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
- {
- gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
- }
-
- mChildList.erase(i);
-
- if(childp->getParent() == this)
- {
- childp->setParent(NULL);
- }
-
- if (childp->isAvatar())
- {
- mSeatCount--;
- }
- break;
- }
- }
-
- if (childp->isSelected())
- {
- LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
- BOOL add_to_end = TRUE;
- LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
- }
+ for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+ {
+ if (*i == childp)
+ {
+ if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
+ {
+ gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
+ }
+
+ mChildList.erase(i);
+
+ if(childp->getParent() == this)
+ {
+ childp->setParent(NULL);
+ }
+
+ if (childp->isAvatar())
+ {
+ mSeatCount--;
+ }
+ break;
+ }
+ }
+
+ if (childp->isSelected())
+ {
+ LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
+ BOOL add_to_end = TRUE;
+ LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
+ }
}
void LLViewerObject::addThisAndAllChildren(std::vector<LLViewerObject*>& objects)
{
- objects.push_back(this);
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if (!child->isAvatar())
- {
- child->addThisAndAllChildren(objects);
- }
- }
+ objects.push_back(this);
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if (!child->isAvatar())
+ {
+ child->addThisAndAllChildren(objects);
+ }
+ }
}
void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects)
{
- objects.push_back(this);
- // don't add any attachments when temporarily selecting avatar
- if (isAvatar())
- {
- return;
- }
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if ( (!child->isAvatar()))
- {
- child->addThisAndNonJointChildren(objects);
- }
- }
+ objects.push_back(this);
+ // don't add any attachments when temporarily selecting avatar
+ if (isAvatar())
+ {
+ return;
+ }
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if ( (!child->isAvatar()))
+ {
+ child->addThisAndNonJointChildren(objects);
+ }
+ }
}
BOOL LLViewerObject::isChild(LLViewerObject *childp) const
{
- for (child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* testchild = *iter;
- if (testchild == childp)
- return TRUE;
- }
- return FALSE;
+ for (child_list_t::const_iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* testchild = *iter;
+ if (testchild == childp)
+ return TRUE;
+ }
+ return FALSE;
}
// returns TRUE if at least one avatar is sitting on this object
BOOL LLViewerObject::isSeat() const
{
- return mSeatCount > 0;
+ return mSeatCount > 0;
}
BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
{
- if (mDrawable.isNull())
- {
- return FALSE;
- }
-
- BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
- if(!ret)
- {
- return FALSE ;
- }
- LLDrawable* old_parent = mDrawable->mParent;
- mDrawable->mParent = parentp;
-
- if (parentp && mDrawable->isActive())
- {
- parentp->makeActive();
- parentp->setState(LLDrawable::ACTIVE_CHILD);
- }
-
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- if( (old_parent != parentp && old_parent)
- || (parentp && parentp->isActive()))
- {
- // *TODO we should not be relying on setDrawable parent to call markMoved
- gPipeline.markMoved(mDrawable, FALSE);
- }
- else if (!mDrawable->isAvatar())
- {
- mDrawable->updateXform(TRUE);
- /*if (!mDrawable->getSpatialGroup())
- {
- mDrawable->movePartition();
- }*/
- }
-
- return ret;
+ if (mDrawable.isNull())
+ {
+ return FALSE;
+ }
+
+ BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+ if(!ret)
+ {
+ return FALSE ;
+ }
+ LLDrawable* old_parent = mDrawable->mParent;
+ mDrawable->mParent = parentp;
+
+ if (parentp && mDrawable->isActive())
+ {
+ parentp->makeActive();
+ parentp->setState(LLDrawable::ACTIVE_CHILD);
+ }
+
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+ if( (old_parent != parentp && old_parent)
+ || (parentp && parentp->isActive()))
+ {
+ // *TODO we should not be relying on setDrawable parent to call markMoved
+ gPipeline.markMoved(mDrawable, FALSE);
+ }
+ else if (!mDrawable->isAvatar())
+ {
+ mDrawable->updateXform(TRUE);
+ /*if (!mDrawable->getSpatialGroup())
+ {
+ mDrawable->movePartition();
+ }*/
+ }
+
+ return ret;
}
// Show or hide particles, icon and HUD
void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
{
- if( mPartSourcep.notNull() )
- {
- LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
- partSourceScript->setSuspended( hidden );
- }
+ if( mPartSourcep.notNull() )
+ {
+ LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
+ partSourceScript->setSuspended( hidden );
+ }
- if( mText.notNull() )
- {
- LLHUDText *hudText = mText.get();
- hudText->setHidden( hidden );
- }
+ if( mText.notNull() )
+ {
+ LLHUDText *hudText = mText.get();
+ hudText->setHidden( hidden );
+ }
- if( mIcon.notNull() )
- {
- LLHUDIcon *hudIcon = mIcon.get();
- hudIcon->setHidden( hidden );
- }
+ if( mIcon.notNull() )
+ {
+ LLHUDIcon *hudIcon = mIcon.get();
+ hudIcon->setHidden( hidden );
+ }
}
U32 LLViewerObject::checkMediaURL(const std::string &media_url)
@@ -1121,9 +1121,9 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url)
else if (mMedia->mMediaURL != media_url) // <-- This is an optimization. If they are equal don't bother with below's test.
{
/*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
- LLTextureEntry::getVersionFromMediaVersionString(media_url) ==
+ LLTextureEntry::getVersionFromMediaVersionString(media_url) ==
LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
- */
+ */
{
// If the media URL is different and WE were not the one who
// changed it, mark dirty.
@@ -1141,1354 +1141,1356 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url)
//static
U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot)
{
- U32 parent_id = 0;
- LLViewerObject::unpackParentID(dp, parent_id);
-
- LLViewerObject::unpackVector3(dp, scale, "Scale");
- LLViewerObject::unpackVector3(dp, pos, "Pos");
+ U32 parent_id = 0;
+ LLViewerObject::unpackParentID(dp, parent_id);
- LLVector3 vec;
- LLViewerObject::unpackVector3(dp, vec, "Rot");
- rot.unpackFromVector3(vec);
-
- return parent_id;
+ LLViewerObject::unpackVector3(dp, scale, "Scale");
+ LLViewerObject::unpackVector3(dp, pos, "Pos");
+
+ LLVector3 vec;
+ LLViewerObject::unpackVector3(dp, vec, "Rot");
+ rot.unpackFromVector3(vec);
+
+ return parent_id;
}
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num,
- const EObjectUpdateType update_type,
- LLDataPacker *dp)
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp)
{
LL_PROFILE_ZONE_SCOPED;
- LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
+ LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
dumpStack("ObjectUpdateStack");
- U32 retval = 0x0;
-
- // If region is removed from the list it is also deleted.
- if (!LLWorld::instance().isRegionListed(mRegionp))
- {
- LL_WARNS() << "Updating object in an invalid region" << LL_ENDL;
- return retval;
- }
-
- // Coordinates of objects on simulators are region-local.
- U64 region_handle = 0;
-
- if(mesgsys != NULL)
- {
- mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
- LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
- if(regionp != mRegionp && regionp && mRegionp)//region cross
- {
- //this is the redundant position and region update, but it is necessary in case the viewer misses the following
- //position and region update messages from sim.
- //this redundant update should not cause any problems.
- LLVector3 delta_pos = mRegionp->getOriginAgent() - regionp->getOriginAgent();
- setPositionParent(getPosition() + delta_pos); //update to the new region position immediately.
- setRegion(regionp) ; //change the region.
- }
- else
- {
- if(regionp != mRegionp)
- {
- if(mRegionp)
- {
- mRegionp->removeFromCreatedList(getLocalID());
- }
- if(regionp)
- {
- regionp->addToCreatedList(getLocalID());
- }
- }
- mRegionp = regionp ;
- }
- }
-
- if (!mRegionp)
- {
- U32 x, y;
- from_region_handle(region_handle, &x, &y);
-
- LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL;
- return retval;
- }
-
- F32 time_dilation = 1.f;
- if(mesgsys != NULL)
- {
+ U32 retval = 0x0;
+
+ // If region is removed from the list it is also deleted.
+ if (!LLWorld::instance().isRegionListed(mRegionp))
+ {
+ LL_WARNS() << "Updating object in an invalid region" << LL_ENDL;
+ return retval;
+ }
+
+ // Coordinates of objects on simulators are region-local.
+ U64 region_handle = 0;
+
+ if(mesgsys != NULL)
+ {
+ mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+ LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
+ if(regionp != mRegionp && regionp && mRegionp)//region cross
+ {
+ //this is the redundant position and region update, but it is necessary in case the viewer misses the following
+ //position and region update messages from sim.
+ //this redundant update should not cause any problems.
+ LLVector3 delta_pos = mRegionp->getOriginAgent() - regionp->getOriginAgent();
+ setPositionParent(getPosition() + delta_pos); //update to the new region position immediately.
+ setRegion(regionp) ; //change the region.
+ }
+ else
+ {
+ if(regionp != mRegionp)
+ {
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
+ if(regionp)
+ {
+ regionp->addToCreatedList(getLocalID());
+ }
+ }
+ mRegionp = regionp ;
+ }
+ }
+
+ if (!mRegionp)
+ {
+ U32 x, y;
+ from_region_handle(region_handle, &x, &y);
+
+ LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL;
+ return retval;
+ }
+
+ F32 time_dilation = 1.f;
+ if(mesgsys != NULL)
+ {
U16 time_dilation16;
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
time_dilation = ((F32) time_dilation16) / 65535.f;
mRegionp->setTimeDilation(time_dilation);
- }
+ }
- // this will be used to determine if we've really changed position
- // Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
- LLVector3 test_pos_parent = getPosition();
+ // this will be used to determine if we've really changed position
+ // Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
+ LLVector3 test_pos_parent = getPosition();
- // This needs to match the largest size below. See switch(length)
- U8 data[MAX_OBJECT_BINARY_DATA_SIZE];
+ // This needs to match the largest size below. See switch(length)
+ U8 data[MAX_OBJECT_BINARY_DATA_SIZE];
#ifdef LL_BIG_ENDIAN
- U16 valswizzle[4];
+ U16 valswizzle[4];
#endif
- U16 *val;
- const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();
- const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
- const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
- S32 length;
- S32 count;
- S32 this_update_precision = 32; // in bits
-
- // Temporaries, because we need to compare w/ previous to set dirty flags...
- LLVector3 new_pos_parent;
- LLVector3 new_vel;
- LLVector3 new_acc;
- LLVector3 new_angv;
- LLVector3 old_angv = getAngularVelocity();
- LLQuaternion new_rot;
- LLVector3 new_scale = getScale();
-
- U32 parent_id = 0;
- U8 material = 0;
- U8 click_action = 0;
- U32 crc = 0;
-
- bool old_special_hover_cursor = specialHoverCursor();
-
- LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
-
- if (cur_parentp)
- {
- parent_id = cur_parentp->mLocalID;
- }
-
- if (!dp)
- {
- switch(update_type)
- {
- case OUT_FULL:
- {
+ U16 *val;
+ const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();
+ const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
+ const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
+ S32 length;
+ S32 count;
+ S32 this_update_precision = 32; // in bits
+
+ // Temporaries, because we need to compare w/ previous to set dirty flags...
+ LLVector3 new_pos_parent;
+ LLVector3 new_vel;
+ LLVector3 new_acc;
+ LLVector3 new_angv;
+ LLVector3 old_angv = getAngularVelocity();
+ LLQuaternion new_rot;
+ LLVector3 new_scale = getScale();
+
+ U32 parent_id = 0;
+ U8 material = 0;
+ U8 click_action = 0;
+ U32 crc = 0;
+
+ bool old_special_hover_cursor = specialHoverCursor();
+
+ LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
+
+ if (cur_parentp)
+ {
+ parent_id = cur_parentp->mLocalID;
+ }
+
+ if (!dp)
+ {
+ switch(update_type)
+ {
+ case OUT_FULL:
+ {
#ifdef DEBUG_UPDATE_TYPE
- LL_INFOS() << "Full:" << getID() << LL_ENDL;
+ LL_INFOS() << "Full:" << getID() << LL_ENDL;
#endif
- //clear cost and linkset cost
- setObjectCostStale();
- if (isSelected())
- {
- gFloaterTools->dirty();
- }
-
- LLUUID audio_uuid;
- LLUUID owner_id; // only valid if audio_uuid or particle system is not null
- F32 gain;
- F32 cutoff;
- U8 sound_flags;
-
- mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
- mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
- mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
- // HACK: Owner id only valid if non-null sound id or particle system
- mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
- mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
- mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num );
- mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
- mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
- mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
- mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
- length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
-
- mTotalCRC = crc;
+ //clear cost and linkset cost
+ setObjectCostStale();
+ if (isSelected())
+ {
+ gFloaterTools->dirty();
+ }
+
+ LLUUID audio_uuid;
+ LLUUID owner_id; // only valid if audio_uuid or particle system is not null
+ F32 gain;
+ F32 cutoff;
+ U8 sound_flags;
+
+ mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
+ mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
+ mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
+ // HACK: Owner id only valid if non-null sound id or particle system
+ mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
+ mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
+ mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num );
+ mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
+ mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
+ mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
+ mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
+ length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
+
+ mTotalCRC = crc;
// Might need to update mSourceMuted here to properly pick up new radius
- mSoundCutOffRadius = cutoff;
-
- // Owner ID used for sound muting or particle system muting
- setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
-
- U8 old_material = getMaterial();
- if (old_material != material)
- {
- setMaterial(material);
- if (mDrawable.notNull())
- {
- gPipeline.markMoved(mDrawable, FALSE); // undamped
- }
- }
- setClickAction(click_action);
-
- count = 0;
- LLVector4 collision_plane;
-
- switch(length)
- {
- case (60 + 16):
- // pull out collision normal for avatar
- htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
- ((LLVOAvatar*)this)->setFootPlane(collision_plane);
- count += sizeof(LLVector4);
- // fall through
- case 60:
- this_update_precision = 32;
- // this is a terse update
- // pos
- htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // vel
- htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // acc
- htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // theta
- {
- LLVector3 vec;
- htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- new_rot.unpackFromVector3(vec);
- }
- count += sizeof(LLVector3);
- // omega
- htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- if (new_angv.isExactlyZero())
- {
- // reset rotation time
- resetRot();
- }
- setAngularVelocity(new_angv);
+ mSoundCutOffRadius = cutoff;
+
+ // Owner ID used for sound muting or particle system muting
+ setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
+
+ U8 old_material = getMaterial();
+ if (old_material != material)
+ {
+ setMaterial(material);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markMoved(mDrawable, FALSE); // undamped
+ }
+ }
+ setClickAction(click_action);
+
+ count = 0;
+ LLVector4 collision_plane;
+
+ switch(length)
+ {
+ case (60 + 16):
+ // pull out collision normal for avatar
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ ((LLVOAvatar*)this)->setFootPlane(collision_plane);
+ count += sizeof(LLVector4);
+ // fall through
+ case 60:
+ this_update_precision = 32;
+ // this is a terse update
+ // pos
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // vel
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // acc
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // theta
+ {
+ LLVector3 vec;
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ new_rot.unpackFromVector3(vec);
+ }
+ count += sizeof(LLVector3);
+ // omega
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ if (new_angv.isExactlyZero())
+ {
+ // reset rotation time
+ resetRot();
+ }
+ setAngularVelocity(new_angv);
#if LL_DARWIN
- if (length == 76)
- {
- setAngularVelocity(LLVector3::zero);
- }
+ if (length == 76)
+ {
+ setAngularVelocity(LLVector3::zero);
+ }
#endif
- break;
- case(32 + 16):
- // pull out collision normal for avatar
- htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
- ((LLVOAvatar*)this)->setFootPlane(collision_plane);
- count += sizeof(LLVector4);
- // fall through
- case 32:
- this_update_precision = 16;
- test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
-
- // This is a terse 16 update, so treat data as an array of U16's.
+ break;
+ case(32 + 16):
+ // pull out collision normal for avatar
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ ((LLVOAvatar*)this)->setFootPlane(collision_plane);
+ count += sizeof(LLVector4);
+ // fall through
+ case 32:
+ this_update_precision = 16;
+ test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+
+ // This is a terse 16 update, so treat data as an array of U16's.
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
+ count += sizeof(U16)*3;
+ new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size)));
+ count += sizeof(U16)*3;
+ setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size)));
+ count += sizeof(U16)*3;
+ setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*4;
- new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
- new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
- new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
- new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
+ count += sizeof(U16)*4;
+ new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+ new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+ new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+ new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- new_angv.setVec(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size));
- if (new_angv.isExactlyZero())
- {
- // reset rotation time
- resetRot();
- }
- setAngularVelocity(new_angv);
- break;
-
- case 16:
- this_update_precision = 8;
- test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
- // this is a terse 8 update
- new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
-
- setVelocity(U8_to_F32(data[3], -size, size),
- U8_to_F32(data[4], -size, size),
- U8_to_F32(data[5], -size, size) );
-
- setAcceleration(U8_to_F32(data[6], -size, size),
- U8_to_F32(data[7], -size, size),
- U8_to_F32(data[8], -size, size) );
-
- new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
- new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
- new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
- new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
-
- new_angv.setVec(U8_to_F32(data[13], -size, size),
- U8_to_F32(data[14], -size, size),
- U8_to_F32(data[15], -size, size) );
- if (new_angv.isExactlyZero())
- {
- // reset rotation time
- resetRot();
- }
- setAngularVelocity(new_angv);
- break;
- }
-
- ////////////////////////////////////////////////////
- //
- // Here we handle data specific to the full message.
- //
-
- U32 flags;
- mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
- // clear all but local flags
- mFlags &= FLAGS_LOCAL;
- mFlags |= flags;
-
- U8 state;
- mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
- mAttachmentState = state;
-
- // ...new objects that should come in selected need to be added to the selected list
- mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
-
- // Set all name value pairs
- S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
- if (nv_size > 0)
- {
- std::string name_value_list;
- mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num);
- setNameValueList(name_value_list);
- }
-
- // Clear out any existing generic data
- if (mData)
- {
- delete [] mData;
- }
-
- // Check for appended generic data
- S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
- if (data_size <= 0)
- {
- mData = NULL;
- }
- else
- {
- // ...has generic data
- mData = new U8[data_size];
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
- }
-
- S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
- if (text_size > 1)
- {
- // Setup object text
- if (!mText)
- {
- initHudText();
- }
-
- std::string temp_string;
- mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
-
- LLColor4U coloru;
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
-
- // alpha was flipped so that it zero encoded better
- coloru.mV[3] = 255 - coloru.mV[3];
- mText->setColor(LLColor4(coloru));
- mText->setString(temp_string);
-
- mHudText = temp_string;
- mHudTextColor = LLColor4(coloru);
-
- setChanged(MOVED | SILHOUETTE);
- }
- else
- {
- if (mText.notNull())
- {
- mText->markDead();
- mText = NULL;
- }
- mHudText.clear();
- }
-
- std::string media_url;
- mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
+ new_angv.setVec(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size));
+ if (new_angv.isExactlyZero())
+ {
+ // reset rotation time
+ resetRot();
+ }
+ setAngularVelocity(new_angv);
+ break;
+
+ case 16:
+ this_update_precision = 8;
+ test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+ // this is a terse 8 update
+ new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
+
+ setVelocity(U8_to_F32(data[3], -size, size),
+ U8_to_F32(data[4], -size, size),
+ U8_to_F32(data[5], -size, size) );
+
+ setAcceleration(U8_to_F32(data[6], -size, size),
+ U8_to_F32(data[7], -size, size),
+ U8_to_F32(data[8], -size, size) );
+
+ new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
+ new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
+ new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
+ new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
+
+ new_angv.setVec(U8_to_F32(data[13], -size, size),
+ U8_to_F32(data[14], -size, size),
+ U8_to_F32(data[15], -size, size) );
+ if (new_angv.isExactlyZero())
+ {
+ // reset rotation time
+ resetRot();
+ }
+ setAngularVelocity(new_angv);
+ break;
+ }
+
+ ////////////////////////////////////////////////////
+ //
+ // Here we handle data specific to the full message.
+ //
+
+ U32 flags;
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
+ // clear all but local flags
+ mFlags &= FLAGS_LOCAL;
+ mFlags |= flags;
+
+ U8 state;
+ mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
+ mAttachmentState = state;
+
+ // ...new objects that should come in selected need to be added to the selected list
+ mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+
+ // Set all name value pairs
+ S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
+ if (nv_size > 0)
+ {
+ std::string name_value_list;
+ mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num);
+ setNameValueList(name_value_list);
+ }
+
+ // Clear out any existing generic data
+ if (mData)
+ {
+ delete [] mData;
+ }
+
+ // Check for appended generic data
+ S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
+ if (data_size <= 0)
+ {
+ mData = NULL;
+ }
+ else
+ {
+ // ...has generic data
+ mData = new U8[data_size];
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
+ }
+
+ S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
+ if (text_size > 1)
+ {
+ // Setup object text
+ if (!mText)
+ {
+ initHudText();
+ }
+
+ std::string temp_string;
+ mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
+
+ LLColor4U coloru;
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
+
+ // alpha was flipped so that it zero encoded better
+ coloru.mV[3] = 255 - coloru.mV[3];
+
+ mText->setColor(LLColor4(coloru));
+ mText->setString(temp_string);
+
+ mHudText = temp_string;
+ mHudTextColor = LLColor4(coloru);
+
+ setChanged(MOVED | SILHOUETTE);
+ }
+ else
+ {
+ if (mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ mHudText.clear();
+ }
+
+ std::string media_url;
+ mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
retval |= checkMediaURL(media_url);
-
- //
- // Unpack particle system data
- //
- unpackParticleSource(block_num, owner_id);
-
- // Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- iter->second->in_use = FALSE;
- }
-
- // Unpack extra parameters
- S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
- if (size > 0)
- {
- U8 *buffer = new U8[size];
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
- LLDataPackerBinaryBuffer dp(buffer, size);
-
- U8 num_parameters;
- dp.unpackU8(num_parameters, "num_params");
- U8 param_block[MAX_OBJECT_PARAMS_SIZE];
- for (U8 param=0; param<num_parameters; ++param)
- {
- U16 param_type;
- S32 param_size;
- dp.unpackU16(param_type, "param_type");
- dp.unpackBinaryData(param_block, param_size, "param_data");
- //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL;
- LLDataPackerBinaryBuffer dp2(param_block, param_size);
- unpackParameterEntry(param_type, &dp2);
- }
- delete[] buffer;
- }
-
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- if (!iter->second->in_use)
- {
- // Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, FALSE, false);
- }
- }
-
- break;
- }
-
- case OUT_TERSE_IMPROVED:
- {
+
+ //
+ // Unpack particle system data
+ //
+ unpackParticleSource(block_num, owner_id);
+
+ // Mark all extra parameters not used
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
+ for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ {
+ iter->second->in_use = FALSE;
+ }
+
+ // Unpack extra parameters
+ S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
+ if (size > 0)
+ {
+ U8 *buffer = new U8[size];
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
+ LLDataPackerBinaryBuffer dp(buffer, size);
+
+ U8 num_parameters;
+ dp.unpackU8(num_parameters, "num_params");
+ U8 param_block[MAX_OBJECT_PARAMS_SIZE];
+ for (U8 param=0; param<num_parameters; ++param)
+ {
+ U16 param_type;
+ S32 param_size;
+ dp.unpackU16(param_type, "param_type");
+ dp.unpackBinaryData(param_block, param_size, "param_data");
+ //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL;
+ LLDataPackerBinaryBuffer dp2(param_block, param_size);
+ unpackParameterEntry(param_type, &dp2);
+ }
+ delete[] buffer;
+ }
+
+ for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ {
+ if (!iter->second->in_use)
+ {
+ // Send an update message in case it was formerly in use
+ parameterChanged(iter->first, iter->second->data, FALSE, false);
+ }
+ }
+
+ break;
+ }
+
+ case OUT_TERSE_IMPROVED:
+ {
#ifdef DEBUG_UPDATE_TYPE
- LL_INFOS() << "TI:" << getID() << LL_ENDL;
+ LL_INFOS() << "TI:" << getID() << LL_ENDL;
#endif
- length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
- count = 0;
- LLVector4 collision_plane;
-
- switch(length)
- {
- case(60 + 16):
- // pull out collision normal for avatar
- htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
- ((LLVOAvatar*)this)->setFootPlane(collision_plane);
- count += sizeof(LLVector4);
- // fall through
- case 60:
- // this is a terse 32 update
- // pos
- this_update_precision = 32;
- htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // vel
- htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // acc
- htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- count += sizeof(LLVector3);
- // theta
- {
- LLVector3 vec;
- htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- new_rot.unpackFromVector3(vec);
- }
- count += sizeof(LLVector3);
- // omega
- htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
- if (new_angv.isExactlyZero())
- {
- // reset rotation time
- resetRot();
- }
- setAngularVelocity(new_angv);
+ length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
+ count = 0;
+ LLVector4 collision_plane;
+
+ switch(length)
+ {
+ case(60 + 16):
+ // pull out collision normal for avatar
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ ((LLVOAvatar*)this)->setFootPlane(collision_plane);
+ count += sizeof(LLVector4);
+ // fall through
+ case 60:
+ // this is a terse 32 update
+ // pos
+ this_update_precision = 32;
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // vel
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // acc
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ count += sizeof(LLVector3);
+ // theta
+ {
+ LLVector3 vec;
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ new_rot.unpackFromVector3(vec);
+ }
+ count += sizeof(LLVector3);
+ // omega
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ if (new_angv.isExactlyZero())
+ {
+ // reset rotation time
+ resetRot();
+ }
+ setAngularVelocity(new_angv);
#if LL_DARWIN
- if (length == 76)
- {
- setAngularVelocity(LLVector3::zero);
- }
+ if (length == 76)
+ {
+ setAngularVelocity(LLVector3::zero);
+ }
#endif
- break;
- case(32 + 16):
- // pull out collision normal for avatar
- htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
- ((LLVOAvatar*)this)->setFootPlane(collision_plane);
- count += sizeof(LLVector4);
- // fall through
- case 32:
- // this is a terse 16 update
- this_update_precision = 16;
- test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+ break;
+ case(32 + 16):
+ // pull out collision normal for avatar
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ ((LLVOAvatar*)this)->setFootPlane(collision_plane);
+ count += sizeof(LLVector4);
+ // fall through
+ case 32:
+ // this is a terse 16 update
+ this_update_precision = 16;
+ test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
+ count += sizeof(U16)*3;
+ new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- setVelocity(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size));
+ count += sizeof(U16)*3;
+ setVelocity(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*3;
- setAcceleration(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size));
+ count += sizeof(U16)*3;
+ setAcceleration(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- count += sizeof(U16)*4;
- new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
- new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
- new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
- new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
+ count += sizeof(U16)*4;
+ new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+ new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+ new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+ new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
- val = valswizzle;
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ val = valswizzle;
#else
- val = (U16 *) &data[count];
+ val = (U16 *) &data[count];
#endif
- new_angv.set(U16_to_F32(val[VX], -size, size),
- U16_to_F32(val[VY], -size, size),
- U16_to_F32(val[VZ], -size, size));
- setAngularVelocity(new_angv);
- break;
-
- case 16:
- // this is a terse 8 update
- this_update_precision = 8;
- test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
- new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
- new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
-
- setVelocity(U8_to_F32(data[3], -size, size),
- U8_to_F32(data[4], -size, size),
- U8_to_F32(data[5], -size, size) );
-
- setAcceleration(U8_to_F32(data[6], -size, size),
- U8_to_F32(data[7], -size, size),
- U8_to_F32(data[8], -size, size) );
-
- new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
- new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
- new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
- new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
-
- new_angv.set(U8_to_F32(data[13], -size, size),
- U8_to_F32(data[14], -size, size),
- U8_to_F32(data[15], -size, size) );
- setAngularVelocity(new_angv);
- break;
- }
-
- U8 state;
- mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
- mAttachmentState = state;
- break;
- }
-
- default:
- break;
-
- }
- }
- else
- {
- // handle the compressed case
- LLUUID sound_uuid;
- LLUUID owner_id;
- F32 gain = 0;
- U8 sound_flags = 0;
- F32 cutoff = 0;
-
- U16 val[4];
-
- U8 state;
-
- dp->unpackU8(state, "State");
- mAttachmentState = state;
-
- switch(update_type)
- {
- case OUT_TERSE_IMPROVED:
- {
+ new_angv.set(U16_to_F32(val[VX], -size, size),
+ U16_to_F32(val[VY], -size, size),
+ U16_to_F32(val[VZ], -size, size));
+ setAngularVelocity(new_angv);
+ break;
+
+ case 16:
+ // this is a terse 8 update
+ this_update_precision = 8;
+ test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
+ new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
+ new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
+
+ setVelocity(U8_to_F32(data[3], -size, size),
+ U8_to_F32(data[4], -size, size),
+ U8_to_F32(data[5], -size, size) );
+
+ setAcceleration(U8_to_F32(data[6], -size, size),
+ U8_to_F32(data[7], -size, size),
+ U8_to_F32(data[8], -size, size) );
+
+ new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
+ new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
+ new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
+ new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
+
+ new_angv.set(U8_to_F32(data[13], -size, size),
+ U8_to_F32(data[14], -size, size),
+ U8_to_F32(data[15], -size, size) );
+ setAngularVelocity(new_angv);
+ break;
+ }
+
+ U8 state;
+ mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
+ mAttachmentState = state;
+ break;
+ }
+
+ default:
+ break;
+
+ }
+ }
+ else
+ {
+ // handle the compressed case
+ LLUUID sound_uuid;
+ LLUUID owner_id;
+ F32 gain = 0;
+ U8 sound_flags = 0;
+ F32 cutoff = 0;
+
+ U16 val[4];
+
+ U8 state;
+
+ dp->unpackU8(state, "State");
+ mAttachmentState = state;
+
+ switch(update_type)
+ {
+ case OUT_TERSE_IMPROVED:
+ {
#ifdef DEBUG_UPDATE_TYPE
- LL_INFOS() << "CompTI:" << getID() << LL_ENDL;
+ LL_INFOS() << "CompTI:" << getID() << LL_ENDL;
#endif
- U8 value;
- dp->unpackU8(value, "agent");
- if (value)
- {
- LLVector4 collision_plane;
- dp->unpackVector4(collision_plane, "Plane");
- ((LLVOAvatar*)this)->setFootPlane(collision_plane);
- }
- test_pos_parent = getPosition();
- dp->unpackVector3(new_pos_parent, "Pos");
- dp->unpackU16(val[VX], "VelX");
- dp->unpackU16(val[VY], "VelY");
- dp->unpackU16(val[VZ], "VelZ");
- setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
- U16_to_F32(val[VY], -128.f, 128.f),
- U16_to_F32(val[VZ], -128.f, 128.f));
- dp->unpackU16(val[VX], "AccX");
- dp->unpackU16(val[VY], "AccY");
- dp->unpackU16(val[VZ], "AccZ");
- setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
- U16_to_F32(val[VY], -64.f, 64.f),
- U16_to_F32(val[VZ], -64.f, 64.f));
-
- dp->unpackU16(val[VX], "ThetaX");
- dp->unpackU16(val[VY], "ThetaY");
- dp->unpackU16(val[VZ], "ThetaZ");
- dp->unpackU16(val[VS], "ThetaS");
- new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
- new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
- new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
- new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
- dp->unpackU16(val[VX], "AccX");
- dp->unpackU16(val[VY], "AccY");
- dp->unpackU16(val[VZ], "AccZ");
- new_angv.set(U16_to_F32(val[VX], -64.f, 64.f),
- U16_to_F32(val[VY], -64.f, 64.f),
- U16_to_F32(val[VZ], -64.f, 64.f));
- setAngularVelocity(new_angv);
- }
- break;
- case OUT_FULL_COMPRESSED:
- case OUT_FULL_CACHED:
- {
+ U8 value;
+ dp->unpackU8(value, "agent");
+ if (value)
+ {
+ LLVector4 collision_plane;
+ dp->unpackVector4(collision_plane, "Plane");
+ ((LLVOAvatar*)this)->setFootPlane(collision_plane);
+ }
+ test_pos_parent = getPosition();
+ dp->unpackVector3(new_pos_parent, "Pos");
+ dp->unpackU16(val[VX], "VelX");
+ dp->unpackU16(val[VY], "VelY");
+ dp->unpackU16(val[VZ], "VelZ");
+ setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
+ U16_to_F32(val[VY], -128.f, 128.f),
+ U16_to_F32(val[VZ], -128.f, 128.f));
+ dp->unpackU16(val[VX], "AccX");
+ dp->unpackU16(val[VY], "AccY");
+ dp->unpackU16(val[VZ], "AccZ");
+ setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
+ U16_to_F32(val[VY], -64.f, 64.f),
+ U16_to_F32(val[VZ], -64.f, 64.f));
+
+ dp->unpackU16(val[VX], "ThetaX");
+ dp->unpackU16(val[VY], "ThetaY");
+ dp->unpackU16(val[VZ], "ThetaZ");
+ dp->unpackU16(val[VS], "ThetaS");
+ new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
+ new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
+ new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
+ new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
+ dp->unpackU16(val[VX], "AccX");
+ dp->unpackU16(val[VY], "AccY");
+ dp->unpackU16(val[VZ], "AccZ");
+ new_angv.set(U16_to_F32(val[VX], -64.f, 64.f),
+ U16_to_F32(val[VY], -64.f, 64.f),
+ U16_to_F32(val[VZ], -64.f, 64.f));
+ setAngularVelocity(new_angv);
+ }
+ break;
+ case OUT_FULL_COMPRESSED:
+ case OUT_FULL_CACHED:
+ {
#ifdef DEBUG_UPDATE_TYPE
- LL_INFOS() << "CompFull:" << getID() << LL_ENDL;
+ LL_INFOS() << "CompFull:" << getID() << LL_ENDL;
#endif
- setObjectCostStale();
-
- if (isSelected())
- {
- gFloaterTools->dirty();
- }
-
- dp->unpackU32(crc, "CRC");
- mTotalCRC = crc;
- dp->unpackU8(material, "Material");
- U8 old_material = getMaterial();
- if (old_material != material)
- {
- setMaterial(material);
- if (mDrawable.notNull())
- {
- gPipeline.markMoved(mDrawable, FALSE); // undamped
- }
- }
- dp->unpackU8(click_action, "ClickAction");
- setClickAction(click_action);
- dp->unpackVector3(new_scale, "Scale");
- dp->unpackVector3(new_pos_parent, "Pos");
- LLVector3 vec;
- dp->unpackVector3(vec, "Rot");
- new_rot.unpackFromVector3(vec);
- setAcceleration(LLVector3::zero);
-
- U32 value;
- dp->unpackU32(value, "SpecialCode");
- dp->setPassFlags(value);
- dp->unpackUUID(owner_id, "Owner");
-
- mOwnerID = owner_id;
-
- if (value & 0x80)
- {
- dp->unpackVector3(new_angv, "Omega");
- setAngularVelocity(new_angv);
- }
-
- if (value & 0x20)
- {
- dp->unpackU32(parent_id, "ParentID");
- }
- else
- {
- parent_id = 0;
- }
-
- S32 sp_size;
- U32 size;
- if (value & 0x2)
- {
- sp_size = 1;
- delete [] mData;
- mData = new U8[1];
- dp->unpackU8(((U8*)mData)[0], "TreeData");
- }
- else if (value & 0x1)
- {
- dp->unpackU32(size, "ScratchPadSize");
- delete [] mData;
- mData = new U8[size];
- dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
- }
- else
- {
- mData = NULL;
- }
-
- // Setup object text
- if (!mText && (value & 0x4))
- {
- initHudText();
- }
-
- if (value & 0x4)
- {
- std::string temp_string;
- dp->unpackString(temp_string, "Text");
- LLColor4U coloru;
- dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
- coloru.mV[3] = 255 - coloru.mV[3];
- mText->setColor(LLColor4(coloru));
- mText->setString(temp_string);
+ setObjectCostStale();
+
+ if (isSelected())
+ {
+ gFloaterTools->dirty();
+ }
+
+ dp->unpackU32(crc, "CRC");
+ mTotalCRC = crc;
+ dp->unpackU8(material, "Material");
+ U8 old_material = getMaterial();
+ if (old_material != material)
+ {
+ setMaterial(material);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markMoved(mDrawable, FALSE); // undamped
+ }
+ }
+ dp->unpackU8(click_action, "ClickAction");
+ setClickAction(click_action);
+ dp->unpackVector3(new_scale, "Scale");
+ dp->unpackVector3(new_pos_parent, "Pos");
+ LLVector3 vec;
+ dp->unpackVector3(vec, "Rot");
+ new_rot.unpackFromVector3(vec);
+ setAcceleration(LLVector3::zero);
+
+ U32 value;
+ dp->unpackU32(value, "SpecialCode");
+ dp->setPassFlags(value);
+ dp->unpackUUID(owner_id, "Owner");
+
+ mOwnerID = owner_id;
+
+ if (value & 0x80)
+ {
+ dp->unpackVector3(new_angv, "Omega");
+ setAngularVelocity(new_angv);
+ }
+
+ if (value & 0x20)
+ {
+ dp->unpackU32(parent_id, "ParentID");
+ }
+ else
+ {
+ parent_id = 0;
+ }
+
+ S32 sp_size;
+ U32 size;
+ if (value & 0x2)
+ {
+ sp_size = 1;
+ delete [] mData;
+ mData = new U8[1];
+ dp->unpackU8(((U8*)mData)[0], "TreeData");
+ }
+ else if (value & 0x1)
+ {
+ dp->unpackU32(size, "ScratchPadSize");
+ delete [] mData;
+ mData = new U8[size];
+ dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
+ }
+ else
+ {
+ mData = NULL;
+ }
+
+ // Setup object text
+ if (!mText && (value & 0x4))
+ {
+ initHudText();
+ }
+
+ if (value & 0x4)
+ {
+ std::string temp_string;
+ dp->unpackString(temp_string, "Text");
+
+ LLColor4U coloru;
+ dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
+ coloru.mV[3] = 255 - coloru.mV[3];
+ mText->setColor(LLColor4(coloru));
+ mText->setString(temp_string);
mHudText = temp_string;
mHudTextColor = LLColor4(coloru);
- setChanged(TEXTURE);
- }
- else
- {
- if (mText.notNull())
- {
- mText->markDead();
- mText = NULL;
- }
- mHudText.clear();
- }
+ setChanged(TEXTURE);
+ }
+ else
+ {
+ if (mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ mHudText.clear();
+ }
std::string media_url;
- if (value & 0x200)
- {
- dp->unpackString(media_url, "MediaURL");
- }
+ if (value & 0x200)
+ {
+ dp->unpackString(media_url, "MediaURL");
+ }
retval |= checkMediaURL(media_url);
- //
- // Unpack particle system data (legacy)
- //
- if (value & 0x8)
- {
- unpackParticleSource(*dp, owner_id, true);
- }
- else if (!(value & 0x400))
- {
- deleteParticleSource();
- }
-
- // Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- iter->second->in_use = FALSE;
- }
-
- // Unpack extra params
- U8 num_parameters;
- dp->unpackU8(num_parameters, "num_params");
- U8 param_block[MAX_OBJECT_PARAMS_SIZE];
- for (U8 param=0; param<num_parameters; ++param)
- {
- U16 param_type;
- S32 param_size;
- dp->unpackU16(param_type, "param_type");
- dp->unpackBinaryData(param_block, param_size, "param_data");
- //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL;
- LLDataPackerBinaryBuffer dp2(param_block, param_size);
- unpackParameterEntry(param_type, &dp2);
- }
-
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- if (!iter->second->in_use)
- {
- // Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, FALSE, false);
- }
- }
-
- if (value & 0x10)
- {
- dp->unpackUUID(sound_uuid, "SoundUUID");
- dp->unpackF32(gain, "SoundGain");
- dp->unpackU8(sound_flags, "SoundFlags");
- dp->unpackF32(cutoff, "SoundRadius");
- }
-
- if (value & 0x100)
- {
- std::string name_value_list;
- dp->unpackString(name_value_list, "NV");
-
- setNameValueList(name_value_list);
- }
-
- mTotalCRC = crc;
- mSoundCutOffRadius = cutoff;
-
- setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
-
- // only get these flags on updates from sim, not cached ones
- // Preload these five flags for every object.
- // Finer shades require the object to be selected, and the selection manager
- // stores the extended permission info.
- if(mesgsys != NULL)
- {
- U32 flags;
- mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
- loadFlags(flags);
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- //
- // Fix object parenting.
- //
- BOOL b_changed_status = FALSE;
-
- if (OUT_TERSE_IMPROVED != update_type)
- {
- // We only need to update parenting on full updates, terse updates
- // don't send parenting information.
- if (!cur_parentp)
- {
- if (parent_id == 0)
- {
- // No parent now, no parent in message -> do nothing
- }
- else
- {
- // No parent now, new parent in message -> attach to that parent if possible
- LLUUID parent_uuid;
-
- if(mesgsys != NULL)
- {
- LLViewerObjectList::getUUIDFromLocal(parent_uuid,
- parent_id,
- mesgsys->getSenderIP(),
- mesgsys->getSenderPort());
- }
- else
- {
- LLViewerObjectList::getUUIDFromLocal(parent_uuid,
- parent_id,
- mRegionp->getHost().getAddress(),
- mRegionp->getHost().getPort());
- }
-
- LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
-
- //
- // Check to see if we have the corresponding viewer object for the parent.
- //
- if (sent_parentp && sent_parentp->getParent() == this)
- {
- // Try to recover if we attempt to attach a parent to its child
- LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL;
- this->removeChild(sent_parentp);
- sent_parentp->setDrawableParent(NULL);
- }
-
- if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
- {
+ //
+ // Unpack particle system data (legacy)
+ //
+ if (value & 0x8)
+ {
+ unpackParticleSource(*dp, owner_id, true);
+ }
+ else if (!(value & 0x400))
+ {
+ deleteParticleSource();
+ }
+
+ // Mark all extra parameters not used
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
+ for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ {
+ iter->second->in_use = FALSE;
+ }
+
+ // Unpack extra params
+ U8 num_parameters;
+ dp->unpackU8(num_parameters, "num_params");
+ U8 param_block[MAX_OBJECT_PARAMS_SIZE];
+ for (U8 param=0; param<num_parameters; ++param)
+ {
+ U16 param_type;
+ S32 param_size;
+ dp->unpackU16(param_type, "param_type");
+ dp->unpackBinaryData(param_block, param_size, "param_data");
+ //LL_INFOS() << "Param type: " << param_type << ", Size: " << param_size << LL_ENDL;
+ LLDataPackerBinaryBuffer dp2(param_block, param_size);
+ unpackParameterEntry(param_type, &dp2);
+ }
+
+ for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ {
+ if (!iter->second->in_use)
+ {
+ // Send an update message in case it was formerly in use
+ parameterChanged(iter->first, iter->second->data, FALSE, false);
+ }
+ }
+
+ if (value & 0x10)
+ {
+ dp->unpackUUID(sound_uuid, "SoundUUID");
+ dp->unpackF32(gain, "SoundGain");
+ dp->unpackU8(sound_flags, "SoundFlags");
+ dp->unpackF32(cutoff, "SoundRadius");
+ }
+
+ if (value & 0x100)
+ {
+ std::string name_value_list;
+ dp->unpackString(name_value_list, "NV");
+
+ setNameValueList(name_value_list);
+ }
+
+ mTotalCRC = crc;
+ mSoundCutOffRadius = cutoff;
+
+ setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
+
+ // only get these flags on updates from sim, not cached ones
+ // Preload these five flags for every object.
+ // Finer shades require the object to be selected, and the selection manager
+ // stores the extended permission info.
+ if(mesgsys != NULL)
+ {
+ U32 flags;
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
+ loadFlags(flags);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ //
+ // Fix object parenting.
+ //
+ BOOL b_changed_status = FALSE;
+
+ if (OUT_TERSE_IMPROVED != update_type)
+ {
+ // We only need to update parenting on full updates, terse updates
+ // don't send parenting information.
+ if (!cur_parentp)
+ {
+ if (parent_id == 0)
+ {
+ // No parent now, no parent in message -> do nothing
+ }
+ else
+ {
+ // No parent now, new parent in message -> attach to that parent if possible
+ LLUUID parent_uuid;
+
+ if(mesgsys != NULL)
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ mesgsys->getSenderIP(),
+ mesgsys->getSenderPort());
+ }
+ else
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ mRegionp->getHost().getAddress(),
+ mRegionp->getHost().getPort());
+ }
+
+ LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
+
+ //
+ // Check to see if we have the corresponding viewer object for the parent.
+ //
+ if (sent_parentp && sent_parentp->getParent() == this)
+ {
+ // Try to recover if we attempt to attach a parent to its child
+ LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL;
+ this->removeChild(sent_parentp);
+ sent_parentp->setDrawableParent(NULL);
+ }
+
+ if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
+ {
if (((LLViewerObject*)sent_parentp)->isAvatar())
{
- //LL_DEBUGS("Avatar") << "ATT got object update for attachment " << LL_ENDL;
- }
-
- //
- // We have a viewer object for the parent, and it's not dead.
- // Do the actual reparenting here.
- //
-
- // new parent is valid
- b_changed_status = TRUE;
- // ...no current parent, so don't try to remove child
- if (mDrawable.notNull())
- {
- if (mDrawable->isDead() || !mDrawable->getVObj())
- {
- LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL;
- sent_parentp->addChild(this);
- }
- else
- {
- if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1
- {
- // Bad, we got a cycle somehow.
- // Kill both the parent and the child, and
- // set cache misses for both of them.
- LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL;
- LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL;
- LL_WARNS() << "Adding to cache miss list" << LL_ENDL;
- setParent(NULL);
- sent_parentp->setParent(NULL);
- getRegion()->addCacheMissFull(getLocalID());
- getRegion()->addCacheMissFull(sent_parentp->getLocalID());
- gObjectList.killObject(sent_parentp);
- gObjectList.killObject(this);
- return retval;
- }
- sent_parentp->addChild(this);
- // make sure this object gets a non-damped update
- if (sent_parentp->mDrawable.notNull())
- {
- gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
- }
- }
- }
- else
- {
- sent_parentp->addChild(this);
- }
-
- // Show particles, icon and HUD
- hideExtraDisplayItems( FALSE );
-
- setChanged(MOVED | SILHOUETTE);
- }
- else
- {
- //
- // No corresponding viewer object for the parent, put the various
- // pieces on the orphan list.
- //
-
- //parent_id
- U32 ip, port;
-
- if(mesgsys != NULL)
- {
- ip = mesgsys->getSenderIP();
- port = mesgsys->getSenderPort();
- }
- else
- {
- ip = mRegionp->getHost().getAddress();
- port = mRegionp->getHost().getPort();
- }
- gObjectList.orphanize(this, parent_id, ip, port);
-
- // Hide particles, icon and HUD
- hideExtraDisplayItems( TRUE );
- }
- }
- }
- else
- {
- // BUG: this is a bad assumption once border crossing is alowed
- if ( (parent_id == cur_parentp->mLocalID)
- &&(update_type == OUT_TERSE_IMPROVED))
- {
- // Parent now, same parent in message -> do nothing
-
- // Debugging for suspected problems with local ids.
- //LLUUID parent_uuid;
- //LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() );
- //if (parent_uuid != cur_parentp->getID() )
- //{
- // LL_ERRS() << "Local ID match but UUID mismatch of viewer object" << LL_ENDL;
- //}
- }
- else
- {
- // Parented now, different parent in message
- LLViewerObject *sent_parentp;
- if (parent_id == 0)
- {
- //
- // This object is no longer parented, we sent in a zero parent ID.
- //
- sent_parentp = NULL;
- }
- else
- {
- LLUUID parent_uuid;
-
- if(mesgsys != NULL)
- {
- LLViewerObjectList::getUUIDFromLocal(parent_uuid,
- parent_id,
- gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
- }
- else
- {
- LLViewerObjectList::getUUIDFromLocal(parent_uuid,
- parent_id,
- mRegionp->getHost().getAddress(),
- mRegionp->getHost().getPort());
- }
- sent_parentp = gObjectList.findObject(parent_uuid);
-
- if (isAvatar())
- {
- // This logic is meant to handle the case where a sitting avatar has reached a new sim
- // ahead of the object she was sitting on (which is common as objects are transfered through
- // a slower route than agents)...
- // In this case, the local id for the object will not be valid, since the viewer has not received
- // a full update for the object from that sim yet, so we assume that the agent is still sitting
- // where she was originally. --RN
- if (!sent_parentp)
- {
- sent_parentp = cur_parentp;
- }
- }
- else if (!sent_parentp)
- {
- //
- // Switching parents, but we don't know the new parent.
- //
- U32 ip, port;
-
- if(mesgsys != NULL)
- {
- ip = mesgsys->getSenderIP();
- port = mesgsys->getSenderPort();
- }
- else
- {
- ip = mRegionp->getHost().getAddress();
- port = mRegionp->getHost().getPort();
- }
-
- // We're an orphan, flag things appropriately.
- gObjectList.orphanize(this, parent_id, ip, port);
- }
- }
-
- // Reattach if possible.
- if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
- {
- // New parent is valid, detach and reattach
- b_changed_status = TRUE;
- if (mDrawable.notNull())
- {
- if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2
- {
- // Bad, we got a cycle somehow.
- // Kill both the parent and the child, and
- // set cache misses for both of them.
- LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL;
- LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL;
- LL_WARNS() << "Adding to cache miss list" << LL_ENDL;
- setParent(NULL);
- sent_parentp->setParent(NULL);
- getRegion()->addCacheMissFull(getLocalID());
- getRegion()->addCacheMissFull(sent_parentp->getLocalID());
- gObjectList.killObject(sent_parentp);
- gObjectList.killObject(this);
- return retval;
- }
- // make sure this object gets a non-damped update
- }
- cur_parentp->removeChild(this);
- sent_parentp->addChild(this);
- setChanged(MOVED | SILHOUETTE);
- sent_parentp->setChanged(MOVED | SILHOUETTE);
- if (sent_parentp->mDrawable.notNull())
- {
- gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
- }
- }
- else if (!sent_parentp)
- {
- bool remove_parent = true;
- // No new parent, or the parent that we sent doesn't exist on the viewer.
- LLViewerObject *parentp = (LLViewerObject *)getParent();
- if (parentp)
- {
- if (parentp->getRegion() != getRegion())
- {
- // This is probably an object flying across a region boundary, the
- // object probably ISN'T being reparented, but just got an object
- // update out of order (child update before parent).
- //LL_INFOS() << "Don't reparent object handoffs!" << LL_ENDL;
- remove_parent = false;
- }
- }
-
- if (remove_parent)
- {
- b_changed_status = TRUE;
- if (mDrawable.notNull())
- {
- // clear parent to removeChild can put the drawable on the damped list
- setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3
- }
-
- cur_parentp->removeChild(this);
-
- setChanged(MOVED | SILHOUETTE);
-
- if (mDrawable.notNull())
- {
- // make sure this object gets a non-damped update
- gPipeline.markMoved(mDrawable, FALSE); // undamped
- }
+ //LL_DEBUGS("Avatar") << "ATT got object update for attachment " << LL_ENDL;
}
- }
- }
- }
- }
-
- new_rot.normQuat();
-
- if (sPingInterpolate && mesgsys != NULL)
- {
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
- if (cdp)
- {
- // Note: delay is U32 and usually less then second,
- // converting it into seconds with valueInUnits will result in 0
- F32 ping_delay = 0.5f * time_dilation * ( ((F32)cdp->getPingDelay().value()) * 0.001f + gFrameDTClamped);
- LLVector3 diff = getVelocity() * ping_delay;
- new_pos_parent += diff;
- }
- else
- {
- LL_WARNS() << "findCircuit() returned NULL; skipping interpolation" << LL_ENDL;
- }
- }
-
- //////////////////////////
- //
- // Set the generic change flags...
- //
- //
-
- // If we're going to skip this message, why are we
- // doing all the parenting, etc above?
- if(mesgsys != NULL)
- {
- U32 packet_id = mesgsys->getCurrentRecvPacketID();
- if (packet_id < mLatestRecvPacketID &&
- mLatestRecvPacketID - packet_id < 65536)
- {
- //skip application of this message, it's old
- return retval;
- }
- mLatestRecvPacketID = packet_id;
- }
-
- // Set the change flags for scale
- if (new_scale != getScale())
- {
- setChanged(SCALED | SILHOUETTE);
- setScale(new_scale); // Must follow setting permYouOwner()
- }
-
- // first, let's see if the new position is actually a change
-
- //static S32 counter = 0;
-
- F32 vel_mag_sq = getVelocity().magVecSquared();
- F32 accel_mag_sq = getAcceleration().magVecSquared();
-
- if ( ((b_changed_status)||(test_pos_parent != new_pos_parent))
- ||( (!isSelected())
- &&( (vel_mag_sq != 0.f)
- ||(accel_mag_sq != 0.f)
- ||(this_update_precision > mBestUpdatePrecision))))
- {
- mBestUpdatePrecision = this_update_precision;
-
- LLVector3 diff = new_pos_parent - test_pos_parent ;
- F32 mag_sqr = diff.magVecSquared() ;
- if(llfinite(mag_sqr))
- {
- setPositionParent(new_pos_parent);
- }
- else
- {
- LL_WARNS() << "Can not move the object/avatar to an infinite location!" << LL_ENDL ;
-
- retval |= INVALID_UPDATE ;
- }
-
- if (mParent && ((LLViewerObject*)mParent)->isAvatar())
- {
- // we have changed the position of an attachment, so we need to clamp it
- LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
- avatar->clampAttachmentPositions();
- }
-
- // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
- if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
- {
- record(LLStatViewer::AGENT_POSITION_SNAP, LLUnit<F64, LLUnits::Meters>(diff.length()));
- }
- }
-
- if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO))
- || (new_angv != old_angv))
- {
- if (new_rot != mPreviousRotation)
- {
- resetRot();
- }
- else if (new_angv != old_angv)
- {
- if (flagUsePhysics())
- {
- resetRot();
- }
- else
- {
- resetRotTime();
- }
- }
-
- // Remember the last rotation value
- mPreviousRotation = new_rot;
-
- // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega)
- setRotation(new_rot * mAngularVelocityRot);
- setChanged(ROTATED | SILHOUETTE);
- }
-
- if ( gShowObjectUpdates )
- {
- LLColor4 color;
- if (update_type == OUT_TERSE_IMPROVED)
- {
- color.setVec(0.f, 0.f, 1.f, 1.f);
- }
- else
- {
- color.setVec(1.f, 0.f, 0.f, 1.f);
- }
- gPipeline.addDebugBlip(getPositionAgent(), color);
- LL_DEBUGS("MessageBlip") << "Update type " << (S32)update_type << " blip for local " << mLocalID << " at " << getPositionAgent() << LL_ENDL;
- }
-
- const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO;
-
- llassert(vel_mag_sq >= 0.f);
- llassert(accel_mag_sq >= 0.f);
- llassert(getAngularVelocity().magVecSquared() >= 0.f);
-
- if ((MAG_CUTOFF >= vel_mag_sq) &&
- (MAG_CUTOFF >= accel_mag_sq) &&
- (MAG_CUTOFF >= getAngularVelocity().magVecSquared()))
- {
- mStatic = TRUE; // This object doesn't move!
- }
- else
- {
- mStatic = FALSE;
- }
+
+ //
+ // We have a viewer object for the parent, and it's not dead.
+ // Do the actual reparenting here.
+ //
+
+ // new parent is valid
+ b_changed_status = TRUE;
+ // ...no current parent, so don't try to remove child
+ if (mDrawable.notNull())
+ {
+ if (mDrawable->isDead() || !mDrawable->getVObj())
+ {
+ LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL;
+ sent_parentp->addChild(this);
+ }
+ else
+ {
+ if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1
+ {
+ // Bad, we got a cycle somehow.
+ // Kill both the parent and the child, and
+ // set cache misses for both of them.
+ LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL;
+ LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL;
+ LL_WARNS() << "Adding to cache miss list" << LL_ENDL;
+ setParent(NULL);
+ sent_parentp->setParent(NULL);
+ getRegion()->addCacheMissFull(getLocalID());
+ getRegion()->addCacheMissFull(sent_parentp->getLocalID());
+ gObjectList.killObject(sent_parentp);
+ gObjectList.killObject(this);
+ return retval;
+ }
+ sent_parentp->addChild(this);
+ // make sure this object gets a non-damped update
+ if (sent_parentp->mDrawable.notNull())
+ {
+ gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
+ }
+ }
+ }
+ else
+ {
+ sent_parentp->addChild(this);
+ }
+
+ // Show particles, icon and HUD
+ hideExtraDisplayItems( FALSE );
+
+ setChanged(MOVED | SILHOUETTE);
+ }
+ else
+ {
+ //
+ // No corresponding viewer object for the parent, put the various
+ // pieces on the orphan list.
+ //
+
+ //parent_id
+ U32 ip, port;
+
+ if(mesgsys != NULL)
+ {
+ ip = mesgsys->getSenderIP();
+ port = mesgsys->getSenderPort();
+ }
+ else
+ {
+ ip = mRegionp->getHost().getAddress();
+ port = mRegionp->getHost().getPort();
+ }
+ gObjectList.orphanize(this, parent_id, ip, port);
+
+ // Hide particles, icon and HUD
+ hideExtraDisplayItems( TRUE );
+ }
+ }
+ }
+ else
+ {
+ // BUG: this is a bad assumption once border crossing is alowed
+ if ( (parent_id == cur_parentp->mLocalID)
+ &&(update_type == OUT_TERSE_IMPROVED))
+ {
+ // Parent now, same parent in message -> do nothing
+
+ // Debugging for suspected problems with local ids.
+ //LLUUID parent_uuid;
+ //LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() );
+ //if (parent_uuid != cur_parentp->getID() )
+ //{
+ // LL_ERRS() << "Local ID match but UUID mismatch of viewer object" << LL_ENDL;
+ //}
+ }
+ else
+ {
+ // Parented now, different parent in message
+ LLViewerObject *sent_parentp;
+ if (parent_id == 0)
+ {
+ //
+ // This object is no longer parented, we sent in a zero parent ID.
+ //
+ sent_parentp = NULL;
+ }
+ else
+ {
+ LLUUID parent_uuid;
+
+ if(mesgsys != NULL)
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ gMessageSystem->getSenderIP(),
+ gMessageSystem->getSenderPort());
+ }
+ else
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ mRegionp->getHost().getAddress(),
+ mRegionp->getHost().getPort());
+ }
+ sent_parentp = gObjectList.findObject(parent_uuid);
+
+ if (isAvatar())
+ {
+ // This logic is meant to handle the case where a sitting avatar has reached a new sim
+ // ahead of the object she was sitting on (which is common as objects are transfered through
+ // a slower route than agents)...
+ // In this case, the local id for the object will not be valid, since the viewer has not received
+ // a full update for the object from that sim yet, so we assume that the agent is still sitting
+ // where she was originally. --RN
+ if (!sent_parentp)
+ {
+ sent_parentp = cur_parentp;
+ }
+ }
+ else if (!sent_parentp)
+ {
+ //
+ // Switching parents, but we don't know the new parent.
+ //
+ U32 ip, port;
+
+ if(mesgsys != NULL)
+ {
+ ip = mesgsys->getSenderIP();
+ port = mesgsys->getSenderPort();
+ }
+ else
+ {
+ ip = mRegionp->getHost().getAddress();
+ port = mRegionp->getHost().getPort();
+ }
+
+ // We're an orphan, flag things appropriately.
+ gObjectList.orphanize(this, parent_id, ip, port);
+ }
+ }
+
+ // Reattach if possible.
+ if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
+ {
+ // New parent is valid, detach and reattach
+ b_changed_status = TRUE;
+ if (mDrawable.notNull())
+ {
+ if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2
+ {
+ // Bad, we got a cycle somehow.
+ // Kill both the parent and the child, and
+ // set cache misses for both of them.
+ LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL;
+ LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL;
+ LL_WARNS() << "Adding to cache miss list" << LL_ENDL;
+ setParent(NULL);
+ sent_parentp->setParent(NULL);
+ getRegion()->addCacheMissFull(getLocalID());
+ getRegion()->addCacheMissFull(sent_parentp->getLocalID());
+ gObjectList.killObject(sent_parentp);
+ gObjectList.killObject(this);
+ return retval;
+ }
+ // make sure this object gets a non-damped update
+ }
+ cur_parentp->removeChild(this);
+ sent_parentp->addChild(this);
+ setChanged(MOVED | SILHOUETTE);
+ sent_parentp->setChanged(MOVED | SILHOUETTE);
+ if (sent_parentp->mDrawable.notNull())
+ {
+ gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
+ }
+ }
+ else if (!sent_parentp)
+ {
+ bool remove_parent = true;
+ // No new parent, or the parent that we sent doesn't exist on the viewer.
+ LLViewerObject *parentp = (LLViewerObject *)getParent();
+ if (parentp)
+ {
+ if (parentp->getRegion() != getRegion())
+ {
+ // This is probably an object flying across a region boundary, the
+ // object probably ISN'T being reparented, but just got an object
+ // update out of order (child update before parent).
+ //LL_INFOS() << "Don't reparent object handoffs!" << LL_ENDL;
+ remove_parent = false;
+ }
+ }
+
+ if (remove_parent)
+ {
+ b_changed_status = TRUE;
+ if (mDrawable.notNull())
+ {
+ // clear parent to removeChild can put the drawable on the damped list
+ setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3
+ }
+
+ cur_parentp->removeChild(this);
+
+ setChanged(MOVED | SILHOUETTE);
+
+ if (mDrawable.notNull())
+ {
+ // make sure this object gets a non-damped update
+ gPipeline.markMoved(mDrawable, FALSE); // undamped
+ }
+ }
+ }
+ }
+ }
+ }
+
+ new_rot.normQuat();
+
+ if (sPingInterpolate && mesgsys != NULL)
+ {
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
+ if (cdp)
+ {
+ // Note: delay is U32 and usually less then second,
+ // converting it into seconds with valueInUnits will result in 0
+ F32 ping_delay = 0.5f * time_dilation * ( ((F32)cdp->getPingDelay().value()) * 0.001f + gFrameDTClamped);
+ LLVector3 diff = getVelocity() * ping_delay;
+ new_pos_parent += diff;
+ }
+ else
+ {
+ LL_WARNS() << "findCircuit() returned NULL; skipping interpolation" << LL_ENDL;
+ }
+ }
+
+ //////////////////////////
+ //
+ // Set the generic change flags...
+ //
+ //
+
+ // If we're going to skip this message, why are we
+ // doing all the parenting, etc above?
+ if(mesgsys != NULL)
+ {
+ U32 packet_id = mesgsys->getCurrentRecvPacketID();
+ if (packet_id < mLatestRecvPacketID &&
+ mLatestRecvPacketID - packet_id < 65536)
+ {
+ //skip application of this message, it's old
+ return retval;
+ }
+ mLatestRecvPacketID = packet_id;
+ }
+
+ // Set the change flags for scale
+ if (new_scale != getScale())
+ {
+ setChanged(SCALED | SILHOUETTE);
+ setScale(new_scale); // Must follow setting permYouOwner()
+ }
+
+ // first, let's see if the new position is actually a change
+
+ //static S32 counter = 0;
+
+ F32 vel_mag_sq = getVelocity().magVecSquared();
+ F32 accel_mag_sq = getAcceleration().magVecSquared();
+
+ if ( ((b_changed_status)||(test_pos_parent != new_pos_parent))
+ ||( (!isSelected())
+ &&( (vel_mag_sq != 0.f)
+ ||(accel_mag_sq != 0.f)
+ ||(this_update_precision > mBestUpdatePrecision))))
+ {
+ mBestUpdatePrecision = this_update_precision;
+
+ LLVector3 diff = new_pos_parent - test_pos_parent ;
+ F32 mag_sqr = diff.magVecSquared() ;
+ if(llfinite(mag_sqr))
+ {
+ setPositionParent(new_pos_parent);
+ }
+ else
+ {
+ LL_WARNS() << "Can not move the object/avatar to an infinite location!" << LL_ENDL ;
+
+ retval |= INVALID_UPDATE ;
+ }
+
+ if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+ {
+ // we have changed the position of an attachment, so we need to clamp it
+ LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+ avatar->clampAttachmentPositions();
+ }
+
+ // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
+ if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
+ {
+ record(LLStatViewer::AGENT_POSITION_SNAP, LLUnit<F64, LLUnits::Meters>(diff.length()));
+ }
+ }
+
+ if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO))
+ || (new_angv != old_angv))
+ {
+ if (new_rot != mPreviousRotation)
+ {
+ resetRot();
+ }
+ else if (new_angv != old_angv)
+ {
+ if (flagUsePhysics())
+ {
+ resetRot();
+ }
+ else
+ {
+ resetRotTime();
+ }
+ }
+
+ // Remember the last rotation value
+ mPreviousRotation = new_rot;
+
+ // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega)
+ setRotation(new_rot * mAngularVelocityRot);
+ setChanged(ROTATED | SILHOUETTE);
+ }
+
+ if ( gShowObjectUpdates )
+ {
+ LLColor4 color;
+ if (update_type == OUT_TERSE_IMPROVED)
+ {
+ color.setVec(0.f, 0.f, 1.f, 1.f);
+ }
+ else
+ {
+ color.setVec(1.f, 0.f, 0.f, 1.f);
+ }
+ gPipeline.addDebugBlip(getPositionAgent(), color);
+ LL_DEBUGS("MessageBlip") << "Update type " << (S32)update_type << " blip for local " << mLocalID << " at " << getPositionAgent() << LL_ENDL;
+ }
+
+ const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO;
+
+ llassert(vel_mag_sq >= 0.f);
+ llassert(accel_mag_sq >= 0.f);
+ llassert(getAngularVelocity().magVecSquared() >= 0.f);
+
+ if ((MAG_CUTOFF >= vel_mag_sq) &&
+ (MAG_CUTOFF >= accel_mag_sq) &&
+ (MAG_CUTOFF >= getAngularVelocity().magVecSquared()))
+ {
+ mStatic = TRUE; // This object doesn't move!
+ }
+ else
+ {
+ mStatic = FALSE;
+ }
// BUG: This code leads to problems during group rotate and any scale operation.
-// Small discepencies between the simulator and viewer representations cause the
+// Small discepencies between the simulator and viewer representations cause the
// selection center to creep, leading to objects moving around the wrong center.
-//
+//
// Removing this, however, means that if someone else drags an object you have
// selected, your selection center and dialog boxes will be wrong. It also means
// that higher precision information on selected objects will be ignored.
//
// I believe the group rotation problem is fixed. JNC 1.21.2002
//
- // Additionally, if any child is selected, need to update the dialogs and selection
- // center.
- BOOL needs_refresh = mUserSelected;
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- needs_refresh = needs_refresh || child->mUserSelected;
- }
+ // Additionally, if any child is selected, need to update the dialogs and selection
+ // center.
+ BOOL needs_refresh = mUserSelected;
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ needs_refresh = needs_refresh || child->mUserSelected;
+ }
static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);
- if (needs_refresh)
- {
- LLSelectMgr::getInstance()->updateSelectionCenter();
- dialog_refresh_all();
- }
+ if (needs_refresh)
+ {
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ dialog_refresh_all();
+ }
else if (allow_select_avatar && asAvatar())
{
// Override any avatar position updates received
@@ -2498,280 +2500,280 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
- // Mark update time as approx. now, with the ping delay.
- // Ping delay is off because it's not set for velocity interpolation, causing
- // much jumping and hopping around...
+ // Mark update time as approx. now, with the ping delay.
+ // Ping delay is off because it's not set for velocity interpolation, causing
+ // much jumping and hopping around...
-// U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
- mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
- mLastMessageUpdateSecs = mLastInterpUpdateSecs;
- if (mDrawable.notNull())
- {
- // Don't clear invisibility flag on update if still orphaned!
- if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
- {
-// LL_DEBUGS() << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << LL_ENDL;
- mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
- gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL);
- }
- }
+// U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
+ mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
+ mLastMessageUpdateSecs = mLastInterpUpdateSecs;
+ if (mDrawable.notNull())
+ {
+ // Don't clear invisibility flag on update if still orphaned!
+ if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
+ {
+// LL_DEBUGS() << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << LL_ENDL;
+ mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
+ gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL);
+ }
+ }
- // Update special hover cursor status
- bool special_hover_cursor = specialHoverCursor();
- if (old_special_hover_cursor != special_hover_cursor
- && mDrawable.notNull())
- {
- mDrawable->updateSpecialHoverCursor(special_hover_cursor);
- }
+ // Update special hover cursor status
+ bool special_hover_cursor = specialHoverCursor();
+ if (old_special_hover_cursor != special_hover_cursor
+ && mDrawable.notNull())
+ {
+ mDrawable->updateSpecialHoverCursor(special_hover_cursor);
+ }
- return retval;
+ return retval;
}
BOOL LLViewerObject::isActive() const
{
- return TRUE;
+ return TRUE;
}
//load flags from cache or from message
void LLViewerObject::loadFlags(U32 flags)
{
- if(flags == (U32)(-1))
- {
- return; //invalid
- }
+ if(flags == (U32)(-1))
+ {
+ return; //invalid
+ }
- // keep local flags and overwrite remote-controlled flags
- mFlags = (mFlags & FLAGS_LOCAL) | flags;
+ // keep local flags and overwrite remote-controlled flags
+ mFlags = (mFlags & FLAGS_LOCAL) | flags;
- // ...new objects that should come in selected need to be added to the selected list
- mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
- return;
+ // ...new objects that should come in selected need to be added to the selected list
+ mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+ return;
}
void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time)
{
- if (!mDead)
- {
- if (!mStatic && sVelocityInterpolate && !isSelected())
- {
- // calculate dt from last update
- F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
- F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value();
- F32 dt = time_dilation * dt_raw;
+ if (!mDead)
+ {
+ if (!mStatic && sVelocityInterpolate && !isSelected())
+ {
+ // calculate dt from last update
+ F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
+ F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value();
+ F32 dt = time_dilation * dt_raw;
- applyAngularVelocity(dt);
+ applyAngularVelocity(dt);
- if (isAttachment())
- {
- mLastInterpUpdateSecs = (F64Seconds)frame_time;
- return;
- }
- else
- { // Move object based on it's velocity and rotation
- interpolateLinearMotion(frame_time, dt);
- }
- }
+ if (isAttachment())
+ {
+ mLastInterpUpdateSecs = (F64Seconds)frame_time;
+ return;
+ }
+ else
+ { // Move object based on it's velocity and rotation
+ interpolateLinearMotion(frame_time, dt);
+ }
+ }
- updateDrawable(FALSE);
- }
+ updateDrawable(FALSE);
+ }
}
// Move an object due to idle-time viewer side updates by interpolating motion
void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds)
{
- // linear motion
- // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
- // updates represents the average velocity of the last timestep, rather than the final velocity.
- // the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
- //
- // *TODO: should also wrap linear accel/velocity in check
- // to see if object is selected, instead of explicitly
- // zeroing it out
-
- F32 dt = dt_seconds;
- F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs;
- if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f)
- {
- return;
- }
-
- LLVector3 accel = getAcceleration();
- LLVector3 vel = getVelocity();
-
- if (sMaxUpdateInterpolationTime <= (F64Seconds)0.0)
- { // Old code path ... unbounded, simple interpolation
- if (!(accel.isExactlyZero() && vel.isExactlyZero()))
- {
- LLVector3 pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;
-
- // region local
- setPositionRegion(pos + getPositionRegion());
- setVelocity(vel + accel*dt);
-
- // for objects that are spinning but not translating, make sure to flag them as having moved
- setChanged(MOVED | SILHOUETTE);
- }
- }
- else if (!accel.isExactlyZero() || !vel.isExactlyZero()) // object is moving
- { // Object is moving, and hasn't been too long since we got an update from the server
-
- // Calculate predicted position and velocity
- LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;
- LLVector3 new_v = accel * dt;
-
- if (time_since_last_update > sPhaseOutUpdateInterpolationTime &&
- sPhaseOutUpdateInterpolationTime > (F64Seconds)0.0)
- { // Haven't seen a viewer update in a while, check to see if the circuit is still active
- if (mRegionp)
- { // The simulator will NOT send updates if the object continues normally on the path
- // predicted by the velocity and the acceleration (often gravity) sent to the viewer
- // So check to see if the circuit is blocked, which means the sim is likely in a long lag
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );
- if (cdp)
- {
- // Find out how many seconds since last packet arrived on the circuit
- F64Seconds time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime();
-
- if (!cdp->isAlive() || // Circuit is dead or blocked
- cdp->isBlocked() || // or doesn't seem to be getting any packets
- (time_since_last_packet > sPhaseOutUpdateInterpolationTime))
- {
- // Start to reduce motion interpolation since we haven't seen a server update in a while
- F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs;
- F64 phase_out = 1.0;
- if (time_since_last_update > sMaxUpdateInterpolationTime)
- { // Past the time limit, so stop the object
- phase_out = 0.0;
- //LL_INFOS() << "Motion phase out to zero" << LL_ENDL;
-
- // Kill angular motion as well. Note - not adding this due to paranoia
- // about stopping rotation for llTargetOmega objects and not having it restart
- // setAngularVelocity(LLVector3::zero);
- }
- else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime)
- { // Last update was already phased out a bit
- phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /
- (sMaxUpdateInterpolationTime - time_since_last_interpolation);
- //LL_INFOS() << "Continuing motion phase out of " << (F32) phase_out << LL_ENDL;
- }
- else
- { // Phase out from full value
- phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /
- (sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime);
- //LL_INFOS() << "Starting motion phase out of " << (F32) phase_out << LL_ENDL;
- }
- phase_out = llclamp(phase_out, 0.0, 1.0);
-
- new_pos = new_pos * ((F32) phase_out);
- new_v = new_v * ((F32) phase_out);
- }
- }
- }
- }
-
- new_pos = new_pos + getPositionRegion();
- new_v = new_v + vel;
-
-
- // Clamp interpolated position to minimum underground and maximum region height
- LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);
- F32 min_height;
- if (isAvatar())
- { // Make a better guess about AVs not going underground
- min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global);
- min_height += (0.5f * getScale().mV[VZ]);
- }
- else
- { // This will put the object underground, but we can't tell if it will stop
- // at ground level or not
- min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
- // Cap maximum height
- new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
- }
-
- new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
-
- // Check to see if it's going off the region
- LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f);
- if (temp.clamp(0.f, mRegionp->getWidth()))
- { // Going off this region, so see if we might end up on another region
- LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
- new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); // Re-fetch in case it got clipped above
-
- // Clip the positions to known regions
- LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
- if (clip_pos_global != new_pos_global)
- {
- // Was clipped, so this means we hit a edge where there is no region to enter
- LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
- LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to "
- << clip_pos
- << " from " << new_pos << LL_ENDL;
- new_pos = clip_pos;
-
- // Stop motion and get server update for bouncing on the edge
- new_v.clear();
- setAcceleration(LLVector3::zero);
- }
- else
- {
- // Check for how long we are crossing.
- // Note: theoretically we can find time from velocity, acceleration and
- // distance from border to new position, but it is not going to work
- // if 'phase_out' activates
- if (mRegionCrossExpire == 0)
- {
- // Workaround: we can't accurately figure out time when we cross border
- // so just write down time 'after the fact', it is far from optimal in
- // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
- LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
- mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime;
- }
- else if (frame_time > mRegionCrossExpire)
- {
- // Predicting crossing over 1s, stop motion
- // Stop motion
- LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
- new_v.clear();
- setAcceleration(LLVector3::zero);
- mRegionCrossExpire = 0;
- }
- }
- }
- else
- {
- mRegionCrossExpire = 0;
- }
-
- // Set new position and velocity
- setPositionRegion(new_pos);
- setVelocity(new_v);
-
- // for objects that are spinning but not translating, make sure to flag them as having moved
- setChanged(MOVED | SILHOUETTE);
- }
-
- // Update the last time we did anything
- mLastInterpUpdateSecs = frame_time;
+ // linear motion
+ // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
+ // updates represents the average velocity of the last timestep, rather than the final velocity.
+ // the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
+ //
+ // *TODO: should also wrap linear accel/velocity in check
+ // to see if object is selected, instead of explicitly
+ // zeroing it out
+
+ F32 dt = dt_seconds;
+ F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs;
+ if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f)
+ {
+ return;
+ }
+
+ LLVector3 accel = getAcceleration();
+ LLVector3 vel = getVelocity();
+
+ if (sMaxUpdateInterpolationTime <= (F64Seconds)0.0)
+ { // Old code path ... unbounded, simple interpolation
+ if (!(accel.isExactlyZero() && vel.isExactlyZero()))
+ {
+ LLVector3 pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;
+
+ // region local
+ setPositionRegion(pos + getPositionRegion());
+ setVelocity(vel + accel*dt);
+
+ // for objects that are spinning but not translating, make sure to flag them as having moved
+ setChanged(MOVED | SILHOUETTE);
+ }
+ }
+ else if (!accel.isExactlyZero() || !vel.isExactlyZero()) // object is moving
+ { // Object is moving, and hasn't been too long since we got an update from the server
+
+ // Calculate predicted position and velocity
+ LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;
+ LLVector3 new_v = accel * dt;
+
+ if (time_since_last_update > sPhaseOutUpdateInterpolationTime &&
+ sPhaseOutUpdateInterpolationTime > (F64Seconds)0.0)
+ { // Haven't seen a viewer update in a while, check to see if the circuit is still active
+ if (mRegionp)
+ { // The simulator will NOT send updates if the object continues normally on the path
+ // predicted by the velocity and the acceleration (often gravity) sent to the viewer
+ // So check to see if the circuit is blocked, which means the sim is likely in a long lag
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );
+ if (cdp)
+ {
+ // Find out how many seconds since last packet arrived on the circuit
+ F64Seconds time_since_last_packet = LLMessageSystem::getMessageTimeSeconds() - cdp->getLastPacketInTime();
+
+ if (!cdp->isAlive() || // Circuit is dead or blocked
+ cdp->isBlocked() || // or doesn't seem to be getting any packets
+ (time_since_last_packet > sPhaseOutUpdateInterpolationTime))
+ {
+ // Start to reduce motion interpolation since we haven't seen a server update in a while
+ F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs;
+ F64 phase_out = 1.0;
+ if (time_since_last_update > sMaxUpdateInterpolationTime)
+ { // Past the time limit, so stop the object
+ phase_out = 0.0;
+ //LL_INFOS() << "Motion phase out to zero" << LL_ENDL;
+
+ // Kill angular motion as well. Note - not adding this due to paranoia
+ // about stopping rotation for llTargetOmega objects and not having it restart
+ // setAngularVelocity(LLVector3::zero);
+ }
+ else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime)
+ { // Last update was already phased out a bit
+ phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /
+ (sMaxUpdateInterpolationTime - time_since_last_interpolation);
+ //LL_INFOS() << "Continuing motion phase out of " << (F32) phase_out << LL_ENDL;
+ }
+ else
+ { // Phase out from full value
+ phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) /
+ (sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime);
+ //LL_INFOS() << "Starting motion phase out of " << (F32) phase_out << LL_ENDL;
+ }
+ phase_out = llclamp(phase_out, 0.0, 1.0);
+
+ new_pos = new_pos * ((F32) phase_out);
+ new_v = new_v * ((F32) phase_out);
+ }
+ }
+ }
+ }
+
+ new_pos = new_pos + getPositionRegion();
+ new_v = new_v + vel;
+
+
+ // Clamp interpolated position to minimum underground and maximum region height
+ LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);
+ F32 min_height;
+ if (isAvatar())
+ { // Make a better guess about AVs not going underground
+ min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global);
+ min_height += (0.5f * getScale().mV[VZ]);
+ }
+ else
+ { // This will put the object underground, but we can't tell if it will stop
+ // at ground level or not
+ min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
+ // Cap maximum height
+ new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
+ }
+
+ new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
+
+ // Check to see if it's going off the region
+ LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f);
+ if (temp.clamp(0.f, mRegionp->getWidth()))
+ { // Going off this region, so see if we might end up on another region
+ LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+ new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); // Re-fetch in case it got clipped above
+
+ // Clip the positions to known regions
+ LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
+ if (clip_pos_global != new_pos_global)
+ {
+ // Was clipped, so this means we hit a edge where there is no region to enter
+ LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+ LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to "
+ << clip_pos
+ << " from " << new_pos << LL_ENDL;
+ new_pos = clip_pos;
+
+ // Stop motion and get server update for bouncing on the edge
+ new_v.clear();
+ setAcceleration(LLVector3::zero);
+ }
+ else
+ {
+ // Check for how long we are crossing.
+ // Note: theoretically we can find time from velocity, acceleration and
+ // distance from border to new position, but it is not going to work
+ // if 'phase_out' activates
+ if (mRegionCrossExpire == 0)
+ {
+ // Workaround: we can't accurately figure out time when we cross border
+ // so just write down time 'after the fact', it is far from optimal in
+ // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
+ LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
+ mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime;
+ }
+ else if (frame_time > mRegionCrossExpire)
+ {
+ // Predicting crossing over 1s, stop motion
+ // Stop motion
+ LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
+ new_v.clear();
+ setAcceleration(LLVector3::zero);
+ mRegionCrossExpire = 0;
+ }
+ }
+ }
+ else
+ {
+ mRegionCrossExpire = 0;
+ }
+
+ // Set new position and velocity
+ setPositionRegion(new_pos);
+ setVelocity(new_v);
+
+ // for objects that are spinning but not translating, make sure to flag them as having moved
+ setChanged(MOVED | SILHOUETTE);
+ }
+
+ // Update the last time we did anything
+ mLastInterpUpdateSecs = frame_time;
}
BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
{
- delete [] mData;
+ delete [] mData;
- if (datap)
- {
- mData = new U8[data_size];
- if (!mData)
- {
- return FALSE;
- }
- memcpy(mData, datap, data_size); /* Flawfinder: ignore */
- }
- return TRUE;
+ if (datap)
+ {
+ mData = new U8[data_size];
+ if (!mData)
+ {
+ return FALSE;
+ }
+ memcpy(mData, datap, data_size); /* Flawfinder: ignore */
+ }
+ return TRUE;
}
// delete an item in the inventory, but don't tell the server. This is
@@ -2779,213 +2781,213 @@ BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
// This will only delete the first item with an item_id in the list
void LLViewerObject::deleteInventoryItem(const LLUUID& item_id)
{
- if(mInventory)
- {
- LLInventoryObject::object_list_t::iterator it = mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = mInventory->end();
- for( ; it != end; ++it )
- {
- if((*it)->getUUID() == item_id)
- {
- // This is safe only because we return immediatly.
- mInventory->erase(it); // will deref and delete it
- return;
- }
- }
- doInventoryCallback();
- }
+ if(mInventory)
+ {
+ LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = mInventory->end();
+ for( ; it != end; ++it )
+ {
+ if((*it)->getUUID() == item_id)
+ {
+ // This is safe only because we return immediatly.
+ mInventory->erase(it); // will deref and delete it
+ return;
+ }
+ }
+ doInventoryCallback();
+ }
}
void LLViewerObject::doUpdateInventory(
- LLPointer<LLViewerInventoryItem>& item,
- U8 key,
- bool is_new)
-{
- LLViewerInventoryItem* old_item = NULL;
- if(TASK_INVENTORY_ITEM_KEY == key)
- {
- old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID());
- }
- else if(TASK_INVENTORY_ASSET_KEY == key)
- {
- old_item = getInventoryItemByAsset(item->getAssetUUID());
- }
- LLUUID item_id;
- LLUUID new_owner;
- LLUUID new_group;
- BOOL group_owned = FALSE;
- if(old_item)
- {
- item_id = old_item->getUUID();
- new_owner = old_item->getPermissions().getOwner();
- new_group = old_item->getPermissions().getGroup();
- group_owned = old_item->getPermissions().isGroupOwned();
- old_item = NULL;
- }
- else
- {
- item_id = item->getUUID();
- }
- if(!is_new && mInventory)
- {
- // Attempt to update the local inventory. If we can get the
- // object perm, we have perfect visibility, so we want the
- // serial number to match. Otherwise, take our best guess and
- // make sure that the serial number does not match.
- deleteInventoryItem(item_id);
- LLPermissions perm(item->getPermissions());
- LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
- bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true;
- if(obj_perm)
- {
- perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic);
- }
- else
- {
- if(group_owned)
- {
- perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
- }
- else if(!new_owner.isNull())
- {
- // The object used to be in inventory, so we can
- // assume the owner and group will match what they are
- // there.
- perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
- }
- // *FIX: can make an even better guess by using the mPermGroup flags
- else if(permYouOwner())
- {
- // best guess.
- perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
- --mExpectedInventorySerialNum;
- }
- else
- {
- // dummy it up.
- perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
- --mExpectedInventorySerialNum;
- }
- }
- LLViewerInventoryItem* oldItem = item;
- LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem);
- new_item->setPermissions(perm);
- mInventory->push_front(new_item);
- doInventoryCallback();
- ++mExpectedInventorySerialNum;
- }
- else if (is_new)
- {
- ++mExpectedInventorySerialNum;
- }
+ LLPointer<LLViewerInventoryItem>& item,
+ U8 key,
+ bool is_new)
+{
+ LLViewerInventoryItem* old_item = NULL;
+ if(TASK_INVENTORY_ITEM_KEY == key)
+ {
+ old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID());
+ }
+ else if(TASK_INVENTORY_ASSET_KEY == key)
+ {
+ old_item = getInventoryItemByAsset(item->getAssetUUID());
+ }
+ LLUUID item_id;
+ LLUUID new_owner;
+ LLUUID new_group;
+ BOOL group_owned = FALSE;
+ if(old_item)
+ {
+ item_id = old_item->getUUID();
+ new_owner = old_item->getPermissions().getOwner();
+ new_group = old_item->getPermissions().getGroup();
+ group_owned = old_item->getPermissions().isGroupOwned();
+ old_item = NULL;
+ }
+ else
+ {
+ item_id = item->getUUID();
+ }
+ if(!is_new && mInventory)
+ {
+ // Attempt to update the local inventory. If we can get the
+ // object perm, we have perfect visibility, so we want the
+ // serial number to match. Otherwise, take our best guess and
+ // make sure that the serial number does not match.
+ deleteInventoryItem(item_id);
+ LLPermissions perm(item->getPermissions());
+ LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
+ bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true;
+ if(obj_perm)
+ {
+ perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic);
+ }
+ else
+ {
+ if(group_owned)
+ {
+ perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
+ }
+ else if(!new_owner.isNull())
+ {
+ // The object used to be in inventory, so we can
+ // assume the owner and group will match what they are
+ // there.
+ perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
+ }
+ // *FIX: can make an even better guess by using the mPermGroup flags
+ else if(permYouOwner())
+ {
+ // best guess.
+ perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
+ --mExpectedInventorySerialNum;
+ }
+ else
+ {
+ // dummy it up.
+ perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
+ --mExpectedInventorySerialNum;
+ }
+ }
+ LLViewerInventoryItem* oldItem = item;
+ LLViewerInventoryItem* new_item = new LLViewerInventoryItem(oldItem);
+ new_item->setPermissions(perm);
+ mInventory->push_front(new_item);
+ doInventoryCallback();
+ ++mExpectedInventorySerialNum;
+ }
+ else if (is_new)
+ {
+ ++mExpectedInventorySerialNum;
+ }
}
// save a script, which involves removing the old one, and rezzing
// in the new one. This method should be called with the asset id
// of the new and old script AFTER the bytecode has been saved.
void LLViewerObject::saveScript(
- const LLViewerInventoryItem* item,
- BOOL active,
- bool is_new)
-{
- /*
- * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the
- * interaction with doUpdateInventory() called below.
- */
- LL_DEBUGS() << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << LL_ENDL;
-
- LLPointer<LLViewerInventoryItem> task_item =
- new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
- item->getAssetUUID(), item->getType(),
- item->getInventoryType(),
- item->getName(), item->getDescription(),
- item->getSaleInfo(), item->getFlags(),
- item->getCreationDate());
- task_item->setTransactionID(item->getTransactionID());
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RezScript);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- msg->nextBlockFast(_PREHASH_UpdateBlock);
- msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID));
- U8 enabled = active;
- msg->addBOOLFast(_PREHASH_Enabled, enabled);
- msg->nextBlockFast(_PREHASH_InventoryBlock);
- task_item->packMessage(msg);
- msg->sendReliable(mRegionp->getHost());
-
- // do the internal logic
- doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new);
+ const LLViewerInventoryItem* item,
+ BOOL active,
+ bool is_new)
+{
+ /*
+ * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the
+ * interaction with doUpdateInventory() called below.
+ */
+ LL_DEBUGS() << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << LL_ENDL;
+
+ LLPointer<LLViewerInventoryItem> task_item =
+ new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+ item->getAssetUUID(), item->getType(),
+ item->getInventoryType(),
+ item->getName(), item->getDescription(),
+ item->getSaleInfo(), item->getFlags(),
+ item->getCreationDate());
+ task_item->setTransactionID(item->getTransactionID());
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RezScript);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+ msg->nextBlockFast(_PREHASH_UpdateBlock);
+ msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID));
+ U8 enabled = active;
+ msg->addBOOLFast(_PREHASH_Enabled, enabled);
+ msg->nextBlockFast(_PREHASH_InventoryBlock);
+ task_item->packMessage(msg);
+ msg->sendReliable(mRegionp->getHost());
+
+ // do the internal logic
+ doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new);
}
void LLViewerObject::moveInventory(const LLUUID& folder_id,
- const LLUUID& item_id)
-{
- LL_DEBUGS() << "LLViewerObject::moveInventory " << item_id << LL_ENDL;
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_MoveTaskInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_FolderID, folder_id);
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addU32Fast(_PREHASH_LocalID, mLocalID);
- msg->addUUIDFast(_PREHASH_ItemID, item_id);
- msg->sendReliable(mRegionp->getHost());
-
- LLInventoryObject* inv_obj = getInventoryObject(item_id);
- if(inv_obj)
- {
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj;
- if(!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- deleteInventoryItem(item_id);
- ++mExpectedInventorySerialNum;
- }
- }
+ const LLUUID& item_id)
+{
+ LL_DEBUGS() << "LLViewerObject::moveInventory " << item_id << LL_ENDL;
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoveTaskInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_FolderID, folder_id);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+ msg->addUUIDFast(_PREHASH_ItemID, item_id);
+ msg->sendReliable(mRegionp->getHost());
+
+ LLInventoryObject* inv_obj = getInventoryObject(item_id);
+ if(inv_obj)
+ {
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj;
+ if(!item->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ deleteInventoryItem(item_id);
+ ++mExpectedInventorySerialNum;
+ }
+ }
}
void LLViewerObject::dirtyInventory()
{
- // If there aren't any LLVOInventoryListeners, we won't be
- // able to update our mInventory when it comes back from the
- // simulator, so we should not clear the inventory either.
- if(mInventory && !mInventoryCallbacks.empty())
- {
- mInventory->clear(); // will deref and delete entries
- delete mInventory;
- mInventory = NULL;
- }
- mInventoryDirty = TRUE;
+ // If there aren't any LLVOInventoryListeners, we won't be
+ // able to update our mInventory when it comes back from the
+ // simulator, so we should not clear the inventory either.
+ if(mInventory && !mInventoryCallbacks.empty())
+ {
+ mInventory->clear(); // will deref and delete entries
+ delete mInventory;
+ mInventory = NULL;
+ }
+ mInventoryDirty = TRUE;
}
void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data)
{
- LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
- info->mListener = listener;
- info->mInventoryData = user_data;
- mInventoryCallbacks.push_front(info);
+ LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
+ info->mListener = listener;
+ info->mInventoryData = user_data;
+ mInventoryCallbacks.push_front(info);
}
void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
{
- if (listener == NULL)
- return;
- for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
- iter != mInventoryCallbacks.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLInventoryCallbackInfo* info = *curiter;
- if (info->mListener == listener)
- {
- delete info;
- mInventoryCallbacks.erase(curiter);
- break;
- }
- }
+ if (listener == NULL)
+ return;
+ for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
+ iter != mInventoryCallbacks.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLInventoryCallbackInfo* info = *curiter;
+ if (info->mListener == listener)
+ {
+ delete info;
+ mInventoryCallbacks.erase(curiter);
+ break;
+ }
+ }
}
BOOL LLViewerObject::isInventoryPending()
@@ -2995,60 +2997,60 @@ BOOL LLViewerObject::isInventoryPending()
void LLViewerObject::clearInventoryListeners()
{
- for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
- mInventoryCallbacks.clear();
+ for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
+ mInventoryCallbacks.clear();
}
bool LLViewerObject::hasInventoryListeners()
{
- return !mInventoryCallbacks.empty();
+ return !mInventoryCallbacks.empty();
}
void LLViewerObject::requestInventory()
{
- if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty())
- {
- mInventory->clear(); // will deref and delete entries
- delete mInventory;
- mInventory = NULL;
- }
-
- if(mInventory)
- {
- // inventory is either up to date or doesn't has a listener
- // if it is dirty, leave it this way in case we gain a listener
- doInventoryCallback();
- }
- else
- {
- // since we are going to request it now
- mInventoryDirty = FALSE;
-
- // Note: throws away duplicate requests
- fetchInventoryFromServer();
- }
+ if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty())
+ {
+ mInventory->clear(); // will deref and delete entries
+ delete mInventory;
+ mInventory = NULL;
+ }
+
+ if(mInventory)
+ {
+ // inventory is either up to date or doesn't has a listener
+ // if it is dirty, leave it this way in case we gain a listener
+ doInventoryCallback();
+ }
+ else
+ {
+ // since we are going to request it now
+ mInventoryDirty = FALSE;
+
+ // Note: throws away duplicate requests
+ fetchInventoryFromServer();
+ }
}
void LLViewerObject::fetchInventoryFromServer()
{
- if (!isInventoryPending())
- {
- delete mInventory;
- mInventory = NULL;
-
- // Results in processTaskInv
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RequestTaskInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addU32Fast(_PREHASH_LocalID, mLocalID);
- msg->sendReliable(mRegionp->getHost());
-
- // This will get reset by doInventoryCallback or processTaskInv
- mInvRequestState = INVENTORY_REQUEST_PENDING;
- }
+ if (!isInventoryPending())
+ {
+ delete mInventory;
+ mInventory = NULL;
+
+ // Results in processTaskInv
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RequestTaskInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+ msg->sendReliable(mRegionp->getHost());
+
+ // This will get reset by doInventoryCallback or processTaskInv
+ mInvRequestState = INVENTORY_REQUEST_PENDING;
+ }
}
void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
@@ -3164,8 +3166,8 @@ void LLViewerObject::linkControlAvatar()
return;
}
mControlAvatar = LLControlAvatar::createControlAvatar(volp);
- LL_DEBUGS("AnimatedObjects") << volp->getID()
- << " created control av for "
+ LL_DEBUGS("AnimatedObjects") << volp->getID()
+ << " created control av for "
<< (S32) (1+volp->numChildren()) << " prims" << LL_ENDL;
}
LLControlAvatar *cav = getControlAvatar();
@@ -3215,26 +3217,26 @@ bool LLViewerObject::isAnimatedObject() const
struct LLFilenameAndTask
{
- LLUUID mTaskID;
- std::string mFilename;
+ LLUUID mTaskID;
+ std::string mFilename;
- // for sequencing in case of multiple updates
- S16 mSerial;
+ // for sequencing in case of multiple updates
+ S16 mSerial;
#ifdef _DEBUG
- static S32 sCount;
- LLFilenameAndTask()
- {
- ++sCount;
- LL_DEBUGS() << "Constructing LLFilenameAndTask: " << sCount << LL_ENDL;
- }
- ~LLFilenameAndTask()
- {
- --sCount;
- LL_DEBUGS() << "Destroying LLFilenameAndTask: " << sCount << LL_ENDL;
- }
+ static S32 sCount;
+ LLFilenameAndTask()
+ {
+ ++sCount;
+ LL_DEBUGS() << "Constructing LLFilenameAndTask: " << sCount << LL_ENDL;
+ }
+ ~LLFilenameAndTask()
+ {
+ --sCount;
+ LL_DEBUGS() << "Destroying LLFilenameAndTask: " << sCount << LL_ENDL;
+ }
private:
- LLFilenameAndTask(const LLFilenameAndTask& rhs);
- const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const;
+ LLFilenameAndTask(const LLFilenameAndTask& rhs);
+ const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const;
#endif
};
@@ -3287,7 +3289,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
LLFilenameAndTask* ft = new LLFilenameAndTask;
ft->mTaskID = task_id;
ft->mSerial = serial;
-
+
// We received version we expected or newer. Load it.
object->mInventorySerialNum = ft->mSerial;
object->mExpectedInventorySerialNum = ft->mSerial;
@@ -3343,154 +3345,154 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
{
- LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data;
- LLViewerObject* object = NULL;
-
- if (ft
- && (0 == error_code)
- && (object = gObjectList.findObject(ft->mTaskID))
- && ft->mSerial >= object->mInventorySerialNum)
- {
- object->mInventorySerialNum = ft->mSerial;
- LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL;
- if (ft->mSerial < object->mExpectedInventorySerialNum)
- {
- // User managed to change something while inventory was loading
- LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL;
- }
-
- if (object->loadTaskInvFile(ft->mFilename))
- {
-
- LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
- std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
-
- for (; it != end && pending_lst.size(); ++it)
- {
- LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
- if(item && item->getType() != LLAssetType::AT_CATEGORY)
- {
- std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
- if (id_it != pending_lst.end())
- {
- pending_lst.erase(id_it);
- }
- }
- }
- }
- else
- {
- // MAINT-2597 - crash when trying to edit a no-mod object
- // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
- // Stated repro was specific to no-mod objects so failing without user interaction should be safe.
- LL_WARNS() << "Trying to load invalid task inventory file. Ignoring file contents." << LL_ENDL;
- }
- }
- else
- {
- // This Occurs When two requests were made, and the first one
- // has already handled it.
- LL_DEBUGS() << "Problem loading task inventory. Return code: "
- << error_code << LL_ENDL;
- }
- delete ft;
+ LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data;
+ LLViewerObject* object = NULL;
+
+ if (ft
+ && (0 == error_code)
+ && (object = gObjectList.findObject(ft->mTaskID))
+ && ft->mSerial >= object->mInventorySerialNum)
+ {
+ object->mInventorySerialNum = ft->mSerial;
+ LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL;
+ if (ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // User managed to change something while inventory was loading
+ LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL;
+ }
+
+ if (object->loadTaskInvFile(ft->mFilename))
+ {
+
+ LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+ std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+
+ for (; it != end && pending_lst.size(); ++it)
+ {
+ LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+ if(item && item->getType() != LLAssetType::AT_CATEGORY)
+ {
+ std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+ if (id_it != pending_lst.end())
+ {
+ pending_lst.erase(id_it);
+ }
+ }
+ }
+ }
+ else
+ {
+ // MAINT-2597 - crash when trying to edit a no-mod object
+ // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
+ // Stated repro was specific to no-mod objects so failing without user interaction should be safe.
+ LL_WARNS() << "Trying to load invalid task inventory file. Ignoring file contents." << LL_ENDL;
+ }
+ }
+ else
+ {
+ // This Occurs When two requests were made, and the first one
+ // has already handled it.
+ LL_DEBUGS() << "Problem loading task inventory. Return code: "
+ << error_code << LL_ENDL;
+ }
+ delete ft;
}
BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
{
- std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
- llifstream ifs(filename_and_local_path.c_str());
- if(ifs.good())
- {
- U32 fail_count = 0;
- char buffer[MAX_STRING]; /* Flawfinder: ignore */
- // *NOTE: This buffer size is hard coded into scanf() below.
- char keyword[MAX_STRING]; /* Flawfinder: ignore */
- if(mInventory)
- {
- mInventory->clear(); // will deref and delete it
- }
- else
- {
- mInventory = new LLInventoryObject::object_list_t;
- }
- while(ifs.good())
- {
- ifs.getline(buffer, MAX_STRING);
- if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */
- {
- // Blank file?
- LL_WARNS() << "Issue reading from file '"
- << filename << "'" << LL_ENDL;
- break;
- }
- else if(0 == strcmp("inv_item", keyword))
- {
- LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
- inv->importLegacyStream(ifs);
- mInventory->push_front(inv);
- }
- else if(0 == strcmp("inv_object", keyword))
- {
- LLPointer<LLInventoryObject> inv = new LLInventoryObject;
- inv->importLegacyStream(ifs);
- inv->rename("Contents");
- mInventory->push_front(inv);
- }
- else if (fail_count >= MAX_INV_FILE_READ_FAILS)
- {
- LL_WARNS() << "Encountered too many unknowns while reading from file: '"
- << filename << "'" << LL_ENDL;
- break;
- }
- else
- {
- // Is there really a point to continue processing? We already failing to display full inventory
- fail_count++;
- LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '"
- << keyword << "'" << LL_ENDL;
- }
- }
- ifs.close();
- LLFile::remove(filename_and_local_path);
- }
- else
- {
- LL_WARNS() << "unable to load task inventory: " << filename_and_local_path
- << LL_ENDL;
- return FALSE;
- }
- doInventoryCallback();
-
- return TRUE;
+ std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
+ llifstream ifs(filename_and_local_path.c_str());
+ if(ifs.good())
+ {
+ U32 fail_count = 0;
+ char buffer[MAX_STRING]; /* Flawfinder: ignore */
+ // *NOTE: This buffer size is hard coded into scanf() below.
+ char keyword[MAX_STRING]; /* Flawfinder: ignore */
+ if(mInventory)
+ {
+ mInventory->clear(); // will deref and delete it
+ }
+ else
+ {
+ mInventory = new LLInventoryObject::object_list_t;
+ }
+ while(ifs.good())
+ {
+ ifs.getline(buffer, MAX_STRING);
+ if (sscanf(buffer, " %254s", keyword) == EOF) /* Flawfinder: ignore */
+ {
+ // Blank file?
+ LL_WARNS() << "Issue reading from file '"
+ << filename << "'" << LL_ENDL;
+ break;
+ }
+ else if(0 == strcmp("inv_item", keyword))
+ {
+ LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
+ inv->importLegacyStream(ifs);
+ mInventory->push_front(inv);
+ }
+ else if(0 == strcmp("inv_object", keyword))
+ {
+ LLPointer<LLInventoryObject> inv = new LLInventoryObject;
+ inv->importLegacyStream(ifs);
+ inv->rename("Contents");
+ mInventory->push_front(inv);
+ }
+ else if (fail_count >= MAX_INV_FILE_READ_FAILS)
+ {
+ LL_WARNS() << "Encountered too many unknowns while reading from file: '"
+ << filename << "'" << LL_ENDL;
+ break;
+ }
+ else
+ {
+ // Is there really a point to continue processing? We already failing to display full inventory
+ fail_count++;
+ LL_WARNS_ONCE() << "Unknown token while reading from inventory file. Token: '"
+ << keyword << "'" << LL_ENDL;
+ }
+ }
+ ifs.close();
+ LLFile::remove(filename_and_local_path);
+ }
+ else
+ {
+ LL_WARNS() << "unable to load task inventory: " << filename_and_local_path
+ << LL_ENDL;
+ return FALSE;
+ }
+ doInventoryCallback();
+
+ return TRUE;
}
void LLViewerObject::doInventoryCallback()
{
- for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
- iter != mInventoryCallbacks.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLInventoryCallbackInfo* info = *curiter;
- if (info->mListener != NULL)
- {
- info->mListener->inventoryChanged(this,
- mInventory,
- mInventorySerialNum,
- info->mInventoryData);
- }
- else
- {
- LL_INFOS() << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << LL_ENDL;
- delete info;
- mInventoryCallbacks.erase(curiter);
- }
- }
-
- // release inventory loading state
- mInvRequestXFerId = 0;
- mInvRequestState = INVENTORY_REQUEST_STOPPED;
+ for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
+ iter != mInventoryCallbacks.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLInventoryCallbackInfo* info = *curiter;
+ if (info->mListener != NULL)
+ {
+ info->mListener->inventoryChanged(this,
+ mInventory,
+ mInventorySerialNum,
+ info->mInventoryData);
+ }
+ else
+ {
+ LL_INFOS() << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << LL_ENDL;
+ delete info;
+ mInventoryCallbacks.erase(curiter);
+ }
+ }
+
+ // release inventory loading state
+ mInvRequestXFerId = 0;
+ mInvRequestState = INVENTORY_REQUEST_STOPPED;
}
void LLViewerObject::removeInventory(const LLUUID& item_id)
@@ -3501,17 +3503,17 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
params["object"] = mID;
LLFloaterReg::hideInstance("item_properties", params);
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RemoveTaskInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addU32Fast(_PREHASH_LocalID, mLocalID);
- msg->addUUIDFast(_PREHASH_ItemID, item_id);
- msg->sendReliable(mRegionp->getHost());
- deleteInventoryItem(item_id);
- ++mExpectedInventorySerialNum;
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RemoveTaskInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+ msg->addUUIDFast(_PREHASH_ItemID, item_id);
+ msg->sendReliable(mRegionp->getHost());
+ deleteInventoryItem(item_id);
+ ++mExpectedInventorySerialNum;
}
bool LLViewerObject::isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type)
@@ -3563,136 +3565,136 @@ void LLViewerObject::updateMaterialInventory(LLViewerInventoryItem* item, U8 key
}
void LLViewerObject::updateInventory(
- LLViewerInventoryItem* item,
- U8 key,
- bool is_new)
-{
- // This slices the object into what we're concerned about on the
- // viewer. The simulator will take the permissions and transfer
- // ownership.
- LLPointer<LLViewerInventoryItem> task_item =
- new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
- item->getAssetUUID(), item->getType(),
- item->getInventoryType(),
- item->getName(), item->getDescription(),
- item->getSaleInfo(),
- item->getFlags(),
- item->getCreationDate());
- task_item->setTransactionID(item->getTransactionID());
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_UpdateTaskInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_UpdateData);
- msg->addU32Fast(_PREHASH_LocalID, mLocalID);
- msg->addU8Fast(_PREHASH_Key, key);
- msg->nextBlockFast(_PREHASH_InventoryData);
- task_item->packMessage(msg);
- msg->sendReliable(mRegionp->getHost());
-
- // do the internal logic
- doUpdateInventory(task_item, key, is_new);
+ LLViewerInventoryItem* item,
+ U8 key,
+ bool is_new)
+{
+ // This slices the object into what we're concerned about on the
+ // viewer. The simulator will take the permissions and transfer
+ // ownership.
+ LLPointer<LLViewerInventoryItem> task_item =
+ new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+ item->getAssetUUID(), item->getType(),
+ item->getInventoryType(),
+ item->getName(), item->getDescription(),
+ item->getSaleInfo(),
+ item->getFlags(),
+ item->getCreationDate());
+ task_item->setTransactionID(item->getTransactionID());
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_UpdateTaskInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_UpdateData);
+ msg->addU32Fast(_PREHASH_LocalID, mLocalID);
+ msg->addU8Fast(_PREHASH_Key, key);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ task_item->packMessage(msg);
+ msg->sendReliable(mRegionp->getHost());
+
+ // do the internal logic
+ doUpdateInventory(task_item, key, is_new);
}
void LLViewerObject::updateInventoryLocal(LLInventoryItem* item, U8 key)
{
- LLPointer<LLViewerInventoryItem> task_item =
- new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
- item->getAssetUUID(), item->getType(),
- item->getInventoryType(),
- item->getName(), item->getDescription(),
- item->getSaleInfo(), item->getFlags(),
- item->getCreationDate());
+ LLPointer<LLViewerInventoryItem> task_item =
+ new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+ item->getAssetUUID(), item->getType(),
+ item->getInventoryType(),
+ item->getName(), item->getDescription(),
+ item->getSaleInfo(), item->getFlags(),
+ item->getCreationDate());
- // do the internal logic
- const bool is_new = false;
- doUpdateInventory(task_item, key, is_new);
+ // do the internal logic
+ const bool is_new = false;
+ doUpdateInventory(task_item, key, is_new);
}
LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
{
- LLInventoryObject* rv = NULL;
- if(mInventory)
- {
- LLInventoryObject::object_list_t::iterator it = mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = mInventory->end();
- for ( ; it != end; ++it)
- {
- if((*it)->getUUID() == item_id)
- {
- rv = *it;
- break;
- }
- }
- }
- return rv;
+ LLInventoryObject* rv = NULL;
+ if(mInventory)
+ {
+ LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = mInventory->end();
+ for ( ; it != end; ++it)
+ {
+ if((*it)->getUUID() == item_id)
+ {
+ rv = *it;
+ break;
+ }
+ }
+ }
+ return rv;
}
LLInventoryItem* LLViewerObject::getInventoryItem(const LLUUID& item_id)
{
- LLInventoryObject* iobj = getInventoryObject(item_id);
- if (!iobj || iobj->getType() == LLAssetType::AT_CATEGORY)
- {
- return NULL;
- }
- LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(iobj);
- return item;
+ LLInventoryObject* iobj = getInventoryObject(item_id);
+ if (!iobj || iobj->getType() == LLAssetType::AT_CATEGORY)
+ {
+ return NULL;
+ }
+ LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(iobj);
+ return item;
}
void LLViewerObject::getInventoryContents(LLInventoryObject::object_list_t& objects)
{
- if(mInventory)
- {
- LLInventoryObject::object_list_t::iterator it = mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = mInventory->end();
- for( ; it != end; ++it)
- {
- if ((*it)->getType() != LLAssetType::AT_CATEGORY)
- {
- objects.push_back(*it);
- }
- }
- }
+ if(mInventory)
+ {
+ LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = mInventory->end();
+ for( ; it != end; ++it)
+ {
+ if ((*it)->getType() != LLAssetType::AT_CATEGORY)
+ {
+ objects.push_back(*it);
+ }
+ }
+ }
}
LLInventoryObject* LLViewerObject::getInventoryRoot()
{
- if (!mInventory || !mInventory->size())
- {
- return NULL;
- }
- return mInventory->back();
+ if (!mInventory || !mInventory->size())
+ {
+ return NULL;
+ }
+ return mInventory->back();
}
LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id)
{
- if (mInventoryDirty)
- LL_WARNS() << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << LL_ENDL;
-
- LLViewerInventoryItem* rv = NULL;
- if(mInventory)
- {
- LLViewerInventoryItem* item = NULL;
-
- LLInventoryObject::object_list_t::iterator it = mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = mInventory->end();
- for( ; it != end; ++it)
- {
- LLInventoryObject* obj = *it;
- if(obj->getType() != LLAssetType::AT_CATEGORY)
- {
- // *FIX: gank-ass down cast!
- item = (LLViewerInventoryItem*)obj;
- if(item->getAssetUUID() == asset_id)
- {
- rv = item;
- break;
- }
- }
- }
- }
- return rv;
+ if (mInventoryDirty)
+ LL_WARNS() << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << LL_ENDL;
+
+ LLViewerInventoryItem* rv = NULL;
+ if(mInventory)
+ {
+ LLViewerInventoryItem* item = NULL;
+
+ LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = mInventory->end();
+ for( ; it != end; ++it)
+ {
+ LLInventoryObject* obj = *it;
+ if(obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ // *FIX: gank-ass down cast!
+ item = (LLViewerInventoryItem*)obj;
+ if(item->getAssetUUID() == asset_id)
+ {
+ rv = item;
+ break;
+ }
+ }
+ }
+ }
+ return rv;
}
LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type)
@@ -3734,70 +3736,70 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass
}
void LLViewerObject::updateViewerInventoryAsset(
- const LLViewerInventoryItem* item,
- const LLUUID& new_asset)
+ const LLViewerInventoryItem* item,
+ const LLUUID& new_asset)
{
- LLPointer<LLViewerInventoryItem> task_item =
- new LLViewerInventoryItem(item);
- task_item->setAssetUUID(new_asset);
+ LLPointer<LLViewerInventoryItem> task_item =
+ new LLViewerInventoryItem(item);
+ task_item->setAssetUUID(new_asset);
- // do the internal logic
- doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
+ // do the internal logic
+ doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
}
void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
{
- if (getVolume())
- { //volumes calculate pixel area and angle per face
- return;
- }
-
- LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
- LLVector3 pos_agent = getRenderPosition();
-
- F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
- F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
- F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
-
- F32 max_scale = getMaxScale();
- F32 mid_scale = getMidScale();
- F32 min_scale = getMinScale();
-
- // IW: estimate - when close to large objects, computing range based on distance from center is no good
- // to try to get a min distance from face, subtract min_scale/2 from the range.
- // This means we'll load too much detail sometimes, but that's better than not enough
- // I don't think there's a better way to do this without calculating distance per-poly
- F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
-
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- if (range < 0.001f || isHUDAttachment()) // range == zero
- {
- mAppAngle = 180.f;
- mPixelArea = (F32)camera->getScreenPixelArea();
- }
- else
- {
- mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
-
- F32 pixels_per_meter = camera->getPixelMeterRatio() / range;
-
- mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
- if (mPixelArea > camera->getScreenPixelArea())
- {
- mAppAngle = 180.f;
- mPixelArea = (F32)camera->getScreenPixelArea();
- }
- }
+ if (getVolume())
+ { //volumes calculate pixel area and angle per face
+ return;
+ }
+
+ LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
+ LLVector3 pos_agent = getRenderPosition();
+
+ F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
+ F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
+ F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
+
+ F32 max_scale = getMaxScale();
+ F32 mid_scale = getMidScale();
+ F32 min_scale = getMinScale();
+
+ // IW: estimate - when close to large objects, computing range based on distance from center is no good
+ // to try to get a min distance from face, subtract min_scale/2 from the range.
+ // This means we'll load too much detail sometimes, but that's better than not enough
+ // I don't think there's a better way to do this without calculating distance per-poly
+ F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ if (range < 0.001f || isHUDAttachment()) // range == zero
+ {
+ mAppAngle = 180.f;
+ mPixelArea = (F32)camera->getScreenPixelArea();
+ }
+ else
+ {
+ mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
+
+ F32 pixels_per_meter = camera->getPixelMeterRatio() / range;
+
+ mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
+ if (mPixelArea > camera->getScreenPixelArea())
+ {
+ mAppAngle = 180.f;
+ mPixelArea = (F32)camera->getScreenPixelArea();
+ }
+ }
}
BOOL LLViewerObject::updateLOD()
{
- return FALSE;
+ return FALSE;
}
BOOL LLViewerObject::updateGeometry(LLDrawable *drawable)
{
- return TRUE;
+ return TRUE;
}
void LLViewerObject::updateGL()
@@ -3807,51 +3809,51 @@ void LLViewerObject::updateGL()
void LLViewerObject::updateFaceSize(S32 idx)
{
-
+
}
LLDrawable* LLViewerObject::createDrawable(LLPipeline *pipeline)
{
- return NULL;
+ return NULL;
}
void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
{
- LLPrimitive::setScale(scale);
- if (mDrawable.notNull())
- {
- //encompass completely sheared objects by taking
- //the most extreme point possible (<1,1,0.5>)
- mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec());
- updateDrawable(damped);
- }
-
- if( (LL_PCODE_VOLUME == getPCode()) && !isDead() )
- {
- if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) )
- {
- if (!mOnMap)
- {
- llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle()));
-
- gObjectList.addToMap(this);
- mOnMap = TRUE;
- }
- }
- else
- {
- if (mOnMap)
- {
- gObjectList.removeFromMap(this);
- mOnMap = FALSE;
- }
- }
- }
+ LLPrimitive::setScale(scale);
+ if (mDrawable.notNull())
+ {
+ //encompass completely sheared objects by taking
+ //the most extreme point possible (<1,1,0.5>)
+ mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec());
+ updateDrawable(damped);
+ }
+
+ if( (LL_PCODE_VOLUME == getPCode()) && !isDead() )
+ {
+ if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) )
+ {
+ if (!mOnMap)
+ {
+ llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle()));
+
+ gObjectList.addToMap(this);
+ mOnMap = TRUE;
+ }
+ }
+ else
+ {
+ if (mOnMap)
+ {
+ gObjectList.removeFromMap(this);
+ mOnMap = FALSE;
+ }
+ }
+ }
}
void LLViewerObject::setObjectCostStale()
{
- mCostStale = true;
+ mCostStale = true;
// *NOTE: This is harmlessly redundant for Blinn-Phong material updates, as
// the root prim currently gets set stale anyway due to other property
// updates. But it is needed for GLTF material ID updates.
@@ -3861,96 +3863,96 @@ void LLViewerObject::setObjectCostStale()
void LLViewerObject::setObjectCost(F32 cost)
{
- mObjectCost = cost;
- mCostStale = false;
+ mObjectCost = cost;
+ mCostStale = false;
- if (isSelected())
- {
- gFloaterTools->dirty();
- }
+ if (isSelected())
+ {
+ gFloaterTools->dirty();
+ }
}
void LLViewerObject::setLinksetCost(F32 cost)
{
- mLinksetCost = cost;
- mCostStale = false;
+ mLinksetCost = cost;
+ mCostStale = false;
- BOOL needs_refresh = isSelected();
- child_list_t::iterator iter = mChildList.begin();
- while(iter != mChildList.end() && !needs_refresh)
- {
- LLViewerObject* child = *iter;
- needs_refresh = child->isSelected();
- iter++;
- }
+ BOOL needs_refresh = isSelected();
+ child_list_t::iterator iter = mChildList.begin();
+ while(iter != mChildList.end() && !needs_refresh)
+ {
+ LLViewerObject* child = *iter;
+ needs_refresh = child->isSelected();
+ iter++;
+ }
- if (needs_refresh)
- {
- gFloaterTools->dirty();
- }
+ if (needs_refresh)
+ {
+ gFloaterTools->dirty();
+ }
}
void LLViewerObject::setPhysicsCost(F32 cost)
{
- mPhysicsCost = cost;
- mCostStale = false;
+ mPhysicsCost = cost;
+ mCostStale = false;
- if (isSelected())
- {
- gFloaterTools->dirty();
- }
+ if (isSelected())
+ {
+ gFloaterTools->dirty();
+ }
}
void LLViewerObject::setLinksetPhysicsCost(F32 cost)
{
- mLinksetPhysicsCost = cost;
- mCostStale = false;
-
- if (isSelected())
- {
- gFloaterTools->dirty();
- }
+ mLinksetPhysicsCost = cost;
+ mCostStale = false;
+
+ if (isSelected())
+ {
+ gFloaterTools->dirty();
+ }
}
F32 LLViewerObject::getObjectCost()
{
- if (mCostStale)
- {
- gObjectList.updateObjectCost(this);
- }
-
- return mObjectCost;
+ if (mCostStale)
+ {
+ gObjectList.updateObjectCost(this);
+ }
+
+ return mObjectCost;
}
F32 LLViewerObject::getLinksetCost()
{
- if (mCostStale)
- {
- gObjectList.updateObjectCost(this);
- }
+ if (mCostStale)
+ {
+ gObjectList.updateObjectCost(this);
+ }
- return mLinksetCost;
+ return mLinksetCost;
}
F32 LLViewerObject::getPhysicsCost()
{
- if (mCostStale)
- {
- gObjectList.updateObjectCost(this);
- }
-
- return mPhysicsCost;
+ if (mCostStale)
+ {
+ gObjectList.updateObjectCost(this);
+ }
+
+ return mPhysicsCost;
}
F32 LLViewerObject::getLinksetPhysicsCost()
{
- if (mCostStale)
- {
- gObjectList.updateObjectCost(this);
- }
+ if (mCostStale)
+ {
+ gObjectList.updateObjectCost(this);
+ }
- return mLinksetPhysicsCost;
+ return mLinksetPhysicsCost;
}
F32 LLViewerObject::recursiveGetEstTrianglesMax() const
@@ -3971,7 +3973,7 @@ F32 LLViewerObject::recursiveGetEstTrianglesMax() const
S32 LLViewerObject::getAnimatedObjectMaxTris() const
{
S32 max_tris = 0;
- if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits"))
+ if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits"))
{
max_tris = S32_MAX;
}
@@ -4003,7 +4005,7 @@ F32 LLViewerObject::getEstTrianglesStreamingCost() const
// virtual
F32 LLViewerObject::getStreamingCost() const
{
- return 0.f;
+ return 0.f;
}
// virtual
@@ -4015,12 +4017,12 @@ bool LLViewerObject::getCostData(LLMeshCostData& costs) const
U32 LLViewerObject::getTriangleCount(S32* vcount) const
{
- return 0;
+ return 0;
}
U32 LLViewerObject::getHighLODTriangleCount()
{
- return 0;
+ return 0;
}
U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const
@@ -4055,7 +4057,7 @@ F32 LLViewerObject::recursiveGetScaledSurfaceArea() const
{
if (volume->getVolume())
{
- const LLVector3& scale = volume->getScale();
+ const LLVector3& scale = volume->getScale();
area += volume->getVolume()->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
}
LLViewerObject::const_child_list_t children = volume->getChildren();
@@ -4078,68 +4080,68 @@ F32 LLViewerObject::recursiveGetScaledSurfaceArea() const
void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
{
- LLVector4a center;
- center.load3(getRenderPosition().mV);
- LLVector4a size;
- size.load3(getScale().mV);
- newMin.setSub(center, size);
- newMax.setAdd(center, size);
-
- mDrawable->setPositionGroup(center);
+ LLVector4a center;
+ center.load3(getRenderPosition().mV);
+ LLVector4a size;
+ size.load3(getScale().mV);
+ newMin.setSub(center, size);
+ newMax.setAdd(center, size);
+
+ mDrawable->setPositionGroup(center);
}
F32 LLViewerObject::getBinRadius()
{
- if (mDrawable.notNull())
- {
- const LLVector4a* ext = mDrawable->getSpatialExtents();
- LLVector4a diff;
- diff.setSub(ext[1], ext[0]);
- return diff.getLength3().getF32();
- }
-
- return getScale().magVec();
+ if (mDrawable.notNull())
+ {
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ LLVector4a diff;
+ diff.setSub(ext[1], ext[0]);
+ return diff.getLength3().getF32();
+ }
+
+ return getScale().magVec();
}
F32 LLViewerObject::getMaxScale() const
{
- return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]);
+ return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]);
}
F32 LLViewerObject::getMinScale() const
{
- return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]);
+ return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]);
}
F32 LLViewerObject::getMidScale() const
{
- if (getScale().mV[VX] < getScale().mV[VY])
- {
- if (getScale().mV[VY] < getScale().mV[VZ])
- {
- return getScale().mV[VY];
- }
- else if (getScale().mV[VX] < getScale().mV[VZ])
- {
- return getScale().mV[VZ];
- }
- else
- {
- return getScale().mV[VX];
- }
- }
- else if (getScale().mV[VX] < getScale().mV[VZ])
- {
- return getScale().mV[VX];
- }
- else if (getScale().mV[VY] < getScale().mV[VZ])
- {
- return getScale().mV[VZ];
- }
- else
- {
- return getScale().mV[VY];
- }
+ if (getScale().mV[VX] < getScale().mV[VY])
+ {
+ if (getScale().mV[VY] < getScale().mV[VZ])
+ {
+ return getScale().mV[VY];
+ }
+ else if (getScale().mV[VX] < getScale().mV[VZ])
+ {
+ return getScale().mV[VZ];
+ }
+ else
+ {
+ return getScale().mV[VX];
+ }
+ }
+ else if (getScale().mV[VX] < getScale().mV[VZ])
+ {
+ return getScale().mV[VX];
+ }
+ else if (getScale().mV[VY] < getScale().mV[VZ])
+ {
+ return getScale().mV[VZ];
+ }
+ else
+ {
+ return getScale().mV[VY];
+ }
}
@@ -4149,68 +4151,68 @@ void LLViewerObject::updateTextures()
void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
{
- if (isDead() || !getVolume())
- {
- return;
- }
-
- S32 i;
- S32 tex_count = getNumTEs();
- for (i = 0; i < tex_count; i++)
- {
- getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
- }
-
- if (isSculpted() && !isMesh())
- {
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID sculpt_id = sculpt_params->getSculptTexture();
- LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
- }
-
- if (boost_children)
- {
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->boostTexturePriority();
- }
- }
+ if (isDead() || !getVolume())
+ {
+ return;
+ }
+
+ S32 i;
+ S32 tex_count = getNumTEs();
+ for (i = 0; i < tex_count; i++)
+ {
+ getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
+ }
+
+ if (isSculpted() && !isMesh())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLUUID sculpt_id = sculpt_params->getSculptTexture();
+ LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
+ }
+
+ if (boost_children)
+ {
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ child->boostTexturePriority();
+ }
+ }
}
void LLViewerObject::setLineWidthForWindowSize(S32 window_width)
{
- if (window_width < 700)
- {
- LLUI::setLineWidth(2.0f);
- }
- else if (window_width < 1100)
- {
- LLUI::setLineWidth(3.0f);
- }
- else if (window_width < 2000)
- {
- LLUI::setLineWidth(4.0f);
- }
- else
- {
- // _damn_, what a nice monitor!
- LLUI::setLineWidth(5.0f);
- }
+ if (window_width < 700)
+ {
+ LLUI::setLineWidth(2.0f);
+ }
+ else if (window_width < 1100)
+ {
+ LLUI::setLineWidth(3.0f);
+ }
+ else if (window_width < 2000)
+ {
+ LLUI::setLineWidth(4.0f);
+ }
+ else
+ {
+ // _damn_, what a nice monitor!
+ LLUI::setLineWidth(5.0f);
+ }
}
void LLViewerObject::increaseArrowLength()
{
/* ???
- if (mAxisArrowLength == 50)
- {
- mAxisArrowLength = 100;
- }
- else
- {
- mAxisArrowLength = 150;
- }
+ if (mAxisArrowLength == 50)
+ {
+ mAxisArrowLength = 100;
+ }
+ else
+ {
+ mAxisArrowLength = 150;
+ }
*/
}
@@ -4218,193 +4220,355 @@ void LLViewerObject::increaseArrowLength()
void LLViewerObject::decreaseArrowLength()
{
/* ???
- if (mAxisArrowLength == 150)
- {
- mAxisArrowLength = 100;
- }
- else
- {
- mAxisArrowLength = 50;
- }
+ if (mAxisArrowLength == 150)
+ {
+ mAxisArrowLength = 100;
+ }
+ else
+ {
+ mAxisArrowLength = 50;
+ }
*/
}
// Culled from newsim LLTask::addNVPair
void LLViewerObject::addNVPair(const std::string& data)
{
- // cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl;
- LLNameValue *nv = new LLNameValue(data.c_str());
-
-// char splat[MAX_STRING];
-// temp->printNameValue(splat);
-// LL_INFOS() << "addNVPair " << splat << LL_ENDL;
-
- name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName);
- if (iter != mNameValuePairs.end())
- {
- LLNameValue* foundnv = iter->second;
- if (foundnv->mClass != NVC_READ_ONLY)
- {
- delete foundnv;
- mNameValuePairs.erase(iter);
- }
- else
- {
- delete nv;
-// LL_INFOS() << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << LL_ENDL;
- return;
- }
- }
- mNameValuePairs[nv->mName] = nv;
+ // cout << "LLViewerObject::addNVPair() with ---" << data << "---" << endl;
+ LLNameValue *nv = new LLNameValue(data.c_str());
+
+// char splat[MAX_STRING];
+// temp->printNameValue(splat);
+// LL_INFOS() << "addNVPair " << splat << LL_ENDL;
+
+ name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName);
+ if (iter != mNameValuePairs.end())
+ {
+ LLNameValue* foundnv = iter->second;
+ if (foundnv->mClass != NVC_READ_ONLY)
+ {
+ delete foundnv;
+ mNameValuePairs.erase(iter);
+ }
+ else
+ {
+ delete nv;
+// LL_INFOS() << "Trying to write to Read Only NVPair " << temp->mName << " in addNVPair()" << LL_ENDL;
+ return;
+ }
+ }
+ mNameValuePairs[nv->mName] = nv;
}
BOOL LLViewerObject::removeNVPair(const std::string& name)
{
- char* canonical_name = gNVNameTable.addString(name);
+ char* canonical_name = gNVNameTable.addString(name);
- LL_DEBUGS() << "LLViewerObject::removeNVPair(): " << name << LL_ENDL;
+ LL_DEBUGS() << "LLViewerObject::removeNVPair(): " << name << LL_ENDL;
- name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name);
- if (iter != mNameValuePairs.end())
- {
- if( mRegionp )
- {
- LLNameValue* nv = iter->second;
+ name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name);
+ if (iter != mNameValuePairs.end())
+ {
+ if( mRegionp )
+ {
+ LLNameValue* nv = iter->second;
/*
- std::string buffer = nv->printNameValue();
- gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair);
- gMessageSystem->nextBlockFast(_PREHASH_TaskData);
- gMessageSystem->addUUIDFast(_PREHASH_ID, mID);
-
- gMessageSystem->nextBlockFast(_PREHASH_NameValueData);
- gMessageSystem->addStringFast(_PREHASH_NVPair, buffer);
-
- gMessageSystem->sendReliable( mRegionp->getHost() );
+ std::string buffer = nv->printNameValue();
+ gMessageSystem->newMessageFast(_PREHASH_RemoveNameValuePair);
+ gMessageSystem->nextBlockFast(_PREHASH_TaskData);
+ gMessageSystem->addUUIDFast(_PREHASH_ID, mID);
+
+ gMessageSystem->nextBlockFast(_PREHASH_NameValueData);
+ gMessageSystem->addStringFast(_PREHASH_NVPair, buffer);
+
+ gMessageSystem->sendReliable( mRegionp->getHost() );
*/
- // Remove the NV pair from the local list.
- delete nv;
- mNameValuePairs.erase(iter);
- return TRUE;
- }
- else
- {
- LL_DEBUGS() << "removeNVPair - No region for object" << LL_ENDL;
- }
- }
- return FALSE;
+ // Remove the NV pair from the local list.
+ delete nv;
+ mNameValuePairs.erase(iter);
+ return TRUE;
+ }
+ else
+ {
+ LL_DEBUGS() << "removeNVPair - No region for object" << LL_ENDL;
+ }
+ }
+ return FALSE;
}
LLNameValue *LLViewerObject::getNVPair(const std::string& name) const
{
- char *canonical_name;
+ char *canonical_name;
- canonical_name = gNVNameTable.addString(name);
+ canonical_name = gNVNameTable.addString(name);
- // If you access a map with a name that isn't in it, it will add the name and a null pointer.
- // So first check if the data is in the map.
- name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name);
- if (iter != mNameValuePairs.end())
- {
- return iter->second;
- }
- else
- {
- return NULL;
- }
+ // If you access a map with a name that isn't in it, it will add the name and a null pointer.
+ // So first check if the data is in the map.
+ name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name);
+ if (iter != mNameValuePairs.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return NULL;
+ }
}
void LLViewerObject::updatePositionCaches() const
{
- // If region is removed from the list it is also deleted.
- if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
- {
- if (!isRoot())
- {
- mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
- mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
- }
- else
- {
- mPositionRegion = getPosition();
- mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
- }
- }
+ // If region is removed from the list it is also deleted.
+ if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
+ {
+ if (!isRoot())
+ {
+ mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
+ mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+ }
+ else
+ {
+ mPositionRegion = getPosition();
+ mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+ }
+ }
}
const LLVector3d LLViewerObject::getPositionGlobal() const
+{
+ // If region is removed from the list it is also deleted.
+ if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
+ {
+ LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+
+ if (isAttachment())
+ {
+ position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
+ }
+ return position_global;
+ }
+ else
+ {
+ LLVector3d position_global(getPosition());
+ return position_global;
+ }
+}
+
+const LLVector3 &LLViewerObject::getPositionAgent() const
{
- // If region is removed from the list it is also deleted.
- if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
+ // If region is removed from the list it is also deleted.
+ if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
+ {
+ if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent()))
+ {
+ // Don't return cached position if you have a parent, recalc (until all dirtying is done correctly.
+ LLVector3 position_region;
+ position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
+ mPositionAgent = mRegionp->getPosAgentFromRegion(position_region);
+ }
+ else
+ {
+ mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition());
+ }
+ }
+ return mPositionAgent;
+}
+
+LLMatrix4a LLViewerObject::getGLTFAssetToAgentTransform() const
+{
+ LLMatrix4 root;
+ root.initScale(getScale());
+ root.rotate(getRenderRotation());
+ root.translate(getPositionAgent());
+
+ LLMatrix4a mat;
+ mat.loadu((F32*)root.mMatrix);
+
+ return mat;
+}
+
+LLVector3 LLViewerObject::getGLTFNodePositionAgent(S32 node_index) const
+{
+ LLVector3 ret;
+ getGLTFNodeTransformAgent(node_index, &ret, nullptr, nullptr);
+ return ret;
+
+}
+
+LLMatrix4a LLViewerObject::getAgentToGLTFAssetTransform() const
+{
+ LLMatrix4 root;
+ LLVector3 scale = getScale();
+ scale.mV[0] = 1.f / scale.mV[0];
+ scale.mV[1] = 1.f / scale.mV[1];
+ scale.mV[2] = 1.f / scale.mV[2];
+
+ root.translate(-getPositionAgent());
+ root.rotate(~getRenderRotation());
+
+ LLMatrix4 scale_mat;
+ scale_mat.initScale(scale);
+
+ root *= scale_mat;
+ LLMatrix4a mat;
+ mat.loadu((F32*)root.mMatrix);
+
+ return mat;
+}
+
+LLMatrix4a LLViewerObject::getGLTFNodeTransformAgent(S32 node_index) const
+{
+ LLMatrix4a mat;
+
+ if (mGLTFAsset.notNull() && node_index >= 0 && node_index < mGLTFAsset->mNodes.size())
{
- LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+ auto& node = mGLTFAsset->mNodes[node_index];
- if (isAttachment())
- {
- position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
- }
- return position_global;
+ LLMatrix4a asset_to_agent = getGLTFAssetToAgentTransform();
+ LLMatrix4a node_to_agent;
+ matMul(node.mAssetMatrix, asset_to_agent, node_to_agent);
+
+ mat = node_to_agent;
}
else
{
- LLVector3d position_global(getPosition());
- return position_global;
+ mat.setIdentity();
}
-}
-const LLVector3 &LLViewerObject::getPositionAgent() const
+ return mat;
+}
+void LLViewerObject::getGLTFNodeTransformAgent(S32 node_index, LLVector3* position, LLQuaternion* rotation, LLVector3* scale) const
{
- // If region is removed from the list it is also deleted.
- if(mRegionp && LLWorld::instance().isRegionListed(mRegionp))
+ LLMatrix4a node_to_agent = getGLTFNodeTransformAgent(node_index);
+
+ if (position)
{
- if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent()))
- {
- // Don't return cached position if you have a parent, recalc (until all dirtying is done correctly.
- LLVector3 position_region;
- position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
- mPositionAgent = mRegionp->getPosAgentFromRegion(position_region);
- }
- else
- {
- mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition());
- }
+ LLVector4a p = node_to_agent.getTranslation();
+ position->set(p.getF32ptr());
}
- return mPositionAgent;
-}
-const LLVector3 &LLViewerObject::getPositionRegion() const
-{
- if (!isRoot())
+ if (rotation)
{
- LLViewerObject *parent = (LLViewerObject *)getParent();
- mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
+ rotation->set(node_to_agent.asMatrix4());
}
- else
+
+ if (scale)
{
- mPositionRegion = getPosition();
+ scale->mV[0] = node_to_agent.mMatrix[0].getLength3().getF32();
+ scale->mV[1] = node_to_agent.mMatrix[1].getLength3().getF32();
+ scale->mV[2] = node_to_agent.mMatrix[2].getLength3().getF32();
}
+}
- return mPositionRegion;
+void decomposeMatrix(const LLMatrix4a& mat, LLVector3& position, LLQuaternion& rotation, LLVector3& scale)
+{
+ LLVector4a p = mat.getTranslation();
+ position.set(p.getF32ptr());
+
+ rotation.set(mat.asMatrix4());
+
+ scale.mV[0] = mat.mMatrix[0].getLength3().getF32();
+ scale.mV[1] = mat.mMatrix[1].getLength3().getF32();
+ scale.mV[2] = mat.mMatrix[2].getLength3().getF32();
}
-const LLVector3 LLViewerObject::getPositionEdit() const
+void LLViewerObject::setGLTFNodeRotationAgent(S32 node_index, const LLQuaternion& rotation)
{
- if (isRootEdit())
+ if (mGLTFAsset.notNull() && node_index >= 0 && node_index < mGLTFAsset->mNodes.size())
{
- return getPosition();
+ auto& node = mGLTFAsset->mNodes[node_index];
+
+ LLMatrix4a agent_to_asset = getAgentToGLTFAssetTransform();
+ LLMatrix4a agent_to_node = agent_to_asset;
+
+ if (node.mParent != -1)
+ {
+ auto& parent = mGLTFAsset->mNodes[node.mParent];
+ matMul(agent_to_asset, parent.mAssetMatrixInv, agent_to_node);
+ }
+
+ LLQuaternion agent_to_node_rot(agent_to_node.asMatrix4());
+ LLQuaternion new_rot;
+
+ new_rot = rotation * agent_to_node_rot;
+ new_rot.normalize();
+
+ LLVector3 pos;
+ LLQuaternion rot;
+ LLVector3 scale;
+ decomposeMatrix(node.mMatrix, pos, rot, scale);
+
+ node.mMatrix.asMatrix4().initAll(scale, new_rot, pos);
+
+ mGLTFAsset->updateTransforms();
}
- else
+}
+
+void LLViewerObject::moveGLTFNode(S32 node_index, const LLVector3& offset)
+{
+ if (mGLTFAsset.notNull() && node_index >= 0 && node_index < mGLTFAsset->mNodes.size())
{
- LLViewerObject *parent = (LLViewerObject *)getParent();
- LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit();
- return position_edit;
+ auto& node = mGLTFAsset->mNodes[node_index];
+
+ LLMatrix4a agent_to_asset = getAgentToGLTFAssetTransform();
+ LLMatrix4a agent_to_node;
+ matMul(agent_to_asset, node.mAssetMatrixInv, agent_to_node);
+
+ LLVector4a origin = LLVector4a::getZero();
+ LLVector4a offset_v;
+ offset_v.load3(offset.mV);
+
+
+ agent_to_node.affineTransform(offset_v, offset_v);
+ agent_to_node.affineTransform(origin, origin);
+
+ offset_v.sub(origin);
+ offset_v.getF32ptr()[3] = 1.f;
+
+ LLMatrix4a trans;
+ trans.setIdentity();
+ trans.mMatrix[3] = offset_v;
+
+ matMul(trans, node.mMatrix, node.mMatrix);
+
+ // TODO -- only update transforms for this node and its children (or use a dirty flag)
+ mGLTFAsset->updateTransforms();
}
}
+const LLVector3 &LLViewerObject::getPositionRegion() const
+{
+ if (!isRoot())
+ {
+ LLViewerObject *parent = (LLViewerObject *)getParent();
+ mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
+ }
+ else
+ {
+ mPositionRegion = getPosition();
+ }
+
+ return mPositionRegion;
+}
+
+const LLVector3 LLViewerObject::getPositionEdit() const
+{
+ if (isRootEdit())
+ {
+ return getPosition();
+ }
+ else
+ {
+ LLViewerObject *parent = (LLViewerObject *)getParent();
+ LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit();
+ return position_edit;
+ }
+}
+
const LLVector3 LLViewerObject::getRenderPosition() const
{
- if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
- {
+ if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
+ {
LLControlAvatar *cav = getControlAvatar();
if (isRoot() && cav)
{
@@ -4417,448 +4581,448 @@ const LLVector3 LLViewerObject::getRenderPosition() const
return pos;
}
}
- LLVOAvatar* avatar = getAvatar();
- if ((avatar) && !getControlAvatar())
- {
- return avatar->getPositionAgent();
- }
- }
+ LLVOAvatar* avatar = getAvatar();
+ if ((avatar) && !getControlAvatar())
+ {
+ return avatar->getPositionAgent();
+ }
+ }
- if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
- {
- return getPositionAgent();
- }
- else
- {
- return mDrawable->getPositionAgent();
- }
+ if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
+ {
+ return getPositionAgent();
+ }
+ else
+ {
+ return mDrawable->getPositionAgent();
+ }
}
const LLVector3 LLViewerObject::getPivotPositionAgent() const
{
- return getRenderPosition();
+ return getRenderPosition();
}
const LLQuaternion LLViewerObject::getRenderRotation() const
{
- LLQuaternion ret;
- if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED) && !isAnimatedObject())
- {
- return ret;
- }
-
- if (mDrawable.isNull() || mDrawable->isStatic())
- {
- ret = getRotationEdit();
- }
- else
- {
- if (!mDrawable->isRoot())
- {
- ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
- }
- else
- {
- ret = LLQuaternion(mDrawable->getWorldMatrix());
- }
- }
-
- return ret;
+ LLQuaternion ret;
+ if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED) && !isAnimatedObject())
+ {
+ return ret;
+ }
+
+ if (mDrawable.isNull() || mDrawable->isStatic())
+ {
+ ret = getRotationEdit();
+ }
+ else
+ {
+ if (!mDrawable->isRoot())
+ {
+ ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
+ }
+ else
+ {
+ ret = LLQuaternion(mDrawable->getWorldMatrix());
+ }
+ }
+
+ return ret;
}
const LLMatrix4 LLViewerObject::getRenderMatrix() const
{
- return mDrawable->getWorldMatrix();
+ return mDrawable->getWorldMatrix();
}
const LLQuaternion LLViewerObject::getRotationRegion() const
{
- LLQuaternion global_rotation = getRotation();
- if (!((LLXform *)this)->isRoot())
- {
- global_rotation = global_rotation * getParent()->getRotation();
- }
- return global_rotation;
+ LLQuaternion global_rotation = getRotation();
+ if (!((LLXform *)this)->isRoot())
+ {
+ global_rotation = global_rotation * getParent()->getRotation();
+ }
+ return global_rotation;
}
const LLQuaternion LLViewerObject::getRotationEdit() const
{
- LLQuaternion global_rotation = getRotation();
- if (!((LLXform *)this)->isRootEdit())
- {
- global_rotation = global_rotation * getParent()->getRotation();
- }
- return global_rotation;
+ LLQuaternion global_rotation = getRotation();
+ if (!((LLXform *)this)->isRootEdit())
+ {
+ global_rotation = global_rotation * getParent()->getRotation();
+ }
+ return global_rotation;
}
void LLViewerObject::setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped )
{
- if (isAttachment())
- {
- LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global);
- if (isRootEdit())
- {
- new_pos -= mDrawable->mXform.getParent()->getWorldPosition();
- LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation();
- new_pos = new_pos * ~world_rotation;
- }
- else
- {
- LLViewerObject* parentp = (LLViewerObject*)getParent();
- new_pos -= parentp->getPositionAgent();
- new_pos = new_pos * ~parentp->getRotationRegion();
- }
- LLViewerObject::setPosition(new_pos);
-
- if (mParent && ((LLViewerObject*)mParent)->isAvatar())
- {
- // we have changed the position of an attachment, so we need to clamp it
- LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
- avatar->clampAttachmentPositions();
- }
- }
- else
- {
- if( isRoot() )
- {
- setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
- }
- else
- {
- // the relative position with the parent is not constant
- LLViewerObject* parent = (LLViewerObject *)getParent();
- //RN: this assumes we are only calling this function from the edit tools
- gPipeline.updateMoveNormalAsync(parent->mDrawable);
-
- LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion();
- pos_local = pos_local * ~parent->getRotationRegion();
- LLViewerObject::setPosition( pos_local );
- }
- }
- //RN: assumes we always want to snap the object when calling this function
- gPipeline.updateMoveNormalAsync(mDrawable);
+ if (isAttachment())
+ {
+ LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global);
+ if (isRootEdit())
+ {
+ new_pos -= mDrawable->mXform.getParent()->getWorldPosition();
+ LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation();
+ new_pos = new_pos * ~world_rotation;
+ }
+ else
+ {
+ LLViewerObject* parentp = (LLViewerObject*)getParent();
+ new_pos -= parentp->getPositionAgent();
+ new_pos = new_pos * ~parentp->getRotationRegion();
+ }
+ LLViewerObject::setPosition(new_pos);
+
+ if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+ {
+ // we have changed the position of an attachment, so we need to clamp it
+ LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+ avatar->clampAttachmentPositions();
+ }
+ }
+ else
+ {
+ if( isRoot() )
+ {
+ setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
+ }
+ else
+ {
+ // the relative position with the parent is not constant
+ LLViewerObject* parent = (LLViewerObject *)getParent();
+ //RN: this assumes we are only calling this function from the edit tools
+ gPipeline.updateMoveNormalAsync(parent->mDrawable);
+
+ LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion();
+ pos_local = pos_local * ~parent->getRotationRegion();
+ LLViewerObject::setPosition( pos_local );
+ }
+ }
+ //RN: assumes we always want to snap the object when calling this function
+ gPipeline.updateMoveNormalAsync(mDrawable);
}
void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped)
{
- if (getPosition() != pos)
- {
- setChanged(TRANSLATED | SILHOUETTE);
- }
-
- LLXform::setPosition(pos);
- updateDrawable(damped);
- if (isRoot())
- {
- // position caches need to be up to date on root objects
- updatePositionCaches();
- }
+ if (getPosition() != pos)
+ {
+ setChanged(TRANSLATED | SILHOUETTE);
+ }
+
+ LLXform::setPosition(pos);
+ updateDrawable(damped);
+ if (isRoot())
+ {
+ // position caches need to be up to date on root objects
+ updatePositionCaches();
+ }
}
void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped)
{
- if (isAttachment())
- {
- if (isRootEdit())
- {
- LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
- newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
-
- LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation();
- invWorldRotation.transQuat();
-
- newPos = newPos * invWorldRotation;
- LLViewerObject::setPosition(newPos);
- }
- else
- {
- // assumes parent is root editable (root of attachment)
- LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
- newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
- LLVector3 delta_pos = newPos - getPosition();
-
- LLQuaternion invRotation = mDrawable->getRotation();
- invRotation.transQuat();
-
- delta_pos = delta_pos * invRotation;
-
- // *FIX: is this right? Shouldn't we be calling the
- // LLViewerObject version of setPosition?
- LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition();
- mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos);
- setChanged(TRANSLATED | SILHOUETTE);
- }
- if (mParent && ((LLViewerObject*)mParent)->isAvatar())
- {
- // we have changed the position of an attachment, so we need to clamp it
- LLVOAvatar *avatar = (LLVOAvatar*)mParent;
-
- avatar->clampAttachmentPositions();
- }
- }
- else
- {
- if (isRoot())
- {
- setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
- }
- else
- {
- // the relative position with the parent is constant, but the parent's position needs to be changed
- LLVector3d position_offset;
- position_offset.setVec(getPosition()*getParent()->getRotation());
- LLVector3d new_pos_global = pos_global - position_offset;
- ((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global);
- }
- }
- updateDrawable(damped);
+ if (isAttachment())
+ {
+ if (isRootEdit())
+ {
+ LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
+ newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
+
+ LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation();
+ invWorldRotation.transQuat();
+
+ newPos = newPos * invWorldRotation;
+ LLViewerObject::setPosition(newPos);
+ }
+ else
+ {
+ // assumes parent is root editable (root of attachment)
+ LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
+ newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
+ LLVector3 delta_pos = newPos - getPosition();
+
+ LLQuaternion invRotation = mDrawable->getRotation();
+ invRotation.transQuat();
+
+ delta_pos = delta_pos * invRotation;
+
+ // *FIX: is this right? Shouldn't we be calling the
+ // LLViewerObject version of setPosition?
+ LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition();
+ mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos);
+ setChanged(TRANSLATED | SILHOUETTE);
+ }
+ if (mParent && ((LLViewerObject*)mParent)->isAvatar())
+ {
+ // we have changed the position of an attachment, so we need to clamp it
+ LLVOAvatar *avatar = (LLVOAvatar*)mParent;
+
+ avatar->clampAttachmentPositions();
+ }
+ }
+ else
+ {
+ if (isRoot())
+ {
+ setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
+ }
+ else
+ {
+ // the relative position with the parent is constant, but the parent's position needs to be changed
+ LLVector3d position_offset;
+ position_offset.setVec(getPosition()*getParent()->getRotation());
+ LLVector3d new_pos_global = pos_global - position_offset;
+ ((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global);
+ }
+ }
+ updateDrawable(damped);
}
void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped)
{
- // Set position relative to parent, if no parent, relative to region
- if (!isRoot())
- {
- LLViewerObject::setPosition(pos_parent, damped);
- //updateDrawable(damped);
- }
- else
- {
- setPositionRegion(pos_parent, damped);
- }
+ // Set position relative to parent, if no parent, relative to region
+ if (!isRoot())
+ {
+ LLViewerObject::setPosition(pos_parent, damped);
+ //updateDrawable(damped);
+ }
+ else
+ {
+ setPositionRegion(pos_parent, damped);
+ }
}
void LLViewerObject::setPositionRegion(const LLVector3 &pos_region, BOOL damped)
{
- if (!isRootEdit())
- {
- LLViewerObject* parent = (LLViewerObject*) getParent();
- LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion());
- }
- else
- {
- LLViewerObject::setPosition(pos_region);
- mPositionRegion = pos_region;
- mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
- }
+ if (!isRootEdit())
+ {
+ LLViewerObject* parent = (LLViewerObject*) getParent();
+ LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion());
+ }
+ else
+ {
+ LLViewerObject::setPosition(pos_region);
+ mPositionRegion = pos_region;
+ mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+ }
}
void LLViewerObject::setPositionAgent(const LLVector3 &pos_agent, BOOL damped)
{
- LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent);
- setPositionRegion(pos_region, damped);
+ LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent);
+ setPositionRegion(pos_region, damped);
}
-// identical to setPositionRegion() except it checks for child-joints
+// identical to setPositionRegion() except it checks for child-joints
// and doesn't also move the joint-parent
// TODO -- implement similar intelligence for joint-parents toward
// their joint-children
void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped)
{
- if (!isRootEdit())
- {
- // the relative position with the parent is constant, but the parent's position needs to be changed
- LLVector3 position_offset = getPosition() * getParent()->getRotation();
+ if (!isRootEdit())
+ {
+ // the relative position with the parent is constant, but the parent's position needs to be changed
+ LLVector3 position_offset = getPosition() * getParent()->getRotation();
- ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
- updateDrawable(damped);
- }
- else
- {
- LLViewerObject::setPosition(pos_edit, damped);
- mPositionRegion = pos_edit;
- mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
- }
+ ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
+ updateDrawable(damped);
+ }
+ else
+ {
+ LLViewerObject::setPosition(pos_edit, damped);
+ mPositionRegion = pos_edit;
+ mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+ }
}
LLViewerObject* LLViewerObject::getRootEdit() const
{
- const LLViewerObject* root = this;
- while (root->mParent
- && !((LLViewerObject*)root->mParent)->isAvatar())
- {
- root = (LLViewerObject*)root->mParent;
- }
- return (LLViewerObject*)root;
+ const LLViewerObject* root = this;
+ while (root->mParent
+ && !((LLViewerObject*)root->mParent)->isAvatar())
+ {
+ root = (LLViewerObject*)root->mParent;
+ }
+ return (LLViewerObject*)root;
}
BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face,
- BOOL pick_transparent,
- BOOL pick_rigged,
+ S32 face,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable,
- S32* face_hit,
- LLVector4a* intersection,
- LLVector2* tex_coord,
- LLVector4a* normal,
- LLVector4a* tangent)
+ S32* face_hit,
+ LLVector4a* intersection,
+ LLVector2* tex_coord,
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
- return false;
+ return false;
}
BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)
{
- if (mDrawable.isNull() || mDrawable->isDead())
- {
- return FALSE;
- }
+ if (mDrawable.isNull() || mDrawable->isDead())
+ {
+ return FALSE;
+ }
- const LLVector4a* ext = mDrawable->getSpatialExtents();
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
- //VECTORIZE THIS
- LLVector4a center;
- center.setAdd(ext[1], ext[0]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
+ //VECTORIZE THIS
+ LLVector4a center;
+ center.setAdd(ext[1], ext[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
- return LLLineSegmentBoxIntersect(start, end, center, size);
+ return LLLineSegmentBoxIntersect(start, end, center, size);
}
U8 LLViewerObject::getMediaType() const
{
- if (mMedia)
- {
- return mMedia->mMediaType;
- }
- else
- {
- return LLViewerObject::MEDIA_NONE;
- }
+ if (mMedia)
+ {
+ return mMedia->mMediaType;
+ }
+ else
+ {
+ return LLViewerObject::MEDIA_NONE;
+ }
}
void LLViewerObject::setMediaType(U8 media_type)
{
- if (!mMedia)
- {
- // TODO what if we don't have a media pointer?
- }
- else if (mMedia->mMediaType != media_type)
- {
- mMedia->mMediaType = media_type;
+ if (!mMedia)
+ {
+ // TODO what if we don't have a media pointer?
+ }
+ else if (mMedia->mMediaType != media_type)
+ {
+ mMedia->mMediaType = media_type;
- // TODO: update materials with new image
- }
+ // TODO: update materials with new image
+ }
}
std::string LLViewerObject::getMediaURL() const
{
- if (mMedia)
- {
- return mMedia->mMediaURL;
- }
- else
- {
- return std::string();
- }
+ if (mMedia)
+ {
+ return mMedia->mMediaURL;
+ }
+ else
+ {
+ return std::string();
+ }
}
void LLViewerObject::setMediaURL(const std::string& media_url)
{
- if (!mMedia)
- {
- mMedia = new LLViewerObjectMedia;
- mMedia->mMediaURL = media_url;
- mMedia->mPassedWhitelist = FALSE;
+ if (!mMedia)
+ {
+ mMedia = new LLViewerObjectMedia;
+ mMedia->mMediaURL = media_url;
+ mMedia->mPassedWhitelist = FALSE;
- // TODO: update materials with new image
- }
- else if (mMedia->mMediaURL != media_url)
- {
- mMedia->mMediaURL = media_url;
- mMedia->mPassedWhitelist = FALSE;
+ // TODO: update materials with new image
+ }
+ else if (mMedia->mMediaURL != media_url)
+ {
+ mMedia->mMediaURL = media_url;
+ mMedia->mPassedWhitelist = FALSE;
- // TODO: update materials with new image
- }
+ // TODO: update materials with new image
+ }
}
BOOL LLViewerObject::getMediaPassedWhitelist() const
{
- if (mMedia)
- {
- return mMedia->mPassedWhitelist;
- }
- else
- {
- return FALSE;
- }
+ if (mMedia)
+ {
+ return mMedia->mPassedWhitelist;
+ }
+ else
+ {
+ return FALSE;
+ }
}
void LLViewerObject::setMediaPassedWhitelist(BOOL passed)
{
- if (mMedia)
- {
- mMedia->mPassedWhitelist = passed;
- }
+ if (mMedia)
+ {
+ mMedia->mPassedWhitelist = passed;
+ }
}
BOOL LLViewerObject::setMaterial(const U8 material)
{
- BOOL res = LLPrimitive::setMaterial(material);
- if (res)
- {
- setChanged(TEXTURE);
- }
- return res;
+ BOOL res = LLPrimitive::setMaterial(material);
+ if (res)
+ {
+ setChanged(TEXTURE);
+ }
+ return res;
}
void LLViewerObject::setNumTEs(const U8 num_tes)
{
- U32 i;
- if (num_tes != getNumTEs())
- {
- if (num_tes)
- {
- LLPointer<LLViewerTexture> *new_images;
- new_images = new LLPointer<LLViewerTexture>[num_tes];
-
- LLPointer<LLViewerTexture> *new_normmaps;
- new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
-
- LLPointer<LLViewerTexture> *new_specmaps;
- new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
- for (i = 0; i < num_tes; i++)
- {
- if (i < getNumTEs())
- {
- new_images[i] = mTEImages[i];
- new_normmaps[i] = mTENormalMaps[i];
- new_specmaps[i] = mTESpecularMaps[i];
- }
- else if (getNumTEs())
- {
- new_images[i] = mTEImages[getNumTEs()-1];
- new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
- new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
- }
- else
- {
- new_images[i] = NULL;
- new_normmaps[i] = NULL;
- new_specmaps[i] = NULL;
- }
- }
-
- deleteTEImages();
-
- mTEImages = new_images;
- mTENormalMaps = new_normmaps;
- mTESpecularMaps = new_specmaps;
- }
- else
- {
- deleteTEImages();
- }
+ U32 i;
+ if (num_tes != getNumTEs())
+ {
+ if (num_tes)
+ {
+ LLPointer<LLViewerTexture> *new_images;
+ new_images = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_normmaps;
+ new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_specmaps;
+ new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
+ for (i = 0; i < num_tes; i++)
+ {
+ if (i < getNumTEs())
+ {
+ new_images[i] = mTEImages[i];
+ new_normmaps[i] = mTENormalMaps[i];
+ new_specmaps[i] = mTESpecularMaps[i];
+ }
+ else if (getNumTEs())
+ {
+ new_images[i] = mTEImages[getNumTEs()-1];
+ new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
+ new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
+ }
+ else
+ {
+ new_images[i] = NULL;
+ new_normmaps[i] = NULL;
+ new_specmaps[i] = NULL;
+ }
+ }
+
+ deleteTEImages();
+
+ mTEImages = new_images;
+ mTENormalMaps = new_normmaps;
+ mTESpecularMaps = new_specmaps;
+ }
+ else
+ {
+ deleteTEImages();
+ }
S32 original_tes = getNumTEs();
- LLPrimitive::setNumTEs(num_tes);
- setChanged(TEXTURE);
+ LLPrimitive::setNumTEs(num_tes);
+ setChanged(TEXTURE);
// touch up GLTF materials
if (original_tes > 0)
@@ -4886,124 +5050,124 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
}
}
- if (mDrawable.notNull())
- {
- gPipeline.markTextured(mDrawable);
- }
- }
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
}
void LLViewerObject::sendMaterialUpdate() const
{
- LLViewerRegion* regionp = getRegion();
- if(!regionp) return;
- gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
- gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() );
- gMessageSystem->sendReliable( regionp->getHost() );
+ LLViewerRegion* regionp = getRegion();
+ if(!regionp) return;
+ gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+ gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() );
+ gMessageSystem->sendReliable( regionp->getHost() );
}
//formerly send_object_shape(LLViewerObject *object)
void LLViewerObject::sendShapeUpdate()
{
- gMessageSystem->newMessageFast(_PREHASH_ObjectShape);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+ gMessageSystem->newMessageFast(_PREHASH_ObjectShape);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
- LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem);
+ LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem);
- LLViewerRegion *regionp = getRegion();
- gMessageSystem->sendReliable( regionp->getHost() );
+ LLViewerRegion *regionp = getRegion();
+ gMessageSystem->sendReliable( regionp->getHost() );
}
void LLViewerObject::sendTEUpdate() const
{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ObjectImage);
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ObjectImage);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
- if (mMedia)
- {
- msg->addString("MediaURL", mMedia->mMediaURL);
- }
- else
- {
- msg->addString("MediaURL", NULL);
- }
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+ if (mMedia)
+ {
+ msg->addString("MediaURL", mMedia->mMediaURL);
+ }
+ else
+ {
+ msg->addString("MediaURL", NULL);
+ }
- // TODO send media type
+ // TODO send media type
- packTEMessage(msg);
+ packTEMessage(msg);
- LLViewerRegion *regionp = getRegion();
- msg->sendReliable( regionp->getHost() );
+ LLViewerRegion *regionp = getRegion();
+ msg->sendReliable( regionp->getHost() );
}
LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id)
{
- if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
- {
- return NULL;
- }
-
- LLViewerObject *root = getRootEdit();
- if (root && root->isAnimatedObject())
- {
- return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
-
- LLVOAvatar* avatar = getAvatar();
- if (avatar && !isHUDAttachment())
- {
- LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id);
- LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex);
- if (bakedTexture == NULL || bakedTexture->isMissingAsset())
- {
- return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
- else
- {
- return bakedTexture;
- }
- }
- else
- {
- return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
+ if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ return NULL;
+ }
+
+ LLViewerObject *root = getRootEdit();
+ if (root && root->isAnimatedObject())
+ {
+ return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
+
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar && !isHUDAttachment())
+ {
+ LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id);
+ LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex);
+ if (bakedTexture == NULL || bakedTexture->isMissingAsset())
+ {
+ return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
+ else
+ {
+ return bakedTexture;
+ }
+ }
+ else
+ {
+ return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
}
void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id)
{
- if (id == old_id)
- {
- return;
- }
+ if (id == old_id)
+ {
+ return;
+ }
- if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
- {
- return;
- }
+ if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ return;
+ }
- LLVOAvatar* avatar = getAvatar();
- if (avatar)
- {
- avatar->updateMeshVisibility();
- }
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ avatar->updateMeshVisibility();
+ }
}
@@ -5028,14 +5192,14 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry)
void LLViewerObject::updateTEMaterialTextures(U8 te)
{
- if (getTE(te)->getMaterialParams().notNull())
- {
- const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
- mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-
- const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
- mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
+ if (getTE(te)->getMaterialParams().notNull())
+ {
+ const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
+ mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
+ mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(getTE(te)->getGLTFRenderMaterial()) != nullptr);
@@ -5095,355 +5259,354 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
void LLViewerObject::refreshBakeTexture()
{
- for (int face_index = 0; face_index < getNumTEs(); face_index++)
- {
- LLTextureEntry* tex_entry = getTE(face_index);
- if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()))
- {
- const LLUUID& image_id = tex_entry->getID();
- LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
- changeTEImage(face_index, bakedTexture);
- }
- }
+ for (int face_index = 0; face_index < getNumTEs(); face_index++)
+ {
+ LLTextureEntry* tex_entry = getTE(face_index);
+ if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()))
+ {
+ const LLUUID& image_id = tex_entry->getID();
+ LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
+ changeTEImage(face_index, bakedTexture);
+ }
+ }
}
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
{
- if (mTEImages[te] != imagep)
- {
- LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null;
-
- LLPrimitive::setTETexture(te, imagep->getID());
+ if (mTEImages[te] != imagep)
+ {
+ LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null;
+
+ LLPrimitive::setTETexture(te, imagep->getID());
- LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID());
- mTEImages[te] = baked_texture ? baked_texture : imagep;
- updateAvatarMeshVisibility(imagep->getID(), old_image_id);
- setChanged(TEXTURE);
- if (mDrawable.notNull())
- {
- gPipeline.markTextured(mDrawable);
- }
- }
+ LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID());
+ mTEImages[te] = baked_texture ? baked_texture : imagep;
+ updateAvatarMeshVisibility(imagep->getID(), old_image_id);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
}
S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
{
- LLUUID old_image_id = getTE(te)->getID();
- const LLUUID& uuid = image ? image->getID() : LLUUID::null;
- S32 retval = 0;
- if (uuid != getTE(te)->getID() ||
- uuid == LLUUID::null)
- {
- retval = LLPrimitive::setTETexture(te, uuid);
- LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid);
- mTEImages[te] = baked_texture ? baked_texture : image;
- updateAvatarMeshVisibility(uuid,old_image_id);
- setChanged(TEXTURE);
- if (mDrawable.notNull())
- {
- gPipeline.markTextured(mDrawable);
- }
- }
- return retval;
+ LLUUID old_image_id = getTE(te)->getID();
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ S32 retval = 0;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ retval = LLPrimitive::setTETexture(te, uuid);
+ LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid);
+ mTEImages[te] = baked_texture ? baked_texture : image;
+ updateAvatarMeshVisibility(uuid,old_image_id);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
+ return retval;
}
S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
{
- S32 retval = TEM_CHANGE_TEXTURE;
- const LLUUID& uuid = image ? image->getID() : LLUUID::null;
- if (uuid != getTE(te)->getID() ||
- uuid == LLUUID::null)
- {
- LLTextureEntry* tep = getTE(te);
- LLMaterial* mat = NULL;
- if (tep)
- {
- mat = tep->getMaterialParams();
- }
-
- if (mat)
- {
- mat->setNormalID(uuid);
- }
- }
- changeTENormalMap(te,image);
- return retval;
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setNormalID(uuid);
+ }
+ }
+ changeTENormalMap(te,image);
+ return retval;
}
S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
{
- S32 retval = TEM_CHANGE_TEXTURE;
- const LLUUID& uuid = image ? image->getID() : LLUUID::null;
- if (uuid != getTE(te)->getID() ||
- uuid == LLUUID::null)
- {
- LLTextureEntry* tep = getTE(te);
- LLMaterial* mat = NULL;
- if (tep)
- {
- mat = tep->getMaterialParams();
- }
-
- if (mat)
- {
- mat->setSpecularID(uuid);
- }
- }
- changeTESpecularMap(te, image);
- return retval;
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setSpecularID(uuid);
+ }
+ }
+ changeTESpecularMap(te, image);
+ return retval;
}
//virtual
-void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
+void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
- if(index < 0 || index >= getNumTEs())
- {
- return ;
- }
- mTEImages[index] = new_image ;
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTEImages[index] = new_image ;
}
void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
{
- if(index < 0 || index >= getNumTEs())
- {
- return ;
- }
- mTENormalMaps[index] = new_image ;
- refreshMaterials();
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTENormalMaps[index] = new_image ;
+ refreshMaterials();
}
void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
{
- if(index < 0 || index >= getNumTEs())
- {
- return ;
- }
- mTESpecularMaps[index] = new_image ;
- refreshMaterials();
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTESpecularMaps[index] = new_image ;
+ refreshMaterials();
}
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
{
- // Invalid host == get from the agent's sim
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
- return setTETextureCore(te, image);
+ // Invalid host == get from the agent's sim
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ return setTETextureCore(te, image);
}
S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
{
- LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
- return setTENormalMapCore(te, image);
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ return setTENormalMapCore(te, image);
}
S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
{
- LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
- return setTESpecularMapCore(te, image);
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ return setTESpecularMapCore(te, image);
}
S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
{
- return setTEColor(te, LLColor4(color));
+ return setTEColor(te, LLColor4(color));
}
S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (color != tep->getColor())
- {
- retval = LLPrimitive::setTEColor(te, color);
- if (mDrawable.notNull() && retval)
- {
- // These should only happen on updates which are not the initial update.
- dirtyMesh();
- }
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (color != tep->getColor())
+ {
+ retval = LLPrimitive::setTEColor(te, color);
+ if (mDrawable.notNull() && retval)
+ {
+ // These should only happen on updates which are not the initial update.
+ dirtyMesh();
+ }
+ }
+ return retval;
}
S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (bump != tep->getBumpmap())
- {
- retval = LLPrimitive::setTEBumpmap(te, bump);
- setChanged(TEXTURE);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
- }
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (bump != tep->getBumpmap())
+ {
+ retval = LLPrimitive::setTEBumpmap(te, bump);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ }
+ }
+ return retval;
}
S32 LLViewerObject::setTETexGen(const U8 te, const U8 texgen)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (texgen != tep->getTexGen())
- {
- retval = LLPrimitive::setTETexGen(te, texgen);
- setChanged(TEXTURE);
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (texgen != tep->getTexGen())
+ {
+ retval = LLPrimitive::setTETexGen(te, texgen);
+ setChanged(TEXTURE);
+ }
+ return retval;
}
S32 LLViewerObject::setTEMediaTexGen(const U8 te, const U8 media)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (media != tep->getMediaTexGen())
- {
- retval = LLPrimitive::setTEMediaTexGen(te, media);
- setChanged(TEXTURE);
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (media != tep->getMediaTexGen())
+ {
+ retval = LLPrimitive::setTEMediaTexGen(te, media);
+ setChanged(TEXTURE);
+ }
+ return retval;
}
S32 LLViewerObject::setTEShiny(const U8 te, const U8 shiny)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (shiny != tep->getShiny())
- {
- retval = LLPrimitive::setTEShiny(te, shiny);
- setChanged(TEXTURE);
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (shiny != tep->getShiny())
+ {
+ retval = LLPrimitive::setTEShiny(te, shiny);
+ setChanged(TEXTURE);
+ }
+ return retval;
}
S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (fullbright != tep->getFullbright())
- {
- retval = LLPrimitive::setTEFullbright(te, fullbright);
- setChanged(TEXTURE);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markTextured(mDrawable);
- }
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (fullbright != tep->getFullbright())
+ {
+ retval = LLPrimitive::setTEFullbright(te, fullbright);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
+ return retval;
}
-
S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
{
- // this might need work for media type
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (media_flags != tep->getMediaFlags())
- {
- retval = LLPrimitive::setTEMediaFlags(te, media_flags);
- setChanged(TEXTURE);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- gPipeline.markTextured(mDrawable);
- }
- }
- return retval;
+ // this might need work for media type
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (media_flags != tep->getMediaFlags())
+ {
+ retval = LLPrimitive::setTEMediaFlags(te, media_flags);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ gPipeline.markTextured(mDrawable);
+ }
+ }
+ return retval;
}
S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (glow != tep->getGlow())
- {
- retval = LLPrimitive::setTEGlow(te, glow);
- setChanged(TEXTURE);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markTextured(mDrawable);
- }
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (glow != tep->getGlow())
+ {
+ retval = LLPrimitive::setTEGlow(te, glow);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
+ return retval;
}
S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS("Material") << "No texture entry for te " << (S32)te
- << ", object " << mID
- << ", material " << pMaterialID
- << LL_ENDL;
- }
- //else if (pMaterialID != tep->getMaterialID())
- {
- LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
- << ", object " << mID
- << ", material " << pMaterialID
- << LL_ENDL;
- retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
- refreshMaterials();
- }
- return retval;
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS("Material") << "No texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ }
+ //else if (pMaterialID != tep->getMaterialID())
+ {
+ LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
+ refreshMaterials();
+ }
+ return retval;
}
S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- return 0;
- }
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ return 0;
+ }
- retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
- LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
- << ", object " << mID
- << " (" << retval << ")"
- << LL_ENDL;
- setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
- setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
+ retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
+ << ", object " << mID
+ << " (" << retval << ")"
+ << LL_ENDL;
+ setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
+ setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
- return retval;
+ return retval;
}
S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
@@ -5503,287 +5666,287 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
void LLViewerObject::refreshMaterials()
{
- setChanged(TEXTURE);
- if (mDrawable.notNull())
- {
- gPipeline.markTextured(mDrawable);
- }
+ setChanged(TEXTURE);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ }
}
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
{
- S32 retval = 0;
- retval = LLPrimitive::setTEScale(te, s, t);
- setChanged(TEXTURE);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
- return retval;
+ S32 retval = 0;
+ retval = LLPrimitive::setTEScale(te, s, t);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
+ return retval;
}
S32 LLViewerObject::setTEScaleS(const U8 te, const F32 s)
{
- S32 retval = LLPrimitive::setTEScaleS(te, s);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
+ S32 retval = LLPrimitive::setTEScaleS(te, s);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
- return retval;
+ return retval;
}
S32 LLViewerObject::setTEScaleT(const U8 te, const F32 t)
{
- S32 retval = LLPrimitive::setTEScaleT(te, t);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
+ S32 retval = LLPrimitive::setTEScaleT(te, t);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
- return retval;
+ return retval;
}
S32 LLViewerObject::setTEOffset(const U8 te, const F32 s, const F32 t)
{
- S32 retval = LLPrimitive::setTEOffset(te, s, t);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
- return retval;
+ S32 retval = LLPrimitive::setTEOffset(te, s, t);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
+ return retval;
}
S32 LLViewerObject::setTEOffsetS(const U8 te, const F32 s)
{
- S32 retval = LLPrimitive::setTEOffsetS(te, s);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
+ S32 retval = LLPrimitive::setTEOffsetS(te, s);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
- return retval;
+ return retval;
}
S32 LLViewerObject::setTEOffsetT(const U8 te, const F32 t)
{
- S32 retval = LLPrimitive::setTEOffsetT(te, t);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
+ S32 retval = LLPrimitive::setTEOffsetT(te, t);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
- return retval;
+ return retval;
}
S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
{
- S32 retval = LLPrimitive::setTERotation(te, r);
- if (mDrawable.notNull() && retval)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ S32 retval = LLPrimitive::setTERotation(te, r);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
shrinkWrap();
- }
- return retval;
+ }
+ return retval;
}
LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
{
-// llassert(mTEImages);
+// llassert(mTEImages);
- if (face < getNumTEs())
- {
- LLViewerTexture* image = mTEImages[face];
- if (image)
- {
- return image;
- }
- else
- {
- return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
- }
- }
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTEImages[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
- LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
+ LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
- return NULL;
+ return NULL;
}
bool LLViewerObject::isImageAlphaBlended(const U8 te) const
{
- LLViewerTexture* image = getTEImage(te);
- LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
- switch (format)
- {
- case GL_RGBA:
- case GL_ALPHA:
- {
- return true;
- }
- break;
+ LLViewerTexture* image = getTEImage(te);
+ LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
+ switch (format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ return true;
+ }
+ break;
- case GL_RGB: break;
- default:
- {
- LL_WARNS() << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << LL_ENDL;
- }
- break;
- }
+ case GL_RGB: break;
+ default:
+ {
+ LL_WARNS() << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << LL_ENDL;
+ }
+ break;
+ }
- return false;
+ return false;
}
LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
{
- // llassert(mTEImages);
-
- if (face < getNumTEs())
- {
- LLViewerTexture* image = mTENormalMaps[face];
- if (image)
- {
- return image;
- }
- else
- {
- return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
- }
- }
-
- LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
-
- return NULL;
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTENormalMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
+
+ return NULL;
}
LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const
{
- // llassert(mTEImages);
-
- if (face < getNumTEs())
- {
- LLViewerTexture* image = mTESpecularMaps[face];
- if (image)
- {
- return image;
- }
- else
- {
- return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
- }
- }
-
- LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
-
- return NULL;
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTESpecularMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ LL_ERRS() << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << LL_ENDL;
+
+ return NULL;
}
void LLViewerObject::fitFaceTexture(const U8 face)
{
- LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
+ LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
}
LLBBox LLViewerObject::getBoundingBoxAgent() const
{
- LLVector3 position_agent;
- LLQuaternion rot;
- LLViewerObject* avatar_parent = NULL;
- LLViewerObject* root_edit = (LLViewerObject*)getRootEdit();
- if (root_edit)
- {
- avatar_parent = (LLViewerObject*)root_edit->getParent();
- }
-
- if (avatar_parent && avatar_parent->isAvatar() &&
- root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent())
- {
- LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent();
- position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
- rot = getRotationEdit() * parent_xform->getWorldRotation();
- }
- else
- {
- position_agent = getPositionAgent();
- rot = getRotationRegion();
- }
-
- return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f );
+ LLVector3 position_agent;
+ LLQuaternion rot;
+ LLViewerObject* avatar_parent = NULL;
+ LLViewerObject* root_edit = (LLViewerObject*)getRootEdit();
+ if (root_edit)
+ {
+ avatar_parent = (LLViewerObject*)root_edit->getParent();
+ }
+
+ if (avatar_parent && avatar_parent->isAvatar() &&
+ root_edit && root_edit->mDrawable.notNull() && root_edit->mDrawable->getXform()->getParent())
+ {
+ LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent();
+ position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
+ rot = getRotationEdit() * parent_xform->getWorldRotation();
+ }
+ else
+ {
+ position_agent = getPositionAgent();
+ rot = getRotationRegion();
+ }
+
+ return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f );
}
U32 LLViewerObject::getNumVertices() const
{
- U32 num_vertices = 0;
- if (mDrawable.notNull())
- {
- S32 i, num_faces;
- num_faces = mDrawable->getNumFaces();
- for (i = 0; i < num_faces; i++)
- {
- LLFace * facep = mDrawable->getFace(i);
- if (facep)
- {
- num_vertices += facep->getGeomCount();
- }
- }
- }
- return num_vertices;
+ U32 num_vertices = 0;
+ if (mDrawable.notNull())
+ {
+ S32 i, num_faces;
+ num_faces = mDrawable->getNumFaces();
+ for (i = 0; i < num_faces; i++)
+ {
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_vertices += facep->getGeomCount();
+ }
+ }
+ }
+ return num_vertices;
}
U32 LLViewerObject::getNumIndices() const
{
- U32 num_indices = 0;
- if (mDrawable.notNull())
- {
- S32 i, num_faces;
- num_faces = mDrawable->getNumFaces();
- for (i = 0; i < num_faces; i++)
- {
- LLFace * facep = mDrawable->getFace(i);
- if (facep)
- {
- num_indices += facep->getIndicesCount();
- }
- }
- }
- return num_indices;
+ U32 num_indices = 0;
+ if (mDrawable.notNull())
+ {
+ S32 i, num_faces;
+ num_faces = mDrawable->getNumFaces();
+ for (i = 0; i < num_faces; i++)
+ {
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_indices += facep->getIndicesCount();
+ }
+ }
+ }
+ return num_indices;
}
// Find the number of instances of this object's inventory that are of the given type
S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
{
- S32 count = 0;
- if( mInventory )
- {
- LLInventoryObject::object_list_t::const_iterator it = mInventory->begin();
- LLInventoryObject::object_list_t::const_iterator end = mInventory->end();
- for( ; it != end ; ++it )
- {
- if( (*it)->getType() == type )
- {
- ++count;
- }
- }
- }
- return count;
+ S32 count = 0;
+ if( mInventory )
+ {
+ LLInventoryObject::object_list_t::const_iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::const_iterator end = mInventory->end();
+ for( ; it != end ; ++it )
+ {
+ if( (*it)->getType() == type )
+ {
+ ++count;
+ }
+ }
+ }
+ return count;
}
void LLViewerObject::setDebugText(const std::string &utf8text, const LLColor4& color)
{
- if (utf8text.empty() && !mText)
- {
- return;
- }
+ if (utf8text.empty() && !mText)
+ {
+ return;
+ }
- if (!mText)
- {
- initHudText();
- }
- mText->setColor(color);
- mText->setString(utf8text);
- mText->setZCompare(FALSE);
- mText->setDoFade(FALSE);
- updateText();
+ if (!mText)
+ {
+ initHudText();
+ }
+ mText->setColor(color);
+ mText->setString(utf8text);
+ mText->setZCompare(FALSE);
+ mText->setDoFade(FALSE);
+ updateText();
}
void LLViewerObject::appendDebugText(const std::string &utf8text)
@@ -5842,98 +6005,98 @@ void LLViewerObject::restoreHudText()
void LLViewerObject::setIcon(LLViewerTexture* icon_image)
{
- if (!mIcon)
- {
- mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON);
- mIcon->setSourceObject(this);
- mIcon->setImage(icon_image);
- // *TODO: make this user configurable
- mIcon->setScale(0.03f);
- }
- else
- {
- mIcon->restartLifeTimer();
- }
+ if (!mIcon)
+ {
+ mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON);
+ mIcon->setSourceObject(this);
+ mIcon->setImage(icon_image);
+ // *TODO: make this user configurable
+ mIcon->setScale(0.03f);
+ }
+ else
+ {
+ mIcon->restartLifeTimer();
+ }
}
void LLViewerObject::clearIcon()
{
- if (mIcon)
- {
- mIcon = NULL;
- }
+ if (mIcon)
+ {
+ mIcon = NULL;
+ }
}
-LLViewerObject* LLViewerObject::getSubParent()
-{
- return (LLViewerObject*) getParent();
+LLViewerObject* LLViewerObject::getSubParent()
+{
+ return (LLViewerObject*) getParent();
}
const LLViewerObject* LLViewerObject::getSubParent() const
{
- return (const LLViewerObject*) getParent();
+ return (const LLViewerObject*) getParent();
}
BOOL LLViewerObject::isOnMap()
{
- return mOnMap;
+ return mOnMap;
}
void LLViewerObject::updateText()
{
- if (!isDead())
- {
- if (mText.notNull())
- {
- LLVOAvatar* avatar = getAvatar();
- if (avatar)
- {
- mText->setHidden(avatar->isInMuteList());
- }
-
- LLVector3 up_offset(0,0,0);
- up_offset.mV[2] = getScale().mV[VZ]*0.6f;
-
- if (mDrawable.notNull())
- {
- mText->setPositionAgent(getRenderPosition() + up_offset);
- }
- else
- {
- mText->setPositionAgent(getPositionAgent() + up_offset);
- }
- }
- }
+ if (!isDead())
+ {
+ if (mText.notNull())
+ {
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ mText->setHidden(avatar->isInMuteList());
+ }
+
+ LLVector3 up_offset(0,0,0);
+ up_offset.mV[2] = getScale().mV[VZ]*0.6f;
+
+ if (mDrawable.notNull())
+ {
+ mText->setPositionAgent(getRenderPosition() + up_offset);
+ }
+ else
+ {
+ mText->setPositionAgent(getPositionAgent() + up_offset);
+ }
+ }
+ }
}
bool LLViewerObject::isOwnerInMuteList(LLUUID id)
{
- LLUUID owner_id = id.isNull() ? mOwnerID : id;
- if (isAvatar() || owner_id.isNull())
- {
- return false;
- }
- bool muted = false;
- F64 now = LLFrameTimer::getTotalSeconds();
- if (now < mCachedMuteListUpdateTime)
- {
- muted = mCachedOwnerInMuteList;
- }
- else
- {
- muted = LLMuteList::getInstance()->isMuted(owner_id);
-
- const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
- mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
- mCachedOwnerInMuteList = muted;
- }
- return muted;
+ LLUUID owner_id = id.isNull() ? mOwnerID : id;
+ if (isAvatar() || owner_id.isNull())
+ {
+ return false;
+ }
+ bool muted = false;
+ F64 now = LLFrameTimer::getTotalSeconds();
+ if (now < mCachedMuteListUpdateTime)
+ {
+ muted = mCachedOwnerInMuteList;
+ }
+ else
+ {
+ muted = LLMuteList::getInstance()->isMuted(owner_id);
+
+ const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
+ mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
+ mCachedOwnerInMuteList = muted;
+ }
+ return muted;
}
LLVOAvatar* LLViewerObject::asAvatar()
{
- return NULL;
+ return NULL;
}
// If this object is directly or indirectly parented by an avatar,
@@ -5945,348 +6108,348 @@ LLVOAvatar* LLViewerObject::asAvatar()
// attached.
LLVOAvatar* LLViewerObject::getAvatarAncestor()
{
- LLViewerObject *pobj = (LLViewerObject*) getParent();
- while (pobj)
- {
- LLVOAvatar *av = pobj->asAvatar();
- if (av)
- {
- return av;
- }
- pobj = (LLViewerObject*) pobj->getParent();
- }
- return NULL;
+ LLViewerObject *pobj = (LLViewerObject*) getParent();
+ while (pobj)
+ {
+ LLVOAvatar *av = pobj->asAvatar();
+ if (av)
+ {
+ return av;
+ }
+ pobj = (LLViewerObject*) pobj->getParent();
+ }
+ return NULL;
}
BOOL LLViewerObject::isParticleSource() const
{
- return !mPartSourcep.isNull() && !mPartSourcep->isDead();
+ return !mPartSourcep.isNull() && !mPartSourcep->isDead();
}
void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id)
{
- if (mPartSourcep)
- {
- deleteParticleSource();
- }
-
- LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters);
- mPartSourcep = pss;
-
- if (mPartSourcep)
- {
- mPartSourcep->setOwnerUUID(owner_id);
-
- if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
- {
- LLViewerTexture* image;
- if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
- {
- image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga");
- }
- else
- {
- image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
- }
- mPartSourcep->setImage(image);
- }
- }
- LLViewerPartSim::getInstance()->addPartSource(pss);
+ if (mPartSourcep)
+ {
+ deleteParticleSource();
+ }
+
+ LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters);
+ mPartSourcep = pss;
+
+ if (mPartSourcep)
+ {
+ mPartSourcep->setOwnerUUID(owner_id);
+
+ if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+ {
+ LLViewerTexture* image;
+ if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+ {
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga");
+ }
+ else
+ {
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+ }
+ mPartSourcep->setImage(image);
+ }
+ }
+ LLViewerPartSim::getInstance()->addPartSource(pss);
}
void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id)
{
- if (!mPartSourcep.isNull() && mPartSourcep->isDead())
- {
- mPartSourcep = NULL;
- }
- if (mPartSourcep)
- {
- // If we've got one already, just update the existing source (or remove it)
- if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num))
- {
- mPartSourcep->setDead();
- mPartSourcep = NULL;
- }
- }
- else
- {
- LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
- //If the owner is muted, don't create the system
- if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
-
- // We need to be able to deal with a particle source that hasn't changed, but still got an update!
- if (pss)
- {
-// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL;
- pss->setOwnerUUID(owner_id);
- mPartSourcep = pss;
- LLViewerPartSim::getInstance()->addPartSource(pss);
- }
- }
- if (mPartSourcep)
- {
- if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
- {
- LLViewerTexture* image;
- if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
- {
- image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
- }
- else
- {
- image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
- }
- mPartSourcep->setImage(image);
- }
- }
+ if (!mPartSourcep.isNull() && mPartSourcep->isDead())
+ {
+ mPartSourcep = NULL;
+ }
+ if (mPartSourcep)
+ {
+ // If we've got one already, just update the existing source (or remove it)
+ if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num))
+ {
+ mPartSourcep->setDead();
+ mPartSourcep = NULL;
+ }
+ }
+ else
+ {
+ LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
+ //If the owner is muted, don't create the system
+ if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
+
+ // We need to be able to deal with a particle source that hasn't changed, but still got an update!
+ if (pss)
+ {
+// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL;
+ pss->setOwnerUUID(owner_id);
+ mPartSourcep = pss;
+ LLViewerPartSim::getInstance()->addPartSource(pss);
+ }
+ }
+ if (mPartSourcep)
+ {
+ if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+ {
+ LLViewerTexture* image;
+ if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+ {
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
+ }
+ else
+ {
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+ }
+ mPartSourcep->setImage(image);
+ }
+ }
}
void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy)
{
- if (!mPartSourcep.isNull() && mPartSourcep->isDead())
- {
- mPartSourcep = NULL;
- }
- if (mPartSourcep)
- {
- // If we've got one already, just update the existing source (or remove it)
- if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))
- {
- mPartSourcep->setDead();
- mPartSourcep = NULL;
- }
- }
- else
- {
- LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);
- //If the owner is muted, don't create the system
- if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
- // We need to be able to deal with a particle source that hasn't changed, but still got an update!
- if (pss)
- {
-// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL;
- pss->setOwnerUUID(owner_id);
- mPartSourcep = pss;
- LLViewerPartSim::getInstance()->addPartSource(pss);
- }
- }
- if (mPartSourcep)
- {
- if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
- {
- LLViewerTexture* image;
- if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
- {
- image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
- }
- else
- {
- image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
- }
- mPartSourcep->setImage(image);
- }
- }
+ if (!mPartSourcep.isNull() && mPartSourcep->isDead())
+ {
+ mPartSourcep = NULL;
+ }
+ if (mPartSourcep)
+ {
+ // If we've got one already, just update the existing source (or remove it)
+ if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))
+ {
+ mPartSourcep->setDead();
+ mPartSourcep = NULL;
+ }
+ }
+ else
+ {
+ LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);
+ //If the owner is muted, don't create the system
+ if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
+ // We need to be able to deal with a particle source that hasn't changed, but still got an update!
+ if (pss)
+ {
+// LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL;
+ pss->setOwnerUUID(owner_id);
+ mPartSourcep = pss;
+ LLViewerPartSim::getInstance()->addPartSource(pss);
+ }
+ }
+ if (mPartSourcep)
+ {
+ if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
+ {
+ LLViewerTexture* image;
+ if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
+ {
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
+ }
+ else
+ {
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
+ }
+ mPartSourcep->setImage(image);
+ }
+ }
}
void LLViewerObject::deleteParticleSource()
{
- if (mPartSourcep.notNull())
- {
- mPartSourcep->setDead();
- mPartSourcep = NULL;
- }
+ if (mPartSourcep.notNull())
+ {
+ mPartSourcep->setDead();
+ mPartSourcep = NULL;
+ }
}
// virtual
void LLViewerObject::updateDrawable(BOOL force_damped)
{
- if (!isChanged(MOVED))
- { //most common case, having an empty if case here makes for better branch prediction
- }
- else if (mDrawable.notNull() &&
- !mDrawable->isState(LLDrawable::ON_MOVE_LIST))
- {
- BOOL damped_motion =
- !isChanged(SHIFTED) && // not shifted between regions this frame and...
- ( force_damped || // ...forced into damped motion by application logic or...
- ( !isSelected() && // ...not selected and...
- ( mDrawable->isRoot() || // ... is root or ...
- (getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ...
- ) &&
- getPCode() == LL_PCODE_VOLUME && // ...is a volume object and...
- getVelocity().isExactlyZero() && // ...is not moving physically and...
- mDrawable->getGeneration() != -1 // ...was not created this frame.
- )
- );
- gPipeline.markMoved(mDrawable, damped_motion);
- }
- clearChanged(SHIFTED);
+ if (!isChanged(MOVED))
+ { //most common case, having an empty if case here makes for better branch prediction
+ }
+ else if (mDrawable.notNull() &&
+ !mDrawable->isState(LLDrawable::ON_MOVE_LIST))
+ {
+ BOOL damped_motion =
+ !isChanged(SHIFTED) && // not shifted between regions this frame and...
+ ( force_damped || // ...forced into damped motion by application logic or...
+ ( !isSelected() && // ...not selected and...
+ ( mDrawable->isRoot() || // ... is root or ...
+ (getParent() && !((LLViewerObject*)getParent())->isSelected())// ... parent is not selected and ...
+ ) &&
+ getPCode() == LL_PCODE_VOLUME && // ...is a volume object and...
+ getVelocity().isExactlyZero() && // ...is not moving physically and...
+ mDrawable->getGeneration() != -1 // ...was not created this frame.
+ )
+ );
+ gPipeline.markMoved(mDrawable, damped_motion);
+ }
+ clearChanged(SHIFTED);
}
// virtual, overridden by LLVOVolume
F32 LLViewerObject::getVObjRadius() const
{
- return mDrawable.notNull() ? mDrawable->getRadius() : 0.f;
+ return mDrawable.notNull() ? mDrawable->getRadius() : 0.f;
}
void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags)
{
- if (!gAudiop)
- {
- return;
- }
-
- if (audio_uuid.isNull())
- {
- if (!mAudioSourcep)
- {
- return;
- }
- if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
- {
- // We don't clear the sound if it's a loop, it'll go away on its own.
- // At least, this appears to be how the scripts work.
- // The attached sound ID is set to NULL to avoid it playing back when the
- // object rezzes in on non-looping sounds.
- //LL_INFOS() << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << LL_ENDL;
- gAudiop->cleanupAudioSource(mAudioSourcep);
- mAudioSourcep = NULL;
- }
- else if (flags & LL_SOUND_FLAG_STOP)
- {
- // Just shut off the sound
- mAudioSourcep->stop();
- }
- return;
- }
- if (flags & LL_SOUND_FLAG_LOOP
- && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData()
- && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
- {
- //LL_INFOS() << "Already playing this sound on a loop, ignoring" << LL_ENDL;
- return;
- }
-
- // don't clean up before previous sound is done. Solves: SL-33486
- if ( mAudioSourcep && mAudioSourcep->isDone() )
- {
- gAudiop->cleanupAudioSource(mAudioSourcep);
- mAudioSourcep = NULL;
- }
-
- if (mAudioSourcep && mAudioSourcep->isMuted() &&
- mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
- {
- //LL_INFOS() << "Already having this sound as muted sound, ignoring" << LL_ENDL;
- return;
- }
-
- getAudioSource(owner_id);
-
- if (mAudioSourcep)
- {
- BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
- mAudioGain = gain;
- mAudioSourcep->setGain(gain);
- mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
- mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
- mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
- mAudioSourcep->setQueueSounds(queue);
- if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
- {
- mAudioSourcep->stop();
- }
-
- // Play this sound if region maturity permits
- if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
- {
- //LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL;
- // recheck cutoff radius in case this update was an object-update with new value
- mAudioSourcep->checkCutOffRadius();
- mAudioSourcep->play(audio_uuid);
- }
- }
+ if (!gAudiop)
+ {
+ return;
+ }
+
+ if (audio_uuid.isNull())
+ {
+ if (!mAudioSourcep)
+ {
+ return;
+ }
+ if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
+ {
+ // We don't clear the sound if it's a loop, it'll go away on its own.
+ // At least, this appears to be how the scripts work.
+ // The attached sound ID is set to NULL to avoid it playing back when the
+ // object rezzes in on non-looping sounds.
+ //LL_INFOS() << "Clearing attached sound " << mAudioSourcep->getCurrentData()->getID() << LL_ENDL;
+ gAudiop->cleanupAudioSource(mAudioSourcep);
+ mAudioSourcep = NULL;
+ }
+ else if (flags & LL_SOUND_FLAG_STOP)
+ {
+ // Just shut off the sound
+ mAudioSourcep->stop();
+ }
+ return;
+ }
+ if (flags & LL_SOUND_FLAG_LOOP
+ && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData()
+ && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
+ {
+ //LL_INFOS() << "Already playing this sound on a loop, ignoring" << LL_ENDL;
+ return;
+ }
+
+ // don't clean up before previous sound is done. Solves: SL-33486
+ if ( mAudioSourcep && mAudioSourcep->isDone() )
+ {
+ gAudiop->cleanupAudioSource(mAudioSourcep);
+ mAudioSourcep = NULL;
+ }
+
+ if (mAudioSourcep && mAudioSourcep->isMuted() &&
+ mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
+ {
+ //LL_INFOS() << "Already having this sound as muted sound, ignoring" << LL_ENDL;
+ return;
+ }
+
+ getAudioSource(owner_id);
+
+ if (mAudioSourcep)
+ {
+ BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
+ mAudioGain = gain;
+ mAudioSourcep->setGain(gain);
+ mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
+ mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
+ mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
+ mAudioSourcep->setQueueSounds(queue);
+ if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
+ {
+ mAudioSourcep->stop();
+ }
+
+ // Play this sound if region maturity permits
+ if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
+ {
+ //LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL;
+ // recheck cutoff radius in case this update was an object-update with new value
+ mAudioSourcep->checkCutOffRadius();
+ mAudioSourcep->play(audio_uuid);
+ }
+ }
}
LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id)
{
- if (!mAudioSourcep)
- {
- // Arbitrary low gain for a sound that's not playing.
- // This is used for sound preloads, for example.
- LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this);
+ if (!mAudioSourcep)
+ {
+ // Arbitrary low gain for a sound that's not playing.
+ // This is used for sound preloads, for example.
+ LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this);
- mAudioSourcep = asvop;
- if(gAudiop)
- {
- gAudiop->addAudioSource(asvop);
- }
- }
+ mAudioSourcep = asvop;
+ if(gAudiop)
+ {
+ gAudiop->addAudioSource(asvop);
+ }
+ }
- return mAudioSourcep;
+ return mAudioSourcep;
}
void LLViewerObject::adjustAudioGain(const F32 gain)
{
- if (mAudioSourcep)
- {
- mAudioGain = gain;
- mAudioSourcep->setGain(mAudioGain);
- }
+ if (mAudioSourcep)
+ {
+ mAudioGain = gain;
+ mAudioSourcep->setGain(mAudioGain);
+ }
}
//----------------------------------------------------------------------------
bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
{
- if (LLNetworkData::PARAMS_MESH == param_type)
- {
- param_type = LLNetworkData::PARAMS_SCULPT;
- }
- ExtraParameter* param = getExtraParameterEntryCreate(param_type);
- if (param)
- {
- param->data->unpack(*dp);
- param->in_use = TRUE;
- parameterChanged(param_type, param->data, TRUE, false);
- return true;
- }
- else
- {
- return false;
- }
+ if (LLNetworkData::PARAMS_MESH == param_type)
+ {
+ param_type = LLNetworkData::PARAMS_SCULPT;
+ }
+ ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+ if (param)
+ {
+ param->data->unpack(*dp);
+ param->in_use = TRUE;
+ parameterChanged(param_type, param->data, TRUE, false);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
{
- LLNetworkData* new_block = NULL;
- switch (param_type)
- {
- case LLNetworkData::PARAMS_FLEXIBLE:
- {
- new_block = new LLFlexibleObjectData();
- break;
- }
- case LLNetworkData::PARAMS_LIGHT:
- {
- new_block = new LLLightParams();
- break;
- }
- case LLNetworkData::PARAMS_SCULPT:
- {
- new_block = new LLSculptParams();
- break;
- }
- case LLNetworkData::PARAMS_LIGHT_IMAGE:
- {
- new_block = new LLLightImageParams();
- break;
- }
+ LLNetworkData* new_block = NULL;
+ switch (param_type)
+ {
+ case LLNetworkData::PARAMS_FLEXIBLE:
+ {
+ new_block = new LLFlexibleObjectData();
+ break;
+ }
+ case LLNetworkData::PARAMS_LIGHT:
+ {
+ new_block = new LLLightParams();
+ break;
+ }
+ case LLNetworkData::PARAMS_SCULPT:
+ {
+ new_block = new LLSculptParams();
+ break;
+ }
+ case LLNetworkData::PARAMS_LIGHT_IMAGE:
+ {
+ new_block = new LLLightImageParams();
+ break;
+ }
case LLNetworkData::PARAMS_EXTENDED_MESH:
{
- new_block = new LLExtendedMeshParams();
- break;
+ new_block = new LLExtendedMeshParams();
+ break;
}
case LLNetworkData::PARAMS_RENDER_MATERIAL:
{
@@ -6298,90 +6461,90 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLReflectionProbeParams();
break;
}
- default:
- {
- LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL;
- break;
- }
- };
-
- if (new_block)
- {
- ExtraParameter* new_entry = new ExtraParameter;
- new_entry->data = new_block;
- new_entry->in_use = false; // not in use yet
+ default:
+ {
+ LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL;
+ break;
+ }
+ };
+
+ if (new_block)
+ {
+ ExtraParameter* new_entry = new ExtraParameter;
+ new_entry->data = new_block;
+ new_entry->in_use = false; // not in use yet
llassert(mExtraParameterList[param_type] == nullptr); // leak -- redundantly allocated parameter entry
- mExtraParameterList[param_type] = new_entry;
- return new_entry;
- }
- return NULL;
+ mExtraParameterList[param_type] = new_entry;
+ return new_entry;
+ }
+ return NULL;
}
LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
- std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
- if (itor != mExtraParameterList.end())
- {
- return itor->second;
- }
- return NULL;
+ std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
+ if (itor != mExtraParameterList.end())
+ {
+ return itor->second;
+ }
+ return NULL;
}
LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (!param)
- {
- param = createNewParameterEntry(param_type);
- }
- return param;
+ ExtraParameter* param = getExtraParameterEntry(param_type);
+ if (!param)
+ {
+ param = createNewParameterEntry(param_type);
+ }
+ return param;
}
LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->data;
- }
- else
- {
- return NULL;
- }
+ ExtraParameter* param = getExtraParameterEntry(param_type);
+ if (param)
+ {
+ return param->data;
+ }
+ else
+ {
+ return NULL;
+ }
}
BOOL LLViewerObject::getParameterEntryInUse(U16 param_type) const
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->in_use;
- }
- else
- {
- return FALSE;
- }
+ ExtraParameter* param = getExtraParameterEntry(param_type);
+ if (param)
+ {
+ return param->in_use;
+ }
+ else
+ {
+ return FALSE;
+ }
}
bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntryCreate(param_type);
- if (param)
- {
- if (param->in_use && new_value == *(param->data))
- {
- return false;
- }
- param->in_use = true;
- param->data->copy(new_value);
- parameterChanged(param_type, param->data, TRUE, local_origin);
- return true;
- }
- else
- {
- return false;
- }
+ ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+ if (param)
+ {
+ if (param->in_use && new_value == *(param->data))
+ {
+ return false;
+ }
+ param->in_use = true;
+ param->data->copy(new_value);
+ parameterChanged(param_type, param->data, TRUE, local_origin);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
// Assumed to be called locally
@@ -6389,65 +6552,65 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
// Should always return true.
bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntryCreate(param_type);
- if (param && param->in_use != in_use)
- {
- param->in_use = in_use;
- parameterChanged(param_type, param->data, in_use, local_origin);
- return true;
- }
- return false;
+ ExtraParameter* param = getExtraParameterEntryCreate(param_type);
+ if (param && param->in_use != in_use)
+ {
+ param->in_use = in_use;
+ parameterChanged(param_type, param->data, in_use, local_origin);
+ return true;
+ }
+ return false;
}
void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- parameterChanged(param_type, param->data, param->in_use, local_origin);
- }
+ ExtraParameter* param = getExtraParameterEntry(param_type);
+ if (param)
+ {
+ parameterChanged(param_type, param->data, param->in_use, local_origin);
+ }
}
void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
{
- if (local_origin)
- {
+ if (local_origin)
+ {
// *NOTE: Do not send the render material ID in this way as it will get
// out-of-sync with other sent client data.
// See LLViewerObject::setRenderMaterialID and LLGLTFMaterialList
llassert(param_type != LLNetworkData::PARAMS_RENDER_MATERIAL);
- LLViewerRegion* regionp = getRegion();
- if(!regionp) return;
-
- // Change happened on the viewer. Send the change up
- U8 tmp[MAX_OBJECT_PARAMS_SIZE];
- LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE);
- if (data->pack(dpb))
- {
- U32 datasize = (U32)dpb.getCurrentSize();
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ObjectExtraParams);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
-
- msg->addU16Fast(_PREHASH_ParamType, param_type);
- msg->addBOOLFast(_PREHASH_ParamInUse, in_use);
-
- msg->addU32Fast(_PREHASH_ParamSize, datasize);
- msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize);
-
- msg->sendReliable( regionp->getHost() );
- }
- else
- {
- LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL;
- }
- }
+ LLViewerRegion* regionp = getRegion();
+ if(!regionp) return;
+
+ // Change happened on the viewer. Send the change up
+ U8 tmp[MAX_OBJECT_PARAMS_SIZE];
+ LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE);
+ if (data->pack(dpb))
+ {
+ U32 datasize = (U32)dpb.getCurrentSize();
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ObjectExtraParams);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
+
+ msg->addU16Fast(_PREHASH_ParamType, param_type);
+ msg->addBOOLFast(_PREHASH_ParamInUse, in_use);
+
+ msg->addU32Fast(_PREHASH_ParamSize, datasize);
+ msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize);
+
+ msg->sendReliable( regionp->getHost() );
+ }
+ else
+ {
+ LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL;
+ }
+ }
else
{
if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
@@ -6460,256 +6623,256 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
{
- if (mDrawable)
- {
- mDrawable->setState(state);
- }
- if (recursive)
- {
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->setDrawableState(state, recursive);
- }
- }
+ if (mDrawable)
+ {
+ mDrawable->setState(state);
+ }
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ child->setDrawableState(state, recursive);
+ }
+ }
}
void LLViewerObject::clearDrawableState(U32 state, BOOL recursive)
{
- if (mDrawable)
- {
- mDrawable->clearState(state);
- }
- if (recursive)
- {
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->clearDrawableState(state, recursive);
- }
- }
+ if (mDrawable)
+ {
+ mDrawable->clearState(state);
+ }
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ child->clearDrawableState(state, recursive);
+ }
+ }
}
BOOL LLViewerObject::isDrawableState(U32 state, BOOL recursive) const
{
- BOOL matches = FALSE;
- if (mDrawable)
- {
- matches = mDrawable->isState(state);
- }
- if (recursive)
- {
- for (child_list_t::const_iterator iter = mChildList.begin();
- (iter != mChildList.end()) && matches; iter++)
- {
- LLViewerObject* child = *iter;
- matches &= child->isDrawableState(state, recursive);
- }
- }
+ BOOL matches = FALSE;
+ if (mDrawable)
+ {
+ matches = mDrawable->isState(state);
+ }
+ if (recursive)
+ {
+ for (child_list_t::const_iterator iter = mChildList.begin();
+ (iter != mChildList.end()) && matches; iter++)
+ {
+ LLViewerObject* child = *iter;
+ matches &= child->isDrawableState(state, recursive);
+ }
+ }
- return matches;
+ return matches;
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// RN: these functions assume a 2-level hierarchy
+// RN: these functions assume a 2-level hierarchy
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Owned by anyone?
BOOL LLViewerObject::permAnyOwner() const
-{
- if (isRootEdit())
- {
- return flagObjectAnyOwner();
- }
- else
- {
- return ((LLViewerObject*)getParent())->permAnyOwner();
- }
-}
+{
+ if (isRootEdit())
+ {
+ return flagObjectAnyOwner();
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permAnyOwner();
+ }
+}
// Owned by this viewer?
BOOL LLViewerObject::permYouOwner() const
-{
- if (isRootEdit())
- {
+{
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectYouOwner();
+ return flagObjectYouOwner();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permYouOwner();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permYouOwner();
+ }
}
// Owned by a group?
-BOOL LLViewerObject::permGroupOwner() const
-{
- if (isRootEdit())
- {
- return flagObjectGroupOwned();
- }
- else
- {
- return ((LLViewerObject*)getParent())->permGroupOwner();
- }
+BOOL LLViewerObject::permGroupOwner() const
+{
+ if (isRootEdit())
+ {
+ return flagObjectGroupOwned();
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permGroupOwner();
+ }
}
// Can the owner edit
BOOL LLViewerObject::permOwnerModify() const
-{
- if (isRootEdit())
- {
+{
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectOwnerModify();
+ return flagObjectOwnerModify();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permOwnerModify();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permOwnerModify();
+ }
}
// Can edit
BOOL LLViewerObject::permModify() const
-{
- if (isRootEdit())
- {
+{
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectModify();
+ return flagObjectModify();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permModify();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permModify();
+ }
}
// Can copy
BOOL LLViewerObject::permCopy() const
-{
- if (isRootEdit())
- {
+{
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectCopy();
+ return flagObjectCopy();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permCopy();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permCopy();
+ }
}
// Can move
BOOL LLViewerObject::permMove() const
{
- if (isRootEdit())
- {
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectMove();
+ return flagObjectMove();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permMove();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permMove();
+ }
}
// Can be transferred
BOOL LLViewerObject::permTransfer() const
-{
- if (isRootEdit())
- {
+{
+ if (isRootEdit())
+ {
#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
+ return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
+ if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
- {
- return TRUE;
- }
+ {
+ return TRUE;
+ }
# endif
- return flagObjectTransfer();
+ return flagObjectTransfer();
#endif
- }
- else
- {
- return ((LLViewerObject*)getParent())->permTransfer();
- }
+ }
+ else
+ {
+ return ((LLViewerObject*)getParent())->permTransfer();
+ }
}
// Can only open objects that you own, or that someone has
// given you modify rights to. JC
BOOL LLViewerObject::allowOpen() const
{
- return !flagInventoryEmpty() && (permYouOwner() || permModify());
+ return !flagInventoryEmpty() && (permYouOwner() || permModify());
}
LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo()
{
- if (mListener)
- {
- mListener->clearVOInventoryListener();
- }
+ if (mListener)
+ {
+ mListener->clearVOInventoryListener();
+ }
}
void LLViewerObject::updateVolume(const LLVolumeParams& volume_params)
{
- if (setVolume(volume_params, 1)) // *FIX: magic number, ack!
- {
- // Transmit the update to the simulator
- sendShapeUpdate();
- markForUpdate();
- }
+ if (setVolume(volume_params, 1)) // *FIX: magic number, ack!
+ {
+ // Transmit the update to the simulator
+ sendShapeUpdate();
+ markForUpdate();
+ }
}
void LLViewerObject::recursiveMarkForUpdate()
@@ -6725,259 +6888,259 @@ void LLViewerObject::recursiveMarkForUpdate()
void LLViewerObject::markForUpdate()
{
- if (mDrawable.notNull())
- {
- gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
- }
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ }
}
bool LLViewerObject::isPermanentEnforced() const
{
- return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike();
+ return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike();
}
bool LLViewerObject::getIncludeInSearch() const
{
- return flagIncludeInSearch();
+ return flagIncludeInSearch();
}
void LLViewerObject::setIncludeInSearch(bool include_in_search)
{
- setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search);
+ setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search);
}
void LLViewerObject::setRegion(LLViewerRegion *regionp)
{
- if (!regionp)
- {
- LL_WARNS() << "viewer object set region to NULL" << LL_ENDL;
- }
- if(regionp != mRegionp)
- {
- if(mRegionp)
- {
- mRegionp->removeFromCreatedList(getLocalID());
- }
- if(regionp)
- {
- regionp->addToCreatedList(getLocalID());
- }
- }
-
- mLatestRecvPacketID = 0;
- mRegionp = regionp;
-
- for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
- {
- LLViewerObject* child = *i;
- child->setRegion(regionp);
- }
+ if (!regionp)
+ {
+ LL_WARNS() << "viewer object set region to NULL" << LL_ENDL;
+ }
+ if(regionp != mRegionp)
+ {
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
+ if(regionp)
+ {
+ regionp->addToCreatedList(getLocalID());
+ }
+ }
+
+ mLatestRecvPacketID = 0;
+ mRegionp = regionp;
+
+ for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
+ {
+ LLViewerObject* child = *i;
+ child->setRegion(regionp);
+ }
if (mControlAvatar)
{
mControlAvatar->setRegion(regionp);
}
- setChanged(MOVED | SILHOUETTE);
- updateDrawable(FALSE);
+ setChanged(MOVED | SILHOUETTE);
+ updateDrawable(FALSE);
}
// virtual
-void LLViewerObject::updateRegion(LLViewerRegion *regionp)
+void LLViewerObject::updateRegion(LLViewerRegion *regionp)
{
-// if (regionp)
-// {
-// F64 now = LLFrameTimer::getElapsedSeconds();
-// LL_INFOS() << "Updating to region " << regionp->getName()
-// << ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0)
-// << ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0)
-// << LL_ENDL;
-// }
+// if (regionp)
+// {
+// F64 now = LLFrameTimer::getElapsedSeconds();
+// LL_INFOS() << "Updating to region " << regionp->getName()
+// << ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0)
+// << ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0)
+// << LL_ENDL;
+// }
}
bool LLViewerObject::specialHoverCursor() const
{
- return flagUsePhysics()
- || flagHandleTouch()
- || (mClickAction != 0);
+ return flagUsePhysics()
+ || flagHandleTouch()
+ || (mClickAction != 0);
}
void LLViewerObject::updateFlags(BOOL physics_changed)
{
- LLViewerRegion* regionp = getRegion();
- if(!regionp) return;
- gMessageSystem->newMessage("ObjectFlagUpdate");
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
- gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() );
- gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
- gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
-
- // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator
- // The simulator code does not even unpack this value when the message is received.
- // This could be potentially hijacked in the future for another use should the urgent need arise.
- gMessageSystem->addBOOL("CastsShadows", FALSE );
-
- if (physics_changed)
- {
- gMessageSystem->nextBlock("ExtraPhysics");
- gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() );
- gMessageSystem->addF32("Density", getPhysicsDensity() );
- gMessageSystem->addF32("Friction", getPhysicsFriction() );
- gMessageSystem->addF32("Restitution", getPhysicsRestitution() );
- gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() );
- }
- gMessageSystem->sendReliable( regionp->getHost() );
+ LLViewerRegion* regionp = getRegion();
+ if(!regionp) return;
+ gMessageSystem->newMessage("ObjectFlagUpdate");
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
+ gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() );
+ gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
+ gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
+
+ // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator
+ // The simulator code does not even unpack this value when the message is received.
+ // This could be potentially hijacked in the future for another use should the urgent need arise.
+ gMessageSystem->addBOOL("CastsShadows", FALSE );
+
+ if (physics_changed)
+ {
+ gMessageSystem->nextBlock("ExtraPhysics");
+ gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() );
+ gMessageSystem->addF32("Density", getPhysicsDensity() );
+ gMessageSystem->addF32("Friction", getPhysicsFriction() );
+ gMessageSystem->addF32("Restitution", getPhysicsRestitution() );
+ gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() );
+ }
+ gMessageSystem->sendReliable( regionp->getHost() );
}
BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
{
- BOOL setit = setFlagsWithoutUpdate(flags, state);
+ BOOL setit = setFlagsWithoutUpdate(flags, state);
- // BUG: Sometimes viewer physics and simulator physics get
- // out of sync. To fix this, always send update to simulator.
-// if (setit)
- {
- updateFlags();
- }
- return setit;
+ // BUG: Sometimes viewer physics and simulator physics get
+ // out of sync. To fix this, always send update to simulator.
+// if (setit)
+ {
+ updateFlags();
+ }
+ return setit;
}
BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state)
{
- BOOL setit = FALSE;
- if (state)
- {
- if ((mFlags & flags) != flags)
- {
- mFlags |= flags;
- setit = TRUE;
- }
- }
- else
- {
- if ((mFlags & flags) != 0)
- {
- mFlags &= ~flags;
- setit = TRUE;
- }
- }
- return setit;
+ BOOL setit = FALSE;
+ if (state)
+ {
+ if ((mFlags & flags) != flags)
+ {
+ mFlags |= flags;
+ setit = TRUE;
+ }
+ }
+ else
+ {
+ if ((mFlags & flags) != 0)
+ {
+ mFlags &= ~flags;
+ setit = TRUE;
+ }
+ }
+ return setit;
}
void LLViewerObject::setPhysicsShapeType(U8 type)
{
- mPhysicsShapeUnknown = false;
- if (type != mPhysicsShapeType)
- {
- mPhysicsShapeType = type;
- setObjectCostStale();
+ mPhysicsShapeUnknown = false;
+ if (type != mPhysicsShapeType)
+ {
+ mPhysicsShapeType = type;
+ setObjectCostStale();
}
}
void LLViewerObject::setPhysicsGravity(F32 gravity)
{
- mPhysicsGravity = gravity;
+ mPhysicsGravity = gravity;
}
void LLViewerObject::setPhysicsFriction(F32 friction)
{
- mPhysicsFriction = friction;
+ mPhysicsFriction = friction;
}
void LLViewerObject::setPhysicsDensity(F32 density)
{
- mPhysicsDensity = density;
+ mPhysicsDensity = density;
}
void LLViewerObject::setPhysicsRestitution(F32 restitution)
{
- mPhysicsRestitution = restitution;
+ mPhysicsRestitution = restitution;
}
U8 LLViewerObject::getPhysicsShapeType() const
-{
- if (mPhysicsShapeUnknown)
- {
- gObjectList.updatePhysicsFlags(this);
- }
+{
+ if (mPhysicsShapeUnknown)
+ {
+ gObjectList.updatePhysicsFlags(this);
+ }
- return mPhysicsShapeType;
+ return mPhysicsShapeType;
}
void LLViewerObject::applyAngularVelocity(F32 dt)
{
- //do target omega here
- mRotTime += dt;
- LLVector3 ang_vel = getAngularVelocity();
- F32 omega = ang_vel.magVecSquared();
- F32 angle = 0.0f;
- LLQuaternion dQ;
- if (omega > 0.00001f)
- {
- omega = sqrt(omega);
- angle = omega * dt;
-
- ang_vel *= 1.f/omega;
-
- // calculate the delta increment based on the object's angular velocity
- dQ.setQuat(angle, ang_vel);
-
- // accumulate the angular velocity rotations to re-apply in the case of an object update
- mAngularVelocityRot *= dQ;
-
- // Just apply the delta increment to the current rotation
- setRotation(getRotation()*dQ);
- setChanged(MOVED | SILHOUETTE);
- }
+ //do target omega here
+ mRotTime += dt;
+ LLVector3 ang_vel = getAngularVelocity();
+ F32 omega = ang_vel.magVecSquared();
+ F32 angle = 0.0f;
+ LLQuaternion dQ;
+ if (omega > 0.00001f)
+ {
+ omega = sqrt(omega);
+ angle = omega * dt;
+
+ ang_vel *= 1.f/omega;
+
+ // calculate the delta increment based on the object's angular velocity
+ dQ.setQuat(angle, ang_vel);
+
+ // accumulate the angular velocity rotations to re-apply in the case of an object update
+ mAngularVelocityRot *= dQ;
+
+ // Just apply the delta increment to the current rotation
+ setRotation(getRotation()*dQ);
+ setChanged(MOVED | SILHOUETTE);
+ }
}
void LLViewerObject::resetRotTime()
{
- mRotTime = 0.0f;
+ mRotTime = 0.0f;
}
void LLViewerObject::resetRot()
{
- resetRotTime();
+ resetRotTime();
- // Reset the accumulated angular velocity rotation
- mAngularVelocityRot.loadIdentity();
+ // Reset the accumulated angular velocity rotation
+ mAngularVelocityRot.loadIdentity();
}
U32 LLViewerObject::getPartitionType() const
-{
- return LLViewerRegion::PARTITION_NONE;
+{
+ return LLViewerRegion::PARTITION_NONE;
}
void LLViewerObject::dirtySpatialGroup() const
{
- if (mDrawable)
- {
- LLSpatialGroup* group = mDrawable->getSpatialGroup();
- if (group)
- {
- group->dirtyGeom();
- gPipeline.markRebuild(group);
- }
- }
+ if (mDrawable)
+ {
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
+ }
}
void LLViewerObject::dirtyMesh()
{
- if (mDrawable)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
- }
+ if (mDrawable)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ }
}
F32 LLAlphaObject::getPartSize(S32 idx)
{
- return 0.f;
+ return 0.f;
}
void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst)
@@ -6988,235 +7151,235 @@ void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender
// virtual
void LLStaticViewerObject::updateDrawable(BOOL force_damped)
{
- // Force an immediate rebuild on any update
- if (mDrawable.notNull())
- {
- mDrawable->updateXform(TRUE);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
- }
- clearChanged(SHIFTED);
+ // Force an immediate rebuild on any update
+ if (mDrawable.notNull())
+ {
+ mDrawable->updateXform(TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ }
+ clearChanged(SHIFTED);
}
void LLViewerObject::saveUnselectedChildrenPosition(std::vector<LLVector3>& positions)
{
- if(mChildList.empty() || !positions.empty())
- {
- return ;
- }
+ if(mChildList.empty() || !positions.empty())
+ {
+ return ;
+ }
- for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (!childp->isSelected() && childp->mDrawable.notNull())
- {
- positions.push_back(childp->getPositionEdit());
- }
- }
+ for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* childp = *iter;
+ if (!childp->isSelected() && childp->mDrawable.notNull())
+ {
+ positions.push_back(childp->getPositionEdit());
+ }
+ }
- return ;
+ return ;
}
void LLViewerObject::saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations)
{
- if(mChildList.empty())
- {
- return ;
- }
+ if(mChildList.empty())
+ {
+ return ;
+ }
- for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (!childp->isSelected() && childp->mDrawable.notNull())
- {
- rotations.push_back(childp->getRotationEdit());
- }
- }
+ for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* childp = *iter;
+ if (!childp->isSelected() && childp->mDrawable.notNull())
+ {
+ rotations.push_back(childp->getRotationEdit());
+ }
+ }
- return ;
+ return ;
}
//counter-rotation
-void LLViewerObject::resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations,
- const std::vector<LLVector3>& positions)
-{
- if(mChildList.empty())
- {
- return ;
- }
-
- S32 index = 0 ;
- LLQuaternion inv_rotation = ~getRotationEdit() ;
- LLVector3 offset = getPositionEdit() ;
- for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (!childp->isSelected() && childp->mDrawable.notNull())
- {
- if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
- {
- childp->setRotation(rotations[index] * inv_rotation);
- childp->setPosition((positions[index] - offset) * inv_rotation);
- LLManip::rebuild(childp);
- }
- else //avatar
- {
- LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ;
- LLQuaternion reset_rot = rotations[index] * inv_rotation ;
-
- ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
- ((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ;
-
- ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE);
- ((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ;
-
- LLManip::rebuild(childp);
- }
- index++;
- }
- }
-
- return ;
+void LLViewerObject::resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations,
+ const std::vector<LLVector3>& positions)
+{
+ if(mChildList.empty())
+ {
+ return ;
+ }
+
+ S32 index = 0 ;
+ LLQuaternion inv_rotation = ~getRotationEdit() ;
+ LLVector3 offset = getPositionEdit() ;
+ for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* childp = *iter;
+ if (!childp->isSelected() && childp->mDrawable.notNull())
+ {
+ if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+ {
+ childp->setRotation(rotations[index] * inv_rotation);
+ childp->setPosition((positions[index] - offset) * inv_rotation);
+ LLManip::rebuild(childp);
+ }
+ else //avatar
+ {
+ LLVector3 reset_pos = (positions[index] - offset) * inv_rotation ;
+ LLQuaternion reset_rot = rotations[index] * inv_rotation ;
+
+ ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
+ ((LLVOAvatar*)childp)->mDrawable->mXform.setRotation(reset_rot) ;
+
+ ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos, TRUE);
+ ((LLVOAvatar*)childp)->mDrawable->getVObj()->setRotation(reset_rot, TRUE) ;
+
+ LLManip::rebuild(childp);
+ }
+ index++;
+ }
+ }
+
+ return ;
}
//counter-translation
void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplified, BOOL skip_avatar_child)
{
- if(mChildList.empty())
- {
- return ;
- }
-
- LLVector3 child_offset;
- if(simplified) //translation only, rotation matrix does not change
- {
- child_offset = offset * ~getRotation();
- }
- else //rotation matrix might change too.
- {
- if (isAttachment() && mDrawable.notNull())
- {
- LLXform* attachment_point_xform = mDrawable->getXform()->getParent();
- LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation();
- child_offset = offset * ~parent_rotation;
- }
- else
- {
- child_offset = offset * ~getRenderRotation();
- }
- }
-
- for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* childp = *iter;
-
- if (!childp->isSelected() && childp->mDrawable.notNull())
- {
- if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
- {
- childp->setPosition(childp->getPosition() + child_offset);
- LLManip::rebuild(childp);
- }
- else //avatar
- {
- if(!skip_avatar_child)
- {
- LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ;
-
- ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
- ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos);
- LLManip::rebuild(childp);
- }
- }
- }
- }
-
- return ;
-}
-
-// virtual
-BOOL LLViewerObject::isTempAttachment() const
-{
- return (mID.notNull() && (mID == mAttachmentItemID));
+ if(mChildList.empty())
+ {
+ return ;
+ }
+
+ LLVector3 child_offset;
+ if(simplified) //translation only, rotation matrix does not change
+ {
+ child_offset = offset * ~getRotation();
+ }
+ else //rotation matrix might change too.
+ {
+ if (isAttachment() && mDrawable.notNull())
+ {
+ LLXform* attachment_point_xform = mDrawable->getXform()->getParent();
+ LLQuaternion parent_rotation = getRotation() * attachment_point_xform->getWorldRotation();
+ child_offset = offset * ~parent_rotation;
+ }
+ else
+ {
+ child_offset = offset * ~getRenderRotation();
+ }
+ }
+
+ for (LLViewerObject::child_list_t::const_iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* childp = *iter;
+
+ if (!childp->isSelected() && childp->mDrawable.notNull())
+ {
+ if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
+ {
+ childp->setPosition(childp->getPosition() + child_offset);
+ LLManip::rebuild(childp);
+ }
+ else //avatar
+ {
+ if(!skip_avatar_child)
+ {
+ LLVector3 reset_pos = ((LLVOAvatar*)childp)->mDrawable->mXform.getPosition() + child_offset ;
+
+ ((LLVOAvatar*)childp)->mDrawable->mXform.setPosition(reset_pos);
+ ((LLVOAvatar*)childp)->mDrawable->getVObj()->setPosition(reset_pos);
+ LLManip::rebuild(childp);
+ }
+ }
+ }
+ }
+
+ return ;
+}
+
+// virtual
+BOOL LLViewerObject::isTempAttachment() const
+{
+ return (mID.notNull() && (mID == mAttachmentItemID));
}
BOOL LLViewerObject::isHiglightedOrBeacon() const
{
- if (LLFloaterReg::instanceVisible("beacons") && (gPipeline.getRenderBeacons() || gPipeline.getRenderHighlights()))
- {
- BOOL has_media = (getMediaType() == LLViewerObject::MEDIA_SET);
- BOOL is_scripted = !isAvatar() && !getParent() && flagScripted();
- BOOL is_physical = !isAvatar() && flagUsePhysics();
-
- return (isParticleSource() && gPipeline.getRenderParticleBeacons())
- || (isAudioSource() && gPipeline.getRenderSoundBeacons())
- || (has_media && gPipeline.getRenderMOAPBeacons())
- || (is_scripted && gPipeline.getRenderScriptedBeacons())
- || (is_scripted && flagHandleTouch() && gPipeline.getRenderScriptedTouchBeacons())
- || (is_physical && gPipeline.getRenderPhysicalBeacons());
- }
- return FALSE;
+ if (LLFloaterReg::instanceVisible("beacons") && (gPipeline.getRenderBeacons() || gPipeline.getRenderHighlights()))
+ {
+ BOOL has_media = (getMediaType() == LLViewerObject::MEDIA_SET);
+ BOOL is_scripted = !isAvatar() && !getParent() && flagScripted();
+ BOOL is_physical = !isAvatar() && flagUsePhysics();
+
+ return (isParticleSource() && gPipeline.getRenderParticleBeacons())
+ || (isAudioSource() && gPipeline.getRenderSoundBeacons())
+ || (has_media && gPipeline.getRenderMOAPBeacons())
+ || (is_scripted && gPipeline.getRenderScriptedBeacons())
+ || (is_scripted && flagHandleTouch() && gPipeline.getRenderScriptedTouchBeacons())
+ || (is_physical && gPipeline.getRenderPhysicalBeacons());
+ }
+ return FALSE;
}
const LLUUID &LLViewerObject::getAttachmentItemID() const
{
- return mAttachmentItemID;
+ return mAttachmentItemID;
}
void LLViewerObject::setAttachmentItemID(const LLUUID &id)
{
- mAttachmentItemID = id;
+ mAttachmentItemID = id;
}
EObjectUpdateType LLViewerObject::getLastUpdateType() const
{
- return mLastUpdateType;
+ return mLastUpdateType;
}
void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type)
{
- mLastUpdateType = last_update_type;
+ mLastUpdateType = last_update_type;
}
BOOL LLViewerObject::getLastUpdateCached() const
{
- return mLastUpdateCached;
+ return mLastUpdateCached;
}
void LLViewerObject::setLastUpdateCached(BOOL last_update_cached)
{
- mLastUpdateCached = last_update_cached;
+ mLastUpdateCached = last_update_cached;
}
const LLUUID &LLViewerObject::extractAttachmentItemID()
{
- LLUUID item_id = LLUUID::null;
- LLNameValue* item_id_nv = getNVPair("AttachItemID");
- if( item_id_nv )
- {
- const char* s = item_id_nv->getString();
- if( s )
- {
- item_id.set(s);
- }
- }
- setAttachmentItemID(item_id);
- return getAttachmentItemID();
+ LLUUID item_id = LLUUID::null;
+ LLNameValue* item_id_nv = getNVPair("AttachItemID");
+ if( item_id_nv )
+ {
+ const char* s = item_id_nv->getString();
+ if( s )
+ {
+ item_id.set(s);
+ }
+ }
+ setAttachmentItemID(item_id);
+ return getAttachmentItemID();
}
const std::string& LLViewerObject::getAttachmentItemName() const
{
- static std::string empty;
- LLInventoryItem *item = gInventory.getItem(getAttachmentItemID());
- if (isAttachment() && item)
- {
- return item->getName();
- }
- return empty;
+ static std::string empty;
+ LLInventoryItem *item = gInventory.getItem(getAttachmentItemID());
+ if (isAttachment() && item)
+ {
+ return item->getName();
+ }
+ return empty;
}
//virtual
@@ -7226,19 +7389,19 @@ LLVOAvatar* LLViewerObject::getAvatar() const
{
return getControlAvatar();
}
- if (isAttachment())
- {
- LLViewerObject* vobj = (LLViewerObject*) getParent();
+ if (isAttachment())
+ {
+ LLViewerObject* vobj = (LLViewerObject*) getParent();
- while (vobj && !vobj->asAvatar())
- {
- vobj = (LLViewerObject*) vobj->getParent();
- }
+ while (vobj && !vobj->asAvatar())
+ {
+ vobj = (LLViewerObject*) vobj->getParent();
+ }
- return (LLVOAvatar*) vobj;
- }
+ return (LLVOAvatar*) vobj;
+ }
- return NULL;
+ return NULL;
}
bool LLViewerObject::hasRenderMaterialParams() const
@@ -7318,12 +7481,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
{
new_material = gGLTFMaterialList.getMaterial(id);
}
-
+
// update local state
for (S32 te = start_idx; te < end_idx; ++te)
{
LLTextureEntry* tep = getTE(te);
-
+
// If local_origin=false (i.e. it's from the server), we know the
// material has updated or been created, because extra params are
// checked for equality on unpacking. In that case, checking the
@@ -7332,7 +7495,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
bool material_changed = !local_origin || !param_block || id != param_block->getMaterial(te);
if (update_server)
- {
+ {
// Clear most overrides so the render material better matches the material
// ID (preserve transforms). If overrides become passthrough, set the overrides
// to nullptr.
@@ -7343,7 +7506,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
}
if (update_server || material_changed)
- {
+ {
tep->setGLTFRenderMaterial(nullptr);
}
@@ -7460,53 +7623,53 @@ void LLViewerObject::shrinkWrap()
class ObjectPhysicsProperties : public LLHTTPNode
{
public:
- virtual void post(
- ResponsePtr responder,
- const LLSD& context,
- const LLSD& input) const
- {
- LLSD object_data = input["body"]["ObjectData"];
- S32 num_entries = object_data.size();
-
- for ( S32 i = 0; i < num_entries; i++ )
- {
- LLSD& curr_object_data = object_data[i];
- U32 local_id = curr_object_data["LocalID"].asInteger();
-
- // Iterate through nodes at end, since it can be on both the regular AND hover list
- struct f : public LLSelectedNodeFunctor
- {
- U32 mID;
- f(const U32& id) : mID(id) {}
- virtual bool apply(LLSelectNode* node)
- {
- return (node->getObject() && node->getObject()->mLocalID == mID );
- }
- } func(local_id);
-
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
-
- if (node)
- {
- // The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast
- U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger();
- F32 density = (F32)curr_object_data["Density"].asReal();
- F32 friction = (F32)curr_object_data["Friction"].asReal();
- F32 restitution = (F32)curr_object_data["Restitution"].asReal();
- F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal();
-
- node->getObject()->setPhysicsShapeType(type);
- node->getObject()->setPhysicsGravity(gravity);
- node->getObject()->setPhysicsFriction(friction);
- node->getObject()->setPhysicsDensity(density);
- node->getObject()->setPhysicsRestitution(restitution);
- }
- }
-
- dialog_refresh_all();
- };
+ virtual void post(
+ ResponsePtr responder,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD object_data = input["body"]["ObjectData"];
+ S32 num_entries = object_data.size();
+
+ for ( S32 i = 0; i < num_entries; i++ )
+ {
+ LLSD& curr_object_data = object_data[i];
+ U32 local_id = curr_object_data["LocalID"].asInteger();
+
+ // Iterate through nodes at end, since it can be on both the regular AND hover list
+ struct f : public LLSelectedNodeFunctor
+ {
+ U32 mID;
+ f(const U32& id) : mID(id) {}
+ virtual bool apply(LLSelectNode* node)
+ {
+ return (node->getObject() && node->getObject()->mLocalID == mID );
+ }
+ } func(local_id);
+
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
+
+ if (node)
+ {
+ // The LLSD message builder doesn't know how to handle U8, so we need to send as S8 and cast
+ U8 type = (U8)curr_object_data["PhysicsShapeType"].asInteger();
+ F32 density = (F32)curr_object_data["Density"].asReal();
+ F32 friction = (F32)curr_object_data["Friction"].asReal();
+ F32 restitution = (F32)curr_object_data["Restitution"].asReal();
+ F32 gravity = (F32)curr_object_data["GravityMultiplier"].asReal();
+
+ node->getObject()->setPhysicsShapeType(type);
+ node->getObject()->setPhysicsGravity(gravity);
+ node->getObject()->setPhysicsFriction(friction);
+ node->getObject()->setPhysicsDensity(density);
+ node->getObject()->setPhysicsRestitution(restitution);
+ }
+ }
+
+ dialog_refresh_all();
+ };
};
LLHTTPRegistration<ObjectPhysicsProperties>
- gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
+ gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index fa2bbd0a15..64c1ee6633 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -5,21 +5,21 @@
* $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$
*/
@@ -45,8 +45,9 @@
#include "llbbox.h"
#include "llrigginginfo.h"
#include "llreflectionmap.h"
+#include "gltf/asset.h"
-class LLAgent; // TODO: Get rid of this.
+class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
class LLAudioSourceVO;
class LLColor4;
@@ -75,112 +76,112 @@ class LLMeshCostData;
typedef enum e_object_update_type
{
- OUT_FULL,
- OUT_TERSE_IMPROVED,
- OUT_FULL_COMPRESSED,
- OUT_FULL_CACHED,
- OUT_UNKNOWN,
+ OUT_FULL,
+ OUT_TERSE_IMPROVED,
+ OUT_FULL_COMPRESSED,
+ OUT_FULL_CACHED,
+ OUT_UNKNOWN,
} EObjectUpdateType;
// callback typedef for inventory
typedef void (*inventory_callback)(LLViewerObject*,
- LLInventoryObject::object_list_t*,
- S32 serial_num,
- void*);
+ LLInventoryObject::object_list_t*,
+ S32 serial_num,
+ void*);
// for exporting textured materials from SL
struct LLMaterialExportInfo
{
public:
- LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) :
- mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {};
+ LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) :
+ mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {};
- S32 mMaterialIndex;
- S32 mTextureIndex;
- LLColor4 mColor;
+ S32 mMaterialIndex;
+ S32 mTextureIndex;
+ LLColor4 mColor;
};
struct PotentialReturnableObject
{
- LLBBox box;
- LLViewerRegion* pRegion;
+ LLBBox box;
+ LLViewerRegion* pRegion;
};
//============================================================================
-class LLViewerObject
-: public LLPrimitive,
- public LLRefCount,
- public LLGLUpdate
+class LLViewerObject
+: public LLPrimitive,
+ public LLRefCount,
+ public LLGLUpdate
{
protected:
- virtual ~LLViewerObject(); // use unref()
+ virtual ~LLViewerObject(); // use unref()
- // TomY: Provide for a list of extra parameter structures, mapped by structure name
- struct ExtraParameter
- {
- BOOL in_use;
- LLNetworkData *data;
- };
- std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
+ // TomY: Provide for a list of extra parameter structures, mapped by structure name
+ struct ExtraParameter
+ {
+ BOOL in_use;
+ LLNetworkData *data;
+ };
+ std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
public:
- typedef std::list<LLPointer<LLViewerObject> > child_list_t;
- typedef std::list<LLPointer<LLViewerObject> > vobj_list_t;
+ typedef std::list<LLPointer<LLViewerObject> > child_list_t;
+ typedef std::list<LLPointer<LLViewerObject> > vobj_list_t;
- typedef const child_list_t const_child_list_t;
+ typedef const child_list_t const_child_list_t;
- LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
+ LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
- virtual void markDead(); // Mark this object as dead, and clean up its references
- BOOL isDead() const {return mDead;}
- BOOL isOrphaned() const { return mOrphaned; }
- BOOL isParticleSource() const;
+ virtual void markDead(); // Mark this object as dead, and clean up its references
+ BOOL isDead() const {return mDead;}
+ BOOL isOrphaned() const { return mOrphaned; }
+ BOOL isParticleSource() const;
- virtual LLVOAvatar* asAvatar();
+ virtual LLVOAvatar* asAvatar();
- LLVOAvatar* getAvatarAncestor();
+ LLVOAvatar* getAvatarAncestor();
- static void initVOClasses();
- static void cleanupVOClasses();
+ static void initVOClasses();
+ static void cleanupVOClasses();
- void addNVPair(const std::string& data);
- BOOL removeNVPair(const std::string& name);
- LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name
+ void addNVPair(const std::string& data);
+ BOOL removeNVPair(const std::string& name);
+ LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name
- // Object create and update functions
- virtual void idleUpdate(LLAgent &agent, const F64 &time);
+ // Object create and update functions
+ virtual void idleUpdate(LLAgent &agent, const F64 &time);
- // Types of media we can associate
- enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
+ // Types of media we can associate
+ enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
- // Return codes for processUpdateMessage
- enum {
- MEDIA_URL_REMOVED = 0x1,
- MEDIA_URL_ADDED = 0x2,
- MEDIA_URL_UPDATED = 0x4,
+ // Return codes for processUpdateMessage
+ enum {
+ MEDIA_URL_REMOVED = 0x1,
+ MEDIA_URL_ADDED = 0x2,
+ MEDIA_URL_UPDATED = 0x4,
MEDIA_FLAGS_CHANGED = 0x8,
INVALID_UPDATE = 0x80000000
};
- static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot);
- virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num,
- const EObjectUpdateType update_type,
- LLDataPacker *dp);
-
+ static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot);
+ virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp);
- virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- BOOL onActiveList() const {return mOnActiveList;}
- void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
- virtual BOOL isAttachment() const { return FALSE; }
- const std::string& getAttachmentItemName() const;
+ virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate.
+ BOOL onActiveList() const {return mOnActiveList;}
+ void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
- virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
+ virtual BOOL isAttachment() const { return FALSE; }
+ const std::string& getAttachmentItemName() const;
+ virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
+
bool hasRenderMaterialParams() const;
void setHasRenderMaterialParams(bool has_params);
@@ -193,419 +194,431 @@ public:
void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true);
void setRenderMaterialIDs(const LLUUID& id);
- virtual BOOL isHUDAttachment() const { return FALSE; }
- virtual BOOL isTempAttachment() const;
-
- virtual BOOL isHiglightedOrBeacon() const;
+ virtual BOOL isHUDAttachment() const { return FALSE; }
+ virtual BOOL isTempAttachment() const;
- virtual void updateRadius() {};
- virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()
+ virtual BOOL isHiglightedOrBeacon() const;
- // for jointed and other parent-relative hacks
- LLViewerObject* getSubParent();
- const LLViewerObject* getSubParent() const;
+ virtual void updateRadius() {};
+ virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()
+
+ // for jointed and other parent-relative hacks
+ LLViewerObject* getSubParent();
+ const LLViewerObject* getSubParent() const;
+
+ // Object visiblility and GPW functions
+ virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area
- // Object visiblility and GPW functions
- virtual void setPixelAreaAndAngle(LLAgent &agent); // Override to generate accurate apparent angle and area
+ virtual U32 getNumVertices() const;
+ virtual U32 getNumIndices() const;
+ S32 getNumFaces() const { return mNumFaces; }
- virtual U32 getNumVertices() const;
- virtual U32 getNumIndices() const;
- S32 getNumFaces() const { return mNumFaces; }
-
- // Graphical stuff for objects - maybe broken out into render class later?
- virtual void updateTextures();
+ // Graphical stuff for objects - maybe broken out into render class later?
+ virtual void updateTextures();
virtual void faceMappingChanged() {}
- virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
-
- virtual LLDrawable* createDrawable(LLPipeline *pipeline);
- virtual BOOL updateGeometry(LLDrawable *drawable);
- virtual void updateGL();
- virtual void updateFaceSize(S32 idx);
- virtual BOOL updateLOD();
- virtual BOOL setDrawableParent(LLDrawable* parentp);
- F32 getRotTime() { return mRotTime; }
+ virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
+
+ virtual LLDrawable* createDrawable(LLPipeline *pipeline);
+ virtual BOOL updateGeometry(LLDrawable *drawable);
+ virtual void updateGL();
+ virtual void updateFaceSize(S32 idx);
+ virtual BOOL updateLOD();
+ virtual BOOL setDrawableParent(LLDrawable* parentp);
+ F32 getRotTime() { return mRotTime; }
private:
- void resetRotTime();
- void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
+ void resetRotTime();
+ void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
void rebuildMaterial();
public:
- void resetRot();
- void applyAngularVelocity(F32 dt);
+ void resetRot();
+ void applyAngularVelocity(F32 dt);
- void setLineWidthForWindowSize(S32 window_width);
+ void setLineWidthForWindowSize(S32 window_width);
- static void increaseArrowLength(); // makes axis arrows for selections longer
- static void decreaseArrowLength(); // makes axis arrows for selections shorter
+ static void increaseArrowLength(); // makes axis arrows for selections longer
+ static void decreaseArrowLength(); // makes axis arrows for selections shorter
- // Accessor functions
- LLViewerRegion* getRegion() const { return mRegionp; }
+ // Accessor functions
+ LLViewerRegion* getRegion() const { return mRegionp; }
- BOOL isSelected() const { return mUserSelected; }
+ BOOL isSelected() const { return mUserSelected; }
// Check whole linkset
BOOL isAnySelected() const;
- virtual void setSelected(BOOL sel);
-
- const LLUUID &getID() const { return mID; }
- U32 getLocalID() const { return mLocalID; }
- U32 getCRC() const { return mTotalCRC; }
- S32 getListIndex() const { return mListIndex; }
- void setListIndex(S32 idx) { mListIndex = idx; }
-
- virtual BOOL isFlexible() const { return FALSE; }
- virtual BOOL isSculpted() const { return FALSE; }
- virtual BOOL isMesh() const { return FALSE; }
- virtual BOOL isRiggedMesh() const { return FALSE; }
- virtual BOOL hasLightTexture() const { return FALSE; }
+ virtual void setSelected(BOOL sel);
+
+ const LLUUID &getID() const { return mID; }
+ U32 getLocalID() const { return mLocalID; }
+ U32 getCRC() const { return mTotalCRC; }
+ S32 getListIndex() const { return mListIndex; }
+ void setListIndex(S32 idx) { mListIndex = idx; }
+
+ virtual BOOL isFlexible() const { return FALSE; }
+ virtual BOOL isSculpted() const { return FALSE; }
+ virtual BOOL isMesh() const { return FALSE; }
+ virtual BOOL isRiggedMesh() const { return FALSE; }
+ virtual BOOL hasLightTexture() const { return FALSE; }
virtual BOOL isReflectionProbe() const { return FALSE; }
- // This method returns true if the object is over land owned by
- // the agent, one of its groups, or it encroaches and
- // anti-encroachment is enabled
- bool isReturnable();
+ // This method returns true if the object is over land owned by
+ // the agent, one of its groups, or it encroaches and
+ // anti-encroachment is enabled
+ bool isReturnable();
- void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
- void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
+ void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
+ void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
- // This method returns true if the object crosses
- // any parcel bounds in the region.
- bool crossesParcelBounds();
+ // This method returns true if the object crosses
+ // any parcel bounds in the region.
+ bool crossesParcelBounds();
- /*
- // This method will scan through this object, and then query the
- // selection manager to see if the local agent probably has the
- // ability to modify the object. Since this calls into the
- // selection manager, you should avoid calling this method from
- // there.
- BOOL isProbablyModifiable() const;
- */
+ /*
+ // This method will scan through this object, and then query the
+ // selection manager to see if the local agent probably has the
+ // ability to modify the object. Since this calls into the
+ // selection manager, you should avoid calling this method from
+ // there.
+ BOOL isProbablyModifiable() const;
+ */
- virtual BOOL setParent(LLViewerObject* parent);
+ virtual BOOL setParent(LLViewerObject* parent);
virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
virtual void afterReparent();
- virtual void addChild(LLViewerObject *childp);
- virtual void removeChild(LLViewerObject *childp);
- const_child_list_t& getChildren() const { return mChildList; }
- S32 numChildren() const { return mChildList.size(); }
- void addThisAndAllChildren(std::vector<LLViewerObject*>& objects);
- void addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects);
- BOOL isChild(LLViewerObject *childp) const;
- BOOL isSeat() const;
-
-
- //detect if given line segment (in agent space) intersects with this viewer object.
- //returns TRUE if intersection detected and returns information about intersection
- virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = -1, // which face to check, -1 = ALL_SIDES
- BOOL pick_transparent = FALSE,
- BOOL pick_rigged = FALSE,
+ virtual void addChild(LLViewerObject *childp);
+ virtual void removeChild(LLViewerObject *childp);
+ const_child_list_t& getChildren() const { return mChildList; }
+ S32 numChildren() const { return mChildList.size(); }
+ void addThisAndAllChildren(std::vector<LLViewerObject*>& objects);
+ void addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects);
+ BOOL isChild(LLViewerObject *childp) const;
+ BOOL isSeat() const;
+
+
+ //detect if given line segment (in agent space) intersects with this viewer object.
+ //returns TRUE if intersection detected and returns information about intersection
+ virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face = -1, // which face to check, -1 = ALL_SIDES
+ BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
BOOL pick_unselectable = TRUE,
- S32* face_hit = NULL, // which face was hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
-
- virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);
-
- virtual const LLVector3d getPositionGlobal() const;
- virtual const LLVector3 &getPositionRegion() const;
- virtual const LLVector3 getPositionEdit() const;
- virtual const LLVector3 &getPositionAgent() const;
- virtual const LLVector3 getRenderPosition() const;
-
- virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not
-
- LLViewerObject* getRootEdit() const;
-
- const LLQuaternion getRotationRegion() const;
- const LLQuaternion getRotationEdit() const;
- const LLQuaternion getRenderRotation() const;
- virtual const LLMatrix4 getRenderMatrix() const;
-
- void setPosition(const LLVector3 &pos, BOOL damped = FALSE);
- void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE);
- void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE);
- void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE);
- void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE);
- void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE);
- void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE );
-
- virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); }
-
- inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE);
- inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE);
-
- /*virtual*/ void setNumTEs(const U8 num_tes);
- /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
+ S32* face_hit = NULL, // which face was hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+ virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);
+
+ virtual const LLVector3d getPositionGlobal() const;
+ virtual const LLVector3 &getPositionRegion() const;
+ virtual const LLVector3 getPositionEdit() const;
+ virtual const LLVector3 &getPositionAgent() const;
+ virtual const LLVector3 getRenderPosition() const;
+
+ LLMatrix4a getAgentToGLTFAssetTransform() const;
+ LLMatrix4a getGLTFAssetToAgentTransform() const;
+ LLVector3 getGLTFNodePositionAgent(S32 node_index) const;
+ LLMatrix4a getGLTFNodeTransformAgent(S32 node_index) const;
+ void getGLTFNodeTransformAgent(S32 node_index, LLVector3* position, LLQuaternion* rotation, LLVector3* scale) const;
+
+ // move the node at the given index by the given offset in agent space
+ void moveGLTFNode(S32 node_index, const LLVector3& offset);
+
+ // set the rotation in agent space of the given node
+ void setGLTFNodeRotationAgent(S32 node_index, const LLQuaternion& rotation);
+
+ virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not
+
+ LLViewerObject* getRootEdit() const;
+
+ const LLQuaternion getRotationRegion() const;
+ const LLQuaternion getRotationEdit() const;
+ const LLQuaternion getRenderRotation() const;
+ virtual const LLMatrix4 getRenderMatrix() const;
+
+ void setPosition(const LLVector3 &pos, BOOL damped = FALSE);
+ void setPositionGlobal(const LLVector3d &position, BOOL damped = FALSE);
+ void setPositionRegion(const LLVector3 &position, BOOL damped = FALSE);
+ void setPositionEdit(const LLVector3 &position, BOOL damped = FALSE);
+ void setPositionAgent(const LLVector3 &pos_agent, BOOL damped = FALSE);
+ void setPositionParent(const LLVector3 &pos_parent, BOOL damped = FALSE);
+ void setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped = FALSE );
+
+ virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const { return xform->getWorldMatrix(); }
+
+ inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE);
+ inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE);
+
+ /*virtual*/ void setNumTEs(const U8 num_tes);
+ /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
void updateTEMaterialTextures(U8 te);
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
- /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
- S32 setTETextureCore(const U8 te, LLViewerTexture *image);
- S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
- S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
- /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
- /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
- /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
- /*virtual*/ S32 setTEOffset(const U8 te, const F32 s, const F32 t);
- /*virtual*/ S32 setTEOffsetS(const U8 te, const F32 s);
- /*virtual*/ S32 setTEOffsetT(const U8 te, const F32 t);
- /*virtual*/ S32 setTERotation(const U8 te, const F32 r);
- /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump );
- /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen );
- /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics
- /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny );
- /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
- /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
- /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
- /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
+ /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
+ /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
+ S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
+ S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
+ /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
+ /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
+ /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
+ /*virtual*/ S32 setTEOffset(const U8 te, const F32 s, const F32 t);
+ /*virtual*/ S32 setTEOffsetS(const U8 te, const F32 s);
+ /*virtual*/ S32 setTEOffsetT(const U8 te, const F32 t);
+ /*virtual*/ S32 setTERotation(const U8 te, const F32 r);
+ /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump );
+ /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen );
+ /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics
+ /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny );
+ /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
+ /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
+ /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
- // Used by Materials update functions to properly kick off rebuilds
- // of VBs etc when materials updates require changes.
- //
- void refreshMaterials();
-
- /*virtual*/ BOOL setMaterial(const U8 material);
- virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
- virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
- virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
- virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
- LLViewerTexture *getTEImage(const U8 te) const;
- LLViewerTexture *getTENormalMap(const U8 te) const;
- LLViewerTexture *getTESpecularMap(const U8 te) const;
+ // Used by Materials update functions to properly kick off rebuilds
+ // of VBs etc when materials updates require changes.
+ //
+ void refreshMaterials();
- bool isImageAlphaBlended(const U8 te) const;
+ /*virtual*/ BOOL setMaterial(const U8 material);
+ virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
+ virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
+ LLViewerTexture *getTEImage(const U8 te) const;
+ LLViewerTexture *getTENormalMap(const U8 te) const;
+ LLViewerTexture *getTESpecularMap(const U8 te) const;
- void fitFaceTexture(const U8 face);
- void sendTEUpdate() const; // Sends packed representation of all texture entry information
+ bool isImageAlphaBlended(const U8 te) const;
- virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
+ void fitFaceTexture(const U8 face);
+ void sendTEUpdate() const; // Sends packed representation of all texture entry information
+
+ virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
S32 getAnimatedObjectMaxTris() const;
F32 recursiveGetEstTrianglesMax() const;
virtual F32 getEstTrianglesMax() const;
virtual F32 getEstTrianglesStreamingCost() const;
- virtual F32 getStreamingCost() const;
+ virtual F32 getStreamingCost() const;
virtual bool getCostData(LLMeshCostData& costs) const;
- virtual U32 getTriangleCount(S32* vcount = NULL) const;
- virtual U32 getHighLODTriangleCount();
+ virtual U32 getTriangleCount(S32* vcount = NULL) const;
+ virtual U32 getHighLODTriangleCount();
F32 recursiveGetScaledSurfaceArea() const;
U32 recursiveGetTriangleCount(S32* vcount = NULL) const;
- void setObjectCost(F32 cost);
- F32 getObjectCost();
-
- void setLinksetCost(F32 cost);
- F32 getLinksetCost();
-
- void setPhysicsCost(F32 cost);
- F32 getPhysicsCost();
-
- void setLinksetPhysicsCost(F32 cost);
- F32 getLinksetPhysicsCost();
-
- void sendShapeUpdate();
-
- U8 getAttachmentState() { return mAttachmentState; }
-
- F32 getAppAngle() const { return mAppAngle; }
- F32 getPixelArea() const { return mPixelArea; }
- void setPixelArea(F32 area) { mPixelArea = area; }
- F32 getMaxScale() const;
- F32 getMidScale() const;
- F32 getMinScale() const;
-
- // Owner id is this object's owner
- void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
- void adjustAudioGain(const F32 gain);
- F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; }
- void clearAttachedSound() { mAudioSourcep = NULL; }
-
- // Create if necessary
- LLAudioSource *getAudioSource(const LLUUID& owner_id);
- BOOL isAudioSource() const {return mAudioSourcep != NULL;}
-
- U8 getMediaType() const;
- void setMediaType(U8 media_type);
-
- std::string getMediaURL() const;
- void setMediaURL(const std::string& media_url);
-
- BOOL getMediaPassedWhitelist() const;
- void setMediaPassedWhitelist(BOOL passed);
-
- void sendMaterialUpdate() const;
-
- void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white);
- void appendDebugText(const std::string &utf8text);
- void initHudText();
- void restoreHudText();
- void setIcon(LLViewerTexture* icon_image);
- void clearIcon();
+ void setObjectCost(F32 cost);
+ F32 getObjectCost();
+
+ void setLinksetCost(F32 cost);
+ F32 getLinksetCost();
+
+ void setPhysicsCost(F32 cost);
+ F32 getPhysicsCost();
+
+ void setLinksetPhysicsCost(F32 cost);
+ F32 getLinksetPhysicsCost();
+
+ void sendShapeUpdate();
+
+ U8 getAttachmentState() { return mAttachmentState; }
+
+ F32 getAppAngle() const { return mAppAngle; }
+ F32 getPixelArea() const { return mPixelArea; }
+ void setPixelArea(F32 area) { mPixelArea = area; }
+ F32 getMaxScale() const;
+ F32 getMidScale() const;
+ F32 getMinScale() const;
+
+ // Owner id is this object's owner
+ void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
+ void adjustAudioGain(const F32 gain);
+ F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; }
+ void clearAttachedSound() { mAudioSourcep = NULL; }
+
+ // Create if necessary
+ LLAudioSource *getAudioSource(const LLUUID& owner_id);
+ BOOL isAudioSource() const {return mAudioSourcep != NULL;}
+
+ U8 getMediaType() const;
+ void setMediaType(U8 media_type);
+
+ std::string getMediaURL() const;
+ void setMediaURL(const std::string& media_url);
+
+ BOOL getMediaPassedWhitelist() const;
+ void setMediaPassedWhitelist(BOOL passed);
+
+ void sendMaterialUpdate() const;
+
+ void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white);
+ void appendDebugText(const std::string &utf8text);
+ void initHudText();
+ void restoreHudText();
+ void setIcon(LLViewerTexture* icon_image);
+ void clearIcon();
void recursiveMarkForUpdate();
- virtual void markForUpdate();
- void updateVolume(const LLVolumeParams& volume_params);
- virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
- virtual F32 getBinRadius();
-
- LLBBox getBoundingBoxAgent() const;
-
- void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform.
- void updateText(); // update text label position
- virtual void updateDrawable(BOOL force_damped); // force updates on static objects
-
- bool isOwnerInMuteList(LLUUID item_id = LLUUID());
-
- void setDrawableState(U32 state, BOOL recursive = TRUE);
- void clearDrawableState(U32 state, BOOL recursive = TRUE);
- BOOL isDrawableState(U32 state, BOOL recursive = TRUE) const;
-
- // Called when the drawable shifts
- virtual void onShift(const LLVector4a &shift_vector) { }
-
- //////////////////////////////////////
- //
- // Inventory methods
- //
-
- // This function is called when someone is interested in a viewer
- // object's inventory. The callback is called as soon as the
- // viewer object has the inventory stored locally.
- void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
- void removeInventoryListener(LLVOInventoryListener* listener);
- BOOL isInventoryPending();
- void clearInventoryListeners();
- bool hasInventoryListeners();
- void requestInventory();
- static void processTaskInv(LLMessageSystem* msg, void** user_data);
- void removeInventory(const LLUUID& item_id);
-
- // The updateInventory() call potentially calls into the selection
- // manager, so do no call updateInventory() from the selection
- // manager until we have better iterators.
- void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
- void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
- void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
- LLInventoryObject* getInventoryObject(const LLUUID& item_id);
- LLInventoryItem* getInventoryItem(const LLUUID& item_id);
-
- // Get content except for root category
- void getInventoryContents(LLInventoryObject::object_list_t& objects);
- LLInventoryObject* getInventoryRoot();
- LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
+ virtual void markForUpdate();
+ void updateVolume(const LLVolumeParams& volume_params);
+ virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
+ virtual F32 getBinRadius();
+
+ LLBBox getBoundingBoxAgent() const;
+
+ void updatePositionCaches() const; // Update the global and region position caches from the object (and parent's) xform.
+ void updateText(); // update text label position
+ virtual void updateDrawable(BOOL force_damped); // force updates on static objects
+
+ bool isOwnerInMuteList(LLUUID item_id = LLUUID());
+
+ void setDrawableState(U32 state, BOOL recursive = TRUE);
+ void clearDrawableState(U32 state, BOOL recursive = TRUE);
+ BOOL isDrawableState(U32 state, BOOL recursive = TRUE) const;
+
+ // Called when the drawable shifts
+ virtual void onShift(const LLVector4a &shift_vector) { }
+
+ //////////////////////////////////////
+ //
+ // Inventory methods
+ //
+
+ // This function is called when someone is interested in a viewer
+ // object's inventory. The callback is called as soon as the
+ // viewer object has the inventory stored locally.
+ void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
+ void removeInventoryListener(LLVOInventoryListener* listener);
+ BOOL isInventoryPending();
+ void clearInventoryListeners();
+ bool hasInventoryListeners();
+ void requestInventory();
+ static void processTaskInv(LLMessageSystem* msg, void** user_data);
+ void removeInventory(const LLUUID& item_id);
+
+ // The updateInventory() call potentially calls into the selection
+ // manager, so do no call updateInventory() from the selection
+ // manager until we have better iterators.
+ void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
+ void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ LLInventoryObject* getInventoryObject(const LLUUID& item_id);
+ LLInventoryItem* getInventoryItem(const LLUUID& item_id);
+
+ // Get content except for root category
+ void getInventoryContents(LLInventoryObject::object_list_t& objects);
+ LLInventoryObject* getInventoryRoot();
+ LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type);
- S16 getInventorySerial() const { return mInventorySerialNum; }
-
- // These functions does viewer-side only object inventory modifications
- void updateViewerInventoryAsset(
- const LLViewerInventoryItem* item,
- const LLUUID& new_asset);
-
- // This function will make sure that we refresh the inventory.
- void dirtyInventory();
- BOOL isInventoryDirty() { return mInventoryDirty; }
-
- // save a script, which involves removing the old one, and rezzing
- // in the new one. This method should be called with the asset id
- // of the new and old script AFTER the bytecode has been saved.
- void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new);
-
- // move an inventory item out of the task and into agent
- // inventory. This operation is based on messaging. No permissions
- // checks are made on the viewer - the server will double check.
- void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id);
-
- // Find the number of instances of this object's inventory that are of the given type
- S32 countInventoryContents( LLAssetType::EType type );
-
- BOOL permAnyOwner() const;
- BOOL permYouOwner() const;
- BOOL permGroupOwner() const;
- BOOL permOwnerModify() const;
- BOOL permModify() const;
- BOOL permCopy() const;
- BOOL permMove() const;
- BOOL permTransfer() const;
- inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
- inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); }
- inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); }
- inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); }
- inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); }
- inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); }
- inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); }
- inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
- inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); }
- inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); }
- inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); }
- inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); }
- inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); }
- inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); }
- inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); }
- inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); }
- inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); }
- inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); }
- inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); }
- inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); }
- inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
- inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
- inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
-
- U8 getPhysicsShapeType() const;
- inline F32 getPhysicsGravity() const { return mPhysicsGravity; }
- inline F32 getPhysicsFriction() const { return mPhysicsFriction; }
- inline F32 getPhysicsDensity() const { return mPhysicsDensity; }
- inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; }
-
- bool isPermanentEnforced() const;
-
- bool getIncludeInSearch() const;
- void setIncludeInSearch(bool include_in_search);
-
- // Does "open" object menu item apply?
- BOOL allowOpen() const;
-
- void setClickAction(U8 action) { mClickAction = action; }
- U8 getClickAction() const { return mClickAction; }
- bool specialHoverCursor() const; // does it have a special hover cursor?
-
- void setRegion(LLViewerRegion *regionp);
- virtual void updateRegion(LLViewerRegion *regionp);
-
- void updateFlags(BOOL physics_changed = FALSE);
- void loadFlags(U32 flags); //load flags from cache or from message
- BOOL setFlags(U32 flag, BOOL state);
- BOOL setFlagsWithoutUpdate(U32 flag, BOOL state);
- void setPhysicsShapeType(U8 type);
- void setPhysicsGravity(F32 gravity);
- void setPhysicsFriction(F32 friction);
- void setPhysicsDensity(F32 density);
- void setPhysicsRestitution(F32 restitution);
-
- virtual void dump() const;
- static U32 getNumZombieObjects() { return sNumZombieObjects; }
-
- void printNameValuePairs() const;
-
- virtual S32 getLOD() const { return 3; }
- virtual U32 getPartitionType() const;
- void dirtySpatialGroup() const;
- virtual void dirtyMesh();
-
- virtual LLNetworkData* getParameterEntry(U16 param_type) const;
- virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
- virtual BOOL getParameterEntryInUse(U16 param_type) const;
- virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin);
- // Called when a parameter is changed
- virtual void parameterChanged(U16 param_type, bool local_origin);
- virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
-
+ S16 getInventorySerial() const { return mInventorySerialNum; }
+
+ // These functions does viewer-side only object inventory modifications
+ void updateViewerInventoryAsset(
+ const LLViewerInventoryItem* item,
+ const LLUUID& new_asset);
+
+ // This function will make sure that we refresh the inventory.
+ void dirtyInventory();
+ BOOL isInventoryDirty() { return mInventoryDirty; }
+
+ // save a script, which involves removing the old one, and rezzing
+ // in the new one. This method should be called with the asset id
+ // of the new and old script AFTER the bytecode has been saved.
+ void saveScript(const LLViewerInventoryItem* item, BOOL active, bool is_new);
+
+ // move an inventory item out of the task and into agent
+ // inventory. This operation is based on messaging. No permissions
+ // checks are made on the viewer - the server will double check.
+ void moveInventory(const LLUUID& agent_folder, const LLUUID& item_id);
+
+ // Find the number of instances of this object's inventory that are of the given type
+ S32 countInventoryContents( LLAssetType::EType type );
+
+ BOOL permAnyOwner() const;
+ BOOL permYouOwner() const;
+ BOOL permGroupOwner() const;
+ BOOL permOwnerModify() const;
+ BOOL permModify() const;
+ BOOL permCopy() const;
+ BOOL permMove() const;
+ BOOL permTransfer() const;
+ inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
+ inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); }
+ inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); }
+ inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); }
+ inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); }
+ inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); }
+ inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); }
+ inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
+ inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); }
+ inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); }
+ inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); }
+ inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); }
+ inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); }
+ inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); }
+ inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); }
+ inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); }
+ inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); }
+ inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); }
+ inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); }
+ inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); }
+ inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
+ inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
+ inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
+
+ U8 getPhysicsShapeType() const;
+ inline F32 getPhysicsGravity() const { return mPhysicsGravity; }
+ inline F32 getPhysicsFriction() const { return mPhysicsFriction; }
+ inline F32 getPhysicsDensity() const { return mPhysicsDensity; }
+ inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; }
+
+ bool isPermanentEnforced() const;
+
+ bool getIncludeInSearch() const;
+ void setIncludeInSearch(bool include_in_search);
+
+ // Does "open" object menu item apply?
+ BOOL allowOpen() const;
+
+ void setClickAction(U8 action) { mClickAction = action; }
+ U8 getClickAction() const { return mClickAction; }
+ bool specialHoverCursor() const; // does it have a special hover cursor?
+
+ void setRegion(LLViewerRegion *regionp);
+ virtual void updateRegion(LLViewerRegion *regionp);
+
+ void updateFlags(BOOL physics_changed = FALSE);
+ void loadFlags(U32 flags); //load flags from cache or from message
+ BOOL setFlags(U32 flag, BOOL state);
+ BOOL setFlagsWithoutUpdate(U32 flag, BOOL state);
+ void setPhysicsShapeType(U8 type);
+ void setPhysicsGravity(F32 gravity);
+ void setPhysicsFriction(F32 friction);
+ void setPhysicsDensity(F32 density);
+ void setPhysicsRestitution(F32 restitution);
+
+ virtual void dump() const;
+ static U32 getNumZombieObjects() { return sNumZombieObjects; }
+
+ void printNameValuePairs() const;
+
+ virtual S32 getLOD() const { return 3; }
+ virtual U32 getPartitionType() const;
+ void dirtySpatialGroup() const;
+ virtual void dirtyMesh();
+
+ virtual LLNetworkData* getParameterEntry(U16 param_type) const;
+ virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
+ virtual BOOL getParameterEntryInUse(U16 param_type) const;
+ virtual bool setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin);
+ // Called when a parameter is changed
+ virtual void parameterChanged(U16 param_type, bool local_origin);
+ virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+
bool isShrinkWrapped() const { return mShouldShrinkWrap; }
// Used to improve performance. If an object is likely to rebuild its vertex buffer often
@@ -614,137 +627,139 @@ public:
// so that nearby objects won't attempt to share a vertex buffer with this object.
void shrinkWrap();
- friend class LLViewerObjectList;
- friend class LLViewerMediaList;
+ friend class LLViewerObjectList;
+ friend class LLViewerMediaList;
public:
- LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id);
- void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id);
- void refreshBakeTexture();
+ LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id);
+ void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id);
+ void refreshBakeTexture();
public:
- static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name);
- static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name);
- static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name);
- static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name);
- static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id);
+ static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name);
+ static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name);
+ static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name);
+ static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name);
+ static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id);
public:
- //counter-translation
- void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE, BOOL skip_avatar_child = FALSE) ;
- //counter-rotation
- void resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations,
- const std::vector<LLVector3>& positions) ;
- void saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations) ;
- void saveUnselectedChildrenPosition(std::vector<LLVector3>& positions) ;
- std::vector<LLVector3> mUnselectedChildrenPositions ;
+ //counter-translation
+ void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE, BOOL skip_avatar_child = FALSE) ;
+ //counter-rotation
+ void resetChildrenRotationAndPosition(const std::vector<LLQuaternion>& rotations,
+ const std::vector<LLVector3>& positions) ;
+ void saveUnselectedChildrenRotation(std::vector<LLQuaternion>& rotations) ;
+ void saveUnselectedChildrenPosition(std::vector<LLVector3>& positions) ;
+ std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
void setObjectCostStale();
bool isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type);
- ExtraParameter* createNewParameterEntry(U16 param_type);
- ExtraParameter* getExtraParameterEntry(U16 param_type) const;
- ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
- bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
+ ExtraParameter* createNewParameterEntry(U16 param_type);
+ ExtraParameter* getExtraParameterEntry(U16 param_type) const;
+ ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
+ bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
// This function checks to see if the given media URL has changed its version
// and the update wasn't due to this agent's last action.
U32 checkMediaURL(const std::string &media_url);
+
+ // Motion prediction between updates
+ void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt);
- // Motion prediction between updates
- void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt);
+ static void initObjectDataMap();
- static void initObjectDataMap();
+ // forms task inventory request if none are pending, marks request as pending
+ void fetchInventoryFromServer();
- // forms task inventory request if none are pending, marks request as pending
- void fetchInventoryFromServer();
-
- // forms task inventory request after some time passed, marks request as pending
- void fetchInventoryDelayed(const F64 &time_seconds);
- static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
+ // forms task inventory request after some time passed, marks request as pending
+ void fetchInventoryDelayed(const F64 &time_seconds);
+ static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
public:
- //
- // Viewer-side only types - use the LL_PCODE_APP mask.
- //
- typedef enum e_vo_types
- {
- LL_VO_CLOUDS = LL_PCODE_APP | 0x20, // no longer used
- LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30,
- LL_VO_WL_SKY = LL_PCODE_APP | 0x40,
- LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50,
- LL_VO_SKY = LL_PCODE_APP | 0x60,
- LL_VO_VOID_WATER = LL_PCODE_APP | 0x70,
- LL_VO_WATER = LL_PCODE_APP | 0x80,
- LL_VO_PART_GROUP = LL_PCODE_APP | 0xa0,
- LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xb0,
- LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0,
- } EVOType;
-
- typedef enum e_physics_shape_types
- {
- PHYSICS_SHAPE_PRIM = 0,
- PHYSICS_SHAPE_NONE,
- PHYSICS_SHAPE_CONVEX_HULL,
- } EPhysicsShapeType;
-
- LLUUID mID;
- LLUUID mOwnerID; //null if unknown
-
- // unique within region, not unique across regions
- // Local ID = 0 is not used
- U32 mLocalID;
-
- // Last total CRC received from sim, used for caching
- U32 mTotalCRC;
-
- // index into LLViewerObjectList::mActiveObjects or -1 if not in list
- S32 mListIndex;
-
- LLPointer<LLViewerTexture> *mTEImages;
- LLPointer<LLViewerTexture> *mTENormalMaps;
- LLPointer<LLViewerTexture> *mTESpecularMaps;
-
+ //
+ // Viewer-side only types - use the LL_PCODE_APP mask.
+ //
+ typedef enum e_vo_types
+ {
+ LL_VO_CLOUDS = LL_PCODE_APP | 0x20, // no longer used
+ LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30,
+ LL_VO_WL_SKY = LL_PCODE_APP | 0x40,
+ LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50,
+ LL_VO_SKY = LL_PCODE_APP | 0x60,
+ LL_VO_VOID_WATER = LL_PCODE_APP | 0x70,
+ LL_VO_WATER = LL_PCODE_APP | 0x80,
+ LL_VO_PART_GROUP = LL_PCODE_APP | 0xa0,
+ LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xb0,
+ LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0,
+ } EVOType;
+
+ typedef enum e_physics_shape_types
+ {
+ PHYSICS_SHAPE_PRIM = 0,
+ PHYSICS_SHAPE_NONE,
+ PHYSICS_SHAPE_CONVEX_HULL,
+ } EPhysicsShapeType;
+
+ LLUUID mID;
+ LLUUID mOwnerID; //null if unknown
+
+ // unique within region, not unique across regions
+ // Local ID = 0 is not used
+ U32 mLocalID;
+
+ // Last total CRC received from sim, used for caching
+ U32 mTotalCRC;
+
+ // index into LLViewerObjectList::mActiveObjects or -1 if not in list
+ S32 mListIndex;
+
+ LLPointer<LLViewerTexture> *mTEImages;
+ LLPointer<LLViewerTexture> *mTENormalMaps;
+ LLPointer<LLViewerTexture> *mTESpecularMaps;
+
// true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
// can likely be factored out
- BOOL mbCanSelect;
+ BOOL mbCanSelect;
private:
- // Grabbed from UPDATE_FLAGS
- U32 mFlags;
+ // Grabbed from UPDATE_FLAGS
+ U32 mFlags;
- static std::map<std::string, U32> sObjectDataMap;
+ static std::map<std::string, U32> sObjectDataMap;
public:
- // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
- U8 mPhysicsShapeType;
- F32 mPhysicsGravity;
- F32 mPhysicsFriction;
- F32 mPhysicsDensity;
- F32 mPhysicsRestitution;
-
+ // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
+ U8 mPhysicsShapeType;
+ F32 mPhysicsGravity;
+ F32 mPhysicsFriction;
+ F32 mPhysicsDensity;
+ F32 mPhysicsRestitution;
+
+ // Associated GLTF Asset
+ LLPointer<LL::GLTF::Asset> mGLTFAsset;
- // Pipeline classes
- LLPointer<LLDrawable> mDrawable;
+ // Pipeline classes
+ LLPointer<LLDrawable> mDrawable;
- // Band-aid to select object after all creation initialization is done
- BOOL mCreateSelected;
+ // Band-aid to select object after all creation initialization is done
+ BOOL mCreateSelected;
- // Replace textures with web pages on this object while drawing
- BOOL mRenderMedia;
+ // Replace textures with web pages on this object while drawing
+ BOOL mRenderMedia;
bool mRiggedAttachedWarned;
- // In bits
- S32 mBestUpdatePrecision;
+ // In bits
+ S32 mBestUpdatePrecision;
- // TODO: Make all this stuff private. JC
- LLPointer<LLHUDText> mText;
- LLPointer<class LLHUDIcon> mIcon;
+ // TODO: Make all this stuff private. JC
+ LLPointer<LLHUDText> mText;
+ LLPointer<class LLHUDIcon> mIcon;
- std::string mHudText;
- LLColor4 mHudTextColor;
+ std::string mHudText;
+ LLColor4 mHudTextColor;
- static BOOL sUseSharedDrawables;
+ static BOOL sUseSharedDrawables;
public:
// Returns mControlAvatar for the edit root prim of this linkset
@@ -768,182 +783,183 @@ protected:
LLPointer<LLControlAvatar> mControlAvatar;
protected:
- // delete an item in the inventory, but don't tell the
- // server. This is used internally by remove, update, and
- // savescript.
- void deleteInventoryItem(const LLUUID& item_id);
-
- // do the update/caching logic. called by saveScript and
- // updateInventory.
- void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
-
- static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0);
-
- BOOL setData(const U8 *datap, const U32 data_size);
-
- // Hide or show HUD, icon and particles
- void hideExtraDisplayItems( BOOL hidden );
-
- //////////////////////////
- //
- // inventory functionality
- //
-
- static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
- BOOL loadTaskInvFile(const std::string& filename);
- void doInventoryCallback();
-
- BOOL isOnMap();
-
- void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
- void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
- void deleteParticleSource();
- void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
-
+ // delete an item in the inventory, but don't tell the
+ // server. This is used internally by remove, update, and
+ // savescript.
+ void deleteInventoryItem(const LLUUID& item_id);
+
+ // do the update/caching logic. called by saveScript and
+ // updateInventory.
+ void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
+
+ static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0);
+
+ BOOL setData(const U8 *datap, const U32 data_size);
+
+ // Hide or show HUD, icon and particles
+ void hideExtraDisplayItems( BOOL hidden );
+
+ //////////////////////////
+ //
+ // inventory functionality
+ //
+
+ static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
+ BOOL loadTaskInvFile(const std::string& filename);
+ void doInventoryCallback();
+
+ BOOL isOnMap();
+
+ void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
+ void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
+ void deleteParticleSource();
+ void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
+
private:
- void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
- void deleteTEImages(); // correctly deletes list of images
-
+ void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
+ void deleteTEImages(); // correctly deletes list of images
+
protected:
- typedef std::map<char *, LLNameValue *> name_value_map_t;
- name_value_map_t mNameValuePairs; // Any name-value pairs stored by script
-
- child_list_t mChildList;
-
- F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation
- F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator
- TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator
- F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time
-
- // extra data sent from the sim...currently only used for tree species info
- U8* mData;
-
- LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object.
- LLAudioSourceVO* mAudioSourcep;
- F32 mAudioGain;
- F32 mSoundCutOffRadius;
-
- F32 mAppAngle; // Apparent visual arc in degrees
- F32 mPixelArea; // Apparent area in pixels
-
- // IDs of of all items in the object's content which are added to the object's content,
- // but not updated on the server yet. After item was updated, its ID will be removed from this list.
- std::list<LLUUID> mPendingInventoryItemsIDs;
-
- // This is the object's inventory from the viewer's perspective.
- LLInventoryObject::object_list_t* mInventory;
- class LLInventoryCallbackInfo
- {
- public:
- ~LLInventoryCallbackInfo();
- LLVOInventoryListener* mListener;
- void* mInventoryData;
- };
- typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
- callback_list_t mInventoryCallbacks;
- S16 mInventorySerialNum;
- S16 mExpectedInventorySerialNum;
-
- enum EInventoryRequestState
- {
- INVENTORY_REQUEST_STOPPED,
- INVENTORY_REQUEST_WAIT, // delay before requesting
- INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
- INVENTORY_XFER // processed response from 'fetch', now doing an xfer
- };
- EInventoryRequestState mInvRequestState;
- U64 mInvRequestXFerId;
- BOOL mInventoryDirty;
-
- LLViewerRegion *mRegionp; // Region that this object belongs to.
- BOOL mDead;
- BOOL mOrphaned; // This is an orphaned child
- BOOL mUserSelected; // Cached user select information
- BOOL mOnActiveList;
- BOOL mOnMap; // On the map.
- BOOL mStatic; // Object doesn't move.
- S32 mSeatCount;
- S32 mNumFaces;
-
- F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
- LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
- LLQuaternion mPreviousRotation;
-
- U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment.
- LLViewerObjectMedia* mMedia; // NULL if no media associated
- U8 mClickAction;
- F32 mObjectCost; //resource cost of this object or -1 if unknown
- F32 mLinksetCost;
- F32 mPhysicsCost;
- F32 mLinksetPhysicsCost;
-
+ typedef std::map<char *, LLNameValue *> name_value_map_t;
+ name_value_map_t mNameValuePairs; // Any name-value pairs stored by script
+
+ child_list_t mChildList;
+
+ F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation
+ F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator
+ TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator
+ F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time
+
+ // extra data sent from the sim...currently only used for tree species info
+ U8* mData;
+
+ LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object.
+ LLAudioSourceVO* mAudioSourcep;
+ F32 mAudioGain;
+ F32 mSoundCutOffRadius;
+
+ F32 mAppAngle; // Apparent visual arc in degrees
+ F32 mPixelArea; // Apparent area in pixels
+
+ // IDs of of all items in the object's content which are added to the object's content,
+ // but not updated on the server yet. After item was updated, its ID will be removed from this list.
+ std::list<LLUUID> mPendingInventoryItemsIDs;
+
+ // This is the object's inventory from the viewer's perspective.
+ LLInventoryObject::object_list_t* mInventory;
+ class LLInventoryCallbackInfo
+ {
+ public:
+ ~LLInventoryCallbackInfo();
+ LLVOInventoryListener* mListener;
+ void* mInventoryData;
+ };
+ typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
+ callback_list_t mInventoryCallbacks;
+ S16 mInventorySerialNum;
+ S16 mExpectedInventorySerialNum;
+
+ enum EInventoryRequestState
+ {
+ INVENTORY_REQUEST_STOPPED,
+ INVENTORY_REQUEST_WAIT, // delay before requesting
+ INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
+ INVENTORY_XFER // processed response from 'fetch', now doing an xfer
+ };
+ EInventoryRequestState mInvRequestState;
+ U64 mInvRequestXFerId;
+ BOOL mInventoryDirty;
+
+ LLViewerRegion *mRegionp; // Region that this object belongs to.
+ BOOL mDead;
+ BOOL mOrphaned; // This is an orphaned child
+ BOOL mUserSelected; // Cached user select information
+ BOOL mOnActiveList;
+ BOOL mOnMap; // On the map.
+ BOOL mStatic; // Object doesn't move.
+ S32 mSeatCount;
+ S32 mNumFaces;
+
+ F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
+ LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
+ LLQuaternion mPreviousRotation;
+
+ U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment.
+ LLViewerObjectMedia* mMedia; // NULL if no media associated
+ U8 mClickAction;
+ F32 mObjectCost; //resource cost of this object or -1 if unknown
+ F32 mLinksetCost;
+ F32 mPhysicsCost;
+ F32 mLinksetPhysicsCost;
+
// If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap"
bool mShouldShrinkWrap = false;
- bool mCostStale;
- mutable bool mPhysicsShapeUnknown;
+ bool mCostStale;
+ mutable bool mPhysicsShapeUnknown;
- static U32 sNumZombieObjects; // Objects which are dead, but not deleted
+ static U32 sNumZombieObjects; // Objects which are dead, but not deleted
- static BOOL sMapDebug; // Map render mode
- static LLColor4 sEditSelectColor;
- static LLColor4 sNoEditSelectColor;
- static F32 sCurrentPulse;
- static BOOL sPulseEnabled;
+ static BOOL sMapDebug; // Map render mode
+ static LLColor4 sEditSelectColor;
+ static LLColor4 sNoEditSelectColor;
+ static F32 sCurrentPulse;
+ static BOOL sPulseEnabled;
- static S32 sAxisArrowLength;
+ static S32 sAxisArrowLength;
- // These two caches are only correct for non-parented objects right now!
- mutable LLVector3 mPositionRegion;
- mutable LLVector3 mPositionAgent;
+ // These two caches are only correct for non-parented objects right now!
+ mutable LLVector3 mPositionRegion;
+ mutable LLVector3 mPositionAgent;
- static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; }
- static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; }
- static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; }
+ static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; }
+ static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; }
+ static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; }
- static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; }
- static void setPingInterpolate(BOOL value) { sPingInterpolate = value; }
+ static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; }
+ static void setPingInterpolate(BOOL value) { sPingInterpolate = value; }
-private:
- static S32 sNumObjects;
+private:
+ static S32 sNumObjects;
- static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation
- static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation
- static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation
+ static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation
+ static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation
+ static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation
- static BOOL sVelocityInterpolate;
- static BOOL sPingInterpolate;
+ static BOOL sVelocityInterpolate;
+ static BOOL sPingInterpolate;
- bool mCachedOwnerInMuteList;
- F64 mCachedMuteListUpdateTime;
+ bool mCachedOwnerInMuteList;
+ F64 mCachedMuteListUpdateTime;
- //--------------------------------------------------------------------
- // For objects that are attachments
- //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ // For objects that are attachments
+ //--------------------------------------------------------------------
public:
- const LLUUID &getAttachmentItemID() const;
- void setAttachmentItemID(const LLUUID &id);
- const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
- EObjectUpdateType getLastUpdateType() const;
- void setLastUpdateType(EObjectUpdateType last_update_type);
- BOOL getLastUpdateCached() const;
- void setLastUpdateCached(BOOL last_update_cached);
+ const LLUUID &getAttachmentItemID() const;
+ void setAttachmentItemID(const LLUUID &id);
+ const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
+ EObjectUpdateType getLastUpdateType() const;
+ void setLastUpdateType(EObjectUpdateType last_update_type);
+ BOOL getLastUpdateCached() const;
+ void setLastUpdateCached(BOOL last_update_cached);
virtual void updateRiggingInfo() {}
LLJointRiggingInfoTab mJointRiggingInfoTab;
private:
- LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
- EObjectUpdateType mLastUpdateType;
- BOOL mLastUpdateCached;
+ LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
+ EObjectUpdateType mLastUpdateType;
+ BOOL mLastUpdateCached;
public:
// reflection probe state
bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager
LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed
+ bool mIsHeroProbe = false; // This is a special case for mirrors and other high resolution probes.
// the amount of GPU time (in ms) it took to render this object according to LLPipeline::profileAvatar
// -1.f if no profile data available
@@ -958,58 +974,58 @@ public:
inline void LLViewerObject::setRotation(const LLQuaternion& quat, BOOL damped)
{
- LLPrimitive::setRotation(quat);
- setChanged(ROTATED | SILHOUETTE);
- updateDrawable(damped);
+ LLPrimitive::setRotation(quat);
+ setChanged(ROTATED | SILHOUETTE);
+ updateDrawable(damped);
}
inline void LLViewerObject::setRotation(const F32 x, const F32 y, const F32 z, BOOL damped)
{
- LLPrimitive::setRotation(x, y, z);
- setChanged(ROTATED | SILHOUETTE);
- updateDrawable(damped);
+ LLPrimitive::setRotation(x, y, z);
+ setChanged(ROTATED | SILHOUETTE);
+ updateDrawable(damped);
}
class LLViewerObjectMedia
{
public:
- LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { }
+ LLViewerObjectMedia() : mMediaURL(), mPassedWhitelist(FALSE), mMediaType(0) { }
- std::string mMediaURL; // for web pages on surfaces, one per prim
- BOOL mPassedWhitelist; // user has OK'd display
- U8 mMediaType; // see LLTextureEntry::WEB_PAGE, etc.
+ std::string mMediaURL; // for web pages on surfaces, one per prim
+ BOOL mPassedWhitelist; // user has OK'd display
+ U8 mMediaType; // see LLTextureEntry::WEB_PAGE, etc.
};
// subclass of viewer object that can be added to particle partitions
class LLAlphaObject : public LLViewerObject
{
public:
- LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
- : LLViewerObject(id,pcode,regionp)
- { mDepth = 0.f; }
-
- virtual F32 getPartSize(S32 idx);
- virtual void getGeometry(S32 idx,
- LLStrider<LLVector4a>& verticesp,
- LLStrider<LLVector3>& normalsp,
- LLStrider<LLVector2>& texcoordsp,
- LLStrider<LLColor4U>& colorsp,
- LLStrider<LLColor4U>& emissivep,
- LLStrider<U16>& indicesp) = 0;
-
- virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst);
-
- F32 mDepth;
+ LLAlphaObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
+ : LLViewerObject(id,pcode,regionp)
+ { mDepth = 0.f; }
+
+ virtual F32 getPartSize(S32 idx);
+ virtual void getGeometry(S32 idx,
+ LLStrider<LLVector4a>& verticesp,
+ LLStrider<LLVector3>& normalsp,
+ LLStrider<LLVector2>& texcoordsp,
+ LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
+ LLStrider<U16>& indicesp) = 0;
+
+ virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst);
+
+ F32 mDepth;
};
class LLStaticViewerObject : public LLViewerObject
{
public:
- LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE)
- : LLViewerObject(id,pcode,regionp, is_global)
- { }
+ LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE)
+ : LLViewerObject(id,pcode,regionp, is_global)
+ { }
- virtual void updateDrawable(BOOL force_damped);
+ virtual void updateDrawable(BOOL force_damped);
};
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a9efe072f8..61ab2791fb 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerregion.cpp
* @brief Implementation of the LLViewerRegion class.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010-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$
*/
@@ -31,7 +31,7 @@
// linden libraries
#include "indra_constants.h"
#include "llaisapi.h"
-#include "llavatarnamecache.h" // name lookup cap url
+#include "llavatarnamecache.h" // name lookup cap url
#include "llfloaterreg.h"
#include "llmath.h"
#include "llregionflags.h"
@@ -86,11 +86,11 @@
#include <boost/regex.hpp>
#ifdef LL_WINDOWS
- #pragma warning(disable:4355)
+ #pragma warning(disable:4355)
#endif
-// When we receive a base grant of capabilities that has a different number of
-// capabilities than the original base grant received for the region, print
+// When we receive a base grant of capabilities that has a different number of
+// capabilities than the original base grant received for the region, print
// out the two lists of capabilities for analysis.
//#define DEBUG_CAPS_GRANTS
@@ -144,25 +144,25 @@ public:
{
return false;
}
-
+
// build a secondlife://{PLACE} SLurl from this SLapp
std::string url = "secondlife://";
if (!grid.empty())
{
url += grid + "/secondlife/";
}
- boost::regex name_rx("[A-Za-z0-9()_%]+");
- boost::regex coord_rx("[0-9]+");
+ boost::regex name_rx("[A-Za-z0-9()_%]+");
+ boost::regex coord_rx("[0-9]+");
for (int i = 0; i < num_params; i++)
{
if (i > 0)
{
url += "/";
}
- if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx))
- {
- return false;
- }
+ if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx))
+ {
+ return false;
+ }
url += params[i].asString();
}
@@ -171,15 +171,15 @@ public:
LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_CLICKED, web, true);
return true;
}
-
+
};
LLRegionHandler gRegionHandler;
-class LLViewerRegionImpl
+class LLViewerRegionImpl
{
public:
- LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host):
+ LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host):
mHost(host),
mCompositionp(NULL),
mEventPoll(NULL),
@@ -190,62 +190,62 @@ public:
mLastCameraOrigin(),
mVOCachePartition(NULL),
mLandp(NULL)
- {}
+ {}
- static void buildCapabilityNames(LLSD& capabilityNames);
+ static void buildCapabilityNames(LLSD& capabilityNames);
- // The surfaces and other layers
- LLSurface* mLandp;
+ // The surfaces and other layers
+ LLSurface* mLandp;
- // Region geometry data
- LLVector3d mOriginGlobal; // Location of southwest corner of region (meters)
- LLVector3d mCenterGlobal; // Location of center in world space (meters)
- LLHost mHost;
+ // Region geometry data
+ LLVector3d mOriginGlobal; // Location of southwest corner of region (meters)
+ LLVector3d mCenterGlobal; // Location of center in world space (meters)
+ LLHost mHost;
- // The unique ID for this region.
- LLUUID mRegionID;
+ // The unique ID for this region.
+ LLUUID mRegionID;
- // region/estate owner - usually null.
- LLUUID mOwnerID;
+ // region/estate owner - usually null.
+ LLUUID mOwnerID;
- // Network statistics for the region's circuit...
- LLTimer mLastNetUpdate;
+ // Network statistics for the region's circuit...
+ LLTimer mLastNetUpdate;
- // Misc
- LLVLComposition *mCompositionp; // Composition layer for the surface
+ // Misc
+ LLVLComposition *mCompositionp; // Composition layer for the surface
- LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries
- LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries;
- LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated.
- std::set< LLPointer<LLViewerOctreeGroup> > mVisibleGroups; //visible groupa
- LLVOCachePartition* mVOCachePartition;
- LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation.
- LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation.
- std::set<U32> mNonCacheableCreatedList; //list of local ids of all non-cacheable objects
+ LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries
+ LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries;
+ LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated.
+ std::set< LLPointer<LLViewerOctreeGroup> > mVisibleGroups; //visible groupa
+ LLVOCachePartition* mVOCachePartition;
+ LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation.
+ LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation.
+ std::set<U32> mNonCacheableCreatedList; //list of local ids of all non-cacheable objects
LLVOCacheEntry::vocache_gltf_overrides_map_t mGLTFOverridesLLSD; // for materials
- // time?
- // LRU info?
+ // time?
+ // LRU info?
- // Cache ID is unique per-region, across renames, moving locations,
- // etc.
- LLUUID mCacheID;
+ // Cache ID is unique per-region, across renames, moving locations,
+ // etc.
+ LLUUID mCacheID;
- CapabilityMap mCapabilities;
- CapabilityMap mSecondCapabilitiesTracker;
+ CapabilityMap mCapabilities;
+ CapabilityMap mSecondCapabilitiesTracker;
- LLEventPoll* mEventPoll;
+ LLEventPoll* mEventPoll;
- S32 mSeedCapMaxAttempts;
- S32 mSeedCapAttempts;
+ S32 mSeedCapMaxAttempts;
+ S32 mSeedCapAttempts;
- S32 mHttpResponderID;
+ S32 mHttpResponderID;
- //spatial partitions for objects in this region
- std::vector<LLViewerOctreePartition*> mObjectPartition;
+ //spatial partitions for objects in this region
+ std::vector<LLViewerOctreePartition*> mObjectPartition;
- LLVector3 mLastCameraOrigin;
- U32 mLastCameraUpdate;
+ LLVector3 mLastCameraOrigin;
+ U32 mLastCameraUpdate;
static void requestBaseCapabilitiesCoro(U64 regionHandle);
static void requestBaseCapabilitiesCompleteCoro(U64 regionHandle);
@@ -255,7 +255,7 @@ public:
void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
@@ -284,7 +284,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return; // this error condition is not recoverable.
}
LLViewerRegionImpl* impl = regionp->getRegionImplNC();
- LL_DEBUGS("AppInit", "Capabilities") << "requesting seed caps for handle " << regionHandle
+ LL_DEBUGS("AppInit", "Capabilities") << "requesting seed caps for handle " << regionHandle
<< " name " << regionp->getName() << LL_ENDL;
std::string url = regionp->getCapability("Seed");
@@ -310,12 +310,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
LLSD capabilityNames = LLSD::emptyArray();
impl->buildCapabilityNames(capabilityNames);
- LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
+ LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
<< " region name " << regionp->getName()
<< " region id " << regionp->getRegionID()
<< " handle " << regionp->getHandle()
<< " (attempt #" << impl->mSeedCapAttempts + 1 << ")" << LL_ENDL;
- LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;
+ LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;
regionp = NULL;
impl = NULL;
@@ -389,12 +389,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
log_capabilities(mCapabilities);
#endif
- LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle
- << " region name " << regionp->getName() << LL_ENDL;
+ LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle
+ << " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
break;
- }
+ }
while (true);
if (regionp && regionp->isCapabilityAvailable("ServerReleaseNotes") &&
@@ -535,7 +535,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
}
impl->mSecondCapabilitiesTracker.clear();
- }
+ }
while (false);
}
@@ -555,7 +555,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
if (attemptNumber > MAX_CAP_REQUEST_ATTEMPTS)
{
- LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from "
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from "
<< url << LL_ENDL;
break;
}
@@ -583,7 +583,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
if (!status)
{
LL_WARNS("AppInit", "SimulatorFeatures") << "HttpStatus error retrying" << LL_ENDL;
- continue;
+ continue;
}
if (LLApp::isExiting() || gDisconnected)
@@ -617,217 +617,218 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
}
LLViewerRegion::LLViewerRegion(const U64 &handle,
- const LLHost &host,
- const U32 grids_per_region_edge,
- const U32 grids_per_patch_edge,
- const F32 region_width_meters)
-: mImpl(new LLViewerRegionImpl(this, host)),
- mHandle(handle),
- mTimeDilation(1.0f),
- mName(""),
- mZoning(""),
- mIsEstateManager(FALSE),
- mRegionFlags( REGION_FLAGS_DEFAULT ),
- mRegionProtocols( 0 ),
- mSimAccess( SIM_ACCESS_MIN ),
- mBillableFactor(1.0),
- mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
- mCentralBakeVersion(1),
- mClassID(0),
- mCPURatio(0),
- mColoName("unknown"),
- mProductSKU("unknown"),
- mProductName("unknown"),
- mViewerAssetUrl(""),
- mCacheLoaded(FALSE),
- mCacheDirty(FALSE),
- mReleaseNotesRequested(FALSE),
- mCapabilitiesState(CAPABILITIES_STATE_INIT),
- mSimulatorFeaturesReceived(false),
- mBitsReceived(0.f),
- mPacketsReceived(0.f),
- mDead(FALSE),
- mLastVisitedEntry(NULL),
- mInvisibilityCheckHistory(-1),
- mPaused(FALSE),
- mRegionCacheHitCount(0),
- mRegionCacheMissCount(0),
+ const LLHost &host,
+ const U32 grids_per_region_edge,
+ const U32 grids_per_patch_edge,
+ const F32 region_width_meters)
+: mImpl(new LLViewerRegionImpl(this, host)),
+ mHandle(handle),
+ mTimeDilation(1.0f),
+ mName(""),
+ mZoning(""),
+ mIsEstateManager(FALSE),
+ mRegionFlags( REGION_FLAGS_DEFAULT ),
+ mRegionProtocols( 0 ),
+ mSimAccess( SIM_ACCESS_MIN ),
+ mBillableFactor(1.0),
+ mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+ mCentralBakeVersion(1),
+ mClassID(0),
+ mCPURatio(0),
+ mColoName("unknown"),
+ mProductSKU("unknown"),
+ mProductName("unknown"),
+ mViewerAssetUrl(""),
+ mCacheLoaded(FALSE),
+ mCacheDirty(FALSE),
+ mReleaseNotesRequested(FALSE),
+ mCapabilitiesState(CAPABILITIES_STATE_INIT),
+ mSimulatorFeaturesReceived(false),
+ mBitsReceived(0.f),
+ mPacketsReceived(0.f),
+ mDead(FALSE),
+ mLastVisitedEntry(NULL),
+ mInvisibilityCheckHistory(-1),
+ mPaused(FALSE),
+ mRegionCacheHitCount(0),
+ mRegionCacheMissCount(0),
mInterestListMode(IL_MODE_DEFAULT)
{
- mWidth = region_width_meters;
- mImpl->mOriginGlobal = from_region_handle(handle);
- updateRenderMatrix();
+ mWidth = region_width_meters;
+ mImpl->mOriginGlobal = from_region_handle(handle);
+ updateRenderMatrix();
- mImpl->mLandp = new LLSurface('l', NULL);
+ mImpl->mLandp = new LLSurface('l', NULL);
- // Create the composition layer for the surface
- mImpl->mCompositionp =
- new LLVLComposition(mImpl->mLandp,
- grids_per_region_edge,
- region_width_meters / grids_per_region_edge);
- mImpl->mCompositionp->setSurface(mImpl->mLandp);
+ // Create the composition layer for the surface
+ mImpl->mCompositionp =
+ new LLVLComposition(mImpl->mLandp,
+ grids_per_region_edge,
+ region_width_meters / grids_per_region_edge);
+ mImpl->mCompositionp->setSurface(mImpl->mLandp);
- // Create the surfaces
- mImpl->mLandp->setRegion(this);
- mImpl->mLandp->create(grids_per_region_edge,
- grids_per_patch_edge,
- mImpl->mOriginGlobal,
- mWidth);
+ // Create the surfaces
+ mImpl->mLandp->setRegion(this);
+ mImpl->mLandp->create(grids_per_region_edge,
+ grids_per_patch_edge,
+ mImpl->mOriginGlobal,
+ mWidth);
- mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
+ mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
- setOriginGlobal(from_region_handle(handle));
- calculateCenterGlobal();
+ setOriginGlobal(from_region_handle(handle));
+ calculateCenterGlobal();
- // Create the object lists
- initStats();
+ // Create the object lists
+ initStats();
- //create object partitions
- //MUST MATCH declaration of eObjectPartitions
- mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD
- mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN
- mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER
- mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER
- mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE
- mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE
- mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
- mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
- mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
- mImpl->mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR
- mImpl->mObjectPartition.push_back(new LLControlAVPartition(this)); //PARTITION_CONTROL_AV
- mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
- mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
- mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
- mImpl->mVOCachePartition = getVOCachePartition();
+ //create object partitions
+ //MUST MATCH declaration of eObjectPartitions
+ mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD
+ mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN
+ mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER
+ mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER
+ mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE
+ mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE
+ mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
+ mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
+ mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
+ mImpl->mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR
+ mImpl->mObjectPartition.push_back(new LLControlAVPartition(this)); //PARTITION_CONTROL_AV
+ mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
+ mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
+ mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
+ mImpl->mVOCachePartition = getVOCachePartition();
- setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::scanNewRegion, _1));
+ setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::scanNewRegion, _1));
}
void LLViewerRegion::initStats()
{
- mImpl->mLastNetUpdate.reset();
- mPacketsIn = 0;
- mBitsIn = (U32Bits)0;
- mLastBitsIn = (U32Bits)0;
- mLastPacketsIn = 0;
- mPacketsOut = 0;
- mLastPacketsOut = 0;
- mPacketsLost = 0;
- mLastPacketsLost = 0;
- mPingDelay = (U32Seconds)0;
- mAlive = false; // can become false if circuit disconnects
+ mImpl->mLastNetUpdate.reset();
+ mPacketsIn = 0;
+ mBitsIn = (U32Bits)0;
+ mLastBitsIn = (U32Bits)0;
+ mLastPacketsIn = 0;
+ mPacketsOut = 0;
+ mLastPacketsOut = 0;
+ mPacketsLost = 0;
+ mLastPacketsLost = 0;
+ mPingDelay = (U32Seconds)0;
+ mAlive = false; // can become false if circuit disconnects
}
static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects");
static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache");
-LLViewerRegion::~LLViewerRegion()
+LLViewerRegion::~LLViewerRegion()
{
LL_PROFILE_ZONE_SCOPED;
- mDead = TRUE;
- mImpl->mActiveSet.clear();
- mImpl->mVisibleEntries.clear();
- mImpl->mVisibleGroups.clear();
- mImpl->mWaitingSet.clear();
-
- gVLManager.cleanupData(this);
- // Can't do this on destruction, because the neighbor pointers might be invalid.
- // This should be reference counted...
- disconnectAllNeighbors();
- LLViewerPartSim::getInstance()->cleanupRegion(this);
+ mDead = TRUE;
+ mImpl->mActiveSet.clear();
+ mImpl->mVisibleEntries.clear();
+ mImpl->mVisibleGroups.clear();
+ mImpl->mWaitingSet.clear();
+
+ gVLManager.cleanupData(this);
+ // Can't do this on destruction, because the neighbor pointers might be invalid.
+ // This should be reference counted...
+ disconnectAllNeighbors();
+ LLViewerPartSim::getInstance()->cleanupRegion(this);
{
LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS);
gObjectList.killObjects(this);
}
- delete mImpl->mCompositionp;
- delete mParcelOverlay;
- delete mImpl->mLandp;
- delete mImpl->mEventPoll;
+ delete mImpl->mCompositionp;
+ delete mParcelOverlay;
+ delete mImpl->mLandp;
+ delete mImpl->mEventPoll;
#if 0
- LLHTTPSender::clearSender(mImpl->mHost);
-#endif
- std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
+ LLHTTPSender::clearSender(mImpl->mHost);
+#endif
+ std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
{
LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE);
saveObjectCache();
}
- delete mImpl;
- mImpl = NULL;
+ delete mImpl;
+ mImpl = NULL;
}
-/*virtual*/
-const LLHost& LLViewerRegion::getHost() const
-{
- return mImpl->mHost;
+/*virtual*/
+const LLHost& LLViewerRegion::getHost() const
+{
+ return mImpl->mHost;
}
LLSurface & LLViewerRegion::getLand() const
{
- return *mImpl->mLandp;
+ return *mImpl->mLandp;
}
const LLUUID& LLViewerRegion::getRegionID() const
{
- return mImpl->mRegionID;
+ return mImpl->mRegionID;
}
void LLViewerRegion::setRegionID(const LLUUID& region_id)
{
- mImpl->mRegionID = region_id;
+ mImpl->mRegionID = region_id;
}
void LLViewerRegion::loadObjectCache()
{
- if (mCacheLoaded)
- {
- return;
- }
+ if (mCacheLoaded)
+ {
+ return;
+ }
- // Presume success. If it fails, we don't want to try again.
- mCacheLoaded = TRUE;
+ // Presume success. If it fails, we don't want to try again.
+ mCacheLoaded = TRUE;
- if(LLVOCache::instanceExists())
- {
+ if(LLVOCache::instanceExists())
+ {
LLVOCache & vocache = LLVOCache::instance();
- vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap);
- vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD);
+ // Without this a "corrupted" vocache persists until a cache clear or other rewrite. Mark as dirty hereif read fails to force a rewrite.
+ mCacheDirty = !vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap);
+ vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mImpl->mCacheMap);
- if (mImpl->mCacheMap.empty())
- {
- mCacheDirty = TRUE;
- }
- }
+ if (mImpl->mCacheMap.empty())
+ {
+ mCacheDirty = TRUE;
+ }
+ }
}
void LLViewerRegion::saveObjectCache()
{
- if (!mCacheLoaded)
- {
- return;
- }
+ if (!mCacheLoaded)
+ {
+ return;
+ }
- if (mImpl->mCacheMap.empty())
- {
- return;
- }
+ if (mImpl->mCacheMap.empty())
+ {
+ return;
+ }
- if(LLVOCache::instanceExists())
- {
- const F32 start_time_threshold = 600.0f; //seconds
- bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file.
+ if(LLVOCache::instanceExists())
+ {
+ const F32 start_time_threshold = 600.0f; //seconds
+ bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file.
LLVOCache & instance = LLVOCache::instance();
instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled);
instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mCacheDirty, removal_enabled);
- mCacheDirty = FALSE;
- }
+ mCacheDirty = FALSE;
+ }
if (LLAppViewer::instance()->isQuitting())
{
@@ -844,253 +845,253 @@ void LLViewerRegion::saveObjectCache()
void LLViewerRegion::sendMessage()
{
- gMessageSystem->sendMessage(mImpl->mHost);
+ gMessageSystem->sendMessage(mImpl->mHost);
}
void LLViewerRegion::sendReliableMessage()
{
- gMessageSystem->sendReliable(mImpl->mHost);
+ gMessageSystem->sendReliable(mImpl->mHost);
}
void LLViewerRegion::setWaterHeight(F32 water_level)
{
- mImpl->mLandp->setWaterHeight(water_level);
+ mImpl->mLandp->setWaterHeight(water_level);
}
F32 LLViewerRegion::getWaterHeight() const
{
- return mImpl->mLandp->getWaterHeight();
+ return mImpl->mLandp->getWaterHeight();
}
BOOL LLViewerRegion::isVoiceEnabled() const
{
- return getRegionFlag(REGION_FLAGS_ALLOW_VOICE);
+ return getRegionFlag(REGION_FLAGS_ALLOW_VOICE);
}
void LLViewerRegion::setRegionFlags(U64 flags)
{
- mRegionFlags = flags;
+ mRegionFlags = flags;
}
-void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global)
-{
- mImpl->mOriginGlobal = origin_global;
- updateRenderMatrix();
- mImpl->mLandp->setOriginGlobal(origin_global);
- mWind.setOriginGlobal(origin_global);
- calculateCenterGlobal();
+void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global)
+{
+ mImpl->mOriginGlobal = origin_global;
+ updateRenderMatrix();
+ mImpl->mLandp->setOriginGlobal(origin_global);
+ mWind.setOriginGlobal(origin_global);
+ calculateCenterGlobal();
}
void LLViewerRegion::updateRenderMatrix()
{
- mRenderMatrix.setTranslation(getOriginAgent());
+ mRenderMatrix.setTranslation(getOriginAgent());
}
void LLViewerRegion::setTimeDilation(F32 time_dilation)
{
- mTimeDilation = time_dilation;
+ mTimeDilation = time_dilation;
}
const LLVector3d & LLViewerRegion::getOriginGlobal() const
{
- return mImpl->mOriginGlobal;
+ return mImpl->mOriginGlobal;
}
LLVector3 LLViewerRegion::getOriginAgent() const
{
- return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
+ return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
}
const LLVector3d & LLViewerRegion::getCenterGlobal() const
{
- return mImpl->mCenterGlobal;
+ return mImpl->mCenterGlobal;
}
LLVector3 LLViewerRegion::getCenterAgent() const
{
- return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
+ return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
}
void LLViewerRegion::setOwner(const LLUUID& owner_id)
{
- mImpl->mOwnerID = owner_id;
+ mImpl->mOwnerID = owner_id;
}
const LLUUID& LLViewerRegion::getOwner() const
{
- return mImpl->mOwnerID;
+ return mImpl->mOwnerID;
}
-void LLViewerRegion::setRegionNameAndZone (const std::string& name_zone)
+void LLViewerRegion::setRegionNameAndZone (const std::string& name_zone)
{
- std::string::size_type pipe_pos = name_zone.find('|');
- S32 length = name_zone.size();
- if (pipe_pos != std::string::npos)
- {
- mName = name_zone.substr(0, pipe_pos);
- mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
- }
- else
- {
- mName = name_zone;
- mZoning = "";
- }
+ std::string::size_type pipe_pos = name_zone.find('|');
+ S32 length = name_zone.size();
+ if (pipe_pos != std::string::npos)
+ {
+ mName = name_zone.substr(0, pipe_pos);
+ mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
+ }
+ else
+ {
+ mName = name_zone;
+ mZoning = "";
+ }
- LLStringUtil::stripNonprintable(mName);
- LLStringUtil::stripNonprintable(mZoning);
+ LLStringUtil::stripNonprintable(mName);
+ LLStringUtil::stripNonprintable(mZoning);
}
BOOL LLViewerRegion::canManageEstate() const
{
- return gAgent.isGodlike()
- || isEstateManager()
- || gAgent.getID() == getOwner();
+ return gAgent.isGodlike()
+ || isEstateManager()
+ || gAgent.getID() == getOwner();
}
const std::string LLViewerRegion::getSimAccessString() const
{
- return accessToString(mSimAccess);
+ return accessToString(mSimAccess);
}
std::string LLViewerRegion::getLocalizedSimProductName() const
{
- std::string localized_spn;
- return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
+ std::string localized_spn;
+ return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
}
// static
std::string LLViewerRegion::regionFlagsToString(U64 flags)
{
- std::string result;
+ std::string result;
- if (flags & REGION_FLAGS_SANDBOX)
- {
- result += "Sandbox";
- }
+ if (flags & REGION_FLAGS_SANDBOX)
+ {
+ result += "Sandbox";
+ }
- if (flags & REGION_FLAGS_ALLOW_DAMAGE)
- {
- result += " Not Safe";
- }
+ if (flags & REGION_FLAGS_ALLOW_DAMAGE)
+ {
+ result += " Not Safe";
+ }
- return result;
+ return result;
}
// static
std::string LLViewerRegion::accessToString(U8 sim_access)
{
- switch(sim_access)
- {
- case SIM_ACCESS_PG:
- return LLTrans::getString("SIM_ACCESS_PG");
+ switch(sim_access)
+ {
+ case SIM_ACCESS_PG:
+ return LLTrans::getString("SIM_ACCESS_PG");
- case SIM_ACCESS_MATURE:
- return LLTrans::getString("SIM_ACCESS_MATURE");
+ case SIM_ACCESS_MATURE:
+ return LLTrans::getString("SIM_ACCESS_MATURE");
- case SIM_ACCESS_ADULT:
- return LLTrans::getString("SIM_ACCESS_ADULT");
+ case SIM_ACCESS_ADULT:
+ return LLTrans::getString("SIM_ACCESS_ADULT");
- case SIM_ACCESS_DOWN:
- return LLTrans::getString("SIM_ACCESS_DOWN");
+ case SIM_ACCESS_DOWN:
+ return LLTrans::getString("SIM_ACCESS_DOWN");
- case SIM_ACCESS_MIN:
- default:
- return LLTrans::getString("SIM_ACCESS_MIN");
- }
+ case SIM_ACCESS_MIN:
+ default:
+ return LLTrans::getString("SIM_ACCESS_MIN");
+ }
}
// static
std::string LLViewerRegion::getAccessIcon(U8 sim_access)
{
- switch(sim_access)
- {
- case SIM_ACCESS_MATURE:
- return "Parcel_M_Dark";
+ switch(sim_access)
+ {
+ case SIM_ACCESS_MATURE:
+ return "Parcel_M_Dark";
- case SIM_ACCESS_ADULT:
- return "Parcel_R_Light";
+ case SIM_ACCESS_ADULT:
+ return "Parcel_R_Light";
- case SIM_ACCESS_PG:
- return "Parcel_PG_Light";
+ case SIM_ACCESS_PG:
+ return "Parcel_PG_Light";
- case SIM_ACCESS_MIN:
- default:
- return "";
- }
+ case SIM_ACCESS_MIN:
+ default:
+ return "";
+ }
}
// static
std::string LLViewerRegion::accessToShortString(U8 sim_access)
{
- switch(sim_access) /* Flawfinder: ignore */
- {
- case SIM_ACCESS_PG:
- return "PG";
+ switch(sim_access) /* Flawfinder: ignore */
+ {
+ case SIM_ACCESS_PG:
+ return "PG";
- case SIM_ACCESS_MATURE:
- return "M";
+ case SIM_ACCESS_MATURE:
+ return "M";
- case SIM_ACCESS_ADULT:
- return "A";
+ case SIM_ACCESS_ADULT:
+ return "A";
- case SIM_ACCESS_MIN:
- default:
- return "U";
- }
+ case SIM_ACCESS_MIN:
+ default:
+ return "U";
+ }
}
// static
U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access)
{
- U8 accessValue;
+ U8 accessValue;
- if (LLStringUtil::compareStrings(sim_access, "PG") == 0)
- {
- accessValue = SIM_ACCESS_PG;
- }
- else if (LLStringUtil::compareStrings(sim_access, "M") == 0)
- {
- accessValue = SIM_ACCESS_MATURE;
- }
- else if (LLStringUtil::compareStrings(sim_access, "A") == 0)
- {
- accessValue = SIM_ACCESS_ADULT;
- }
- else
- {
- accessValue = SIM_ACCESS_MIN;
- }
+ if (LLStringUtil::compareStrings(sim_access, "PG") == 0)
+ {
+ accessValue = SIM_ACCESS_PG;
+ }
+ else if (LLStringUtil::compareStrings(sim_access, "M") == 0)
+ {
+ accessValue = SIM_ACCESS_MATURE;
+ }
+ else if (LLStringUtil::compareStrings(sim_access, "A") == 0)
+ {
+ accessValue = SIM_ACCESS_ADULT;
+ }
+ else
+ {
+ accessValue = SIM_ACCESS_MIN;
+ }
- return accessValue;
+ return accessValue;
}
// static
void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
{
- // send it to 'observers'
- // *TODO: switch the floaters to using LLRegionInfoModel
- LL_INFOS() << "Processing region info" << LL_ENDL;
- LLRegionInfoModel::instance().update(msg);
- LLFloaterGodTools::processRegionInfo(msg);
- LLFloaterRegionInfo::processRegionInfo(msg);
+ // send it to 'observers'
+ // *TODO: switch the floaters to using LLRegionInfoModel
+ LL_INFOS() << "Processing region info" << LL_ENDL;
+ LLRegionInfoModel::instance().update(msg);
+ LLFloaterGodTools::processRegionInfo(msg);
+ LLFloaterRegionInfo::processRegionInfo(msg);
}
void LLViewerRegion::setCacheID(const LLUUID& id)
{
- mImpl->mCacheID = id;
+ mImpl->mCacheID = id;
}
S32 LLViewerRegion::renderPropertyLines()
{
- if (mParcelOverlay)
- {
- return mParcelOverlay->renderPropertyLines();
- }
- else
- {
- return 0;
- }
+ if (mParcelOverlay)
+ {
+ return mParcelOverlay->renderPropertyLines();
+ }
+ else
+ {
+ return 0;
+ }
}
void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
@@ -1105,168 +1106,173 @@ void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, co
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
- // Property lines need to be reconstructed when the land changes.
- if (mParcelOverlay)
- {
- mParcelOverlay->setDirty();
- }
+ // Property lines need to be reconstructed when the land changes.
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->setDirty();
+ }
}
-//physically delete the cache entry
-void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
+void LLViewerRegion::dirtyAllPatches()
{
- if(!entry || !entry->isValid())
- {
- return;
- }
-
- if(for_rendering && !entry->isState(LLVOCacheEntry::ACTIVE))
- {
- addNewObject(entry); //force to add to rendering pipeline
- }
-
- //remove from active list and waiting list
- if(entry->isState(LLVOCacheEntry::ACTIVE))
- {
- mImpl->mActiveSet.erase(entry);
- }
- else
- {
- if(entry->isState(LLVOCacheEntry::WAITING))
- {
- mImpl->mWaitingSet.erase(entry);
- }
-
- //remove from mVOCachePartition
- removeFromVOCacheTree(entry);
- }
-
- //remove from the forced visible list
- mImpl->mVisibleEntries.erase(entry);
-
- //disconnect from parent if it is a child
- if(entry->getParentID() > 0)
- {
- LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
- if(parent)
- {
- parent->removeChild(entry);
- }
- }
- else if(entry->getNumOfChildren() > 0)//remove children from cache if has any
- {
- LLVOCacheEntry* child = entry->getChild();
- while(child != NULL)
- {
- killCacheEntry(child, for_rendering);
- child = entry->getChild();
- }
- }
-
- //will remove it from the object cache, real deletion
- entry->setState(LLVOCacheEntry::INACTIVE);
- entry->removeOctreeEntry();
- entry->setValid(FALSE);
-
- // TODO kill extras/material overrides cache too
+ getLand().dirtyAllPatches();
}
//physically delete the cache entry
-void LLViewerRegion::killCacheEntry(U32 local_id)
-{
- killCacheEntry(getCacheEntry(local_id));
+void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
+{
+ if(!entry || !entry->isValid())
+ {
+ return;
+ }
+
+ if(for_rendering && !entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ addNewObject(entry); //force to add to rendering pipeline
+ }
+
+ //remove from active list and waiting list
+ if(entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ mImpl->mActiveSet.erase(entry);
+ }
+ else
+ {
+ if(entry->isState(LLVOCacheEntry::WAITING))
+ {
+ mImpl->mWaitingSet.erase(entry);
+ }
+
+ //remove from mVOCachePartition
+ removeFromVOCacheTree(entry);
+ }
+
+ //remove from the forced visible list
+ mImpl->mVisibleEntries.erase(entry);
+
+ //disconnect from parent if it is a child
+ if(entry->getParentID() > 0)
+ {
+ LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
+ if(parent)
+ {
+ parent->removeChild(entry);
+ }
+ }
+ else if(entry->getNumOfChildren() > 0)//remove children from cache if has any
+ {
+ LLVOCacheEntry* child = entry->getChild();
+ while(child != NULL)
+ {
+ killCacheEntry(child, for_rendering);
+ child = entry->getChild();
+ }
+ }
+ // Kill the assocaited overrides
+ mImpl->mGLTFOverridesLLSD.erase(entry->getLocalID());
+ //will remove it from the object cache, real deletion
+ entry->setState(LLVOCacheEntry::INACTIVE);
+ entry->removeOctreeEntry();
+ entry->setValid(FALSE);
+
+}
+
+//physically delete the cache entry
+void LLViewerRegion::killCacheEntry(U32 local_id)
+{
+ killCacheEntry(getCacheEntry(local_id));
}
U32 LLViewerRegion::getNumOfActiveCachedObjects() const
{
- return mImpl->mActiveSet.size();
+ return mImpl->mActiveSet.size();
}
void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
{
- if(!entry || mDead)
- {
- return;
- }
- if(entry->isState(LLVOCacheEntry::ACTIVE))
- {
- return; //already inserted.
- }
+ if(!entry || mDead)
+ {
+ return;
+ }
+ if(entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ return; //already inserted.
+ }
- if(entry->isState(LLVOCacheEntry::WAITING))
- {
- mImpl->mWaitingSet.erase(entry);
- }
+ if(entry->isState(LLVOCacheEntry::WAITING))
+ {
+ mImpl->mWaitingSet.erase(entry);
+ }
- entry->setState(LLVOCacheEntry::ACTIVE);
- entry->setVisible();
+ entry->setState(LLVOCacheEntry::ACTIVE);
+ entry->setVisible();
- llassert(entry->getEntry()->hasDrawable());
- mImpl->mActiveSet.insert(entry);
+ llassert(entry->getEntry()->hasDrawable());
+ mImpl->mActiveSet.insert(entry);
}
void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep)
{
- if(mDead || !entry || !entry->isValid())
- {
- return;
- }
- if(!entry->isState(LLVOCacheEntry::ACTIVE))
- {
- return; //not an active entry.
- }
-
- //shift to the local regional space from agent space
- if(drawablep != NULL && drawablep->getVObj().notNull())
- {
- const LLVector3& pos = drawablep->getVObj()->getPositionRegion();
- LLVector4a shift;
- shift.load3(pos.mV);
- shift.sub(entry->getPositionGroup());
- entry->shift(shift);
- }
-
- if(entry->getParentID() > 0) //is a child
- {
- LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
- if(parent)
- {
- parent->addChild(entry);
- }
- else //parent not in cache.
- {
- //this happens only when parent is not cacheable.
- mOrphanMap[entry->getParentID()].push_back(entry->getLocalID());
- }
- }
- else //insert to vo cache tree.
- {
- entry->updateParentBoundingInfo();
- entry->saveBoundingSphere();
- addToVOCacheTree(entry);
- }
-
- mImpl->mVisibleEntries.erase(entry);
- mImpl->mActiveSet.erase(entry);
- mImpl->mWaitingSet.erase(entry);
- entry->setState(LLVOCacheEntry::INACTIVE);
+ if(mDead || !entry || !entry->isValid())
+ {
+ return;
+ }
+ if(!entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ return; //not an active entry.
+ }
+
+ //shift to the local regional space from agent space
+ if(drawablep != NULL && drawablep->getVObj().notNull())
+ {
+ const LLVector3& pos = drawablep->getVObj()->getPositionRegion();
+ LLVector4a shift;
+ shift.load3(pos.mV);
+ shift.sub(entry->getPositionGroup());
+ entry->shift(shift);
+ }
+
+ if(entry->getParentID() > 0) //is a child
+ {
+ LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
+ if(parent)
+ {
+ parent->addChild(entry);
+ }
+ else //parent not in cache.
+ {
+ //this happens only when parent is not cacheable.
+ mOrphanMap[entry->getParentID()].push_back(entry->getLocalID());
+ }
+ }
+ else //insert to vo cache tree.
+ {
+ entry->updateParentBoundingInfo();
+ entry->saveBoundingSphere();
+ addToVOCacheTree(entry);
+ }
+
+ mImpl->mVisibleEntries.erase(entry);
+ mImpl->mActiveSet.erase(entry);
+ mImpl->mWaitingSet.erase(entry);
+ entry->setState(LLVOCacheEntry::INACTIVE);
}
bool LLViewerRegion::addVisibleGroup(LLViewerOctreeGroup* group)
{
- if(mDead || group->isEmpty())
- {
- return false;
- }
-
- mImpl->mVisibleGroups.insert(group);
+ if(mDead || group->isEmpty())
+ {
+ return false;
+ }
+
+ mImpl->mVisibleGroups.insert(group);
- return true;
+ return true;
}
U32 LLViewerRegion::getNumOfVisibleGroups() const
{
- return mImpl ? mImpl->mVisibleGroups.size() : 0;
+ return mImpl ? mImpl->mVisibleGroups.size() : 0;
}
void LLViewerRegion::updateReflectionProbes()
@@ -1311,350 +1317,362 @@ void LLViewerRegion::updateReflectionProbes()
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
{
- if(!sVOCacheCullingEnabled)
- {
- return;
- }
+ if(!sVOCacheCullingEnabled)
+ {
+ return;
+ }
- if(mDead || !entry || !entry->getEntry() || !entry->isValid())
- {
- return;
- }
- if(entry->getParentID() > 0)
- {
- return; //no child prim in cache octree.
- }
+ if(mDead || !entry || !entry->getEntry() || !entry->isValid())
+ {
+ return;
+ }
+ if(entry->getParentID() > 0)
+ {
+ return; //no child prim in cache octree.
+ }
- if(entry->hasState(LLVOCacheEntry::IN_VO_TREE))
- {
- return; //already in the tree.
- }
+ if(entry->hasState(LLVOCacheEntry::IN_VO_TREE))
+ {
+ return; //already in the tree.
+ }
- llassert_always(!entry->getGroup()); //not in octree.
- llassert(!entry->getEntry()->hasDrawable()); //not have drawables
+ llassert_always(!entry->getGroup()); //not in octree.
+ llassert(!entry->getEntry()->hasDrawable()); //not have drawables
- if(mImpl->mVOCachePartition->addEntry(entry->getEntry()))
- {
- entry->setState(LLVOCacheEntry::IN_VO_TREE);
- }
+ if(mImpl->mVOCachePartition->addEntry(entry->getEntry()))
+ {
+ entry->setState(LLVOCacheEntry::IN_VO_TREE);
+ }
}
void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
{
- if(mDead || !entry || !entry->getEntry())
- {
- return;
- }
+ if(mDead || !entry || !entry->getEntry())
+ {
+ return;
+ }
+
+ if(!entry->hasState(LLVOCacheEntry::IN_VO_TREE))
+ {
+ return; //not in the tree.
+ }
+ entry->clearState(LLVOCacheEntry::IN_VO_TREE);
- if(!entry->hasState(LLVOCacheEntry::IN_VO_TREE))
- {
- return; //not in the tree.
- }
- entry->clearState(LLVOCacheEntry::IN_VO_TREE);
-
- mImpl->mVOCachePartition->removeEntry(entry->getEntry());
+ mImpl->mVOCachePartition->removeEntry(entry->getEntry());
}
//add child objects as visible entries
void LLViewerRegion::addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child)
{
- if(mDead)
- {
- return;
- }
-
- if(parent && (!parent->isValid() || !parent->isState(LLVOCacheEntry::ACTIVE)))
- {
- return; //parent must be valid and in rendering pipeline
- }
-
- if(child && (!child->getEntry() || !child->isValid() || !child->isState(LLVOCacheEntry::INACTIVE)))
- {
- return; //child must be valid and not in the rendering pipeline
- }
-
- if(child)
- {
- child->setState(LLVOCacheEntry::IN_QUEUE);
- mImpl->mVisibleEntries.insert(child);
- }
- else if(parent && parent->getNumOfChildren() > 0) //add all children
- {
- child = parent->getChild();
- while(child != NULL)
- {
- addVisibleChildCacheEntry(NULL, child);
- child = parent->getChild();
- }
- }
+ if(mDead)
+ {
+ return;
+ }
+
+ if(parent && (!parent->isValid() || !parent->isState(LLVOCacheEntry::ACTIVE)))
+ {
+ return; //parent must be valid and in rendering pipeline
+ }
+
+ if(child && (!child->getEntry() || !child->isValid() || !child->isState(LLVOCacheEntry::INACTIVE)))
+ {
+ return; //child must be valid and not in the rendering pipeline
+ }
+
+ if(child)
+ {
+ child->setState(LLVOCacheEntry::IN_QUEUE);
+ mImpl->mVisibleEntries.insert(child);
+ }
+ else if(parent && parent->getNumOfChildren() > 0) //add all children
+ {
+ child = parent->getChild();
+ while(child != NULL)
+ {
+ addVisibleChildCacheEntry(NULL, child);
+ child = parent->getChild();
+ }
+ }
}
void LLViewerRegion::updateVisibleEntries(F32 max_time)
{
- if(mDead)
- {
- return;
- }
-
- if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty())
- {
- return;
- }
-
- if(!sNewObjectCreationThrottle)
- {
- return;
- }
-
- const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
- const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin();
- const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
- bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);
- U32 last_update = mImpl->mLastCameraUpdate;
- LLVector4a local_origin;
- local_origin.load3((camera_origin - getOriginAgent()).mV);
-
- //process visible entries
- for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
- {
- LLVOCacheEntry* vo_entry = *iter;
-
- if(vo_entry->isValid() && vo_entry->getState() < LLVOCacheEntry::WAITING)
- {
- //set a large number to force to load this object.
- vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION);
-
- mImpl->mWaitingList.insert(vo_entry);
- ++iter;
- }
- else
- {
- LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
- ++next_iter;
- mImpl->mVisibleEntries.erase(iter);
- iter = next_iter;
- }
- }
-
- //
- //process visible groups
- //
- //object projected area threshold
- F32 projection_threshold = LLVOCacheEntry::getSquaredPixelThreshold(mImpl->mVOCachePartition->isFrontCull());
- F32 dist_threshold = mImpl->mVOCachePartition->isFrontCull() ? gAgentCamera.mDrawDistance : LLVOCacheEntry::sRearFarRadius;
-
- std::set< LLPointer<LLViewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin();
- for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter)
- {
- LLPointer<LLViewerOctreeGroup> group = *group_iter;
- if(group->getNumRefs() < 3 || //group to be deleted
- !group->getOctreeNode() || group->isEmpty()) //group empty
- {
- continue;
- }
-
- for (LLViewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- if((*i)->hasVOCacheEntry())
- {
- LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry();
-
- if(vo_entry->getParentID() > 0) //is a child
- {
- //child visibility depends on its parent.
- continue;
- }
- if(!vo_entry->isValid())
- {
- continue; //skip invalid entry.
- }
-
- vo_entry->calcSceneContribution(local_origin, needs_update, last_update, dist_threshold);
- if(vo_entry->getSceneContribution() > projection_threshold)
- {
- mImpl->mWaitingList.insert(vo_entry);
- }
- }
- }
- }
-
- if(needs_update)
- {
- mImpl->mLastCameraOrigin = camera_origin;
- mImpl->mLastCameraUpdate = cur_frame;
- }
-
- return;
+ if(mDead)
+ {
+ return;
+ }
+
+ if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty())
+ {
+ return;
+ }
+
+ if(!sNewObjectCreationThrottle)
+ {
+ return;
+ }
+
+ const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
+ const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin();
+ const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
+ bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);
+ U32 last_update = mImpl->mLastCameraUpdate;
+ LLVector4a local_origin;
+ local_origin.load3((camera_origin - getOriginAgent()).mV);
+
+ //process visible entries
+ for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
+ {
+ LLVOCacheEntry* vo_entry = *iter;
+
+ if(vo_entry->isValid() && vo_entry->getState() < LLVOCacheEntry::WAITING)
+ {
+ //set a large number to force to load this object.
+ vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION);
+
+ mImpl->mWaitingList.insert(vo_entry);
+ ++iter;
+ }
+ else
+ {
+ LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
+ ++next_iter;
+ mImpl->mVisibleEntries.erase(iter);
+ iter = next_iter;
+ }
+ }
+
+ //
+ //process visible groups
+ //
+ //object projected area threshold
+ F32 projection_threshold = LLVOCacheEntry::getSquaredPixelThreshold(mImpl->mVOCachePartition->isFrontCull());
+ F32 dist_threshold = mImpl->mVOCachePartition->isFrontCull() ? gAgentCamera.mDrawDistance : LLVOCacheEntry::sRearFarRadius;
+
+ std::set< LLPointer<LLViewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin();
+ for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter)
+ {
+ LLPointer<LLViewerOctreeGroup> group = *group_iter;
+ if(group->getNumRefs() < 3 || //group to be deleted
+ !group->getOctreeNode() || group->isEmpty()) //group empty
+ {
+ continue;
+ }
+
+ for (LLViewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ if((*i)->hasVOCacheEntry())
+ {
+ LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry();
+
+ if(vo_entry->getParentID() > 0) //is a child
+ {
+ //child visibility depends on its parent.
+ continue;
+ }
+ if(!vo_entry->isValid())
+ {
+ continue; //skip invalid entry.
+ }
+
+ vo_entry->calcSceneContribution(local_origin, needs_update, last_update, dist_threshold);
+ if(vo_entry->getSceneContribution() > projection_threshold)
+ {
+ mImpl->mWaitingList.insert(vo_entry);
+ }
+ }
+ }
+ }
+
+ if(needs_update)
+ {
+ mImpl->mLastCameraOrigin = camera_origin;
+ mImpl->mLastCameraUpdate = cur_frame;
+ }
+
+ return;
}
void LLViewerRegion::createVisibleObjects(F32 max_time)
{
- if(mDead)
- {
- return;
- }
- if(mImpl->mWaitingList.empty())
- {
- mImpl->mVOCachePartition->setCullHistory(FALSE);
- return;
- }
-
- S32 throttle = sNewObjectCreationThrottle;
- BOOL has_new_obj = FALSE;
- LLTimer update_timer;
- for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
- iter != mImpl->mWaitingList.end(); ++iter)
- {
- LLVOCacheEntry* vo_entry = *iter;
-
- if(vo_entry->getState() < LLVOCacheEntry::WAITING)
- {
- addNewObject(vo_entry);
- has_new_obj = TRUE;
- if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time)
- {
- break;
- }
- }
- }
-
- mImpl->mVOCachePartition->setCullHistory(has_new_obj);
-
- return;
+ if(mDead)
+ {
+ return;
+ }
+ if(mImpl->mWaitingList.empty())
+ {
+ mImpl->mVOCachePartition->setCullHistory(FALSE);
+ return;
+ }
+
+ S32 throttle = sNewObjectCreationThrottle;
+ BOOL has_new_obj = FALSE;
+ LLTimer update_timer;
+ for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
+ iter != mImpl->mWaitingList.end(); ++iter)
+ {
+ LLVOCacheEntry* vo_entry = *iter;
+
+ if(vo_entry->getState() < LLVOCacheEntry::WAITING)
+ {
+ addNewObject(vo_entry);
+ has_new_obj = TRUE;
+ if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ }
+
+ mImpl->mVOCachePartition->setCullHistory(has_new_obj);
+
+ return;
}
void LLViewerRegion::clearCachedVisibleObjects()
{
- mImpl->mWaitingList.clear();
- mImpl->mVisibleGroups.clear();
-
- //reset all occluders
- mImpl->mVOCachePartition->resetOccluders();
- mPaused = TRUE;
-
- //clean visible entries
- for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
- {
- LLVOCacheEntry* entry = *iter;
- LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
-
- if(!entry->getParentID() || parent) //no child or parent is cache-able
- {
- if(parent) //has a cache-able parent
- {
- parent->addChild(entry);
- }
-
- LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
- ++next_iter;
- mImpl->mVisibleEntries.erase(iter);
- iter = next_iter;
- }
- else //parent is not cache-able, leave it.
- {
- ++iter;
- }
- }
-
- //remove all visible entries.
- mLastVisitedEntry = NULL;
- std::vector<LLDrawable*> delete_list;
- for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin();
- iter != mImpl->mActiveSet.end(); ++iter)
- {
+ mImpl->mWaitingList.clear();
+ mImpl->mVisibleGroups.clear();
+
+ //reset all occluders
+ mImpl->mVOCachePartition->resetOccluders();
+ mPaused = TRUE;
+
+ //clean visible entries
+ for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
+ {
+ LLVOCacheEntry* entry = *iter;
+ LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
+
+ if(!entry->getParentID() || parent) //no child or parent is cache-able
+ {
+ if(parent) //has a cache-able parent
+ {
+ parent->addChild(entry);
+ }
+
+ LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
+ ++next_iter;
+ mImpl->mVisibleEntries.erase(iter);
+ iter = next_iter;
+ }
+ else //parent is not cache-able, leave it.
+ {
+ ++iter;
+ }
+ }
+
+ //remove all visible entries.
+ mLastVisitedEntry = NULL;
+ std::vector<LLDrawable*> delete_list;
+ for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin();
+ iter != mImpl->mActiveSet.end(); ++iter)
+ {
LLVOCacheEntry* vo_entry = *iter;
if (!vo_entry || !vo_entry->getEntry())
{
continue;
}
LLDrawable* drawablep = (LLDrawable*)vo_entry->getEntry()->getDrawable();
+
+ if(drawablep && !drawablep->getParent())
+ {
+ delete_list.push_back(drawablep);
+ }
+ }
- if(drawablep && !drawablep->getParent())
- {
- delete_list.push_back(drawablep);
- }
- }
+ if(!delete_list.empty())
+ {
+ for(S32 i = 0; i < delete_list.size(); i++)
+ {
+ gObjectList.killObject(delete_list[i]->getVObj());
+ }
+ delete_list.clear();
+ }
- if(!delete_list.empty())
- {
- for(S32 i = 0; i < delete_list.size(); i++)
- {
- gObjectList.killObject(delete_list[i]->getVObj());
- }
- delete_list.clear();
- }
-
- return;
+ return;
}
//perform some necessary but very light updates.
//to replace the function idleUpdate(...) in case there is no enough time.
void LLViewerRegion::lightIdleUpdate()
{
- if(!sVOCacheCullingEnabled)
- {
- return;
- }
- if(mImpl->mCacheMap.empty())
- {
- return;
- }
+ if(!sVOCacheCullingEnabled)
+ {
+ return;
+ }
+ if(mImpl->mCacheMap.empty())
+ {
+ return;
+ }
- //reset all occluders
- mImpl->mVOCachePartition->resetOccluders();
+ //reset all occluders
+ mImpl->mVOCachePartition->resetOccluders();
}
void LLViewerRegion::idleUpdate(F32 max_update_time)
-{
+{
LL_PROFILE_ZONE_SCOPED;
- LLTimer update_timer;
- F32 max_time;
+ LLTimer update_timer;
+ F32 max_time;
- mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
+ mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
- mImpl->mLandp->idleUpdate(max_update_time);
+ static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+ static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
+ bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
+ bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
- if (mParcelOverlay)
- {
- // Hopefully not a significant time sink...
- mParcelOverlay->idleUpdate();
- }
-
- if(!sVOCacheCullingEnabled)
- {
- return;
- }
- if(mImpl->mCacheMap.empty())
+ if (!pbr_land)
{
- return;
+ mImpl->mLandp->idleUpdate</*PBR=*/false>(max_update_time);
}
- if(mPaused)
+ else
{
- mPaused = FALSE; //unpause.
+ mImpl->mLandp->idleUpdate</*PBR=*/true>(max_update_time);
}
+
+ if (mParcelOverlay)
+ {
+ // Hopefully not a significant time sink...
+ mParcelOverlay->idleUpdate();
+ }
+
+ if(!sVOCacheCullingEnabled)
+ {
+ return;
+ }
+ if(mImpl->mCacheMap.empty())
+ {
+ return;
+ }
+ if(mPaused)
+ {
+ mPaused = FALSE; //unpause.
+ }
- LLViewerCamera::eCameraID old_camera_id = LLViewerCamera::sCurCameraID;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLViewerCamera::eCameraID old_camera_id = LLViewerCamera::sCurCameraID;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- //reset all occluders
- mImpl->mVOCachePartition->resetOccluders();
+ //reset all occluders
+ mImpl->mVOCachePartition->resetOccluders();
- max_time = max_update_time - update_timer.getElapsedTimeF32();
+ max_time = max_update_time - update_timer.getElapsedTimeF32();
- //kill invisible objects
- killInvisibleObjects(max_time * 0.4f);
- max_time = max_update_time - update_timer.getElapsedTimeF32();
+ //kill invisible objects
+ killInvisibleObjects(max_time * 0.4f);
+ max_time = max_update_time - update_timer.getElapsedTimeF32();
- updateVisibleEntries(max_time);
- max_time = max_update_time - update_timer.getElapsedTimeF32();
+ updateVisibleEntries(max_time);
+ max_time = max_update_time - update_timer.getElapsedTimeF32();
- createVisibleObjects(max_time);
+ createVisibleObjects(max_time);
- mImpl->mWaitingList.clear();
- mImpl->mVisibleGroups.clear();
+ mImpl->mWaitingList.clear();
+ mImpl->mVisibleGroups.clear();
- LLViewerCamera::sCurCameraID = old_camera_id;
- return;
+ LLViewerCamera::sCurCameraID = old_camera_id;
+ return;
}
// static
@@ -1670,381 +1688,395 @@ void LLViewerRegion::idleCleanup(F32 max_update_time)
//update the throttling number for new object creation
void LLViewerRegion::calcNewObjectCreationThrottle()
{
- static LLCachedControl<S32> new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle");
- static LLCachedControl<F32> throttle_delay_time(gSavedSettings,"NewObjectCreationThrottleDelayTime");
- static LLFrameTimer timer;
-
- //
- //sNewObjectCreationThrottle =
- //-2: throttle is disabled because either the screen is showing progress view, or immediate after the screen is not black
- //-1: throttle is disabled by the debug setting
- //0: no new object creation is allowed
- //>0: valid throttling number
- //
-
- if(gViewerWindow->getProgressView()->getVisible() && throttle_delay_time > 0.f)
- {
- sNewObjectCreationThrottle = -2; //cancel the throttling
- timer.reset();
- }
- else if(sNewObjectCreationThrottle < -1) //just recoved from the login/teleport screen
- {
- if(timer.getElapsedTimeF32() > throttle_delay_time) //wait for throttle_delay_time to reset the throttle
- {
- sNewObjectCreationThrottle = new_object_creation_throttle; //reset
- if(sNewObjectCreationThrottle < -1)
- {
- sNewObjectCreationThrottle = -1;
- }
- }
- }
-
- //update some LLVOCacheEntry debug setting factors.
- LLVOCacheEntry::updateDebugSettings();
+ static LLCachedControl<S32> new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle");
+ static LLCachedControl<F32> throttle_delay_time(gSavedSettings,"NewObjectCreationThrottleDelayTime");
+ static LLFrameTimer timer;
+
+ //
+ //sNewObjectCreationThrottle =
+ //-2: throttle is disabled because either the screen is showing progress view, or immediate after the screen is not black
+ //-1: throttle is disabled by the debug setting
+ //0: no new object creation is allowed
+ //>0: valid throttling number
+ //
+
+ if(gViewerWindow->getProgressView()->getVisible() && throttle_delay_time > 0.f)
+ {
+ sNewObjectCreationThrottle = -2; //cancel the throttling
+ timer.reset();
+ }
+ else if(sNewObjectCreationThrottle < -1) //just recoved from the login/teleport screen
+ {
+ if(timer.getElapsedTimeF32() > throttle_delay_time) //wait for throttle_delay_time to reset the throttle
+ {
+ sNewObjectCreationThrottle = new_object_creation_throttle; //reset
+ if(sNewObjectCreationThrottle < -1)
+ {
+ sNewObjectCreationThrottle = -1;
+ }
+ }
+ }
+
+ //update some LLVOCacheEntry debug setting factors.
+ LLVOCacheEntry::updateDebugSettings();
}
BOOL LLViewerRegion::isViewerCameraStatic()
{
- return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame();
+ return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame();
}
void LLViewerRegion::killInvisibleObjects(F32 max_time)
{
#if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory.
// because of this, every time you turn around the simulator sends a swarm of full object update messages from cache
- // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to
+ // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to
// appear in the scene when flying back and forth between regions
- if(!sVOCacheCullingEnabled)
- {
- return;
- }
- if(mImpl->mActiveSet.empty())
- {
- return;
- }
- if(sNewObjectCreationThrottle < 0)
- {
- return;
- }
-
- LLTimer update_timer;
- LLVector4a camera_origin;
- camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
- LLVector4a local_origin;
- local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV);
- F32 back_threshold = LLVOCacheEntry::sRearFarRadius;
-
- size_t max_update = 64;
- if(!mInvisibilityCheckHistory && isViewerCameraStatic())
- {
- //history is clean, reduce number of checking
- max_update /= 2;
- }
-
- std::vector<LLDrawable*> delete_list;
- S32 update_counter = llmin(max_update, mImpl->mActiveSet.size());
- LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(mLastVisitedEntry);
-
- for(; update_counter > 0; --update_counter, ++iter)
- {
- if(iter == mImpl->mActiveSet.end())
- {
- iter = mImpl->mActiveSet.begin();
- }
- if((*iter)->getParentID() > 0)
- {
- continue; //skip child objects, they are removed with their parent.
- }
-
- LLVOCacheEntry* vo_entry = *iter;
- if(!vo_entry->isAnyVisible(camera_origin, local_origin, back_threshold) && vo_entry->mLastCameraUpdated < sLastCameraUpdated)
- {
- killObject(vo_entry, delete_list);
- }
-
- if(max_time < update_timer.getElapsedTimeF32()) //time out
- {
- break;
- }
- }
-
- if(iter == mImpl->mActiveSet.end())
- {
- mLastVisitedEntry = NULL;
- }
- else
- {
- mLastVisitedEntry = *iter;
- }
-
- mInvisibilityCheckHistory <<= 1;
- if(!delete_list.empty())
- {
- mInvisibilityCheckHistory |= 1;
- S32 count = delete_list.size();
- for(S32 i = 0; i < count; i++)
- {
- gObjectList.killObject(delete_list[i]->getVObj());
- }
- delete_list.clear();
- }
-
- return;
+ if(!sVOCacheCullingEnabled)
+ {
+ return;
+ }
+ if(mImpl->mActiveSet.empty())
+ {
+ return;
+ }
+ if(sNewObjectCreationThrottle < 0)
+ {
+ return;
+ }
+
+ LLTimer update_timer;
+ LLVector4a camera_origin;
+ camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
+ LLVector4a local_origin;
+ local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV);
+ F32 back_threshold = LLVOCacheEntry::sRearFarRadius;
+
+ size_t max_update = 64;
+ if(!mInvisibilityCheckHistory && isViewerCameraStatic())
+ {
+ //history is clean, reduce number of checking
+ max_update /= 2;
+ }
+
+ std::vector<LLDrawable*> delete_list;
+ S32 update_counter = llmin(max_update, mImpl->mActiveSet.size());
+ LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(mLastVisitedEntry);
+
+ for(; update_counter > 0; --update_counter, ++iter)
+ {
+ if(iter == mImpl->mActiveSet.end())
+ {
+ iter = mImpl->mActiveSet.begin();
+ }
+ if((*iter)->getParentID() > 0)
+ {
+ continue; //skip child objects, they are removed with their parent.
+ }
+
+ LLVOCacheEntry* vo_entry = *iter;
+ if(!vo_entry->isAnyVisible(camera_origin, local_origin, back_threshold) && vo_entry->mLastCameraUpdated < sLastCameraUpdated)
+ {
+ killObject(vo_entry, delete_list);
+ }
+
+ if(max_time < update_timer.getElapsedTimeF32()) //time out
+ {
+ break;
+ }
+ }
+
+ if(iter == mImpl->mActiveSet.end())
+ {
+ mLastVisitedEntry = NULL;
+ }
+ else
+ {
+ mLastVisitedEntry = *iter;
+ }
+
+ mInvisibilityCheckHistory <<= 1;
+ if(!delete_list.empty())
+ {
+ mInvisibilityCheckHistory |= 1;
+ S32 count = delete_list.size();
+ for(S32 i = 0; i < count; i++)
+ {
+ gObjectList.killObject(delete_list[i]->getVObj());
+ }
+ delete_list.clear();
+ }
+
+ return;
#endif
}
void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
{
- //kill the object.
- LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
- llassert(drawablep);
- llassert(drawablep->getRegion() == this);
-
- if(drawablep && !drawablep->getParent())
- {
- LLViewerObject* v_obj = drawablep->getVObj();
- if (v_obj->isSelected()
- || (v_obj->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(v_obj->getID())))
- {
- // do not remove objects user is interacting with
- ((LLViewerOctreeEntryData*)drawablep)->setVisible();
- return;
- }
- LLViewerObject::const_child_list_t& child_list = v_obj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if(child->mDrawable)
- {
- if( !child->mDrawable->getEntry()
- || !child->mDrawable->getEntry()->hasVOCacheEntry()
- || child->isSelected()
- || (child->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(child->getID())))
- {
- //do not remove parent if any of its children non-cacheable, animating or selected
- //especially for the case that an avatar sits on a cache-able object
- ((LLViewerOctreeEntryData*)drawablep)->setVisible();
- return;
- }
-
- LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)child->mDrawable->getGroup();
- if(group && group->isAnyRecentlyVisible())
- {
- //set the parent visible if any of its children visible.
- ((LLViewerOctreeEntryData*)drawablep)->setVisible();
- return;
- }
- }
- }
- delete_list.push_back(drawablep);
- }
+ //kill the object.
+ LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
+ llassert(drawablep);
+ llassert(drawablep->getRegion() == this);
+
+ if(drawablep && !drawablep->getParent())
+ {
+ LLViewerObject* v_obj = drawablep->getVObj();
+ if (v_obj->isSelected()
+ || (v_obj->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(v_obj->getID())))
+ {
+ // do not remove objects user is interacting with
+ ((LLViewerOctreeEntryData*)drawablep)->setVisible();
+ return;
+ }
+ LLViewerObject::const_child_list_t& child_list = v_obj->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if(child->mDrawable)
+ {
+ if( !child->mDrawable->getEntry()
+ || !child->mDrawable->getEntry()->hasVOCacheEntry()
+ || child->isSelected()
+ || (child->flagAnimSource() && isAgentAvatarValid() && gAgentAvatarp->hasMotionFromSource(child->getID())))
+ {
+ //do not remove parent if any of its children non-cacheable, animating or selected
+ //especially for the case that an avatar sits on a cache-able object
+ ((LLViewerOctreeEntryData*)drawablep)->setVisible();
+ return;
+ }
+
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)child->mDrawable->getGroup();
+ if(group && group->isAnyRecentlyVisible())
+ {
+ //set the parent visible if any of its children visible.
+ ((LLViewerOctreeEntryData*)drawablep)->setVisible();
+ return;
+ }
+ }
+ }
+ delete_list.push_back(drawablep);
+ }
}
LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
{
- if(!entry || !entry->getEntry())
- {
- if(entry)
- {
- mImpl->mVisibleEntries.erase(entry);
- entry->setState(LLVOCacheEntry::INACTIVE);
- }
- return NULL;
- }
-
- LLViewerObject* obj = NULL;
- if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
- {
- //add the object
- obj = gObjectList.processObjectUpdateFromCache(entry, this);
- if(obj)
- {
- if(!entry->isState(LLVOCacheEntry::ACTIVE))
- {
- mImpl->mWaitingSet.insert(entry);
- entry->setState(LLVOCacheEntry::WAITING);
- }
- }
- }
- else
- {
- LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
- if(old_regionp != this)
- {
- //this object exists in two regions at the same time;
- //this case can be safely ignored here because
- //server should soon send update message to remove one region for this object.
-
- LL_WARNS() << "Entry: " << entry->getLocalID() << " exists in two regions at the same time." << LL_ENDL;
- return NULL;
- }
-
- LL_WARNS() << "Entry: " << entry->getLocalID() << " in rendering pipeline but not set to be active." << LL_ENDL;
-
- //should not hit here any more, but does not hurt either, just put it back to active list
- addActiveCacheEntry(entry);
- }
-
- return obj;
+ if(!entry || !entry->getEntry())
+ {
+ if(entry)
+ {
+ mImpl->mVisibleEntries.erase(entry);
+ entry->setState(LLVOCacheEntry::INACTIVE);
+ }
+ return NULL;
+ }
+
+ LLViewerObject* obj = NULL;
+ if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
+ {
+ //add the object
+ obj = gObjectList.processObjectUpdateFromCache(entry, this);
+ if(obj)
+ {
+ if(!entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ mImpl->mWaitingSet.insert(entry);
+ entry->setState(LLVOCacheEntry::WAITING);
+ }
+ }
+ }
+ else
+ {
+ LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
+ if(old_regionp != this)
+ {
+ //this object exists in two regions at the same time;
+ //this case can be safely ignored here because
+ //server should soon send update message to remove one region for this object.
+
+ LL_WARNS() << "Entry: " << entry->getLocalID() << " exists in two regions at the same time." << LL_ENDL;
+ return NULL;
+ }
+
+ LL_WARNS() << "Entry: " << entry->getLocalID() << " in rendering pipeline but not set to be active." << LL_ENDL;
+
+ //should not hit here any more, but does not hurt either, just put it back to active list
+ addActiveCacheEntry(entry);
+ }
+
+ return obj;
}
//update object cache if the object receives a full-update or terse update
//update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL
LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)
{
- LLVOCacheEntry* entry = getCacheEntry(local_id);
- if (!entry)
- {
- return objectp; //not in the cache, do nothing.
- }
- if(!objectp) //object not created
- {
- //create a new object from cache.
- objectp = addNewObject(entry);
- }
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
+ if (!entry)
+ {
+ return objectp; //not in the cache, do nothing.
+ }
+ if(!objectp) //object not created
+ {
+ //create a new object from cache.
+ objectp = addNewObject(entry);
+ }
//remove from cache.
killCacheEntry(entry, true);
- return objectp;
+ return objectp;
}
// As above, but forcibly do the update.
void LLViewerRegion::forceUpdate()
{
- mImpl->mLandp->idleUpdate(0.f);
+ constexpr F32 max_update_time = 0.f;
- if (mParcelOverlay)
- {
- mParcelOverlay->idleUpdate(true);
- }
+ static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+ static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
+ bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
+ bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
+
+ if (!pbr_land)
+ {
+ mImpl->mLandp->idleUpdate</*PBR=*/false>(max_update_time);
+ }
+ else
+ {
+ mImpl->mLandp->idleUpdate</*PBR=*/true>(max_update_time);
+ }
+
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->idleUpdate(true);
+ }
}
void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
{
- mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
+ mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
}
void LLViewerRegion::disconnectAllNeighbors()
{
- mImpl->mLandp->disconnectAllNeighbors();
+ mImpl->mLandp->disconnectAllNeighbors();
}
LLVLComposition * LLViewerRegion::getComposition() const
{
- return mImpl->mCompositionp;
+ return mImpl->mCompositionp;
}
F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
{
- if (x >= 256)
- {
- if (y >= 256)
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled(255, 255);
- F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
- else
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
- F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
- }
- else if (y >= 256)
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
- F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
-
- return getComposition()->getValueScaled((F32)x, (F32)y);
-}
-
-void LLViewerRegion::calculateCenterGlobal()
-{
- mImpl->mCenterGlobal = mImpl->mOriginGlobal;
- mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
- mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
- mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
+ if (x >= 256)
+ {
+ if (y >= 256)
+ {
+ LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+ if (regionp)
+ {
+ // OK, we need to do some hackery here - different simulators no longer use
+ // the same composition values, necessarily.
+ // If we're attempting to blend, then we want to make the fractional part of
+ // this region match the fractional of the adjacent. For now, just minimize
+ // the delta.
+ F32 our_comp = getComposition()->getValueScaled(255, 255);
+ F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
+ while (llabs(our_comp - adj_comp) >= 1.f)
+ {
+ if (our_comp > adj_comp)
+ {
+ adj_comp += 1.f;
+ }
+ else
+ {
+ adj_comp -= 1.f;
+ }
+ }
+ return adj_comp;
+ }
+ }
+ else
+ {
+ LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+ if (regionp)
+ {
+ // OK, we need to do some hackery here - different simulators no longer use
+ // the same composition values, necessarily.
+ // If we're attempting to blend, then we want to make the fractional part of
+ // this region match the fractional of the adjacent. For now, just minimize
+ // the delta.
+ F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
+ F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
+ while (llabs(our_comp - adj_comp) >= 1.f)
+ {
+ if (our_comp > adj_comp)
+ {
+ adj_comp += 1.f;
+ }
+ else
+ {
+ adj_comp -= 1.f;
+ }
+ }
+ return adj_comp;
+ }
+ }
+ }
+ else if (y >= 256)
+ {
+ LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+ if (regionp)
+ {
+ // OK, we need to do some hackery here - different simulators no longer use
+ // the same composition values, necessarily.
+ // If we're attempting to blend, then we want to make the fractional part of
+ // this region match the fractional of the adjacent. For now, just minimize
+ // the delta.
+ F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
+ F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
+ while (llabs(our_comp - adj_comp) >= 1.f)
+ {
+ if (our_comp > adj_comp)
+ {
+ adj_comp += 1.f;
+ }
+ else
+ {
+ adj_comp -= 1.f;
+ }
+ }
+ return adj_comp;
+ }
+ }
+
+ return getComposition()->getValueScaled((F32)x, (F32)y);
+}
+
+void LLViewerRegion::calculateCenterGlobal()
+{
+ mImpl->mCenterGlobal = mImpl->mOriginGlobal;
+ mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
+ mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
+ mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
}
void LLViewerRegion::calculateCameraDistance()
{
- mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
+ mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
}
std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
{
- s << "{ ";
- s << region.mImpl->mHost;
- s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
+ s << "{ ";
+ s << region.mImpl->mHost;
+ s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
std::string name(region.getName()), zone(region.getZoning());
if (! name.empty())
{
@@ -2054,8 +2086,8 @@ std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
{
s << " mZoning = " << zone << '\n';
}
- s << "}";
- return s;
+ s << "}";
+ return s;
}
@@ -2063,143 +2095,143 @@ std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
void LLViewerRegion::updateNetStats()
{
- F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
+ F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
- if (!cdp)
- {
- mAlive = false;
- return;
- }
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+ if (!cdp)
+ {
+ mAlive = false;
+ return;
+ }
- mAlive = true;
- mDeltaTime = dt;
+ mAlive = true;
+ mDeltaTime = dt;
- mLastPacketsIn = mPacketsIn;
- mLastBitsIn = mBitsIn;
- mLastPacketsOut = mPacketsOut;
- mLastPacketsLost = mPacketsLost;
+ mLastPacketsIn = mPacketsIn;
+ mLastBitsIn = mBitsIn;
+ mLastPacketsOut = mPacketsOut;
+ mLastPacketsLost = mPacketsLost;
- mPacketsIn = cdp->getPacketsIn();
- mBitsIn = 8 * cdp->getBytesIn();
- mPacketsOut = cdp->getPacketsOut();
- mPacketsLost = cdp->getPacketsLost();
- mPingDelay = cdp->getPingDelay();
+ mPacketsIn = cdp->getPacketsIn();
+ mBitsIn = 8 * cdp->getBytesIn();
+ mPacketsOut = cdp->getPacketsOut();
+ mPacketsLost = cdp->getPacketsLost();
+ mPingDelay = cdp->getPingDelay();
- mBitsReceived += mBitsIn - mLastBitsIn;
- mPacketsReceived += mPacketsIn - mLastPacketsIn;
+ mBitsReceived += mBitsIn - mLastBitsIn;
+ mPacketsReceived += mPacketsIn - mLastPacketsIn;
}
U32 LLViewerRegion::getPacketsLost() const
{
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
- if (!cdp)
- {
- LL_INFOS() << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << LL_ENDL;
- return 0;
- }
- else
- {
- return cdp->getPacketsLost();
- }
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+ if (!cdp)
+ {
+ LL_INFOS() << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << LL_ENDL;
+ return 0;
+ }
+ else
+ {
+ return cdp->getPacketsLost();
+ }
}
S32 LLViewerRegion::getHttpResponderID() const
{
- return mImpl->mHttpResponderID;
+ return mImpl->mHttpResponderID;
}
BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
{
- LLVector3 pos_region = getPosRegionFromGlobal(point_global);
-
- if (pos_region.mV[VX] < 0)
- {
- return FALSE;
- }
- if (pos_region.mV[VX] >= mWidth)
- {
- return FALSE;
- }
- if (pos_region.mV[VY] < 0)
- {
- return FALSE;
- }
- if (pos_region.mV[VY] >= mWidth)
- {
- return FALSE;
- }
- return TRUE;
+ LLVector3 pos_region = getPosRegionFromGlobal(point_global);
+
+ if (pos_region.mV[VX] < 0)
+ {
+ return FALSE;
+ }
+ if (pos_region.mV[VX] >= mWidth)
+ {
+ return FALSE;
+ }
+ if (pos_region.mV[VY] < 0)
+ {
+ return FALSE;
+ }
+ if (pos_region.mV[VY] >= mWidth)
+ {
+ return FALSE;
+ }
+ return TRUE;
}
LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
{
- LLVector3 pos_region;
- pos_region.setVec(point_global - mImpl->mOriginGlobal);
- return pos_region;
+ LLVector3 pos_region;
+ pos_region.setVec(point_global - mImpl->mOriginGlobal);
+ return pos_region;
}
LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
{
- LLVector3d pos_region_d;
- pos_region_d.setVec(pos_region);
- return pos_region_d + mImpl->mOriginGlobal;
+ LLVector3d pos_region_d;
+ pos_region_d.setVec(pos_region);
+ return pos_region_d + mImpl->mOriginGlobal;
}
LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
{
- LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
+ LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
- return gAgent.getPosAgentFromGlobal(pos_global);
+ return gAgent.getPosAgentFromGlobal(pos_global);
}
LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
{
- return pos_agent - getOriginAgent();
+ return pos_agent - getOriginAgent();
}
F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
{
- return mImpl->mLandp->resolveHeightRegion( region_pos );
+ return mImpl->mLandp->resolveHeightRegion( region_pos );
}
bool LLViewerRegion::isAlive()
{
- return mAlive;
+ return mAlive;
}
BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
{
- if (mParcelOverlay)
- {
- return mParcelOverlay->isOwnedSelf(pos);
- } else {
- return FALSE;
- }
+ if (mParcelOverlay)
+ {
+ return mParcelOverlay->isOwnedSelf(pos);
+ } else {
+ return FALSE;
+ }
}
// Owned by a group you belong to? (officer or member)
BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
{
- if (mParcelOverlay)
- {
- return mParcelOverlay->isOwnedGroup(pos);
- } else {
- return FALSE;
- }
+ if (mParcelOverlay)
+ {
+ return mParcelOverlay->isOwnedGroup(pos);
+ } else {
+ return FALSE;
+ }
}
// the new TCP coarse location handler node
class CoarseLocationUpdate : public LLHTTPNode
{
public:
- virtual void post(
- ResponsePtr responder,
- const LLSD& context,
- const LLSD& input) const
- {
- LLHost host(input["sender"].asString());
+ virtual void post(
+ ResponsePtr responder,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLHost host(input["sender"].asString());
LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
if (!world_inst)
@@ -2207,151 +2239,151 @@ public:
return;
}
- LLViewerRegion* region = world_inst->getRegion(host);
- if( !region )
- {
- return;
- }
-
- S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
- S32 you_index = input["body"]["Index"][0]["You" ].asInteger();
-
- std::vector<U32>* avatar_locs = &region->mMapAvatars;
- std::vector<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
- avatar_locs->clear();
- avatar_ids->clear();
-
- //LL_INFOS() << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << LL_ENDL;
- //LL_INFOS() << "my agent id = " << gAgent.getID() << LL_ENDL;
- //LL_INFOS() << ll_pretty_print_sd(input) << LL_ENDL;
-
- LLSD
- locs = input["body"]["Location"],
- agents = input["body"]["AgentData"];
- LLSD::array_iterator
- locs_it = locs.beginArray(),
- agents_it = agents.beginArray();
- BOOL has_agent_data = input["body"].has("AgentData");
-
- for(int i=0;
- locs_it != locs.endArray();
- i++, locs_it++)
- {
- U8
- x = locs_it->get("X").asInteger(),
- y = locs_it->get("Y").asInteger(),
- z = locs_it->get("Z").asInteger();
- // treat the target specially for the map, and don't add you or the target
- if(i == target_index)
- {
- LLVector3d global_pos(region->getOriginGlobal());
- global_pos.mdV[VX] += (F64)x;
- global_pos.mdV[VY] += (F64)y;
- global_pos.mdV[VZ] += (F64)z * 4.0;
- LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
- }
- else if( i != you_index)
- {
- U32 pos = 0x0;
- pos |= x;
- pos <<= 8;
- pos |= y;
- pos <<= 8;
- pos |= z;
- avatar_locs->push_back(pos);
- //LL_INFOS() << "next pos: " << x << "," << y << "," << z << ": " << pos << LL_ENDL;
- if(has_agent_data) // for backwards compatibility with old message format
- {
- LLUUID agent_id(agents_it->get("AgentID").asUUID());
- //LL_INFOS() << "next agent: " << agent_id.asString() << LL_ENDL;
- avatar_ids->push_back(agent_id);
- }
- }
- if (has_agent_data)
- {
- agents_it++;
- }
- }
- }
+ LLViewerRegion* region = world_inst->getRegion(host);
+ if( !region )
+ {
+ return;
+ }
+
+ S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
+ S32 you_index = input["body"]["Index"][0]["You" ].asInteger();
+
+ std::vector<U32>* avatar_locs = &region->mMapAvatars;
+ std::vector<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
+ avatar_locs->clear();
+ avatar_ids->clear();
+
+ //LL_INFOS() << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << LL_ENDL;
+ //LL_INFOS() << "my agent id = " << gAgent.getID() << LL_ENDL;
+ //LL_INFOS() << ll_pretty_print_sd(input) << LL_ENDL;
+
+ LLSD
+ locs = input["body"]["Location"],
+ agents = input["body"]["AgentData"];
+ LLSD::array_iterator
+ locs_it = locs.beginArray(),
+ agents_it = agents.beginArray();
+ BOOL has_agent_data = input["body"].has("AgentData");
+
+ for(int i=0;
+ locs_it != locs.endArray();
+ i++, locs_it++)
+ {
+ U8
+ x = locs_it->get("X").asInteger(),
+ y = locs_it->get("Y").asInteger(),
+ z = locs_it->get("Z").asInteger();
+ // treat the target specially for the map, and don't add you or the target
+ if(i == target_index)
+ {
+ LLVector3d global_pos(region->getOriginGlobal());
+ global_pos.mdV[VX] += (F64)x;
+ global_pos.mdV[VY] += (F64)y;
+ global_pos.mdV[VZ] += (F64)z * 4.0;
+ LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+ }
+ else if( i != you_index)
+ {
+ U32 pos = 0x0;
+ pos |= x;
+ pos <<= 8;
+ pos |= y;
+ pos <<= 8;
+ pos |= z;
+ avatar_locs->push_back(pos);
+ //LL_INFOS() << "next pos: " << x << "," << y << "," << z << ": " << pos << LL_ENDL;
+ if(has_agent_data) // for backwards compatibility with old message format
+ {
+ LLUUID agent_id(agents_it->get("AgentID").asUUID());
+ //LL_INFOS() << "next agent: " << agent_id.asString() << LL_ENDL;
+ avatar_ids->push_back(agent_id);
+ }
+ }
+ if (has_agent_data)
+ {
+ agents_it++;
+ }
+ }
+ }
};
// build the coarse location HTTP node under the "/message" URL
LLHTTPRegistration<CoarseLocationUpdate>
gHTTPRegistrationCoarseLocationUpdate(
- "/message/CoarseLocationUpdate");
+ "/message/CoarseLocationUpdate");
// the deprecated coarse location handler
void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
{
- //LL_INFOS() << "CoarseLocationUpdate" << LL_ENDL;
- mMapAvatars.clear();
- mMapAvatarIDs.clear(); // only matters in a rare case but it's good to be safe.
-
- U8 x_pos = 0;
- U8 y_pos = 0;
- U8 z_pos = 0;
-
- U32 pos = 0x0;
-
- S16 agent_index;
- S16 target_index;
- msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
- msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
-
- BOOL has_agent_data = msg->has(_PREHASH_AgentData);
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
- for(S32 i = 0; i < count; i++)
- {
- msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
- msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
- msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
- LLUUID agent_id = LLUUID::null;
- if(has_agent_data)
- {
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
- }
-
- //LL_INFOS() << " object X: " << (S32)x_pos << " Y: " << (S32)y_pos
- // << " Z: " << (S32)(z_pos * 4)
- // << LL_ENDL;
-
- // treat the target specially for the map
- if(i == target_index)
- {
- LLVector3d global_pos(mImpl->mOriginGlobal);
- global_pos.mdV[VX] += (F64)(x_pos);
- global_pos.mdV[VY] += (F64)(y_pos);
- global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
- LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
- }
-
- //don't add you
- if( i != agent_index)
- {
- pos = 0x0;
- pos |= x_pos;
- pos <<= 8;
- pos |= y_pos;
- pos <<= 8;
- pos |= z_pos;
- mMapAvatars.push_back(pos);
- if(has_agent_data)
- {
- mMapAvatarIDs.push_back(agent_id);
- }
- }
- }
+ //LL_INFOS() << "CoarseLocationUpdate" << LL_ENDL;
+ mMapAvatars.clear();
+ mMapAvatarIDs.clear(); // only matters in a rare case but it's good to be safe.
+
+ U8 x_pos = 0;
+ U8 y_pos = 0;
+ U8 z_pos = 0;
+
+ U32 pos = 0x0;
+
+ S16 agent_index;
+ S16 target_index;
+ msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
+ msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
+
+ BOOL has_agent_data = msg->has(_PREHASH_AgentData);
+ S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
+ for(S32 i = 0; i < count; i++)
+ {
+ msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
+ msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
+ msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
+ LLUUID agent_id = LLUUID::null;
+ if(has_agent_data)
+ {
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
+ }
+
+ //LL_INFOS() << " object X: " << (S32)x_pos << " Y: " << (S32)y_pos
+ // << " Z: " << (S32)(z_pos * 4)
+ // << LL_ENDL;
+
+ // treat the target specially for the map
+ if(i == target_index)
+ {
+ LLVector3d global_pos(mImpl->mOriginGlobal);
+ global_pos.mdV[VX] += (F64)(x_pos);
+ global_pos.mdV[VY] += (F64)(y_pos);
+ global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
+ LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+ }
+
+ //don't add you
+ if( i != agent_index)
+ {
+ pos = 0x0;
+ pos |= x_pos;
+ pos <<= 8;
+ pos |= y_pos;
+ pos <<= 8;
+ pos |= z_pos;
+ mMapAvatars.push_back(pos);
+ if(has_agent_data)
+ {
+ mMapAvatarIDs.push_back(agent_id);
+ }
+ }
+ }
}
void LLViewerRegion::getInfo(LLSD& info)
{
- info["Region"]["Host"] = getHost().getIPandPort();
- info["Region"]["Name"] = getName();
- U32 x, y;
- from_region_handle(getHandle(), &x, &y);
- info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
- info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
+ info["Region"]["Host"] = getHost().getIPandPort();
+ info["Region"]["Name"] = getName();
+ U32 x, y;
+ from_region_handle(getHandle(), &x, &y);
+ info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
+ info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
}
void LLViewerRegion::requestSimulatorFeatures()
@@ -2370,7 +2402,7 @@ void LLViewerRegion::requestSimulatorFeatures()
// launch() acts like a suspend()
// Make sure we are still good to do
LLCoros::checkStop();
-
+
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
else
@@ -2381,825 +2413,885 @@ void LLViewerRegion::requestSimulatorFeatures()
boost::signals2::connection LLViewerRegion::setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
- return mSimulatorFeaturesReceivedSignal.connect(cb);
+ return mSimulatorFeaturesReceivedSignal.connect(cb);
}
void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
{
- mSimulatorFeaturesReceived = received;
- if (received)
- {
- mSimulatorFeaturesReceivedSignal(getRegionID(), this);
- mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
- }
+ mSimulatorFeaturesReceived = received;
+ if (received)
+ {
+ mSimulatorFeaturesReceivedSignal(getRegionID(), this);
+ mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
+ }
}
bool LLViewerRegion::simulatorFeaturesReceived() const
{
- return mSimulatorFeaturesReceived;
+ return mSimulatorFeaturesReceived;
}
void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const
{
- sim_features = mSimulatorFeatures;
+ sim_features = mSimulatorFeatures;
}
void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
{
- std::stringstream str;
-
- LLSDSerialize::toPrettyXML(sim_features, str);
- LL_INFOS() << "region " << getName() << " " << str.str() << LL_ENDL;
- mSimulatorFeatures = sim_features;
+ std::stringstream str;
+
+ LLSDSerialize::toPrettyXML(sim_features, str);
+ LL_INFOS() << "region " << getName() << " " << str.str() << LL_ENDL;
+ mSimulatorFeatures = sim_features;
- setSimulatorFeaturesReceived(true);
+ setSimulatorFeaturesReceived(true);
-}
+ // WARNING: this is called from a coroutine, and flipping saved settings has a LOT of side effects, shuttle
+ // the work below back to the main loop
+ //
+
+ // copy features to lambda in case the region is deleted before the lambda is executed
+ LLSD features = mSimulatorFeatures;
-//this is called when the parent is not cacheable.
-//move all orphan children out of cache and insert to rendering octree.
-void LLViewerRegion::findOrphans(U32 parent_id)
-{
- orphan_list_t::iterator iter = mOrphanMap.find(parent_id);
- if(iter != mOrphanMap.end())
- {
- std::vector<U32>* children = &mOrphanMap[parent_id];
- for(S32 i = 0; i < children->size(); i++)
+ auto work = [=]()
{
- //parent is visible, so is the child.
- addVisibleChildCacheEntry(NULL, getCacheEntry((*children)[i]));
- }
- children->clear();
- mOrphanMap.erase(parent_id);
- }
-}
-
-void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
-{
- if(!sVOCacheCullingEnabled)
- {
- gObjectList.processObjectUpdateFromCache(entry, this);
- return;
- }
- if(!entry || !entry->isValid())
- {
- return;
- }
-
- if(!entry->getEntry())
- {
- entry->setOctreeEntry(NULL);
- }
-
- if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline
- {
- LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
- if(old_regionp != this && old_regionp)
- {
- LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj();
- if(obj)
+ // if region has MaxTextureResolution, set max_texture_dimension settings, otherwise use default
+ if (features.has("MaxTextureResolution"))
{
- //remove from old region
- old_regionp->killCacheEntry(obj->getLocalID());
-
- //change region
- obj->setRegion(this);
+ S32 max_texture_resolution = features["MaxTextureResolution"].asInteger();
+ gSavedSettings.setS32("max_texture_dimension_X", max_texture_resolution);
+ gSavedSettings.setS32("max_texture_dimension_Y", max_texture_resolution);
}
- }
-
- addActiveCacheEntry(entry);
-
- //set parent id
- U32 parent_id = 0;
- if (entry->getDP()) // NULL if nothing cached
- {
- LLViewerObject::unpackParentID(entry->getDP(), parent_id);
- }
- if(parent_id != entry->getParentID())
- {
- entry->setParentID(parent_id);
- }
-
- //update the object
- gObjectList.processObjectUpdateFromCache(entry, this);
- return; //done
- }
-
- //must not be active.
- llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE));
- removeFromVOCacheTree(entry); //remove from cache octree if it is in.
-
- LLVector3 pos;
- LLVector3 scale;
- LLQuaternion rot;
-
- //decode spatial info and parent info
- U32 parent_id = entry->getDP() ? LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot) : entry->getParentID();
-
- U32 old_parent_id = entry->getParentID();
- bool same_old_parent = false;
- if(parent_id != old_parent_id) //parent changed.
- {
- if(old_parent_id > 0) //has an old parent, disconnect it
- {
- LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id);
- if(old_parent)
+ else
{
- old_parent->removeChild(entry);
- if(!old_parent->isState(LLVOCacheEntry::INACTIVE))
- {
- mImpl->mVisibleEntries.erase(entry);
- entry->setState(LLVOCacheEntry::INACTIVE);
- }
+ gSavedSettings.setS32("max_texture_dimension_X", 1024);
+ gSavedSettings.setS32("max_texture_dimension_Y", 1024);
}
- }
- entry->setParentID(parent_id);
- }
- else
- {
- same_old_parent = true;
- }
-
- if(parent_id > 0) //has a new parent
- {
- //1, find the parent in cache
- LLVOCacheEntry* parent = getCacheEntry(parent_id);
- //2, parent is not in the cache, put into the orphan list.
- if(!parent)
- {
- if(!same_old_parent)
+ if (features.has("PBRTerrainEnabled"))
{
- //check if parent is non-cacheable and already created
- if(isNonCacheableObjectCreated(parent_id))
- {
- //parent is visible, so is the child.
- addVisibleChildCacheEntry(NULL, entry);
- }
- else
- {
- entry->setBoundingInfo(pos, scale);
- mOrphanMap[parent_id].push_back(entry->getLocalID());
- }
+ bool enabled = features["PBRTerrainEnabled"];
+ gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled);
}
else
{
- entry->setBoundingInfo(pos, scale);
+ gSavedSettings.setBOOL("RenderTerrainPBREnabled", false);
}
- }
- else //parent in cache.
- {
- if(!parent->isState(LLVOCacheEntry::INACTIVE))
+
+ if (features.has("PBRMaterialSwatchEnabled"))
{
- //parent is visible, so is the child.
- addVisibleChildCacheEntry(parent, entry);
+ bool enabled = features["PBRMaterialSwatchEnabled"];
+ gSavedSettings.setBOOL("UIPreviewMaterial", enabled);
}
else
{
- entry->setBoundingInfo(pos, scale);
- parent->addChild(entry);
-
- if(parent->getGroup()) //re-insert parent to vo-cache tree because its bounding info changed.
- {
- removeFromVOCacheTree(parent);
- addToVOCacheTree(parent);
- }
+ gSavedSettings.setBOOL("UIPreviewMaterial", false);
}
- }
+ };
- return;
+ auto workqueue = LL::WorkQueue::getInstance("mainloop");
+ if (workqueue)
+ {
+ LL::WorkQueue::postMaybe(workqueue, work);
}
+}
- //
- //no parent
- //
- entry->setBoundingInfo(pos, scale);
+//this is called when the parent is not cacheable.
+//move all orphan children out of cache and insert to rendering octree.
+void LLViewerRegion::findOrphans(U32 parent_id)
+{
+ orphan_list_t::iterator iter = mOrphanMap.find(parent_id);
+ if(iter != mOrphanMap.end())
+ {
+ std::vector<U32>* children = &mOrphanMap[parent_id];
+ for(S32 i = 0; i < children->size(); i++)
+ {
+ //parent is visible, so is the child.
+ addVisibleChildCacheEntry(NULL, getCacheEntry((*children)[i]));
+ }
+ children->clear();
+ mOrphanMap.erase(parent_id);
+ }
+}
- if(!parent_id) //a potential parent
- {
- //find all children and update their bounding info
- orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID());
- if(iter != mOrphanMap.end())
+void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
+{
+ if(!sVOCacheCullingEnabled)
+ {
+ gObjectList.processObjectUpdateFromCache(entry, this);
+ return;
+ }
+ if(!entry || !entry->isValid())
+ {
+ return;
+ }
+
+ if(!entry->getEntry())
+ {
+ entry->setOctreeEntry(NULL);
+ }
+
+ if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline
+ {
+ LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
+ if(old_regionp != this && old_regionp)
+ {
+ LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj();
+ if(obj)
+ {
+ //remove from old region
+ old_regionp->killCacheEntry(obj->getLocalID());
+
+ //change region
+ obj->setRegion(this);
+ }
+ }
+
+ addActiveCacheEntry(entry);
+
+ //set parent id
+ U32 parent_id = 0;
+ if (entry->getDP()) // NULL if nothing cached
{
- std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()];
- S32 size = orphans->size();
- for(S32 i = 0; i < size; i++)
- {
- LLVOCacheEntry* child = getCacheEntry((*orphans)[i]);
- if(child)
- {
- entry->addChild(child);
- }
- }
- orphans->clear();
- mOrphanMap.erase(entry->getLocalID());
+ LLViewerObject::unpackParentID(entry->getDP(), parent_id);
}
- }
-
- if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE))
- {
- addToVOCacheTree(entry);
- }
- return ;
+ if(parent_id != entry->getParentID())
+ {
+ entry->setParentID(parent_id);
+ }
+
+ //update the object
+ gObjectList.processObjectUpdateFromCache(entry, this);
+ return; //done
+ }
+
+ //must not be active.
+ llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE));
+ removeFromVOCacheTree(entry); //remove from cache octree if it is in.
+
+ LLVector3 pos;
+ LLVector3 scale;
+ LLQuaternion rot;
+
+ //decode spatial info and parent info
+ U32 parent_id = entry->getDP() ? LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot) : entry->getParentID();
+
+ U32 old_parent_id = entry->getParentID();
+ bool same_old_parent = false;
+ if(parent_id != old_parent_id) //parent changed.
+ {
+ if(old_parent_id > 0) //has an old parent, disconnect it
+ {
+ LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id);
+ if(old_parent)
+ {
+ old_parent->removeChild(entry);
+ if(!old_parent->isState(LLVOCacheEntry::INACTIVE))
+ {
+ mImpl->mVisibleEntries.erase(entry);
+ entry->setState(LLVOCacheEntry::INACTIVE);
+ }
+ }
+ }
+ entry->setParentID(parent_id);
+ }
+ else
+ {
+ same_old_parent = true;
+ }
+
+ if(parent_id > 0) //has a new parent
+ {
+ //1, find the parent in cache
+ LLVOCacheEntry* parent = getCacheEntry(parent_id);
+
+ //2, parent is not in the cache, put into the orphan list.
+ if(!parent)
+ {
+ if(!same_old_parent)
+ {
+ //check if parent is non-cacheable and already created
+ if(isNonCacheableObjectCreated(parent_id))
+ {
+ //parent is visible, so is the child.
+ addVisibleChildCacheEntry(NULL, entry);
+ }
+ else
+ {
+ entry->setBoundingInfo(pos, scale);
+ mOrphanMap[parent_id].push_back(entry->getLocalID());
+ }
+ }
+ else
+ {
+ entry->setBoundingInfo(pos, scale);
+ }
+ }
+ else //parent in cache.
+ {
+ if(!parent->isState(LLVOCacheEntry::INACTIVE))
+ {
+ //parent is visible, so is the child.
+ addVisibleChildCacheEntry(parent, entry);
+ }
+ else
+ {
+ entry->setBoundingInfo(pos, scale);
+ parent->addChild(entry);
+
+ if(parent->getGroup()) //re-insert parent to vo-cache tree because its bounding info changed.
+ {
+ removeFromVOCacheTree(parent);
+ addToVOCacheTree(parent);
+ }
+ }
+ }
+
+ return;
+ }
+
+ //
+ //no parent
+ //
+ entry->setBoundingInfo(pos, scale);
+
+ if(!parent_id) //a potential parent
+ {
+ //find all children and update their bounding info
+ orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID());
+ if(iter != mOrphanMap.end())
+ {
+ std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()];
+ S32 size = orphans->size();
+ for(S32 i = 0; i < size; i++)
+ {
+ LLVOCacheEntry* child = getCacheEntry((*orphans)[i]);
+ if(child)
+ {
+ entry->addChild(child);
+ }
+ }
+ orphans->clear();
+ mOrphanMap.erase(entry->getLocalID());
+ }
+ }
+
+ if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ addToVOCacheTree(entry);
+ }
+ return ;
}
LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags)
{
- eCacheUpdateResult result;
- U32 crc;
- U32 local_id;
+ eCacheUpdateResult result;
+ U32 crc;
+ U32 local_id;
- LLViewerObject::unpackU32(&dp, local_id, "LocalID");
- LLViewerObject::unpackU32(&dp, crc, "CRC");
+ LLViewerObject::unpackU32(&dp, local_id, "LocalID");
+ LLViewerObject::unpackU32(&dp, crc, "CRC");
- LLVOCacheEntry* entry = getCacheEntry(local_id, false);
+ LLVOCacheEntry* entry = getCacheEntry(local_id, false);
- if (entry)
- {
- entry->setValid();
+ if (entry)
+ {
+ entry->setValid();
- // we've seen this object before
- if (entry->getCRC() == crc)
- {
+ // we've seen this object before
+ if (entry->getCRC() == crc)
+ {
LL_DEBUGS("AnimatedObjects") << " got dupe for local_id " << local_id << LL_ENDL;
dumpStack("AnimatedObjectsStack");
- // Record a hit
- entry->recordDupe();
- result = CACHE_UPDATE_DUPE;
- }
- else //CRC changed
- {
+ // Record a hit
+ entry->recordDupe();
+ result = CACHE_UPDATE_DUPE;
+ }
+ else //CRC changed
+ {
LL_DEBUGS("AnimatedObjects") << " got update for local_id " << local_id << LL_ENDL;
dumpStack("AnimatedObjectsStack");
- // Update the cache entry
- entry->updateEntry(crc, dp);
+ // Update the cache entry
+ entry->updateEntry(crc, dp);
- decodeBoundingInfo(entry);
+ decodeBoundingInfo(entry);
- result = CACHE_UPDATE_CHANGED;
- }
- }
- else
- {
+ result = CACHE_UPDATE_CHANGED;
+ }
+ }
+ else
+ {
LL_DEBUGS("AnimatedObjects") << " got first notification for local_id " << local_id << LL_ENDL;
dumpStack("AnimatedObjectsStack");
- // we haven't seen this object before
- // Create new entry and add to map
- result = CACHE_UPDATE_ADDED;
- entry = new LLVOCacheEntry(local_id, crc, dp);
- record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0));
-
- mImpl->mCacheMap[local_id] = entry;
-
- decodeBoundingInfo(entry);
- }
- entry->setUpdateFlags(flags);
-
- return result;
- }
+ // we haven't seen this object before
+ // Create new entry and add to map
+ result = CACHE_UPDATE_ADDED;
+ entry = new LLVOCacheEntry(local_id, crc, dp);
+ record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0));
+
+ mImpl->mCacheMap[local_id] = entry;
+
+ decodeBoundingInfo(entry);
+ }
+ entry->setUpdateFlags(flags);
+
+ return result;
+ }
LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags)
{
- eCacheUpdateResult result = cacheFullUpdate(dp, flags);
+ eCacheUpdateResult result = cacheFullUpdate(dp, flags);
- return result;
+ return result;
}
void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data)
{
U32 local_id = override_data.mLocalId;
- mImpl->mGLTFOverridesLLSD[local_id] = override_data;
+ if (override_data.mSides.size() > 0)
+ { // empty override means overrides were removed from this object
+ mImpl->mGLTFOverridesLLSD[local_id] = override_data;
+ }
+ else
+ {
+ mImpl->mGLTFOverridesLLSD.erase(local_id);
+ }
}
LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
{
- if(!sVOCacheCullingEnabled)
- {
- return NULL;
- }
-
- LLVOCacheEntry* entry = getCacheEntry(local_id);
- removeFromVOCacheTree(entry);
+ if(!sVOCacheCullingEnabled)
+ {
+ return NULL;
+ }
- return entry;
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
+ removeFromVOCacheTree(entry);
+
+ return entry;
}
LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid)
{
- LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id);
- if(iter != mImpl->mCacheMap.end())
- {
- if(!valid || iter->second->isValid())
- {
- return iter->second;
- }
- }
- return NULL;
+ LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id);
+ if(iter != mImpl->mCacheMap.end())
+ {
+ if(!valid || iter->second->isValid())
+ {
+ return iter->second;
+ }
+ }
+ return NULL;
}
void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType cache_miss_type)
{
- mRegionCacheMissCount++;
+ mRegionCacheMissCount++;
mCacheMissList.push_back(CacheMissItem(id, cache_miss_type));
}
//check if a non-cacheable object is already created.
bool LLViewerRegion::isNonCacheableObjectCreated(U32 local_id)
{
- if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end())
- {
- return true;
- }
- return false;
+ if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end())
+ {
+ return true;
+ }
+ return false;
}
-
+
void LLViewerRegion::removeFromCreatedList(U32 local_id)
-{
- if(mImpl && local_id > 0)
- {
- std::set<U32>::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id);
- if(iter != mImpl->mNonCacheableCreatedList.end())
- {
- mImpl->mNonCacheableCreatedList.erase(iter);
- }
- }
- }
+{
+ if(mImpl && local_id > 0)
+ {
+ std::set<U32>::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id);
+ if(iter != mImpl->mNonCacheableCreatedList.end())
+ {
+ mImpl->mNonCacheableCreatedList.erase(iter);
+ }
+ }
+ }
void LLViewerRegion::addToCreatedList(U32 local_id)
{
- if(mImpl && local_id > 0)
- {
- mImpl->mNonCacheableCreatedList.insert(local_id);
- }
+ if(mImpl && local_id > 0)
+ {
+ mImpl->mNonCacheableCreatedList.insert(local_id);
+ }
}
// Get data packer for this object, if we have cached data
// AND the CRC matches. JC
bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type)
{
- //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18
+ //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18
- LLVOCacheEntry* entry = getCacheEntry(local_id, false);
+ LLVOCacheEntry* entry = getCacheEntry(local_id, false);
- if (entry)
- {
- // we've seen this object before
- if (entry->getCRC() == crc)
- {
- // Record a hit
- mRegionCacheHitCount++;
- entry->recordHit();
+ if (entry)
+ {
+ // we've seen this object before
+ if (entry->getCRC() == crc)
+ {
+ // Record a hit
+ mRegionCacheHitCount++;
+ entry->recordHit();
cache_miss_type = CACHE_MISS_TYPE_NONE;
- entry->setUpdateFlags(flags);
-
- if(entry->isState(LLVOCacheEntry::ACTIVE))
- {
- ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags);
- return true;
- }
-
- if(entry->isValid())
- {
- return true; //already probed
- }
-
- entry->setValid();
- decodeBoundingInfo(entry);
+ entry->setUpdateFlags(flags);
+
+ if(entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags);
+ return true;
+ }
+
+ if(entry->isValid())
+ {
+ return true; //already probed
+ }
+
+ entry->setValid();
+ decodeBoundingInfo(entry);
//loadCacheMiscExtras(local_id, entry, crc);
- return true;
- }
- else
- {
- // LL_INFOS() << "CRC miss for " << local_id << LL_ENDL;
+ return true;
+ }
+ else
+ {
+ // LL_INFOS() << "CRC miss for " << local_id << LL_ENDL;
- addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);
+ addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);
cache_miss_type = CACHE_MISS_TYPE_CRC;
- }
- }
- else
- { // Total miss, don't have the object in cache
- // LL_INFOS() << "Cache miss for " << local_id << LL_ENDL;
+ }
+ }
+ else
+ { // Total miss, don't have the object in cache
+ // LL_INFOS() << "Cache miss for " << local_id << LL_ENDL;
addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL);
cache_miss_type = CACHE_MISS_TYPE_TOTAL;
- }
+ }
- return false;
+ return false;
}
void LLViewerRegion::addCacheMissFull(const U32 local_id)
{
- addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL);
+ addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL);
}
void LLViewerRegion::requestCacheMisses()
{
- if (!mCacheMissList.size())
- {
- return;
- }
-
- LLMessageSystem* msg = gMessageSystem;
- BOOL start_new_message = TRUE;
- S32 blocks = 0;
-
- //send requests for all cache-missed objects
- for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_RequestMultipleObjects);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- start_new_message = FALSE;
- }
-
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType);
- msg->addU32Fast(_PREHASH_ID, (*iter).mID);
+ if (!mCacheMissList.size())
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ BOOL start_new_message = TRUE;
+ S32 blocks = 0;
+
+ //send requests for all cache-missed objects
+ for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)
+ {
+ if (start_new_message)
+ {
+ msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ start_new_message = FALSE;
+ }
+
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType);
+ msg->addU32Fast(_PREHASH_ID, (*iter).mID);
LL_DEBUGS("AnimatedObjects") << "Requesting cache missed object " << (*iter).mID << LL_ENDL;
+
+ blocks++;
- blocks++;
-
- if (blocks >= 255)
- {
- sendReliableMessage();
- start_new_message = TRUE;
- blocks = 0;
- }
- }
+ if (blocks >= 255)
+ {
+ sendReliableMessage();
+ start_new_message = TRUE;
+ blocks = 0;
+ }
+ }
- // finish any pending message
- if (!start_new_message)
- {
- sendReliableMessage();
- }
+ // finish any pending message
+ if (!start_new_message)
+ {
+ sendReliableMessage();
+ }
- mCacheDirty = TRUE ;
- // LL_INFOS() << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << LL_ENDL;
- LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());
+ mCacheDirty = TRUE ;
+ // LL_INFOS() << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << LL_ENDL;
+ LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());
- mCacheMissList.clear();
+ mCacheMissList.clear();
}
void LLViewerRegion::dumpCache()
{
- const S32 BINS = 4;
- S32 hit_bin[BINS];
- S32 change_bin[BINS];
+ const S32 BINS = 4;
+ S32 hit_bin[BINS];
+ S32 change_bin[BINS];
- S32 i;
- for (i = 0; i < BINS; ++i)
- {
- hit_bin[i] = 0;
- change_bin[i] = 0;
- }
+ S32 i;
+ for (i = 0; i < BINS; ++i)
+ {
+ hit_bin[i] = 0;
+ change_bin[i] = 0;
+ }
- LLVOCacheEntry *entry;
- for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
- {
- entry = iter->second ;
+ LLVOCacheEntry *entry;
+ for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
+ {
+ entry = iter->second ;
- S32 hits = entry->getHitCount();
- S32 changes = entry->getCRCChangeCount();
+ S32 hits = entry->getHitCount();
+ S32 changes = entry->getCRCChangeCount();
- hits = llclamp(hits, 0, BINS-1);
- changes = llclamp(changes, 0, BINS-1);
+ hits = llclamp(hits, 0, BINS-1);
+ changes = llclamp(changes, 0, BINS-1);
- hit_bin[hits]++;
- change_bin[changes]++;
- }
+ hit_bin[hits]++;
+ change_bin[changes]++;
+ }
- LL_INFOS() << "Count " << mImpl->mCacheMap.size() << LL_ENDL;
- for (i = 0; i < BINS; i++)
- {
- LL_INFOS() << "Hits " << i << " " << hit_bin[i] << LL_ENDL;
- }
- for (i = 0; i < BINS; i++)
- {
- LL_INFOS() << "Changes " << i << " " << change_bin[i] << LL_ENDL;
- }
- // TODO - add overrides cache too
+ LL_INFOS() << "Count " << mImpl->mCacheMap.size() << LL_ENDL;
+ for (i = 0; i < BINS; i++)
+ {
+ LL_INFOS() << "Hits " << i << " " << hit_bin[i] << LL_ENDL;
+ }
+ for (i = 0; i < BINS; i++)
+ {
+ LL_INFOS() << "Changes " << i << " " << change_bin[i] << LL_ENDL;
+ }
+ // TODO - add overrides cache too
}
-void LLViewerRegion::unpackRegionHandshake()
+void LLViewerRegion::clearVOCacheFromMemory()
{
- LLMessageSystem *msg = gMessageSystem;
-
- U64 region_flags = 0;
- U64 region_protocols = 0;
- U8 sim_access;
- std::string sim_name;
- LLUUID sim_owner;
- BOOL is_estate_manager;
- F32 water_height;
- F32 billable_factor;
- LLUUID cache_id;
-
- msg->getU8 ("RegionInfo", "SimAccess", sim_access);
- msg->getString ("RegionInfo", "SimName", sim_name);
- msg->getUUID ("RegionInfo", "SimOwner", sim_owner);
- msg->getBOOL ("RegionInfo", "IsEstateManager", is_estate_manager);
- msg->getF32 ("RegionInfo", "WaterHeight", water_height);
- msg->getF32 ("RegionInfo", "BillableFactor", billable_factor);
- msg->getUUID ("RegionInfo", "CacheID", cache_id );
-
- if (msg->has(_PREHASH_RegionInfo4))
- {
- msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags);
- msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols);
- }
- else
- {
- U32 flags = 0;
- msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
- region_flags = flags;
- }
-
- setRegionFlags(region_flags);
- setRegionProtocols(region_protocols);
- setSimAccess(sim_access);
- setRegionNameAndZone(sim_name);
- setOwner(sim_owner);
- setIsEstateManager(is_estate_manager);
- setWaterHeight(water_height);
- setBillableFactor(billable_factor);
- setCacheID(cache_id);
-
- LLUUID region_id;
- msg->getUUID("RegionInfo2", "RegionID", region_id);
- setRegionID(region_id);
-
- // Retrieve the CR-53 (Homestead/Land SKU) information
- S32 classID = 0;
- S32 cpuRatio = 0;
- std::string coloName;
- std::string productSKU;
- std::string productName;
-
- // the only reasonable way to decide if we actually have any data is to
- // check to see if any of these fields have positive sizes
- if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
- msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
- msg->getSize("RegionInfo3", "ProductName") > 0)
- {
- msg->getS32 ("RegionInfo3", "CPUClassID", classID);
- msg->getS32 ("RegionInfo3", "CPURatio", cpuRatio);
- msg->getString ("RegionInfo3", "ColoName", coloName);
- msg->getString ("RegionInfo3", "ProductSKU", productSKU);
- msg->getString ("RegionInfo3", "ProductName", productName);
-
- mClassID = classID;
- mCPURatio = cpuRatio;
- mColoName = coloName;
- mProductSKU = productSKU;
- mProductName = productName;
- }
-
- mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");
- LLVLComposition *compp = getComposition();
- if (compp)
- {
- LLUUID tmp_id;
-
- bool changed = false;
-
- // Get the 4 textures for land
- msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
- changed |= (tmp_id != compp->getDetailTextureID(0));
- compp->setDetailTextureID(0, tmp_id);
-
- msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
- changed |= (tmp_id != compp->getDetailTextureID(1));
- compp->setDetailTextureID(1, tmp_id);
-
- msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
- changed |= (tmp_id != compp->getDetailTextureID(2));
- compp->setDetailTextureID(2, tmp_id);
-
- msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
- changed |= (tmp_id != compp->getDetailTextureID(3));
- compp->setDetailTextureID(3, tmp_id);
-
- // Get the start altitude and range values for land textures
- F32 tmp_f32;
- msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
- changed |= (tmp_f32 != compp->getStartHeight(0));
- compp->setStartHeight(0, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
- changed |= (tmp_f32 != compp->getStartHeight(1));
- compp->setStartHeight(1, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
- changed |= (tmp_f32 != compp->getStartHeight(2));
- compp->setStartHeight(2, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
- changed |= (tmp_f32 != compp->getStartHeight(3));
- compp->setStartHeight(3, tmp_f32);
-
-
- msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
- changed |= (tmp_f32 != compp->getHeightRange(0));
- compp->setHeightRange(0, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
- changed |= (tmp_f32 != compp->getHeightRange(1));
- compp->setHeightRange(1, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
- changed |= (tmp_f32 != compp->getHeightRange(2));
- compp->setHeightRange(2, tmp_f32);
-
- msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
- changed |= (tmp_f32 != compp->getHeightRange(3));
- compp->setHeightRange(3, tmp_f32);
-
- // If this is an UPDATE (params already ready, we need to regenerate
- // all of our terrain stuff, by
- if (compp->getParamsReady())
- {
- // Update if the land changed
- if (changed)
- {
- getLand().dirtyAllPatches();
- }
- }
- else
- {
- compp->setParamsReady();
- }
- }
-
-
- // Now that we have the name, we can load the cache file
- // off disk.
- loadObjectCache();
-
- // After loading cache, signal that simulator can start
- // sending data.
- // TODO: Send all upstream viewer->sim handshake info here.
- LLHost host = msg->getSender();
- msg->newMessage("RegionHandshakeReply");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("RegionInfo");
-
- U32 flags = 0;
- flags |= REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE;
-
- if(sVOCacheCullingEnabled)
- {
- flags |= 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects.
- }
- if(mImpl->mCacheMap.empty())
- {
- flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes.
- }
- msg->addU32("Flags", flags );
- msg->sendReliable(host);
+ mImpl->mCacheMap.clear();
+}
- mRegionTimer.reset(); //reset region timer.
+void LLViewerRegion::unpackRegionHandshake()
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ U64 region_flags = 0;
+ U64 region_protocols = 0;
+ U8 sim_access;
+ std::string sim_name;
+ LLUUID sim_owner;
+ BOOL is_estate_manager;
+ F32 water_height;
+ F32 billable_factor;
+ LLUUID cache_id;
+
+ msg->getU8 ("RegionInfo", "SimAccess", sim_access);
+ msg->getString ("RegionInfo", "SimName", sim_name);
+ msg->getUUID ("RegionInfo", "SimOwner", sim_owner);
+ msg->getBOOL ("RegionInfo", "IsEstateManager", is_estate_manager);
+ msg->getF32 ("RegionInfo", "WaterHeight", water_height);
+ msg->getF32 ("RegionInfo", "BillableFactor", billable_factor);
+ msg->getUUID ("RegionInfo", "CacheID", cache_id );
+
+ if (msg->has(_PREHASH_RegionInfo4))
+ {
+ msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags);
+ msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+ region_flags = flags;
+ }
+
+ setRegionFlags(region_flags);
+ setRegionProtocols(region_protocols);
+ setSimAccess(sim_access);
+ setRegionNameAndZone(sim_name);
+ setOwner(sim_owner);
+ setIsEstateManager(is_estate_manager);
+ setWaterHeight(water_height);
+ setBillableFactor(billable_factor);
+ setCacheID(cache_id);
+
+ LLUUID region_id;
+ msg->getUUID("RegionInfo2", "RegionID", region_id);
+ setRegionID(region_id);
+
+ // Retrieve the CR-53 (Homestead/Land SKU) information
+ S32 classID = 0;
+ S32 cpuRatio = 0;
+ std::string coloName;
+ std::string productSKU;
+ std::string productName;
+
+ // the only reasonable way to decide if we actually have any data is to
+ // check to see if any of these fields have positive sizes
+ if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
+ msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
+ msg->getSize("RegionInfo3", "ProductName") > 0)
+ {
+ msg->getS32 ("RegionInfo3", "CPUClassID", classID);
+ msg->getS32 ("RegionInfo3", "CPURatio", cpuRatio);
+ msg->getString ("RegionInfo3", "ColoName", coloName);
+ msg->getString ("RegionInfo3", "ProductSKU", productSKU);
+ msg->getString ("RegionInfo3", "ProductName", productName);
+
+ mClassID = classID;
+ mCPURatio = cpuRatio;
+ mColoName = coloName;
+ mProductSKU = productSKU;
+ mProductName = productName;
+ }
+
+ mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");
+ LLVLComposition *compp = getComposition();
+ if (compp)
+ {
+ LLUUID tmp_id;
+
+ bool changed = false;
+
+ // Get the 4 textures for land
+ msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
+ changed |= (tmp_id != compp->getDetailAssetID(0));
+ compp->setDetailAssetID(0, tmp_id);
+
+ msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
+ changed |= (tmp_id != compp->getDetailAssetID(1));
+ compp->setDetailAssetID(1, tmp_id);
+
+ msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
+ changed |= (tmp_id != compp->getDetailAssetID(2));
+ compp->setDetailAssetID(2, tmp_id);
+
+ msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
+ changed |= (tmp_id != compp->getDetailAssetID(3));
+ compp->setDetailAssetID(3, tmp_id);
+
+ // Get the start altitude and range values for land textures
+ F32 tmp_f32;
+ msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
+ changed |= (tmp_f32 != compp->getStartHeight(0));
+ compp->setStartHeight(0, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
+ changed |= (tmp_f32 != compp->getStartHeight(1));
+ compp->setStartHeight(1, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
+ changed |= (tmp_f32 != compp->getStartHeight(2));
+ compp->setStartHeight(2, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
+ changed |= (tmp_f32 != compp->getStartHeight(3));
+ compp->setStartHeight(3, tmp_f32);
+
+
+ msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
+ changed |= (tmp_f32 != compp->getHeightRange(0));
+ compp->setHeightRange(0, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
+ changed |= (tmp_f32 != compp->getHeightRange(1));
+ compp->setHeightRange(1, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
+ changed |= (tmp_f32 != compp->getHeightRange(2));
+ compp->setHeightRange(2, tmp_f32);
+
+ msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
+ changed |= (tmp_f32 != compp->getHeightRange(3));
+ compp->setHeightRange(3, tmp_f32);
+
+ // If this is an UPDATE (params already ready, we need to regenerate
+ // all of our terrain stuff, by
+ if (compp->getParamsReady())
+ {
+ // Update if the land changed
+ if (changed)
+ {
+ getLand().dirtyAllPatches();
+ }
+ }
+ else
+ {
+ compp->setParamsReady();
+ }
+ }
+
+
+ // Now that we have the name, we can load the cache file
+ // off disk.
+ loadObjectCache();
+
+ // After loading cache, signal that simulator can start
+ // sending data.
+ // TODO: Send all upstream viewer->sim handshake info here.
+ LLHost host = msg->getSender();
+ msg->newMessage("RegionHandshakeReply");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("RegionInfo");
+
+ U32 flags = 0;
+ flags |= REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE;
+
+ if(sVOCacheCullingEnabled)
+ {
+ flags |= 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects.
+ }
+ if(mImpl->mCacheMap.empty())
+ {
+ flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes.
+ }
+ msg->addU32("Flags", flags );
+ msg->sendReliable(host);
+
+ mRegionTimer.reset(); //reset region timer.
}
// static
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
- capabilityNames.append("AbuseCategories");
- capabilityNames.append("AcceptFriendship");
- capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
- capabilityNames.append("AgentPreferences");
+ capabilityNames.append("AbuseCategories");
+ capabilityNames.append("AcceptFriendship");
+ capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
+ capabilityNames.append("AgentPreferences");
capabilityNames.append("AgentProfile");
- capabilityNames.append("AgentState");
- capabilityNames.append("AttachmentResources");
- capabilityNames.append("AvatarPickerSearch");
- capabilityNames.append("AvatarRenderInfo");
- capabilityNames.append("CharacterProperties");
- capabilityNames.append("ChatSessionRequest");
- capabilityNames.append("CopyInventoryFromNotecard");
- capabilityNames.append("CreateInventoryCategory");
- capabilityNames.append("DeclineFriendship");
- capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
- capabilityNames.append("DispatchRegionInfo");
- capabilityNames.append("DirectDelivery");
- capabilityNames.append("EnvironmentSettings");
- capabilityNames.append("EstateAccess");
- capabilityNames.append("EstateChangeInfo");
- capabilityNames.append("EventQueueGet");
+ capabilityNames.append("AgentState");
+ capabilityNames.append("AttachmentResources");
+ capabilityNames.append("AvatarPickerSearch");
+ capabilityNames.append("AvatarRenderInfo");
+ capabilityNames.append("CharacterProperties");
+ capabilityNames.append("ChatSessionRequest");
+ capabilityNames.append("CopyInventoryFromNotecard");
+ capabilityNames.append("CreateInventoryCategory");
+ capabilityNames.append("DeclineFriendship");
+ capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
+ capabilityNames.append("DispatchRegionInfo");
+ capabilityNames.append("DirectDelivery");
+ capabilityNames.append("EnvironmentSettings");
+ capabilityNames.append("EstateAccess");
+ capabilityNames.append("EstateChangeInfo");
+ capabilityNames.append("EventQueueGet");
capabilityNames.append("ExtEnvironment");
- capabilityNames.append("FetchLib2");
- capabilityNames.append("FetchLibDescendents2");
- capabilityNames.append("FetchInventory2");
- capabilityNames.append("FetchInventoryDescendents2");
- capabilityNames.append("IncrementCOFVersion");
- AISAPI::getCapNames(capabilityNames);
+ capabilityNames.append("FetchLib2");
+ capabilityNames.append("FetchLibDescendents2");
+ capabilityNames.append("FetchInventory2");
+ capabilityNames.append("FetchInventoryDescendents2");
+ capabilityNames.append("IncrementCOFVersion");
+ AISAPI::getCapNames(capabilityNames);
- capabilityNames.append("InterestList");
+ capabilityNames.append("InterestList");
capabilityNames.append("InventoryThumbnailUpload");
- capabilityNames.append("GetDisplayNames");
- capabilityNames.append("GetExperiences");
- capabilityNames.append("AgentExperiences");
- capabilityNames.append("FindExperienceByName");
- capabilityNames.append("GetExperienceInfo");
- capabilityNames.append("GetAdminExperiences");
- capabilityNames.append("GetCreatorExperiences");
- capabilityNames.append("ExperiencePreferences");
- capabilityNames.append("GroupExperiences");
- capabilityNames.append("UpdateExperience");
- capabilityNames.append("IsExperienceAdmin");
- capabilityNames.append("IsExperienceContributor");
- capabilityNames.append("RegionExperiences");
+ capabilityNames.append("GetDisplayNames");
+ capabilityNames.append("GetExperiences");
+ capabilityNames.append("AgentExperiences");
+ capabilityNames.append("FindExperienceByName");
+ capabilityNames.append("GetExperienceInfo");
+ capabilityNames.append("GetAdminExperiences");
+ capabilityNames.append("GetCreatorExperiences");
+ capabilityNames.append("ExperiencePreferences");
+ capabilityNames.append("GroupExperiences");
+ capabilityNames.append("UpdateExperience");
+ capabilityNames.append("IsExperienceAdmin");
+ capabilityNames.append("IsExperienceContributor");
+ capabilityNames.append("RegionExperiences");
capabilityNames.append("ExperienceQuery");
- capabilityNames.append("GetMetadata");
- capabilityNames.append("GetObjectCost");
- capabilityNames.append("GetObjectPhysicsData");
- capabilityNames.append("GroupAPIv1");
- capabilityNames.append("GroupMemberData");
- capabilityNames.append("GroupProposalBallot");
- capabilityNames.append("HomeLocation");
- capabilityNames.append("LandResources");
- capabilityNames.append("LSLSyntax");
- capabilityNames.append("MapLayer");
- capabilityNames.append("MapLayerGod");
- capabilityNames.append("MeshUploadFlag");
- capabilityNames.append("ModifyMaterialParams");
- capabilityNames.append("NavMeshGenerationStatus");
- capabilityNames.append("NewFileAgentInventory");
- capabilityNames.append("ObjectAnimation");
- capabilityNames.append("ObjectMedia");
- capabilityNames.append("ObjectMediaNavigate");
- capabilityNames.append("ObjectNavMeshProperties");
- capabilityNames.append("ParcelPropertiesUpdate");
- capabilityNames.append("ParcelVoiceInfoRequest");
- capabilityNames.append("ProductInfoRequest");
- capabilityNames.append("ProvisionVoiceAccountRequest");
- capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite
- capabilityNames.append("RegionObjects");
- capabilityNames.append("RemoteParcelRequest");
- capabilityNames.append("RenderMaterials");
- capabilityNames.append("RequestTextureDownload");
- capabilityNames.append("ResourceCostSelected");
- capabilityNames.append("RetrieveNavMeshSrc");
- capabilityNames.append("SearchStatRequest");
- capabilityNames.append("SearchStatTracking");
- capabilityNames.append("SendPostcard");
- capabilityNames.append("SendUserReport");
- capabilityNames.append("SendUserReportWithScreenshot");
- capabilityNames.append("ServerReleaseNotes");
- capabilityNames.append("SetDisplayName");
- capabilityNames.append("SimConsoleAsync");
- capabilityNames.append("SimulatorFeatures");
- capabilityNames.append("StartGroupProposal");
- capabilityNames.append("TerrainNavMeshProperties");
- capabilityNames.append("TextureStats");
- capabilityNames.append("UntrustedSimulatorMessage");
- capabilityNames.append("UpdateAgentInformation");
- capabilityNames.append("UpdateAgentLanguage");
- capabilityNames.append("UpdateAvatarAppearance");
- capabilityNames.append("UpdateGestureAgentInventory");
- capabilityNames.append("UpdateGestureTaskInventory");
- capabilityNames.append("UpdateNotecardAgentInventory");
- capabilityNames.append("UpdateNotecardTaskInventory");
- capabilityNames.append("UpdateScriptAgent");
- capabilityNames.append("UpdateScriptTask");
+ capabilityNames.append("GetMetadata");
+ capabilityNames.append("GetObjectCost");
+ capabilityNames.append("GetObjectPhysicsData");
+ capabilityNames.append("GroupAPIv1");
+ capabilityNames.append("GroupMemberData");
+ capabilityNames.append("GroupProposalBallot");
+ capabilityNames.append("HomeLocation");
+ capabilityNames.append("LandResources");
+ capabilityNames.append("LSLSyntax");
+ capabilityNames.append("MapLayer");
+ capabilityNames.append("MapLayerGod");
+ capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("ModifyMaterialParams");
+ capabilityNames.append("NavMeshGenerationStatus");
+ capabilityNames.append("NewFileAgentInventory");
+ capabilityNames.append("ObjectAnimation");
+ capabilityNames.append("ObjectMedia");
+ capabilityNames.append("ObjectMediaNavigate");
+ capabilityNames.append("ObjectNavMeshProperties");
+ capabilityNames.append("ParcelPropertiesUpdate");
+ capabilityNames.append("ParcelVoiceInfoRequest");
+ capabilityNames.append("ProductInfoRequest");
+ capabilityNames.append("ProvisionVoiceAccountRequest");
+ capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite
+ capabilityNames.append("RegionObjects");
+ capabilityNames.append("RemoteParcelRequest");
+ capabilityNames.append("RenderMaterials");
+ capabilityNames.append("RequestTextureDownload");
+ capabilityNames.append("ResourceCostSelected");
+ capabilityNames.append("RetrieveNavMeshSrc");
+ capabilityNames.append("SearchStatRequest");
+ capabilityNames.append("SearchStatTracking");
+ capabilityNames.append("SendPostcard");
+ capabilityNames.append("SendUserReport");
+ capabilityNames.append("SendUserReportWithScreenshot");
+ capabilityNames.append("ServerReleaseNotes");
+ capabilityNames.append("SetDisplayName");
+ capabilityNames.append("SimConsoleAsync");
+ capabilityNames.append("SimulatorFeatures");
+ capabilityNames.append("StartGroupProposal");
+ capabilityNames.append("TerrainNavMeshProperties");
+ capabilityNames.append("TextureStats");
+ capabilityNames.append("UntrustedSimulatorMessage");
+ capabilityNames.append("UpdateAgentInformation");
+ capabilityNames.append("UpdateAgentLanguage");
+ capabilityNames.append("UpdateAvatarAppearance");
+ capabilityNames.append("UpdateGestureAgentInventory");
+ capabilityNames.append("UpdateGestureTaskInventory");
+ capabilityNames.append("UpdateNotecardAgentInventory");
+ capabilityNames.append("UpdateNotecardTaskInventory");
+ capabilityNames.append("UpdateScriptAgent");
+ capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
capabilityNames.append("UploadAgentProfileImage");
capabilityNames.append("UpdateMaterialAgentInventory");
capabilityNames.append("UpdateMaterialTaskInventory");
- capabilityNames.append("UploadBakedTexture");
+ capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
- capabilityNames.append("ViewerAsset");
- capabilityNames.append("ViewerBenefits");
- capabilityNames.append("ViewerMetrics");
- capabilityNames.append("ViewerStartAuction");
- capabilityNames.append("ViewerStats");
+ capabilityNames.append("ViewerAsset");
+ capabilityNames.append("ViewerBenefits");
+ capabilityNames.append("ViewerMetrics");
+ capabilityNames.append("ViewerStartAuction");
+ capabilityNames.append("ViewerStats");
- // Please add new capabilities alphabetically to reduce
- // merge conflicts.
+ // Please add new capabilities alphabetically to reduce
+ // merge conflicts.
}
void LLViewerRegion::setSeedCapability(const std::string& url)
{
- if (getCapability("Seed") == url)
- {
- setCapabilityDebug("Seed", url);
- LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " <<
- url << LL_ENDL;
+ if (getCapability("Seed") == url)
+ {
+ setCapabilityDebug("Seed", url);
+ LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " <<
+ url << LL_ENDL;
- //Instead of just returning we build up a second set of seed caps and compare them
- //to the "original" seed cap received and determine why there is problem!
+ //Instead of just returning we build up a second set of seed caps and compare them
+ //to the "original" seed cap received and determine why there is problem!
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle()));
@@ -3209,14 +3301,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
// Make sure we are still good to do
LLCoros::checkStop();
- return;
+ return;
}
-
- delete mImpl->mEventPoll;
- mImpl->mEventPoll = NULL;
-
- mImpl->mCapabilities.clear();
- setCapability("Seed", url);
+
+ delete mImpl->mEventPoll;
+ mImpl->mEventPoll = NULL;
+
+ mImpl->mCapabilities.clear();
+ setCapability("Seed", url);
std::string coroname =
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
@@ -3232,69 +3324,69 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
S32 LLViewerRegion::getNumSeedCapRetries()
{
- return mImpl->mSeedCapAttempts;
+ return mImpl->mSeedCapAttempts;
}
void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
{
- if(name == "EventQueueGet")
- {
- delete mImpl->mEventPoll;
- mImpl->mEventPoll = NULL;
- mImpl->mEventPoll = new LLEventPoll(url, getHost());
- }
- else if(name == "UntrustedSimulatorMessage")
- {
+ if(name == "EventQueueGet")
+ {
+ delete mImpl->mEventPoll;
+ mImpl->mEventPoll = NULL;
+ mImpl->mEventPoll = new LLEventPoll(url, getHost());
+ }
+ else if(name == "UntrustedSimulatorMessage")
+ {
mImpl->mHost.setUntrustedSimulatorCap(url);
- }
- else if (name == "SimulatorFeatures")
- {
+ }
+ else if (name == "SimulatorFeatures")
+ {
mImpl->mCapabilities["SimulatorFeatures"] = url;
requestSimulatorFeatures();
- }
- else
- {
- mImpl->mCapabilities[name] = url;
- if(name == "ViewerAsset")
- {
- /*==============================================================*/
- // The following inserted lines are a hack for testing MAINT-7081,
- // which is why the indentation and formatting are left ugly.
- const char* VIEWERASSET = getenv("VIEWERASSET");
- if (VIEWERASSET)
- {
- mImpl->mCapabilities[name] = VIEWERASSET;
- mViewerAssetUrl = VIEWERASSET;
- }
- else
- /*==============================================================*/
- mViewerAssetUrl = url;
- }
- }
+ }
+ else
+ {
+ mImpl->mCapabilities[name] = url;
+ if(name == "ViewerAsset")
+ {
+ /*==============================================================*/
+ // The following inserted lines are a hack for testing MAINT-7081,
+ // which is why the indentation and formatting are left ugly.
+ const char* VIEWERASSET = getenv("VIEWERASSET");
+ if (VIEWERASSET)
+ {
+ mImpl->mCapabilities[name] = VIEWERASSET;
+ mViewerAssetUrl = VIEWERASSET;
+ }
+ else
+ /*==============================================================*/
+ mViewerAssetUrl = url;
+ }
+ }
}
void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url)
{
- // Continue to not add certain caps, as we do in setCapability. This is so they match up when we check them later.
- if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) )
- {
- mImpl->mSecondCapabilitiesTracker[name] = url;
- if(name == "ViewerAsset")
- {
- /*==============================================================*/
- // The following inserted lines are a hack for testing MAINT-7081,
- // which is why the indentation and formatting are left ugly.
- const char* VIEWERASSET = getenv("VIEWERASSET");
- if (VIEWERASSET)
- {
- mImpl->mSecondCapabilitiesTracker[name] = VIEWERASSET;
- mViewerAssetUrl = VIEWERASSET;
- }
- else
- /*==============================================================*/
- mViewerAssetUrl = url;
- }
- }
+ // Continue to not add certain caps, as we do in setCapability. This is so they match up when we check them later.
+ if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) )
+ {
+ mImpl->mSecondCapabilitiesTracker[name] = url;
+ if(name == "ViewerAsset")
+ {
+ /*==============================================================*/
+ // The following inserted lines are a hack for testing MAINT-7081,
+ // which is why the indentation and formatting are left ugly.
+ const char* VIEWERASSET = getenv("VIEWERASSET");
+ if (VIEWERASSET)
+ {
+ mImpl->mSecondCapabilitiesTracker[name] = VIEWERASSET;
+ mViewerAssetUrl = VIEWERASSET;
+ }
+ else
+ /*==============================================================*/
+ mViewerAssetUrl = url;
+ }
+ }
}
std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
@@ -3311,44 +3403,44 @@ std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
{
- return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
+ return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
}
std::string LLViewerRegion::getCapability(const std::string& name) const
{
- if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
- {
- LL_WARNS() << "getCapability called before caps received for " << name << LL_ENDL;
- }
-
- CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
- if(iter == mImpl->mCapabilities.end())
- {
- return "";
- }
+ if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+ {
+ LL_WARNS() << "getCapability called before caps received for " << name << LL_ENDL;
+ }
+
+ CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
+ if(iter == mImpl->mCapabilities.end())
+ {
+ return "";
+ }
- return iter->second;
+ return iter->second;
}
bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
{
- if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
- {
- LL_WARNS() << "isCapabilityAvailable called before caps received for " << name << LL_ENDL;
- }
+ if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+ {
+ LL_WARNS() << "isCapabilityAvailable called before caps received for " << name << LL_ENDL;
+ }
+
+ CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
+ if(iter == mImpl->mCapabilities.end())
+ {
+ return false;
+ }
- CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
- if(iter == mImpl->mCapabilities.end())
- {
- return false;
- }
-
- return true;
+ return true;
}
bool LLViewerRegion::capabilitiesReceived() const
{
- return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
+ return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
}
bool LLViewerRegion::capabilitiesError() const
@@ -3358,22 +3450,22 @@ bool LLViewerRegion::capabilitiesError() const
void LLViewerRegion::setCapabilitiesReceived(bool received)
{
- mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
+ mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
- // Tell interested parties that we've received capabilities,
- // so that they can safely use getCapability().
- if (received)
- {
- mCapabilitiesReceivedSignal(getRegionID(), this);
+ // Tell interested parties that we've received capabilities,
+ // so that they can safely use getCapability().
+ if (received)
+ {
+ mCapabilitiesReceivedSignal(getRegionID(), this);
- LLFloaterPermsDefault::sendInitialPerms();
+ LLFloaterPermsDefault::sendInitialPerms();
- // This is a single-shot signal. Forget callbacks to save resources.
- mCapabilitiesReceivedSignal.disconnect_all_slots();
+ // This is a single-shot signal. Forget callbacks to save resources.
+ mCapabilitiesReceivedSignal.disconnect_all_slots();
- // Set the region to the desired interest list mode
+ // Set the region to the desired interest list mode
setInterestListMode(gAgent.getInterestListMode());
- }
+ }
}
void LLViewerRegion::setCapabilitiesError()
@@ -3383,12 +3475,12 @@ void LLViewerRegion::setCapabilitiesError()
boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
- return mCapabilitiesReceivedSignal.connect(cb);
+ return mCapabilitiesReceivedSignal.connect(cb);
}
void LLViewerRegion::logActiveCapabilities() const
{
- log_capabilities(mImpl->mCapabilities);
+ log_capabilities(mImpl->mCapabilities);
}
@@ -3399,7 +3491,7 @@ bool LLViewerRegion::requestPostCapability(const std::string &capName, LLSD &pos
if (url.empty())
{
LL_WARNS("Region") << "Could not retrieve region " << getRegionID()
- << " POST capability \"" << capName << "\"" << LL_ENDL;
+ << " POST capability \"" << capName << "\"" << LL_ENDL;
return false;
}
@@ -3446,14 +3538,14 @@ void LLViewerRegion::setInterestListMode(const std::string &new_mode)
{
mInterestListMode = new_mode;
- if (mInterestListMode != std::string(IL_MODE_DEFAULT) && mInterestListMode != std::string(IL_MODE_360))
- {
- LL_WARNS("360Capture") << "Region " << getRegionID() << " setInterestListMode() invalid interest list mode: "
- << mInterestListMode << ", setting to default" << LL_ENDL;
+ if (mInterestListMode != std::string(IL_MODE_DEFAULT) && mInterestListMode != std::string(IL_MODE_360))
+ {
+ LL_WARNS("360Capture") << "Region " << getRegionID() << " setInterestListMode() invalid interest list mode: "
+ << mInterestListMode << ", setting to default" << LL_ENDL;
mInterestListMode = IL_MODE_DEFAULT;
- }
+ }
- LLSD body;
+ LLSD body;
body["mode"] = mInterestListMode;
if (requestPostCapability("InterestList", body,
[](const LLSD &response) {
@@ -3467,99 +3559,99 @@ void LLViewerRegion::setInterestListMode(const std::string &new_mode)
}
else
{
- LL_WARNS("360Capture") << "Region " << getRegionID()
- << " Unable to post an InterestList capability request with payload: \n"
+ LL_WARNS("360Capture") << "Region " << getRegionID()
+ << " Unable to post an InterestList capability request with payload: \n"
<< ll_pretty_print_sd(body) << LL_ENDL;
}
}
else
{
LL_DEBUGS("360Capture") << "Region " << getRegionID() << "No change, skipping Interest List mode POST to "
- << new_mode << " mode" << LL_ENDL;
+ << new_mode << " mode" << LL_ENDL;
}
}
void LLViewerRegion::resetInterestList()
{
- if (requestDelCapability("InterestList", [](const LLSD &response) {
- LL_DEBUGS("360Capture") << "InterestList capability DEL responded: \n" << ll_pretty_print_sd(response) << LL_ENDL;
- }))
- {
- LL_DEBUGS("360Capture") << "Region " << getRegionID() << " Successfully reset InterestList capability" << LL_ENDL;
- }
- else
- {
- LL_WARNS("360Capture") << "Region " << getRegionID() << " Unable to DEL InterestList capability request" << LL_ENDL;
- }
+ if (requestDelCapability("InterestList", [](const LLSD &response) {
+ LL_DEBUGS("360Capture") << "InterestList capability DEL responded: \n" << ll_pretty_print_sd(response) << LL_ENDL;
+ }))
+ {
+ LL_DEBUGS("360Capture") << "Region " << getRegionID() << " Successfully reset InterestList capability" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("360Capture") << "Region " << getRegionID() << " Unable to DEL InterestList capability request" << LL_ENDL;
+ }
}
LLSpatialPartition *LLViewerRegion::getSpatialPartition(U32 type)
{
- if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE)
- {
- return (LLSpatialPartition*)mImpl->mObjectPartition[type];
- }
- return NULL;
+ if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE)
+ {
+ return (LLSpatialPartition*)mImpl->mObjectPartition[type];
+ }
+ return NULL;
}
LLVOCachePartition* LLViewerRegion::getVOCachePartition()
{
- if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())
- {
- return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];
- }
- return NULL;
+ if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())
+ {
+ return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];
+ }
+ return NULL;
}
// the viewer can not yet distinquish between normal- and estate-owned objects
// so we collapse these two bits and enable the UI if either are set
const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
- | REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
+ | REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
{
- return (mParcelOverlay != NULL)
- && (mParcelOverlay->isOwnedSelf(pos)
- || mParcelOverlay->isOwnedGroup(pos)
- || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT)
- && mParcelOverlay->encroachesOwned(boxes)) );
+ return (mParcelOverlay != NULL)
+ && (mParcelOverlay->isOwnedSelf(pos)
+ || mParcelOverlay->isOwnedGroup(pos)
+ || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT)
+ && mParcelOverlay->encroachesOwned(boxes)) );
}
bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
{
- bool result = false;
- result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
- return result;
+ bool result = false;
+ result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
+ return result;
}
bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
{
- return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
+ return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
}
void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
{
- mImpl->mLandp->getNeighboringRegions( uniqueRegions );
+ mImpl->mLandp->getNeighboringRegions( uniqueRegions );
}
void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
{
- mImpl->mLandp->getNeighboringRegionsStatus( regions );
+ mImpl->mLandp->getNeighboringRegionsStatus( regions );
}
void LLViewerRegion::showReleaseNotes()
{
- std::string url = this->getCapability("ServerReleaseNotes");
+ std::string url = this->getCapability("ServerReleaseNotes");
- if (url.empty()) {
- // HACK haven't received the capability yet, we'll wait until
- // it arives.
- mReleaseNotesRequested = TRUE;
- return;
- }
+ if (url.empty()) {
+ // HACK haven't received the capability yet, we'll wait until
+ // it arives.
+ mReleaseNotesRequested = TRUE;
+ return;
+ }
- LLWeb::loadURL(url);
- mReleaseNotesRequested = FALSE;
+ LLWeb::loadURL(url);
+ mReleaseNotesRequested = FALSE;
}
std::string LLViewerRegion::getDescription() const
@@ -3569,98 +3661,98 @@ std::string LLViewerRegion::getDescription() const
bool LLViewerRegion::meshUploadEnabled() const
{
- return (mSimulatorFeatures.has("MeshUploadEnabled") &&
- mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
+ return (mSimulatorFeatures.has("MeshUploadEnabled") &&
+ mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
}
bool LLViewerRegion::bakesOnMeshEnabled() const
{
- return (mSimulatorFeatures.has("BakesOnMeshEnabled") &&
- mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
+ return (mSimulatorFeatures.has("BakesOnMeshEnabled") &&
+ mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
}
bool LLViewerRegion::meshRezEnabled() const
{
- return (mSimulatorFeatures.has("MeshRezEnabled") &&
- mSimulatorFeatures["MeshRezEnabled"].asBoolean());
+ return (mSimulatorFeatures.has("MeshRezEnabled") &&
+ mSimulatorFeatures["MeshRezEnabled"].asBoolean());
}
bool LLViewerRegion::dynamicPathfindingEnabled() const
{
- return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
- mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
+ return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
+ mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
}
bool LLViewerRegion::avatarHoverHeightEnabled() const
{
- return ( mSimulatorFeatures.has("AvatarHoverHeightEnabled") &&
- mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean());
+ return ( mSimulatorFeatures.has("AvatarHoverHeightEnabled") &&
+ mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean());
}
/* Static Functions */
void log_capabilities(const CapabilityMap &capmap)
{
- S32 count = 0;
- CapabilityMap::const_iterator iter;
- for (iter = capmap.begin(); iter != capmap.end(); ++iter, ++count)
- {
- if (!iter->second.empty())
- {
- LL_INFOS() << "log_capabilities: " << iter->first << " URL is " << iter->second << LL_ENDL;
- }
- }
- LL_INFOS() << "log_capabilities: Dumped " << count << " entries." << LL_ENDL;
+ S32 count = 0;
+ CapabilityMap::const_iterator iter;
+ for (iter = capmap.begin(); iter != capmap.end(); ++iter, ++count)
+ {
+ if (!iter->second.empty())
+ {
+ LL_INFOS() << "log_capabilities: " << iter->first << " URL is " << iter->second << LL_ENDL;
+ }
+ }
+ LL_INFOS() << "log_capabilities: Dumped " << count << " entries." << LL_ENDL;
}
void LLViewerRegion::resetMaterialsCapThrottle()
{
- F32 requests_per_sec = 1.0f; // original default;
- if ( mSimulatorFeatures.has("RenderMaterialsCapability")
- && mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
- {
- requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
- if ( requests_per_sec == 0.0f )
- {
- requests_per_sec = 1.0f;
- LL_WARNS("Materials")
- << "region '" << getName()
- << "' returned zero for RenderMaterialsCapability; using default "
- << requests_per_sec << " per second"
- << LL_ENDL;
- }
- LL_DEBUGS("Materials") << "region '" << getName()
- << "' RenderMaterialsCapability " << requests_per_sec
- << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("Materials")
- << "region '" << getName()
- << "' did not return RenderMaterialsCapability, using default "
- << requests_per_sec << " per second"
- << LL_ENDL;
- }
-
- mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
+ F32 requests_per_sec = 1.0f; // original default;
+ if ( mSimulatorFeatures.has("RenderMaterialsCapability")
+ && mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
+ {
+ requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
+ if ( requests_per_sec == 0.0f )
+ {
+ requests_per_sec = 1.0f;
+ LL_WARNS("Materials")
+ << "region '" << getName()
+ << "' returned zero for RenderMaterialsCapability; using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+ LL_DEBUGS("Materials") << "region '" << getName()
+ << "' RenderMaterialsCapability " << requests_per_sec
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials")
+ << "region '" << getName()
+ << "' did not return RenderMaterialsCapability, using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+
+ mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
}
U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
{
- U32 max_entries = 50; // original hard coded default
- if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
- && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
- {
- max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
- }
- return max_entries;
+ U32 max_entries = 50; // original hard coded default
+ if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
+ && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
+ {
+ max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
+ }
+ return max_entries;
}
std::string LLViewerRegion::getSimHostName()
{
- if (mSimulatorFeaturesReceived)
- {
- return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName();
- }
- return std::string("...");
+ if (mSimulatorFeaturesReceived)
+ {
+ return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName();
+ }
+ return std::string("...");
}
void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj)
@@ -3672,6 +3764,11 @@ void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj)
auto iter = mImpl->mGLTFOverridesLLSD.find(local_id);
if (iter != mImpl->mGLTFOverridesLLSD.end())
{
+ // UUID can be inserted null, so backfill the UUID if it was left empty
+ if (iter->second.mObjectId.isNull())
+ {
+ iter->second.mObjectId = obj->getID();
+ }
llassert(iter->second.mGLTFMaterial.size() == iter->second.mSides.size());
for (auto& side : iter->second.mGLTFMaterial)
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 08eda19b16..1c89cc4e6d 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerregion.h
* @brief Description of the LLViewerRegion class.
*
* $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$
*/
@@ -40,14 +40,14 @@
#include "lluuid.h"
#include "llweb.h"
#include "llcapabilityprovider.h"
-#include "m4math.h" // LLMatrix4
+#include "m4math.h" // LLMatrix4
#include "llframetimer.h"
#include "llreflectionmap.h"
// Surface id's
#define LAND 1
#define WATER 2
-const U32 MAX_OBJECT_CACHE_ENTRIES = 50000;
+const U32 MAX_OBJECT_CACHE_ENTRIES = 50000;
// Region handshake flags
const U32 REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE = 1U << 2;
@@ -77,211 +77,214 @@ class LLVOCachePartition;
class LLViewerRegion: public LLCapabilityProvider // implements this interface
{
public:
- //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR
- typedef enum
- {
- PARTITION_HUD=0,
- PARTITION_TERRAIN,
- PARTITION_VOIDWATER,
- PARTITION_WATER,
- PARTITION_TREE,
- PARTITION_PARTICLE,
- PARTITION_GRASS,
- PARTITION_VOLUME,
- PARTITION_BRIDGE,
- PARTITION_AVATAR,
- PARTITION_CONTROL_AV, // Animesh
- PARTITION_HUD_PARTICLE,
- PARTITION_VO_CACHE,
- PARTITION_NONE,
- NUM_PARTITIONS
- } eObjectPartitions;
-
- typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
-
- LLViewerRegion(const U64 &handle,
- const LLHost &host,
- const U32 surface_grid_width,
- const U32 patch_grid_width,
- const F32 region_width_meters);
- ~LLViewerRegion();
-
- // Call this after you have the region name and handle.
- void loadObjectCache();
- void saveObjectCache();
-
- void sendMessage(); // Send the current message to this region's simulator
- void sendReliableMessage(); // Send the current message to this region's simulator
-
- void setOriginGlobal(const LLVector3d &origin);
- //void setAgentOffset(const LLVector3d &offset);
- void updateRenderMatrix();
-
- void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); }
- void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); }
- void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); }
- void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); }
- void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); }
- //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used
- void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); }
-
-
- inline BOOL getAllowDamage() const;
- inline BOOL getAllowLandmark() const;
- inline BOOL getAllowSetHome() const;
- inline BOOL getResetHomeOnTeleport() const;
- inline BOOL getSunFixed() const;
- inline BOOL getBlockFly() const;
- inline BOOL getAllowDirectTeleport() const;
- inline BOOL isPrelude() const;
- inline BOOL getAllowTerraform() const;
- inline BOOL getRestrictPushObject() const;
+ //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR
+ typedef enum
+ {
+ PARTITION_HUD=0,
+ PARTITION_TERRAIN,
+ PARTITION_VOIDWATER,
+ PARTITION_WATER,
+ PARTITION_TREE,
+ PARTITION_PARTICLE,
+ PARTITION_GRASS,
+ PARTITION_VOLUME,
+ PARTITION_BRIDGE,
+ PARTITION_AVATAR,
+ PARTITION_CONTROL_AV, // Animesh
+ PARTITION_HUD_PARTICLE,
+ PARTITION_VO_CACHE,
+ PARTITION_NONE,
+ NUM_PARTITIONS
+ } eObjectPartitions;
+
+ typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
+
+ LLViewerRegion(const U64 &handle,
+ const LLHost &host,
+ const U32 surface_grid_width,
+ const U32 patch_grid_width,
+ const F32 region_width_meters);
+ ~LLViewerRegion();
+
+ // Call this after you have the region name and handle.
+ void loadObjectCache();
+ void saveObjectCache();
+
+ void sendMessage(); // Send the current message to this region's simulator
+ void sendReliableMessage(); // Send the current message to this region's simulator
+
+ void setOriginGlobal(const LLVector3d &origin);
+ //void setAgentOffset(const LLVector3d &offset);
+ void updateRenderMatrix();
+
+ void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); }
+ void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); }
+ void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); }
+ void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); }
+ void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); }
+ //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used
+ void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); }
+
+
+ inline BOOL getAllowDamage() const;
+ inline BOOL getAllowLandmark() const;
+ inline BOOL getAllowSetHome() const;
+ inline BOOL getResetHomeOnTeleport() const;
+ inline BOOL getSunFixed() const;
+ inline BOOL getBlockFly() const;
+ inline BOOL getAllowDirectTeleport() const;
+ inline BOOL isPrelude() const;
+ inline BOOL getAllowTerraform() const;
+ inline BOOL getRestrictPushObject() const;
inline BOOL getAllowEnvironmentOverride() const;
- inline BOOL getReleaseNotesRequested() const;
+ inline BOOL getReleaseNotesRequested() const;
- bool isAlive(); // can become false if circuit disconnects
+ bool isAlive(); // can become false if circuit disconnects
- void setWaterHeight(F32 water_level);
- F32 getWaterHeight() const;
+ void setWaterHeight(F32 water_level);
+ F32 getWaterHeight() const;
- BOOL isVoiceEnabled() const;
+ BOOL isVoiceEnabled() const;
- void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; }
- F32 getBillableFactor() const { return mBillableFactor; }
+ void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; }
+ F32 getBillableFactor() const { return mBillableFactor; }
- // Maximum number of primitives allowed, regardless of object
- // bonus factor.
- U32 getMaxTasks() const { return mMaxTasks; }
- void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; }
+ // Maximum number of primitives allowed, regardless of object
+ // bonus factor.
+ U32 getMaxTasks() const { return mMaxTasks; }
+ void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; }
- // Draw lines in the dirt showing ownership. Return number of
- // vertices drawn.
- S32 renderPropertyLines();
+ // Draw lines in the dirt showing ownership. Return number of
+ // vertices drawn.
+ S32 renderPropertyLines();
void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
- // Call this whenever you change the height data in the region.
- // (Automatically called by LLSurfacePatch's update routine)
- void dirtyHeights();
-
- LLViewerParcelOverlay *getParcelOverlay() const
- { return mParcelOverlay; }
-
- inline void setRegionFlag(U64 flag, BOOL on);
- inline BOOL getRegionFlag(U64 flag) const;
- void setRegionFlags(U64 flags);
- U64 getRegionFlags() const { return mRegionFlags; }
-
- inline void setRegionProtocol(U64 protocol, BOOL on);
- BOOL getRegionProtocol(U64 protocol) const;
- void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; }
- U64 getRegionProtocols() const { return mRegionProtocols; }
-
- void setTimeDilation(F32 time_dilation);
- F32 getTimeDilation() const { return mTimeDilation; }
-
- // Origin height is at zero.
- const LLVector3d &getOriginGlobal() const;
- LLVector3 getOriginAgent() const;
-
- // Center is at the height of the water table.
- const LLVector3d &getCenterGlobal() const;
- LLVector3 getCenterAgent() const;
-
- void setRegionNameAndZone(const std::string& name_and_zone);
- const std::string& getName() const { return mName; }
- const std::string& getZoning() const { return mZoning; }
-
- void setOwner(const LLUUID& owner_id);
- const LLUUID& getOwner() const;
-
- // Is the current agent on the estate manager list for this region?
- void setIsEstateManager(BOOL b) { mIsEstateManager = b; }
- BOOL isEstateManager() const { return mIsEstateManager; }
- BOOL canManageEstate() const;
-
- void setSimAccess(U8 sim_access) { mSimAccess = sim_access; }
- U8 getSimAccess() const { return mSimAccess; }
- const std::string getSimAccessString() const;
-
- // Homestead-related getters; there are no setters as nobody should be
- // setting them other than the individual message handler which is a member
- S32 getSimClassID() const { return mClassID; }
- S32 getSimCPURatio() const { return mCPURatio; }
- const std::string& getSimColoName() const { return mColoName; }
- const std::string& getSimProductSKU() const { return mProductSKU; }
- std::string getLocalizedSimProductName() const;
-
- // Returns "Sandbox", "Expensive", etc.
- static std::string regionFlagsToString(U64 flags);
-
- // Returns translated version of "Mature", "PG", "Adult", etc.
- static std::string accessToString(U8 sim_access);
-
- // Returns "M", "PG", "A" etc.
- static std::string accessToShortString(U8 sim_access);
- static U8 shortStringToAccess(const std::string &sim_access);
-
- // Return access icon name
- static std::string getAccessIcon(U8 sim_access);
-
- // helper function which just makes sure all interested parties
- // can process the message.
- static void processRegionInfo(LLMessageSystem* msg, void**);
-
- //check if the viewer camera is static
- static BOOL isViewerCameraStatic();
- static void calcNewObjectCreationThrottle();
-
- void setCacheID(const LLUUID& id);
-
- F32 getWidth() const { return mWidth; }
-
- // regions are expensive to release, this function gradually releases cache from memory
- static void idleCleanup(F32 max_update_time);
-
- void idleUpdate(F32 max_update_time);
- void lightIdleUpdate();
- bool addVisibleGroup(LLViewerOctreeGroup* group);
- void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child);
- void addActiveCacheEntry(LLVOCacheEntry* entry);
- void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
- void killCacheEntry(U32 local_id); //physically delete the cache entry
-
- // Like idleUpdate, but forces everything to complete regardless of
- // how long it takes.
- void forceUpdate();
-
- void connectNeighbor(LLViewerRegion *neighborp, U32 direction);
+ // Call this whenever you change the height data in the region.
+ // (Automatically called by LLSurfacePatch's update routine)
+ void dirtyHeights();
+ // Call this whenever you want to force all terrain to rebuild.
+ // (For example, if a global terrain config option has changed)
+ void dirtyAllPatches();
- void updateNetStats();
-
- U32 getPacketsLost() const;
-
- S32 getHttpResponderID() const;
-
- // Get/set named capability URLs for this region.
- void setSeedCapability(const std::string& url);
- S32 getNumSeedCapRetries();
- void setCapability(const std::string& name, const std::string& url);
- void setCapabilityDebug(const std::string& name, const std::string& url);
- bool isCapabilityAvailable(const std::string& name) const;
- // implements LLCapabilityProvider
+ LLViewerParcelOverlay *getParcelOverlay() const
+ { return mParcelOverlay; }
+
+ inline void setRegionFlag(U64 flag, BOOL on);
+ inline BOOL getRegionFlag(U64 flag) const;
+ void setRegionFlags(U64 flags);
+ U64 getRegionFlags() const { return mRegionFlags; }
+
+ inline void setRegionProtocol(U64 protocol, BOOL on);
+ BOOL getRegionProtocol(U64 protocol) const;
+ void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; }
+ U64 getRegionProtocols() const { return mRegionProtocols; }
+
+ void setTimeDilation(F32 time_dilation);
+ F32 getTimeDilation() const { return mTimeDilation; }
+
+ // Origin height is at zero.
+ const LLVector3d &getOriginGlobal() const;
+ LLVector3 getOriginAgent() const;
+
+ // Center is at the height of the water table.
+ const LLVector3d &getCenterGlobal() const;
+ LLVector3 getCenterAgent() const;
+
+ void setRegionNameAndZone(const std::string& name_and_zone);
+ const std::string& getName() const { return mName; }
+ const std::string& getZoning() const { return mZoning; }
+
+ void setOwner(const LLUUID& owner_id);
+ const LLUUID& getOwner() const;
+
+ // Is the current agent on the estate manager list for this region?
+ void setIsEstateManager(BOOL b) { mIsEstateManager = b; }
+ BOOL isEstateManager() const { return mIsEstateManager; }
+ BOOL canManageEstate() const;
+
+ void setSimAccess(U8 sim_access) { mSimAccess = sim_access; }
+ U8 getSimAccess() const { return mSimAccess; }
+ const std::string getSimAccessString() const;
+
+ // Homestead-related getters; there are no setters as nobody should be
+ // setting them other than the individual message handler which is a member
+ S32 getSimClassID() const { return mClassID; }
+ S32 getSimCPURatio() const { return mCPURatio; }
+ const std::string& getSimColoName() const { return mColoName; }
+ const std::string& getSimProductSKU() const { return mProductSKU; }
+ std::string getLocalizedSimProductName() const;
+
+ // Returns "Sandbox", "Expensive", etc.
+ static std::string regionFlagsToString(U64 flags);
+
+ // Returns translated version of "Mature", "PG", "Adult", etc.
+ static std::string accessToString(U8 sim_access);
+
+ // Returns "M", "PG", "A" etc.
+ static std::string accessToShortString(U8 sim_access);
+ static U8 shortStringToAccess(const std::string &sim_access);
+
+ // Return access icon name
+ static std::string getAccessIcon(U8 sim_access);
+
+ // helper function which just makes sure all interested parties
+ // can process the message.
+ static void processRegionInfo(LLMessageSystem* msg, void**);
+
+ //check if the viewer camera is static
+ static BOOL isViewerCameraStatic();
+ static void calcNewObjectCreationThrottle();
+
+ void setCacheID(const LLUUID& id);
+
+ F32 getWidth() const { return mWidth; }
+
+ // regions are expensive to release, this function gradually releases cache from memory
+ static void idleCleanup(F32 max_update_time);
+
+ void idleUpdate(F32 max_update_time);
+ void lightIdleUpdate();
+ bool addVisibleGroup(LLViewerOctreeGroup* group);
+ void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child);
+ void addActiveCacheEntry(LLVOCacheEntry* entry);
+ void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
+ void killCacheEntry(U32 local_id); //physically delete the cache entry
+
+ // Like idleUpdate, but forces everything to complete regardless of
+ // how long it takes.
+ void forceUpdate();
+
+ void connectNeighbor(LLViewerRegion *neighborp, U32 direction);
+
+ void updateNetStats();
+
+ U32 getPacketsLost() const;
+
+ S32 getHttpResponderID() const;
+
+ // Get/set named capability URLs for this region.
+ void setSeedCapability(const std::string& url);
+ S32 getNumSeedCapRetries();
+ void setCapability(const std::string& name, const std::string& url);
+ void setCapabilityDebug(const std::string& name, const std::string& url);
+ bool isCapabilityAvailable(const std::string& name) const;
+ // implements LLCapabilityProvider
virtual std::string getCapability(const std::string& name) const;
std::string getCapabilityDebug(const std::string& name) const;
- // has region received its final (not seed) capability list?
- bool capabilitiesReceived() const;
+ // has region received its final (not seed) capability list?
+ bool capabilitiesReceived() const;
bool capabilitiesError() const;
- void setCapabilitiesReceived(bool received);
- void setCapabilitiesError();
- boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
+ void setCapabilitiesReceived(bool received);
+ void setCapabilitiesError();
+ boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
- static bool isSpecialCapabilityName(const std::string &name);
- void logActiveCapabilities() const;
+ static bool isSpecialCapabilityName(const std::string &name);
+ void logActiveCapabilities() const;
- // Utilities to post and get via
+ // Utilities to post and get via
// HTTP using the agent's policy settings and headers.
typedef LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t httpCallback_t;
bool requestPostCapability(const std::string &capName,
@@ -292,278 +295,279 @@ public:
bool requestDelCapability(const std::string &capName, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL);
/// implements LLCapabilityProvider
- /*virtual*/ const LLHost& getHost() const;
- const U64 &getHandle() const { return mHandle; }
-
- LLSurface &getLand() const;
+ /*virtual*/ const LLHost& getHost() const;
+ const U64 &getHandle() const { return mHandle; }
- // set and get the region id
- const LLUUID& getRegionID() const;
- void setRegionID(const LLUUID& region_id);
+ LLSurface &getLand() const;
- BOOL pointInRegionGlobal(const LLVector3d &point_global) const;
- LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const;
- LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const;
- LLVector3 getPosAgentFromRegion(const LLVector3 &region_pos) const;
- LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const;
+ // set and get the region id
+ const LLUUID& getRegionID() const;
+ void setRegionID(const LLUUID& region_id);
- LLVLComposition *getComposition() const;
- F32 getCompositionXY(const S32 x, const S32 y) const;
+ BOOL pointInRegionGlobal(const LLVector3d &point_global) const;
+ LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const;
+ LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const;
+ LLVector3 getPosAgentFromRegion(const LLVector3 &region_pos) const;
+ LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const;
- BOOL isOwnedSelf(const LLVector3& pos);
+ LLVLComposition *getComposition() const;
+ F32 getCompositionXY(const S32 x, const S32 y) const;
- // Owned by a group you belong to? (officer OR member)
- BOOL isOwnedGroup(const LLVector3& pos);
+ BOOL isOwnedSelf(const LLVector3& pos);
- // deal with map object updates in the world.
- void updateCoarseLocations(LLMessageSystem* msg);
+ // Owned by a group you belong to? (officer OR member)
+ BOOL isOwnedGroup(const LLVector3& pos);
- F32 getLandHeightRegion(const LLVector3& region_pos);
+ // deal with map object updates in the world.
+ void updateCoarseLocations(LLMessageSystem* msg);
- U8 getCentralBakeVersion() { return mCentralBakeVersion; }
+ F32 getLandHeightRegion(const LLVector3& region_pos);
- void getInfo(LLSD& info);
+ U8 getCentralBakeVersion() { return mCentralBakeVersion; }
- bool meshRezEnabled() const;
- bool meshUploadEnabled() const;
+ void getInfo(LLSD& info);
+
+ bool meshRezEnabled() const;
+ bool meshUploadEnabled() const;
- bool bakesOnMeshEnabled() const;
+ bool bakesOnMeshEnabled() const;
- // has region received its simulator features list? Requires an additional query after caps received.
+ // has region received its simulator features list? Requires an additional query after caps received.
void requestSimulatorFeatures();
- void setSimulatorFeaturesReceived(bool);
- bool simulatorFeaturesReceived() const;
- boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb);
-
- void getSimulatorFeatures(LLSD& info) const;
- void setSimulatorFeatures(const LLSD& info);
-
-
- bool dynamicPathfindingEnabled() const;
-
- bool avatarHoverHeightEnabled() const;
-
- typedef enum
- {
- CACHE_MISS_TYPE_TOTAL = 0, // total cache miss - object not in cache
- CACHE_MISS_TYPE_CRC, // object in cache, but CRC doesn't match
- CACHE_MISS_TYPE_NONE // not a miss: cache hit
- } eCacheMissType;
-
- typedef enum
- {
- CACHE_UPDATE_DUPE = 0,
- CACHE_UPDATE_CHANGED,
- CACHE_UPDATE_ADDED,
- CACHE_UPDATE_REPLACED
- } eCacheUpdateResult;
-
- // handle a full update message
- eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags);
- eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
+ void setSimulatorFeaturesReceived(bool);
+ bool simulatorFeaturesReceived() const;
+ boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb);
+
+ void getSimulatorFeatures(LLSD& info) const;
+ void setSimulatorFeatures(const LLSD& info);
+
+
+ bool dynamicPathfindingEnabled() const;
+
+ bool avatarHoverHeightEnabled() const;
+
+ typedef enum
+ {
+ CACHE_MISS_TYPE_TOTAL = 0, // total cache miss - object not in cache
+ CACHE_MISS_TYPE_CRC, // object in cache, but CRC doesn't match
+ CACHE_MISS_TYPE_NONE // not a miss: cache hit
+ } eCacheMissType;
+
+ typedef enum
+ {
+ CACHE_UPDATE_DUPE = 0,
+ CACHE_UPDATE_CHANGED,
+ CACHE_UPDATE_ADDED,
+ CACHE_UPDATE_REPLACED
+ } eCacheUpdateResult;
+
+ // handle a full update message
+ eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags);
+ eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
void cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data);
- LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
- LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true);
- bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
- U64 getRegionCacheHitCount() { return mRegionCacheHitCount; }
- U64 getRegionCacheMissCount() { return mRegionCacheMissCount; }
- void requestCacheMisses();
- void addCacheMissFull(const U32 local_id);
- //update object cache if the object receives a full-update or terse update
- LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
- void findOrphans(U32 parent_id);
- void clearCachedVisibleObjects();
- void dumpCache();
-
- void unpackRegionHandshake();
-
- void calculateCenterGlobal();
- void calculateCameraDistance();
-
- friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region);
+ LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
+ LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true);
+ bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
+ U64 getRegionCacheHitCount() { return mRegionCacheHitCount; }
+ U64 getRegionCacheMissCount() { return mRegionCacheMissCount; }
+ void requestCacheMisses();
+ void addCacheMissFull(const U32 local_id);
+ //update object cache if the object receives a full-update or terse update
+ LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
+ void findOrphans(U32 parent_id);
+ void clearCachedVisibleObjects();
+ void dumpCache ();
+ void clearVOCacheFromMemory();
+
+ void unpackRegionHandshake();
+
+ void calculateCenterGlobal();
+ void calculateCameraDistance();
+
+ friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region);
/// implements LLCapabilityProvider
virtual std::string getDescription() const;
std::string getViewerAssetUrl() const { return mViewerAssetUrl; }
- U32 getNumOfVisibleGroups() const;
- U32 getNumOfActiveCachedObjects() const;
- LLSpatialPartition* getSpatialPartition(U32 type);
- LLVOCachePartition* getVOCachePartition();
+ U32 getNumOfVisibleGroups() const;
+ U32 getNumOfActiveCachedObjects() const;
+ LLSpatialPartition* getSpatialPartition(U32 type);
+ LLVOCachePartition* getVOCachePartition();
- bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
- bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
- bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
+ bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
+ bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
+ bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
- void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
- void getNeighboringRegionsStatus( std::vector<S32>& regions );
- const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
- LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
+ void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+ void getNeighboringRegionsStatus( std::vector<S32>& regions );
+ const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
+ LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
- // implements the materials capability throttle
- bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); }
- void resetMaterialsCapThrottle();
+ // implements the materials capability throttle
+ bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); }
+ void resetMaterialsCapThrottle();
+
+ U32 getMaxMaterialsPerTransaction() const;
- U32 getMaxMaterialsPerTransaction() const;
+ void removeFromCreatedList(U32 local_id);
+ void addToCreatedList(U32 local_id);
- void removeFromCreatedList(U32 local_id);
- void addToCreatedList(U32 local_id);
+ BOOL isPaused() const {return mPaused;}
+ S32 getLastUpdate() const {return mLastUpdate;}
- BOOL isPaused() const {return mPaused;}
- S32 getLastUpdate() const {return mLastUpdate;}
+ std::string getSimHostName();
- std::string getSimHostName();
-
- static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
+ static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
// rebuild reflection probe list
void updateReflectionProbes();
private:
- void addToVOCacheTree(LLVOCacheEntry* entry);
- LLViewerObject* addNewObject(LLVOCacheEntry* entry);
- void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); //adds entry into list if it is safe to move into cache
- void removeFromVOCacheTree(LLVOCacheEntry* entry);
- void killCacheEntry(LLVOCacheEntry* entry, bool for_rendering = false); //physically delete the cache entry
- void killInvisibleObjects(F32 max_time);
- void createVisibleObjects(F32 max_time);
- void updateVisibleEntries(F32 max_time); //update visible entries
-
- void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type);
- void decodeBoundingInfo(LLVOCacheEntry* entry);
- bool isNonCacheableObjectCreated(U32 local_id);
+ void addToVOCacheTree(LLVOCacheEntry* entry);
+ LLViewerObject* addNewObject(LLVOCacheEntry* entry);
+ void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); //adds entry into list if it is safe to move into cache
+ void removeFromVOCacheTree(LLVOCacheEntry* entry);
+ void killCacheEntry(LLVOCacheEntry* entry, bool for_rendering = false); //physically delete the cache entry
+ void killInvisibleObjects(F32 max_time);
+ void createVisibleObjects(F32 max_time);
+ void updateVisibleEntries(F32 max_time); //update visible entries
+
+ void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type);
+ void decodeBoundingInfo(LLVOCacheEntry* entry);
+ bool isNonCacheableObjectCreated(U32 local_id);
public:
void applyCacheMiscExtras(LLViewerObject* obj);
- struct CompareDistance
- {
- bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs)
- {
- return lhs->mCameraDistanceSquared < rhs->mCameraDistanceSquared;
- }
- };
+ struct CompareDistance
+ {
+ bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs)
+ {
+ return lhs->mCameraDistanceSquared < rhs->mCameraDistanceSquared;
+ }
+ };
- void showReleaseNotes();
+ void showReleaseNotes();
protected:
- void disconnectAllNeighbors();
- void initStats();
+ void disconnectAllNeighbors();
+ void initStats();
public:
- LLWind mWind;
- LLViewerParcelOverlay *mParcelOverlay;
-
- F32Bits mBitsReceived;
- F32 mPacketsReceived;
-
- LLMatrix4 mRenderMatrix;
-
- // These arrays are maintained in parallel. Ideally they'd be combined into a
- // single array of an aggrigate data type but for compatibility with the old
- // messaging system in which the previous message only sends and parses the
- // positions stored in the first array so they're maintained separately until
- // we stop supporting the old CoarseLocationUpdate message.
- std::vector<U32> mMapAvatars;
- std::vector<LLUUID> mMapAvatarIDs;
-
- static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
- static S32 sLastCameraUpdated;
-
- LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; };
- LLFrameTimer & getRenderInfoReportTimer() { return mRenderInfoReportTimer; };
-
- struct CompareRegionByLastUpdate
- {
- bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) const
- {
- S32 lpa = lhs->getLastUpdate();
- S32 rpa = rhs->getLastUpdate();
-
- //small mLastUpdate first
- if(lpa < rpa)
- {
- return true;
- }
- else if(lpa > rpa)
- {
- return false;
- }
- else
- {
- return lhs < rhs;
- }
- }
- };
- typedef std::set<LLViewerRegion*, CompareRegionByLastUpdate> region_priority_list_t;
-
- void setInterestListMode(const std::string & new_mode);
+ LLWind mWind;
+ LLViewerParcelOverlay *mParcelOverlay;
+
+ F32Bits mBitsReceived;
+ F32 mPacketsReceived;
+
+ LLMatrix4 mRenderMatrix;
+
+ // These arrays are maintained in parallel. Ideally they'd be combined into a
+ // single array of an aggrigate data type but for compatibility with the old
+ // messaging system in which the previous message only sends and parses the
+ // positions stored in the first array so they're maintained separately until
+ // we stop supporting the old CoarseLocationUpdate message.
+ std::vector<U32> mMapAvatars;
+ std::vector<LLUUID> mMapAvatarIDs;
+
+ static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
+ static S32 sLastCameraUpdated;
+
+ LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; };
+ LLFrameTimer & getRenderInfoReportTimer() { return mRenderInfoReportTimer; };
+
+ struct CompareRegionByLastUpdate
+ {
+ bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) const
+ {
+ S32 lpa = lhs->getLastUpdate();
+ S32 rpa = rhs->getLastUpdate();
+
+ //small mLastUpdate first
+ if(lpa < rpa)
+ {
+ return true;
+ }
+ else if(lpa > rpa)
+ {
+ return false;
+ }
+ else
+ {
+ return lhs < rhs;
+ }
+ }
+ };
+ typedef std::set<LLViewerRegion*, CompareRegionByLastUpdate> region_priority_list_t;
+
+ void setInterestListMode(const std::string & new_mode);
const std::string & getInterestListMode() const { return mInterestListMode; }
- void resetInterestList();
+ void resetInterestList();
- static const std::string IL_MODE_DEFAULT;
+ static const std::string IL_MODE_DEFAULT;
static const std::string IL_MODE_360;
private:
- static S32 sNewObjectCreationThrottle;
- LLViewerRegionImpl * mImpl;
- LLFrameTimer mRegionTimer;
-
- F32 mWidth; // Width of region on a side (meters)
- U64 mHandle;
- F32 mTimeDilation; // time dilation of physics simulation on simulator
- S32 mLastUpdate; //last time called idleUpdate()
-
- // simulator name
- std::string mName;
- std::string mZoning;
-
- // Is this agent on the estate managers list for this region?
- BOOL mIsEstateManager;
-
- U32 mPacketsIn;
- U32Bits mBitsIn,
- mLastBitsIn;
- U32 mLastPacketsIn;
- U32 mPacketsOut;
- U32 mLastPacketsOut;
- S32 mPacketsLost;
- S32 mLastPacketsLost;
- U32Milliseconds mPingDelay;
- F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc
-
- U64 mRegionFlags; // includes damage flags
- U64 mRegionProtocols; // protocols supported by this region
- U8 mSimAccess;
- F32 mBillableFactor;
- U32 mMaxTasks; // max prim count
- F32 mCameraDistanceSquared; // updated once per frame
- U8 mCentralBakeVersion;
-
- LLVOCacheEntry* mLastVisitedEntry;
- U32 mInvisibilityCheckHistory;
-
- // Information for Homestead / CR-53
- S32 mClassID;
- S32 mCPURatio;
-
- std::string mColoName;
- std::string mProductSKU;
- std::string mProductName;
- std::string mViewerAssetUrl ;
-
- // Maps local ids to cache entries.
- // Regions can have order 10,000 objects, so assume
- // a structure of size 2^14 = 16,000
- BOOL mCacheLoaded;
- BOOL mCacheDirty;
- BOOL mAlive; // can become false if circuit disconnects
- BOOL mSimulatorFeaturesReceived;
- BOOL mReleaseNotesRequested;
- BOOL mDead; //if true, this region is in the process of deleting.
- BOOL mPaused; //pause processing the objects in the region
+ static S32 sNewObjectCreationThrottle;
+ LLViewerRegionImpl * mImpl;
+ LLFrameTimer mRegionTimer;
+
+ F32 mWidth; // Width of region on a side (meters)
+ U64 mHandle;
+ F32 mTimeDilation; // time dilation of physics simulation on simulator
+ S32 mLastUpdate; //last time called idleUpdate()
+
+ // simulator name
+ std::string mName;
+ std::string mZoning;
+
+ // Is this agent on the estate managers list for this region?
+ BOOL mIsEstateManager;
+
+ U32 mPacketsIn;
+ U32Bits mBitsIn,
+ mLastBitsIn;
+ U32 mLastPacketsIn;
+ U32 mPacketsOut;
+ U32 mLastPacketsOut;
+ S32 mPacketsLost;
+ S32 mLastPacketsLost;
+ U32Milliseconds mPingDelay;
+ F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc
+
+ U64 mRegionFlags; // includes damage flags
+ U64 mRegionProtocols; // protocols supported by this region
+ U8 mSimAccess;
+ F32 mBillableFactor;
+ U32 mMaxTasks; // max prim count
+ F32 mCameraDistanceSquared; // updated once per frame
+ U8 mCentralBakeVersion;
+
+ LLVOCacheEntry* mLastVisitedEntry;
+ U32 mInvisibilityCheckHistory;
+
+ // Information for Homestead / CR-53
+ S32 mClassID;
+ S32 mCPURatio;
+
+ std::string mColoName;
+ std::string mProductSKU;
+ std::string mProductName;
+ std::string mViewerAssetUrl ;
+
+ // Maps local ids to cache entries.
+ // Regions can have order 10,000 objects, so assume
+ // a structure of size 2^14 = 16,000
+ BOOL mCacheLoaded;
+ BOOL mCacheDirty;
+ BOOL mAlive; // can become false if circuit disconnects
+ BOOL mSimulatorFeaturesReceived;
+ BOOL mReleaseNotesRequested;
+ BOOL mDead; //if true, this region is in the process of deleting.
+ BOOL mPaused; //pause processing the objects in the region
typedef enum
{
@@ -572,39 +576,39 @@ public:
CAPABILITIES_STATE_RECEIVED
} eCababilitiesState;
- eCababilitiesState mCapabilitiesState;
+ eCababilitiesState mCapabilitiesState;
- typedef std::map<U32, std::vector<U32> > orphan_list_t;
- orphan_list_t mOrphanMap;
+ typedef std::map<U32, std::vector<U32> > orphan_list_t;
+ orphan_list_t mOrphanMap;
- class CacheMissItem
- {
- public:
+ class CacheMissItem
+ {
+ public:
CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type) {}
- U32 mID; //local object id
- LLViewerRegion::eCacheMissType mType; // cache miss type
+ U32 mID; //local object id
+ LLViewerRegion::eCacheMissType mType; // cache miss type
- typedef std::list<CacheMissItem> cache_miss_list_t;
- };
- CacheMissItem::cache_miss_list_t mCacheMissList;
- U64 mRegionCacheHitCount;
- U64 mRegionCacheMissCount;
+ typedef std::list<CacheMissItem> cache_miss_list_t;
+ };
+ CacheMissItem::cache_miss_list_t mCacheMissList;
+ U64 mRegionCacheHitCount;
+ U64 mRegionCacheMissCount;
- caps_received_signal_t mCapabilitiesReceivedSignal;
- caps_received_signal_t mSimulatorFeaturesReceivedSignal;
+ caps_received_signal_t mCapabilitiesReceivedSignal;
+ caps_received_signal_t mSimulatorFeaturesReceivedSignal;
- LLSD mSimulatorFeatures;
+ LLSD mSimulatorFeatures;
- typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
+ typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
static vocache_entry_map_t sRegionCacheCleanup;
- // the materials capability throttle
- LLFrameTimer mMaterialsCapThrottleTimer;
- LLFrameTimer mRenderInfoRequestTimer;
- LLFrameTimer mRenderInfoReportTimer;
+ // the materials capability throttle
+ LLFrameTimer mMaterialsCapThrottleTimer;
+ LLFrameTimer mRenderInfoRequestTimer;
+ LLFrameTimer mRenderInfoReportTimer;
- // how the server interest list works
+ // how the server interest list works
std::string mInterestListMode;
// list of reflection maps being managed by this llviewer region
@@ -614,86 +618,86 @@ public:
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
{
- return ((mRegionProtocols & protocol) != 0);
+ return ((mRegionProtocols & protocol) != 0);
}
inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on)
{
- if (on)
- {
- mRegionProtocols |= protocol;
- }
- else
- {
- mRegionProtocols &= ~protocol;
- }
+ if (on)
+ {
+ mRegionProtocols |= protocol;
+ }
+ else
+ {
+ mRegionProtocols &= ~protocol;
+ }
}
inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const
{
- return ((mRegionFlags & flag) != 0);
+ return ((mRegionFlags & flag) != 0);
}
inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on)
{
- if (on)
- {
- mRegionFlags |= flag;
- }
- else
- {
- mRegionFlags &= ~flag;
- }
+ if (on)
+ {
+ mRegionFlags |= flag;
+ }
+ else
+ {
+ mRegionFlags &= ~flag;
+ }
}
inline BOOL LLViewerRegion::getAllowDamage() const
{
- return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0);
+ return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0);
}
inline BOOL LLViewerRegion::getAllowLandmark() const
{
- return ((mRegionFlags & REGION_FLAGS_ALLOW_LANDMARK) !=0);
+ return ((mRegionFlags & REGION_FLAGS_ALLOW_LANDMARK) !=0);
}
inline BOOL LLViewerRegion::getAllowSetHome() const
{
- return ((mRegionFlags & REGION_FLAGS_ALLOW_SET_HOME) != 0);
+ return ((mRegionFlags & REGION_FLAGS_ALLOW_SET_HOME) != 0);
}
inline BOOL LLViewerRegion::getResetHomeOnTeleport() const
{
- return ((mRegionFlags & REGION_FLAGS_RESET_HOME_ON_TELEPORT) !=0);
+ return ((mRegionFlags & REGION_FLAGS_RESET_HOME_ON_TELEPORT) !=0);
}
inline BOOL LLViewerRegion::getSunFixed() const
{
- return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) !=0);
+ return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) !=0);
}
inline BOOL LLViewerRegion::getBlockFly() const
{
- return ((mRegionFlags & REGION_FLAGS_BLOCK_FLY) !=0);
+ return ((mRegionFlags & REGION_FLAGS_BLOCK_FLY) !=0);
}
inline BOOL LLViewerRegion::getAllowDirectTeleport() const
{
- return ((mRegionFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT) !=0);
+ return ((mRegionFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT) !=0);
}
inline BOOL LLViewerRegion::isPrelude() const
{
- return is_prelude( mRegionFlags );
+ return is_prelude( mRegionFlags );
}
inline BOOL LLViewerRegion::getAllowTerraform() const
{
- return ((mRegionFlags & REGION_FLAGS_BLOCK_TERRAFORM) == 0);
+ return ((mRegionFlags & REGION_FLAGS_BLOCK_TERRAFORM) == 0);
}
inline BOOL LLViewerRegion::getRestrictPushObject() const
{
- return ((mRegionFlags & REGION_FLAGS_RESTRICT_PUSHOBJECT) != 0);
+ return ((mRegionFlags & REGION_FLAGS_RESTRICT_PUSHOBJECT) != 0);
}
inline BOOL LLViewerRegion::getAllowEnvironmentOverride() const
@@ -703,7 +707,7 @@ inline BOOL LLViewerRegion::getAllowEnvironmentOverride() const
inline BOOL LLViewerRegion::getReleaseNotesRequested() const
{
- return mReleaseNotesRequested;
+ return mReleaseNotesRequested;
}
#endif
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index d1969a5675..5144b28ce9 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewershadermgr.cpp
* @brief Viewer shader manager implementation.
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -64,159 +64,172 @@ using std::pair;
using std::make_pair;
using std::string;
-BOOL LLViewerShaderMgr::sInitialized = FALSE;
-bool LLViewerShaderMgr::sSkipReload = false;
+BOOL LLViewerShaderMgr::sInitialized = FALSE;
+bool LLViewerShaderMgr::sSkipReload = false;
-LLVector4 gShinyOrigin;
+LLVector4 gShinyOrigin;
+
+S32 clamp_terrain_mapping(S32 mapping)
+{
+ // 1 = "flat", 2 not implemented, 3 = triplanar mapping
+ mapping = llclamp(mapping, 1, 3);
+ if (mapping == 2) { mapping = 1; }
+ return mapping;
+}
//utility shaders
-LLGLSLShader gOcclusionProgram;
+LLGLSLShader gOcclusionProgram;
LLGLSLShader gSkinnedOcclusionProgram;
-LLGLSLShader gOcclusionCubeProgram;
-LLGLSLShader gGlowCombineProgram;
-LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gOcclusionCubeProgram;
+LLGLSLShader gGlowCombineProgram;
+LLGLSLShader gReflectionMipProgram;
LLGLSLShader gGaussianProgram;
LLGLSLShader gRadianceGenProgram;
-LLGLSLShader gIrradianceGenProgram;
-LLGLSLShader gGlowCombineFXAAProgram;
-LLGLSLShader gTwoTextureCompareProgram;
-LLGLSLShader gOneTextureFilterProgram;
-LLGLSLShader gDebugProgram;
+LLGLSLShader gHeroRadianceGenProgram;
+LLGLSLShader gIrradianceGenProgram;
+LLGLSLShader gGlowCombineFXAAProgram;
+LLGLSLShader gTwoTextureCompareProgram;
+LLGLSLShader gOneTextureFilterProgram;
+LLGLSLShader gDebugProgram;
LLGLSLShader gSkinnedDebugProgram;
-LLGLSLShader gClipProgram;
-LLGLSLShader gAlphaMaskProgram;
-LLGLSLShader gBenchmarkProgram;
+LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
+LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
+LLGLSLShader gClipProgram;
+LLGLSLShader gAlphaMaskProgram;
+LLGLSLShader gBenchmarkProgram;
LLGLSLShader gReflectionProbeDisplayProgram;
LLGLSLShader gCopyProgram;
LLGLSLShader gCopyDepthProgram;
//object shaders
-LLGLSLShader gObjectPreviewProgram;
+LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gSkinnedObjectPreviewProgram;
LLGLSLShader gPhysicsPreviewProgram;
-LLGLSLShader gObjectFullbrightAlphaMaskProgram;
-LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
-LLGLSLShader gObjectBumpProgram;
+LLGLSLShader gObjectFullbrightAlphaMaskProgram;
+LLGLSLShader gObjectBumpProgram;
LLGLSLShader gSkinnedObjectBumpProgram;
-LLGLSLShader gObjectAlphaMaskNoColorProgram;
+LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
-LLGLSLShader gWaterProgram;
+LLGLSLShader gWaterProgram;
LLGLSLShader gWaterEdgeProgram;
-LLGLSLShader gUnderWaterProgram;
+LLGLSLShader gUnderWaterProgram;
//interface shaders
-LLGLSLShader gHighlightProgram;
+LLGLSLShader gHighlightProgram;
LLGLSLShader gSkinnedHighlightProgram;
-LLGLSLShader gHighlightNormalProgram;
-LLGLSLShader gHighlightSpecularProgram;
+LLGLSLShader gHighlightNormalProgram;
+LLGLSLShader gHighlightSpecularProgram;
-LLGLSLShader gDeferredHighlightProgram;
+LLGLSLShader gDeferredHighlightProgram;
-LLGLSLShader gPathfindingProgram;
-LLGLSLShader gPathfindingNoNormalsProgram;
+LLGLSLShader gPathfindingProgram;
+LLGLSLShader gPathfindingNoNormalsProgram;
//avatar shader handles
-LLGLSLShader gAvatarProgram;
-LLGLSLShader gAvatarEyeballProgram;
-LLGLSLShader gImpostorProgram;
+LLGLSLShader gAvatarProgram;
+LLGLSLShader gAvatarEyeballProgram;
+LLGLSLShader gImpostorProgram;
// Effects Shaders
-LLGLSLShader gGlowProgram;
-LLGLSLShader gGlowExtractProgram;
-LLGLSLShader gPostScreenSpaceReflectionProgram;
+LLGLSLShader gGlowProgram;
+LLGLSLShader gGlowExtractProgram;
+LLGLSLShader gPostScreenSpaceReflectionProgram;
// Deferred rendering shaders
-LLGLSLShader gDeferredImpostorProgram;
-LLGLSLShader gDeferredDiffuseProgram;
-LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredImpostorProgram;
+LLGLSLShader gDeferredDiffuseProgram;
+LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
-LLGLSLShader gDeferredSkinnedDiffuseProgram;
-LLGLSLShader gDeferredSkinnedBumpProgram;
-LLGLSLShader gDeferredBumpProgram;
-LLGLSLShader gDeferredTerrainProgram;
-LLGLSLShader gDeferredTreeProgram;
-LLGLSLShader gDeferredTreeShadowProgram;
+LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
+LLGLSLShader gDeferredSkinnedDiffuseProgram;
+LLGLSLShader gDeferredSkinnedBumpProgram;
+LLGLSLShader gDeferredBumpProgram;
+LLGLSLShader gDeferredTerrainProgram;
+LLGLSLShader gDeferredTreeProgram;
+LLGLSLShader gDeferredTreeShadowProgram;
LLGLSLShader gDeferredSkinnedTreeShadowProgram;
-LLGLSLShader gDeferredAvatarProgram;
-LLGLSLShader gDeferredAvatarAlphaProgram;
-LLGLSLShader gDeferredLightProgram;
-LLGLSLShader gDeferredMultiLightProgram[16];
-LLGLSLShader gDeferredSpotLightProgram;
-LLGLSLShader gDeferredMultiSpotLightProgram;
-LLGLSLShader gDeferredSunProgram;
+LLGLSLShader gDeferredAvatarProgram;
+LLGLSLShader gDeferredAvatarAlphaProgram;
+LLGLSLShader gDeferredLightProgram;
+LLGLSLShader gDeferredMultiLightProgram[16];
+LLGLSLShader gDeferredSpotLightProgram;
+LLGLSLShader gDeferredMultiSpotLightProgram;
+LLGLSLShader gDeferredSunProgram;
LLGLSLShader gHazeProgram;
LLGLSLShader gHazeWaterProgram;
-LLGLSLShader gDeferredBlurLightProgram;
-LLGLSLShader gDeferredSoftenProgram;
-LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredBlurLightProgram;
+LLGLSLShader gDeferredSoftenProgram;
+LLGLSLShader gDeferredShadowProgram;
LLGLSLShader gDeferredSkinnedShadowProgram;
-LLGLSLShader gDeferredShadowCubeProgram;
-LLGLSLShader gDeferredShadowAlphaMaskProgram;
+LLGLSLShader gDeferredShadowCubeProgram;
+LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram;
-LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram;
LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
LLGLSLShader gDeferredSkinnedShadowGLTFAlphaBlendProgram;
-LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredAvatarShadowProgram;
-LLGLSLShader gDeferredAvatarAlphaShadowProgram;
-LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
-LLGLSLShader gDeferredAlphaProgram;
-LLGLSLShader gHUDAlphaProgram;
+LLGLSLShader gDeferredAvatarShadowProgram;
+LLGLSLShader gDeferredAvatarAlphaShadowProgram;
+LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
+LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gHUDAlphaProgram;
LLGLSLShader gDeferredSkinnedAlphaProgram;
-LLGLSLShader gDeferredAlphaImpostorProgram;
+LLGLSLShader gDeferredAlphaImpostorProgram;
LLGLSLShader gDeferredSkinnedAlphaImpostorProgram;
-LLGLSLShader gDeferredAvatarEyesProgram;
-LLGLSLShader gDeferredFullbrightProgram;
+LLGLSLShader gDeferredAvatarEyesProgram;
+LLGLSLShader gDeferredFullbrightProgram;
LLGLSLShader gHUDFullbrightProgram;
-LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
-LLGLSLShader gHUDFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gDeferredEmissiveProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gDeferredEmissiveProgram;
LLGLSLShader gDeferredSkinnedEmissiveProgram;
-LLGLSLShader gDeferredPostProgram;
-LLGLSLShader gDeferredCoFProgram;
-LLGLSLShader gDeferredDoFCombineProgram;
-LLGLSLShader gDeferredPostGammaCorrectProgram;
+LLGLSLShader gDeferredPostProgram;
+LLGLSLShader gDeferredCoFProgram;
+LLGLSLShader gDeferredDoFCombineProgram;
+LLGLSLShader gDeferredPostGammaCorrectProgram;
LLGLSLShader gNoPostGammaCorrectProgram;
LLGLSLShader gLegacyPostGammaCorrectProgram;
-LLGLSLShader gExposureProgram;
-LLGLSLShader gLuminanceProgram;
-LLGLSLShader gFXAAProgram;
-LLGLSLShader gDeferredPostNoDoFProgram;
-LLGLSLShader gDeferredWLSkyProgram;
-LLGLSLShader gDeferredWLCloudProgram;
-LLGLSLShader gDeferredWLSunProgram;
-LLGLSLShader gDeferredWLMoonProgram;
-LLGLSLShader gDeferredStarProgram;
-LLGLSLShader gDeferredFullbrightShinyProgram;
+LLGLSLShader gExposureProgram;
+LLGLSLShader gExposureProgramNoFade;
+LLGLSLShader gLuminanceProgram;
+LLGLSLShader gFXAAProgram;
+LLGLSLShader gDeferredPostNoDoFProgram;
+LLGLSLShader gDeferredWLSkyProgram;
+LLGLSLShader gEnvironmentMapProgram;
+LLGLSLShader gDeferredWLCloudProgram;
+LLGLSLShader gDeferredWLSunProgram;
+LLGLSLShader gDeferredWLMoonProgram;
+LLGLSLShader gDeferredStarProgram;
+LLGLSLShader gDeferredFullbrightShinyProgram;
LLGLSLShader gHUDFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
-LLGLSLShader gDeferredSkinnedFullbrightProgram;
+LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gNormalMapGenProgram;
LLGLSLShader gDeferredGenBrdfLutProgram;
LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
-LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-LLGLSLShader gHUDPBROpaqueProgram;
+LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gHUDPBROpaqueProgram;
LLGLSLShader gPBRGlowProgram;
LLGLSLShader gPBRGlowSkinnedProgram;
-LLGLSLShader gDeferredPBROpaqueProgram;
+LLGLSLShader gDeferredPBROpaqueProgram;
LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
LLGLSLShader gHUDPBRAlphaProgram;
LLGLSLShader gDeferredPBRAlphaProgram;
LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
+LLGLSLShader gDeferredPBRTerrainProgram;
//helper for making a rigged variant of a given shader
-bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
+static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
{
riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
riggedShader.mFeatures = shader.mFeatures;
@@ -231,9 +244,49 @@ bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
return riggedShader.createShader(NULL, NULL);
}
+#ifdef SHOW_ASSERT
+// return true if there are no redundant shaders in the given vector
+// also checks for redundant variants
+static bool no_redundant_shaders(const std::vector<LLGLSLShader*>& shaders)
+{
+ std::set<std::string> names;
+ for (LLGLSLShader* shader : shaders)
+ {
+ if (names.find(shader->mName) != names.end())
+ {
+ LL_WARNS("Shader") << "Redundant shader: " << shader->mName << LL_ENDL;
+ return false;
+ }
+ names.insert(shader->mName);
+
+ if (shader->mRiggedVariant)
+ {
+ if (names.find(shader->mRiggedVariant->mName) != names.end())
+ {
+ LL_WARNS("Shader") << "Redundant shader: " << shader->mRiggedVariant->mName << LL_ENDL;
+ return false;
+ }
+ names.insert(shader->mRiggedVariant->mName);
+ }
+ }
+ return true;
+}
+#endif
+
+
LLViewerShaderMgr::LLViewerShaderMgr() :
- mShaderLevel(SHADER_COUNT, 0),
- mMaxAvatarShaderLevel(0)
+ mShaderLevel(SHADER_COUNT, 0),
+ mMaxAvatarShaderLevel(0)
+{
+}
+
+LLViewerShaderMgr::~LLViewerShaderMgr()
+{
+ mShaderLevel.clear();
+ mShaderList.clear();
+}
+
+void LLViewerShaderMgr::finalizeShaderList()
{
//ONLY shaders that need WL Param management should be added here
mShaderList.push_back(&gAvatarProgram);
@@ -242,9 +295,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectBumpProgram);
- mShaderList.push_back(&gSkinnedObjectBumpProgram);
mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
@@ -253,9 +304,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredSoftenProgram);
mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gHUDAlphaProgram);
- mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredAlphaImpostorProgram);
- mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
mShaderList.push_back(&gHUDFullbrightProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
@@ -264,69 +313,69 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightShinyProgram);
mShaderList.push_back(&gHUDFullbrightShinyProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
- mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
+ mShaderList.push_back(&gEnvironmentMapProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
mShaderList.push_back(&gDeferredWLMoonProgram);
mShaderList.push_back(&gDeferredWLSunProgram);
mShaderList.push_back(&gDeferredPBRAlphaProgram);
mShaderList.push_back(&gHUDPBRAlphaProgram);
- mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
mShaderList.push_back(&gNoPostGammaCorrectProgram);
mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
-
-}
-
-LLViewerShaderMgr::~LLViewerShaderMgr()
-{
- mShaderLevel.clear();
- mShaderList.clear();
+ mShaderList.push_back(&gDeferredDiffuseProgram);
+ mShaderList.push_back(&gDeferredBumpProgram);
+ mShaderList.push_back(&gDeferredPBROpaqueProgram);
+ mShaderList.push_back(&gDeferredAvatarProgram);
+ mShaderList.push_back(&gDeferredTerrainProgram);
+ mShaderList.push_back(&gDeferredPBRTerrainProgram);
+ mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredTreeProgram);
+
+ // make sure there are no redundancies
+ llassert(no_redundant_shaders(mShaderList));
}
// static
LLViewerShaderMgr * LLViewerShaderMgr::instance()
{
- if(NULL == sInstance)
- {
- sInstance = new LLViewerShaderMgr();
- }
+ if(NULL == sInstance)
+ {
+ sInstance = new LLViewerShaderMgr();
+ }
- return static_cast<LLViewerShaderMgr*>(sInstance);
+ return static_cast<LLViewerShaderMgr*>(sInstance);
}
// static
void LLViewerShaderMgr::releaseInstance()
{
- if (sInstance != NULL)
- {
- delete sInstance;
- sInstance = NULL;
- }
+ if (sInstance != NULL)
+ {
+ delete sInstance;
+ sInstance = NULL;
+ }
}
void LLViewerShaderMgr::initAttribsAndUniforms(void)
{
- if (mReservedAttribs.empty())
- {
- LLShaderMgr::initAttribsAndUniforms();
- }
+ if (mReservedAttribs.empty())
+ {
+ LLShaderMgr::initAttribsAndUniforms();
+ }
}
-
+
//============================================================================
// Set Levels
S32 LLViewerShaderMgr::getShaderLevel(S32 type)
{
- return mShaderLevel[type];
+ return mShaderLevel[type];
}
//============================================================================
@@ -337,12 +386,16 @@ void LLViewerShaderMgr::setShaders()
LL_PROFILE_ZONE_SCOPED;
//setShaders might be called redundantly by gSavedSettings, so return on reentrance
static bool reentrance = false;
-
+
if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
{
return;
}
+ mShaderList.clear();
+
+ LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors;
+
if (!gGLManager.mHasRequirements)
{
// Viewer will show 'hardware requirements' warning later
@@ -350,41 +403,44 @@ void LLViewerShaderMgr::setShaders()
return;
}
- {
- static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true);
- static LLUUID old_cache_version;
- static LLUUID current_cache_version;
- if (current_cache_version.isNull())
- {
- HBXXH128 hash_obj;
- hash_obj.update(LLVersionInfo::instance().getVersion());
- current_cache_version = hash_obj.digest();
+ {
+ static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true);
+ static LLUUID old_cache_version;
+ static LLUUID current_cache_version;
+ if (current_cache_version.isNull())
+ {
+ HBXXH128 hash_obj;
+ hash_obj.update(LLVersionInfo::instance().getVersion());
+ current_cache_version = hash_obj.digest();
- old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion"));
- gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
- }
+ old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion"));
+ gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
+ }
- initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
- }
+ initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
+ }
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
-
+
// when using indexed texture rendering, leave some texture units available for shadow and reflection maps
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
+ static LLCachedControl<S32> reserved_texture_units(gSavedSettings, "RenderReservedTextureIndices", 14);
+
+ LLGLSLShader::sIndexedTextureChannels =
+ llclamp<S32>(max_texture_index, 1, gGLManager.mNumTextureImageUnits-reserved_texture_units);
reentrance = true;
// Make sure the compiled shader map is cleared before we recompile shaders.
mVertexShaderObjects.clear();
mFragmentShaderObjects.clear();
-
+
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- unloadShaders();
-
- LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
+ unloadShaders();
+ LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
+
if (gViewerWindow)
{
gViewerWindow->setCursor(UI_CURSOR_WAIT);
@@ -404,7 +460,7 @@ void LLViewerShaderMgr::setShaders()
llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
-
+
S32 light_class = 3;
S32 interface_class = 2;
S32 env_class = 2;
@@ -443,7 +499,7 @@ void LLViewerShaderMgr::setShaders()
loadBasicShaders();
LLError::setDefaultLevel(lvl);
LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
- reentrance = false; // For hygiene only, re-try probably helps nothing
+ reentrance = false; // For hygiene only, re-try probably helps nothing
return;
}
@@ -499,7 +555,7 @@ void LLViewerShaderMgr::setShaders()
{ //hardware skinning is enabled and rigged attachment shaders loaded correctly
// cloth is a class3 shader
S32 avatar_class = 1;
-
+
// Set the actual level
mShaderLevel[SHADER_AVATAR] = avatar_class;
@@ -516,7 +572,7 @@ void LLViewerShaderMgr::setShaders()
loaded = loaded && loadShadersDeferred();
llassert(loaded);
- persistShaderCacheMetadata();
+ persistShaderCacheMetadata();
if (gViewerWindow)
{
@@ -524,81 +580,83 @@ void LLViewerShaderMgr::setShaders()
}
gPipeline.createGLBuffers();
+ finalizeShaderList();
+
reentrance = false;
}
void LLViewerShaderMgr::unloadShaders()
{
- while (!LLGLSLShader::sInstances.empty())
- {
- LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
- shader->unload();
- }
-
- mShaderLevel[SHADER_LIGHTING] = 0;
- mShaderLevel[SHADER_OBJECT] = 0;
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_ENVIRONMENT] = 0;
- mShaderLevel[SHADER_WATER] = 0;
- mShaderLevel[SHADER_INTERFACE] = 0;
- mShaderLevel[SHADER_EFFECT] = 0;
- mShaderLevel[SHADER_WINDLIGHT] = 0;
-
- gPipeline.mShadersLoaded = false;
+ while (!LLGLSLShader::sInstances.empty())
+ {
+ LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
+ shader->unload();
+ }
+
+ mShaderLevel[SHADER_LIGHTING] = 0;
+ mShaderLevel[SHADER_OBJECT] = 0;
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mShaderLevel[SHADER_WATER] = 0;
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ mShaderLevel[SHADER_EFFECT] = 0;
+ mShaderLevel[SHADER_WINDLIGHT] = 0;
+
+ gPipeline.mShadersLoaded = false;
}
std::string LLViewerShaderMgr::loadBasicShaders()
{
- // Load basic dependency shaders first
- // All of these have to load for any shaders to function
-
- S32 sum_lights_class = 3;
+ // Load basic dependency shaders first
+ // All of these have to load for any shaders to function
+
+ S32 sum_lights_class = 3;
#if LL_DARWIN
- // Work around driver crashes on older Macs when using deferred rendering
- // NORSPEC-59
- //
- if (gGLManager.mIsMobileGF)
- sum_lights_class = 3;
+ // Work around driver crashes on older Macs when using deferred rendering
+ // NORSPEC-59
+ //
+ if (gGLManager.mIsMobileGF)
+ sum_lights_class = 3;
#endif
- // Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
- S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
- sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
-
- // Load the Basic Vertex Shaders at the appropriate level.
- // (in order of shader function call depth for reference purposes, deepest level first)
-
- vector< pair<string, S32> > shaders;
- shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ // Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
+ S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
+ sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
+
+ // Load the Basic Vertex Shaders at the appropriate level.
+ // (in order of shader function call depth for reference purposes, deepest level first)
+
+ vector< pair<string, S32> > shaders;
+ shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
+ shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
+ shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
- shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
- shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
- if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
- {
- shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
- }
- shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
+ if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
+ {
+ shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
+ }
+ shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
- std::map<std::string, std::string> attribs;
- attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
- std::to_string(LLSkinningUtil::getMaxJointCount());
+ std::map<std::string, std::string> attribs;
+ attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
+ std::to_string(LLSkinningUtil::getMaxJointCount());
BOOL ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
- bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
+ bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
- S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3);
+ S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3);
S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
@@ -617,99 +675,110 @@ std::string LLViewerShaderMgr::loadBasicShaders()
attribs["SSR"] = "1";
}
- if (has_reflection_probes)
- {
+ if (has_reflection_probes)
+ {
attribs["REFMAP_LEVEL"] = std::to_string(probe_level);
- attribs["REF_SAMPLE_COUNT"] = "32";
- }
-
- LLGLSLShader::sGlobalDefines = attribs;
-
- // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
- for (U32 i = 0; i < shaders.size(); i++)
- {
- // Note usage of GL_VERTEX_SHADER
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
- {
- LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return shaders[i].first;
- }
- }
-
- // Load the Basic Fragment Shaders at the appropriate level.
- // (in order of shader function call depth for reference purposes, deepest level first)
-
- shaders.clear();
- S32 ch = 1;
-
- if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
- { //use indexed texture rendering for GLSL >= 1.30
- ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
- }
-
-
- std::vector<S32> index_channels;
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
+ attribs["REF_SAMPLE_COUNT"] = "32";
+ }
+
+ { // PBR terrain
+ const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount"));
+ attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping);
+ const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor");
+ attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor);
+ S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail");
+ detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX);
+ attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail);
+ }
+
+ LLGLSLShader::sGlobalDefines = attribs;
+
+ // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
+ }
+ }
+
+ // Load the Basic Fragment Shaders at the appropriate level.
+ // (in order of shader function call depth for reference purposes, deepest level first)
+
+ shaders.clear();
+ S32 ch = 1;
+
+ if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
+ { //use indexed texture rendering for GLSL >= 1.30
+ ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
+ }
+
+
+ std::vector<S32> index_channels;
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/globalF.glsl", 1));
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
-
- for (U32 i = 0; i < shaders.size(); i++)
- {
- // Note usage of GL_FRAGMENT_SHADER
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
- {
- LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return shaders[i].first;
- }
- }
-
- return std::string();
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
+ }
+ }
+
+ return std::string();
}
BOOL LLViewerShaderMgr::loadShadersWater()
{
LL_PROFILE_ZONE_SCOPED;
- BOOL success = TRUE;
- BOOL terrainWaterSuccess = TRUE;
-
+ BOOL success = TRUE;
+ BOOL terrainWaterSuccess = TRUE;
+
bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
gSavedSettings.getS32("RenderShadowDetail") > 0;
- if (mShaderLevel[SHADER_WATER] == 0)
- {
- gWaterProgram.unload();
- gWaterEdgeProgram.unload();
- gUnderWaterProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- // load water shader
- gWaterProgram.mName = "Water Shader";
- gWaterProgram.mFeatures.calculatesAtmospherics = true;
+ if (mShaderLevel[SHADER_WATER] == 0)
+ {
+ gWaterProgram.unload();
+ gWaterEdgeProgram.unload();
+ gUnderWaterProgram.unload();
+ return TRUE;
+ }
+
+ if (success)
+ {
+ // load water shader
+ gWaterProgram.mName = "Water Shader";
+ gWaterProgram.mFeatures.calculatesAtmospherics = true;
gWaterProgram.mFeatures.hasAtmospherics = true;
- gWaterProgram.mFeatures.hasGamma = true;
- gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasGamma = true;
+ gWaterProgram.mFeatures.hasSrgb = true;
gWaterProgram.mFeatures.hasReflectionProbes = true;
gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterProgram.mShaderFiles.clear();
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterProgram.mShaderFiles.clear();
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
gWaterProgram.clearPermutations();
if (LLPipeline::sRenderTransparentWater)
{
@@ -721,27 +790,27 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
- gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- // load water shader
- gWaterEdgeProgram.mName = "Water Edge Shader";
- gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ success = gWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ // load water shader
+ gWaterEdgeProgram.mName = "Water Edge Shader";
+ gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasGamma = true;
- gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasGamma = true;
+ gWaterEdgeProgram.mFeatures.hasSrgb = true;
gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterEdgeProgram.mShaderFiles.clear();
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
gWaterEdgeProgram.clearPermutations();
- gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+ gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
if (LLPipeline::sRenderTransparentWater)
{
gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
@@ -751,54 +820,54 @@ BOOL LLViewerShaderMgr::loadShadersWater()
{
gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
- gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterEdgeProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- //load under water vertex shader
- gUnderWaterProgram.mName = "Underwater Shader";
- gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
- gUnderWaterProgram.mFeatures.hasAtmospherics = true;
- gUnderWaterProgram.mShaderFiles.clear();
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
- gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ success = gWaterEdgeProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ //load under water vertex shader
+ gUnderWaterProgram.mName = "Underwater Shader";
+ gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gUnderWaterProgram.mFeatures.hasAtmospherics = true;
+ gUnderWaterProgram.mShaderFiles.clear();
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
+ gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gUnderWaterProgram.clearPermutations();
if (LLPipeline::sRenderTransparentWater)
{
gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
}
- success = gUnderWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- /// Keep track of water shader levels
- if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
- || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
- {
- mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
- }
-
- if (!success)
- {
- mShaderLevel[SHADER_WATER] = 0;
- return FALSE;
- }
-
- // if we failed to load the terrain water shaders and we need them (using class2 water),
- // then drop down to class1 water.
- if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
- {
- mShaderLevel[SHADER_WATER]--;
- return loadShadersWater();
- }
-
- LLWorld::getInstance()->updateWaterObjects();
+ success = gUnderWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ /// Keep track of water shader levels
+ if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
+ || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
+ {
+ mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
+ }
+
+ if (!success)
+ {
+ mShaderLevel[SHADER_WATER] = 0;
+ return FALSE;
+ }
+
+ // if we failed to load the terrain water shaders and we need them (using class2 water),
+ // then drop down to class1 water.
+ if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
+ {
+ mShaderLevel[SHADER_WATER]--;
+ return loadShadersWater();
+ }
+
+ LLWorld::getInstance()->updateWaterObjects();
return TRUE;
}
@@ -806,144 +875,146 @@ BOOL LLViewerShaderMgr::loadShadersWater()
BOOL LLViewerShaderMgr::loadShadersEffects()
{
LL_PROFILE_ZONE_SCOPED;
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_EFFECT] == 0)
- {
- gGlowProgram.unload();
- gGlowExtractProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gGlowProgram.mName = "Glow Shader (Post)";
- gGlowProgram.mShaderFiles.clear();
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
- gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
- success = gGlowProgram.createShader(NULL, NULL);
- if (!success)
- {
- LLPipeline::sRenderGlow = FALSE;
- }
- }
-
- if (success)
- {
+ BOOL success = TRUE;
+
+ if (mShaderLevel[SHADER_EFFECT] == 0)
+ {
+ gGlowProgram.unload();
+ gGlowExtractProgram.unload();
+ return TRUE;
+ }
+
+ if (success)
+ {
+ gGlowProgram.mName = "Glow Shader (Post)";
+ gGlowProgram.mShaderFiles.clear();
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
+ gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+ success = gGlowProgram.createShader(NULL, NULL);
+ if (!success)
+ {
+ LLPipeline::sRenderGlow = FALSE;
+ }
+ }
+
+ if (success)
+ {
const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise");
const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : "";
- gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
- gGlowExtractProgram.mShaderFiles.clear();
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
- gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+ gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
+ gGlowExtractProgram.mShaderFiles.clear();
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
+ gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
if (use_glow_noise)
{
gGlowExtractProgram.addPermutation("HAS_NOISE", "1");
}
- success = gGlowExtractProgram.createShader(NULL, NULL);
- if (!success)
- {
- LLPipeline::sRenderGlow = FALSE;
- }
- }
-
- return success;
+ success = gGlowExtractProgram.createShader(NULL, NULL);
+ if (!success)
+ {
+ LLPipeline::sRenderGlow = FALSE;
+ }
+ }
+
+ return success;
}
BOOL LLViewerShaderMgr::loadShadersDeferred()
{
LL_PROFILE_ZONE_SCOPED;
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
gSavedSettings.getS32("RenderShadowDetail") > 0;
- if (mShaderLevel[SHADER_DEFERRED] == 0)
- {
- gDeferredTreeProgram.unload();
- gDeferredTreeShadowProgram.unload();
+ if (mShaderLevel[SHADER_DEFERRED] == 0)
+ {
+ gDeferredTreeProgram.unload();
+ gDeferredTreeShadowProgram.unload();
gDeferredSkinnedTreeShadowProgram.unload();
- gDeferredDiffuseProgram.unload();
+ gDeferredDiffuseProgram.unload();
gDeferredSkinnedDiffuseProgram.unload();
- gDeferredDiffuseAlphaMaskProgram.unload();
+ gDeferredDiffuseAlphaMaskProgram.unload();
gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
- gDeferredBumpProgram.unload();
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
+ gDeferredBumpProgram.unload();
gDeferredSkinnedBumpProgram.unload();
- gDeferredImpostorProgram.unload();
- gDeferredTerrainProgram.unload();
- gDeferredLightProgram.unload();
- for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
- {
- gDeferredMultiLightProgram[i].unload();
- }
- gDeferredSpotLightProgram.unload();
- gDeferredMultiSpotLightProgram.unload();
- gDeferredSunProgram.unload();
- gDeferredBlurLightProgram.unload();
- gDeferredSoftenProgram.unload();
- gDeferredShadowProgram.unload();
+ gDeferredImpostorProgram.unload();
+ gDeferredTerrainProgram.unload();
+ gDeferredLightProgram.unload();
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
+ {
+ gDeferredMultiLightProgram[i].unload();
+ }
+ gDeferredSpotLightProgram.unload();
+ gDeferredMultiSpotLightProgram.unload();
+ gDeferredSunProgram.unload();
+ gDeferredBlurLightProgram.unload();
+ gDeferredSoftenProgram.unload();
+ gDeferredShadowProgram.unload();
gDeferredSkinnedShadowProgram.unload();
- gDeferredShadowCubeProgram.unload();
+ gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
gDeferredSkinnedShadowAlphaMaskProgram.unload();
gDeferredShadowGLTFAlphaMaskProgram.unload();
gDeferredSkinnedShadowGLTFAlphaMaskProgram.unload();
gDeferredShadowFullbrightAlphaMaskProgram.unload();
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();
- gDeferredAvatarShadowProgram.unload();
+ gDeferredAvatarShadowProgram.unload();
gDeferredAvatarAlphaShadowProgram.unload();
gDeferredAvatarAlphaMaskShadowProgram.unload();
- gDeferredAvatarProgram.unload();
- gDeferredAvatarAlphaProgram.unload();
- gDeferredAlphaProgram.unload();
+ gDeferredAvatarProgram.unload();
+ gDeferredAvatarAlphaProgram.unload();
+ gDeferredAlphaProgram.unload();
gHUDAlphaProgram.unload();
gDeferredSkinnedAlphaProgram.unload();
- gDeferredFullbrightProgram.unload();
+ gDeferredFullbrightProgram.unload();
gHUDFullbrightProgram.unload();
- gDeferredFullbrightAlphaMaskProgram.unload();
+ gDeferredFullbrightAlphaMaskProgram.unload();
gHUDFullbrightAlphaMaskProgram.unload();
gDeferredFullbrightAlphaMaskAlphaProgram.unload();
gHUDFullbrightAlphaMaskAlphaProgram.unload();
- gDeferredEmissiveProgram.unload();
+ gDeferredEmissiveProgram.unload();
gDeferredSkinnedEmissiveProgram.unload();
- gDeferredAvatarEyesProgram.unload();
- gDeferredPostProgram.unload();
- gDeferredCoFProgram.unload();
- gDeferredDoFCombineProgram.unload();
+ gDeferredAvatarEyesProgram.unload();
+ gDeferredPostProgram.unload();
+ gDeferredCoFProgram.unload();
+ gDeferredDoFCombineProgram.unload();
gExposureProgram.unload();
+ gExposureProgramNoFade.unload();
gLuminanceProgram.unload();
- gDeferredPostGammaCorrectProgram.unload();
+ gDeferredPostGammaCorrectProgram.unload();
gNoPostGammaCorrectProgram.unload();
gLegacyPostGammaCorrectProgram.unload();
- gFXAAProgram.unload();
- gDeferredWLSkyProgram.unload();
- gDeferredWLCloudProgram.unload();
+ gFXAAProgram.unload();
+ gEnvironmentMapProgram.unload();
+ gDeferredWLSkyProgram.unload();
+ gDeferredWLCloudProgram.unload();
gDeferredWLSunProgram.unload();
gDeferredWLMoonProgram.unload();
- gDeferredStarProgram.unload();
- gDeferredFullbrightShinyProgram.unload();
+ gDeferredStarProgram.unload();
+ gDeferredFullbrightShinyProgram.unload();
gHUDFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightShinyProgram.unload();
- gDeferredSkinnedFullbrightProgram.unload();
+ gDeferredSkinnedFullbrightProgram.unload();
gDeferredSkinnedFullbrightAlphaMaskProgram.unload();
gDeferredSkinnedFullbrightAlphaMaskAlphaProgram.unload();
gDeferredHighlightProgram.unload();
-
- gNormalMapGenProgram.unload();
+
+ gNormalMapGenProgram.unload();
gDeferredGenBrdfLutProgram.unload();
- gDeferredBufferVisualProgram.unload();
+ gDeferredBufferVisualProgram.unload();
- for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
- {
- gDeferredMaterialProgram[i].unload();
- }
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ gDeferredMaterialProgram[i].unload();
+ }
gHUDPBROpaqueProgram.unload();
gPBRGlowProgram.unload();
@@ -951,124 +1022,128 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedPBROpaqueProgram.unload();
gDeferredPBRAlphaProgram.unload();
gDeferredSkinnedPBRAlphaProgram.unload();
+ gDeferredPBRTerrainProgram.unload();
- return TRUE;
- }
+ return TRUE;
+ }
- BOOL success = TRUE;
+ BOOL success = TRUE;
if (success)
- {
- gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
- gDeferredHighlightProgram.mShaderFiles.clear();
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDeferredHighlightProgram.createShader(NULL, NULL);
- }
+ {
+ gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
+ gDeferredHighlightProgram.mShaderFiles.clear();
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gDeferredHighlightProgram.createShader(NULL, NULL);
+ }
- if (success)
- {
- gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
- gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
+ if (success)
+ {
+ gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredDiffuseProgram.mShaderFiles.clear();
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredDiffuseProgram.mShaderFiles.clear();
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
- success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
- gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
- success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
- }
-
- 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));
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
- gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ }
+
+ if (success)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredBumpProgram.mName = "Deferred Bump Shader";
+ gDeferredBumpProgram.mShaderFiles.clear();
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
- success = success && gDeferredBumpProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-
- for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
- {
- if (success)
- {
- mShaderList.push_back(&gDeferredMaterialProgram[i]);
-
- gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
+ success = success && gDeferredBumpProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ if (success)
+ {
+ bool has_skin = i & 0x10;
- U32 alpha_mode = i & 0x3;
+ if (!has_skin)
+ {
+ mShaderList.push_back(&gDeferredMaterialProgram[i]);
+ gDeferredMaterialProgram[i].mName = llformat("Material Shader %d", i);
+ }
+ else
+ {
+ gDeferredMaterialProgram[i].mName = llformat("Skinned Material Shader %d", i);
+ }
+
+ U32 alpha_mode = i & 0x3;
- gDeferredMaterialProgram[i].mShaderFiles.clear();
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialProgram[i].mShaderFiles.clear();
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredMaterialProgram[i].clearPermutations();
+ gDeferredMaterialProgram[i].clearPermutations();
- bool has_normal_map = (i & 0x8) > 0;
- bool has_specular_map = (i & 0x4) > 0;
+ bool has_normal_map = (i & 0x8) > 0;
+ bool has_specular_map = (i & 0x4) > 0;
- if (has_normal_map)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
- }
+ if (has_normal_map)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+ }
- if (has_specular_map)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
- }
+ if (has_specular_map)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
+ }
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
@@ -1083,9 +1158,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
}
- bool has_skin = i & 0x10;
+
gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
- gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
@@ -1104,22 +1178,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
llassert(success);
- }
- }
+ }
+ }
- gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
if (success)
{
gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
- gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
gDeferredPBROpaqueProgram.mShaderFiles.clear();
@@ -1127,7 +1200,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredPBROpaqueProgram.clearPermutations();
-
+
success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
if (success)
{
@@ -1165,22 +1238,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1");
success = gHUDPBROpaqueProgram.createShader(NULL, NULL);
-
+
llassert(success);
}
+
-
- if (success)
- {
+ if (success)
+ {
LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
shader->mName = "Deferred PBR Alpha Shader";
-
+
shader->mFeatures.calculatesLighting = false;
shader->mFeatures.hasLighting = false;
shader->mFeatures.isAlphaLighting = true;
shader->mFeatures.hasSrgb = true;
- shader->mFeatures.encodesNormal = true;
shader->mFeatures.calculatesAtmospherics = true;
shader->mFeatures.hasAtmospherics = true;
shader->mFeatures.hasGamma = true;
@@ -1229,7 +1301,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mName = "HUD PBR Alpha Shader";
shader->mFeatures.hasSrgb = true;
-
+
shader->mShaderFiles.clear();
shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
@@ -1243,28 +1315,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredTreeProgram.mName = "Deferred Tree Shader";
- gDeferredTreeProgram.mShaderFiles.clear();
- gDeferredTreeProgram.mFeatures.encodesNormal = true;
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredTreeProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
- gDeferredTreeShadowProgram.mShaderFiles.clear();
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (success)
+ {
+ S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail");
+ detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX);
+ const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount"));
+ gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d %s",
+ detail,
+ (mapping == 1 ? "flat" : "triplanar"));
+ gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true;
+ gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true;
+ gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true;
+ gDeferredPBRTerrainProgram.mFeatures.hasGamma = true;
+ gDeferredPBRTerrainProgram.mFeatures.hasTransport = true;
+ gDeferredPBRTerrainProgram.mFeatures.isPBRTerrain = true;
+
+ gDeferredPBRTerrainProgram.mShaderFiles.clear();
+ gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PBR_DETAIL", llformat("%d", detail));
+ gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT", llformat("%d", mapping));
+ success = gDeferredPBRTerrainProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredTreeProgram.mName = "Deferred Tree Shader";
+ gDeferredTreeProgram.mShaderFiles.clear();
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredTreeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
+ gDeferredTreeShadowProgram.mShaderFiles.clear();
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
- success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
+ success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
if (success)
{
@@ -1278,98 +1376,96 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
- gDeferredImpostorProgram.mFeatures.hasSrgb = true;
- gDeferredImpostorProgram.mFeatures.encodesNormal = true;
- //gDeferredImpostorProgram.mFeatures.isDeferred = true;
- gDeferredImpostorProgram.mShaderFiles.clear();
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
+ if (success)
+ {
+ gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
+ gDeferredImpostorProgram.mFeatures.hasSrgb = true;
+ gDeferredImpostorProgram.mShaderFiles.clear();
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredImpostorProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
- gDeferredLightProgram.mName = "Deferred Light Shader";
- gDeferredLightProgram.mFeatures.isDeferred = true;
- gDeferredLightProgram.mFeatures.hasShadows = true;
+ if (success)
+ {
+ gDeferredLightProgram.mName = "Deferred Light Shader";
+ gDeferredLightProgram.mFeatures.isDeferred = true;
+ gDeferredLightProgram.mFeatures.hasShadows = true;
gDeferredLightProgram.mFeatures.hasSrgb = true;
- gDeferredLightProgram.mShaderFiles.clear();
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredLightProgram.mShaderFiles.clear();
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredLightProgram.clearPermutations();
- success = gDeferredLightProgram.createShader(NULL, NULL);
+ success = gDeferredLightProgram.createShader(NULL, NULL);
llassert(success);
- }
-
- for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
- {
- if (success)
- {
- gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
- gDeferredMultiLightProgram[i].mFeatures.isDeferred = true;
- gDeferredMultiLightProgram[i].mFeatures.hasShadows = true;
+ }
+
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
+ {
+ if (success)
+ {
+ gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mFeatures.isDeferred = true;
+ gDeferredMultiLightProgram[i].mFeatures.hasShadows = true;
gDeferredMultiLightProgram[i].mFeatures.hasSrgb = true;
gDeferredMultiLightProgram[i].clearPermutations();
- gDeferredMultiLightProgram[i].mShaderFiles.clear();
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+ gDeferredMultiLightProgram[i].mShaderFiles.clear();
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
- success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+ success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
llassert(success);
- }
- }
+ }
+ }
- if (success)
- {
- gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
- gDeferredSpotLightProgram.mShaderFiles.clear();
- gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
- gDeferredSpotLightProgram.mFeatures.isDeferred = true;
- gDeferredSpotLightProgram.mFeatures.hasShadows = true;
+ if (success)
+ {
+ gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
+ gDeferredSpotLightProgram.mShaderFiles.clear();
+ gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredSpotLightProgram.mFeatures.isDeferred = true;
+ gDeferredSpotLightProgram.mFeatures.hasShadows = true;
gDeferredSpotLightProgram.clearPermutations();
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSpotLightProgram.createShader(NULL, NULL);
+ success = gDeferredSpotLightProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
- gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
- gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
- gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true;
- gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
+ if (success)
+ {
+ gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
+ gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true;
+ gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
gDeferredMultiSpotLightProgram.clearPermutations();
gDeferredMultiSpotLightProgram.addPermutation("MULTI_SPOTLIGHT", "1");
- gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiSpotLightProgram.mShaderFiles.clear();
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
+ success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
- std::string fragment;
- std::string vertex = "deferred/sunLightV.glsl";
+ if (success)
+ {
+ std::string fragment;
+ std::string vertex = "deferred/sunLightV.glsl";
bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO");
@@ -1392,30 +1488,30 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
gDeferredSunProgram.mShaderFiles.clear();
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
- gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
+ gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSunProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
- gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
- gDeferredBlurLightProgram.mFeatures.isDeferred = true;
+ if (success)
+ {
+ gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
+ gDeferredBlurLightProgram.mFeatures.isDeferred = true;
- gDeferredBlurLightProgram.mShaderFiles.clear();
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredBlurLightProgram.mShaderFiles.clear();
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredBlurLightProgram.createShader(NULL, NULL);
+ success = gDeferredBlurLightProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
+ if (success)
+ {
for (int i = 0; i < 3 && success; ++i)
{
LLGLSLShader* shader = nullptr;
@@ -1445,7 +1541,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.isAlphaLighting = true;
shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
shader->mFeatures.hasSrgb = true;
- shader->mFeatures.encodesNormal = true;
shader->mFeatures.calculatesAtmospherics = true;
shader->mFeatures.hasAtmospherics = true;
shader->mFeatures.hasGamma = true;
@@ -1489,9 +1584,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- LLGLSLShader* shaders[] = {
- &gDeferredAlphaImpostorProgram,
- &gDeferredSkinnedAlphaImpostorProgram
+ LLGLSLShader* shaders[] = {
+ &gDeferredAlphaImpostorProgram,
+ &gDeferredSkinnedAlphaImpostorProgram
};
for (int i = 0; i < 2 && success; ++i)
@@ -1507,7 +1602,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.hasSrgb = true;
shader->mFeatures.isAlphaLighting = true;
- shader->mFeatures.encodesNormal = true;
shader->mFeatures.hasShadows = use_sun_shadow;
shader->mFeatures.hasReflectionProbes = true;
shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
@@ -1547,41 +1641,40 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
}
- if (success)
- {
- gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
- gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
- gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true;
- gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
- gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
- gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true;
- gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
-
- gDeferredAvatarEyesProgram.mShaderFiles.clear();
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";
- gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightProgram.mFeatures.hasAtmospherics = 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));
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (success)
+ {
+ gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
+ gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
+
+ gDeferredAvatarEyesProgram.mShaderFiles.clear();
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";
+ gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightProgram.mFeatures.hasAtmospherics = 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));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
- success = gDeferredFullbrightProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ success = gDeferredFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
@@ -1601,24 +1694,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
- gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = 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));
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = 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));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskProgram.clearPermutations();
- gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
- gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
- success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
@@ -1681,23 +1774,23 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
- gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (success)
+ {
+ gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
+ gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightShinyProgram.mShaderFiles.clear();
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
- success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
@@ -1718,54 +1811,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
- gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredEmissiveProgram.mFeatures.hasGamma = true;
- gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true;
- gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredEmissiveProgram.mShaderFiles.clear();
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
- gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (success)
+ {
+ gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
+ gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredEmissiveProgram.mFeatures.hasGamma = true;
+ gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true;
+ gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredEmissiveProgram.mShaderFiles.clear();
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
- success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSoftenProgram.mName = "Deferred Soften Shader";
- gDeferredSoftenProgram.mShaderFiles.clear();
- gDeferredSoftenProgram.mFeatures.hasSrgb = true;
- gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
- gDeferredSoftenProgram.mFeatures.hasGamma = true;
- gDeferredSoftenProgram.mFeatures.isDeferred = true;
- gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+ success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredSoftenProgram.mName = "Deferred Soften Shader";
+ gDeferredSoftenProgram.mShaderFiles.clear();
+ gDeferredSoftenProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasGamma = true;
+ gDeferredSoftenProgram.mFeatures.isDeferred = true;
+ gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
gDeferredSoftenProgram.clearPermutations();
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
if (use_sun_shadow)
{
gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
- if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
- { //if using SSAO, take screen space light map into account as if shadows are enabled
- gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ { //if using SSAO, take screen space light map into account as if shadows are enabled
+ gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
- }
-
- success = gDeferredSoftenProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ }
+
+ success = gDeferredSoftenProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
@@ -1814,17 +1907,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
- if (success)
- {
- gDeferredShadowProgram.mName = "Deferred Shadow Shader";
- gDeferredShadowProgram.mShaderFiles.clear();
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
- success = gDeferredShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ if (success)
+ {
+ gDeferredShadowProgram.mName = "Deferred Shadow Shader";
+ gDeferredShadowProgram.mShaderFiles.clear();
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
+ success = gDeferredShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
@@ -1841,52 +1934,52 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
- gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
- gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
- gDeferredShadowCubeProgram.mShaderFiles.clear();
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
- // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
- gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader";
- gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ if (success)
+ {
+ gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+ gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
+ gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
+ gDeferredShadowCubeProgram.mShaderFiles.clear();
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
+ gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader";
+ gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredShadowFullbrightAlphaMaskProgram, gDeferredSkinnedShadowFullbrightAlphaMaskProgram);
success = success && gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
- gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
+ gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredShadowAlphaMaskProgram, gDeferredSkinnedShadowAlphaMaskProgram);
success = success && gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
+ llassert(success);
+ }
+
if (success)
{
@@ -1914,113 +2007,108 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
- gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
-
- gDeferredAvatarShadowProgram.mShaderFiles.clear();
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
- gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
+ gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
+
+ gDeferredAvatarShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
+ gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
- }
- if (success)
- {
- gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
- gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
+ }
+ if (success)
+ {
+ gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
+ gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
- }
-
- if (success)
- {
- gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
- gDeferredTerrainProgram.mFeatures.encodesNormal = true;
- gDeferredTerrainProgram.mFeatures.hasSrgb = true;
- gDeferredTerrainProgram.mFeatures.calculatesLighting = false;
- gDeferredTerrainProgram.mFeatures.hasLighting = false;
- gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
- gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
- gDeferredTerrainProgram.mFeatures.hasGamma = true;
-
- gDeferredTerrainProgram.mShaderFiles.clear();
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ }
+
+ if (success)
+ {
+ gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
+ gDeferredTerrainProgram.mFeatures.hasSrgb = true;
+ gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
+ gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasGamma = true;
+
+ gDeferredTerrainProgram.mShaderFiles.clear();
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTerrainProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarProgram.mName = "Deferred 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));
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";
- gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
- gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true;
- gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
+ gDeferredAvatarProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarProgram.mShaderFiles.clear();
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";
+ gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
+ gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
+ gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
- gDeferredAvatarAlphaProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaProgram.mShaderFiles.clear();
gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarAlphaProgram.clearPermutations();
- gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
- gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
- if (use_sun_shadow)
- {
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
+ gDeferredAvatarAlphaProgram.clearPermutations();
+ gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
+ if (use_sun_shadow)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
- gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
- llassert(success);
+ success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
- gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
- }
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
+ }
if (success)
{
@@ -2029,6 +2117,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gExposureProgram.mFeatures.isDeferred = true;
gExposureProgram.mShaderFiles.clear();
gExposureProgram.clearPermutations();
+ gExposureProgram.addPermutation("USE_LAST_EXPOSURE", "1");
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2038,6 +2127,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gExposureProgramNoFade.mName = "Exposure (no fade)";
+ gExposureProgramNoFade.mFeatures.hasSrgb = true;
+ gExposureProgramNoFade.mFeatures.isDeferred = true;
+ gExposureProgramNoFade.mShaderFiles.clear();
+ gExposureProgramNoFade.clearPermutations();
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
+ gExposureProgramNoFade.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gExposureProgramNoFade.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
gLuminanceProgram.mName = "Luminance";
gLuminanceProgram.mShaderFiles.clear();
gLuminanceProgram.clearPermutations();
@@ -2048,20 +2151,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
- if (success)
- {
- gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
- gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
- gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
- gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
+ if (success)
+ {
+ gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
gDeferredPostGammaCorrectProgram.clearPermutations();
gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
+ success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process";
@@ -2093,105 +2196,125 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
- if (success && gGLManager.mGLVersion > 3.9f)
- {
- gFXAAProgram.mName = "FXAA Shader";
- gFXAAProgram.mFeatures.isDeferred = true;
- gFXAAProgram.mShaderFiles.clear();
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
- gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gFXAAProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ if (success && gGLManager.mGLVersion > 3.9f)
+ {
+ gFXAAProgram.mName = "FXAA Shader";
+ gFXAAProgram.mFeatures.isDeferred = true;
+ gFXAAProgram.mShaderFiles.clear();
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
+ gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gFXAAProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
- if (success)
- {
- gDeferredPostProgram.mName = "Deferred Post Shader";
+ if (success)
+ {
+ gDeferredPostProgram.mName = "Deferred Post Shader";
gDeferredPostProgram.mFeatures.isDeferred = true;
- gDeferredPostProgram.mShaderFiles.clear();
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
- gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredCoFProgram.mName = "Deferred CoF Shader";
- gDeferredCoFProgram.mShaderFiles.clear();
- gDeferredCoFProgram.mFeatures.isDeferred = true;
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
- gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredCoFProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
- gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
- gDeferredDoFCombineProgram.mShaderFiles.clear();
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
+ gDeferredPostProgram.mShaderFiles.clear();
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredCoFProgram.mName = "Deferred CoF Shader";
+ gDeferredCoFProgram.mShaderFiles.clear();
+ gDeferredCoFProgram.mFeatures.isDeferred = true;
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredCoFProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
+ gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
+ gDeferredDoFCombineProgram.mShaderFiles.clear();
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";
+ gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
+ gDeferredPostNoDoFProgram.mShaderFiles.clear();
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gEnvironmentMapProgram.mName = "Environment Map Program";
+ gEnvironmentMapProgram.mShaderFiles.clear();
+ gEnvironmentMapProgram.mFeatures.calculatesAtmospherics = true;
+ gEnvironmentMapProgram.mFeatures.hasAtmospherics = true;
+ gEnvironmentMapProgram.mFeatures.hasGamma = true;
+ gEnvironmentMapProgram.mFeatures.hasSrgb = true;
+
+ gEnvironmentMapProgram.clearPermutations();
+ gEnvironmentMapProgram.addPermutation("HAS_HDRI", "1");
+ gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
+ gEnvironmentMapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gEnvironmentMapProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+
+ success = gEnvironmentMapProgram.createShader(NULL, NULL);
llassert(success);
}
- if (success)
- {
- gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";
- gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
- gDeferredPostNoDoFProgram.mShaderFiles.clear();
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
- gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
- gDeferredWLSkyProgram.mShaderFiles.clear();
- gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLSkyProgram.mFeatures.hasGamma = true;
- gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
-
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
-
- success = gDeferredWLSkyProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
- gDeferredWLCloudProgram.mShaderFiles.clear();
- gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true;
+ if (success)
+ {
+ gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
+ gDeferredWLSkyProgram.mShaderFiles.clear();
+ gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLSkyProgram.mFeatures.hasGamma = true;
+ gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
+
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+
+ success = gDeferredWLSkyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
+ gDeferredWLCloudProgram.mShaderFiles.clear();
+ gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true;
gDeferredWLCloudProgram.mFeatures.hasGamma = true;
gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
-
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
- success = gDeferredWLCloudProgram.createShader(NULL, NULL);
- llassert(success);
- }
+ success = gDeferredWLCloudProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
- if (success)
- {
- gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
+ if (success)
+ {
+ gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true;
gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
gDeferredWLSunProgram.mFeatures.hasGamma = true;
@@ -2216,40 +2339,40 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
gDeferredWLMoonProgram.mFeatures.hasSrgb = true;
gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
-
+
gDeferredWLMoonProgram.mShaderFiles.clear();
gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
- success = gDeferredWLMoonProgram.createShader(NULL, NULL);
+ success = gDeferredWLMoonProgram.createShader(NULL, NULL);
llassert(success);
- }
-
- if (success)
- {
- gDeferredStarProgram.mName = "Deferred Star Program";
- gDeferredStarProgram.mShaderFiles.clear();
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
- gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ }
+
+ if (success)
+ {
+ gDeferredStarProgram.mName = "Deferred Star Program";
+ gDeferredStarProgram.mShaderFiles.clear();
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
- success = gDeferredStarProgram.createShader(NULL, NULL);
+ success = gDeferredStarProgram.createShader(NULL, NULL);
llassert(success);
- }
+ }
- if (success)
- {
- gNormalMapGenProgram.mName = "Normal Map Generation Program";
- gNormalMapGenProgram.mShaderFiles.clear();
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
- gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gNormalMapGenProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ gNormalMapGenProgram.mName = "Normal Map Generation Program";
+ gNormalMapGenProgram.mShaderFiles.clear();
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
+ gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gNormalMapGenProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -2261,7 +2384,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
}
- if (success) {
+ if (success) {
gPostScreenSpaceReflectionProgram.mName = "Screen Space Reflection Post";
gPostScreenSpaceReflectionProgram.mShaderFiles.clear();
gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostV.glsl", GL_VERTEX_SHADER));
@@ -2270,29 +2393,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gPostScreenSpaceReflectionProgram.mFeatures.isDeferred = true;
gPostScreenSpaceReflectionProgram.mShaderLevel = 3;
success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL);
- }
-
- if (success) {
- gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
- gDeferredBufferVisualProgram.mShaderFiles.clear();
- gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
- gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
- }
-
- return success;
+ }
+
+ if (success) {
+ gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
+ gDeferredBufferVisualProgram.mShaderFiles.clear();
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
+ }
+
+ return success;
}
BOOL LLViewerShaderMgr::loadShadersObject()
{
LL_PROFILE_ZONE_SCOPED;
- BOOL success = TRUE;
+ BOOL success = TRUE;
if (success)
{
gObjectBumpProgram.mName = "Bump Shader";
- gObjectBumpProgram.mFeatures.encodesNormal = true;
gObjectBumpProgram.mShaderFiles.clear();
gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
@@ -2312,66 +2434,66 @@ BOOL LLViewerShaderMgr::loadShadersObject()
}
}
- if (success)
- {
- gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader";
- gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
- gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
- gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- 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));
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
- gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gImpostorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectPreviewProgram.mName = "Object Preview Shader";
- gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
- gObjectPreviewProgram.mShaderFiles.clear();
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
- gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ if (success)
+ {
+ gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader";
+ gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ 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));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
+ gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gImpostorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectPreviewProgram.mName = "Object Preview Shader";
+ gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
+ gObjectPreviewProgram.mShaderFiles.clear();
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
+ gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram);
- success = gObjectPreviewProgram.createShader(NULL, NULL);
- gObjectPreviewProgram.mFeatures.hasLighting = true;
+ success = gObjectPreviewProgram.createShader(NULL, NULL);
+ gObjectPreviewProgram.mFeatures.hasLighting = true;
gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true;
- }
-
- if (success)
- {
- gPhysicsPreviewProgram.mName = "Preview Physics Shader";
- gPhysicsPreviewProgram.mFeatures.calculatesLighting = false;
- gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false;
- gPhysicsPreviewProgram.mFeatures.hasGamma = false;
- gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false;
- gPhysicsPreviewProgram.mFeatures.hasLighting = false;
- gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
- gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
- gPhysicsPreviewProgram.mShaderFiles.clear();
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
- gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gPhysicsPreviewProgram.createShader(NULL, NULL);
- gPhysicsPreviewProgram.mFeatures.hasLighting = false;
- }
+ }
+
+ if (success)
+ {
+ gPhysicsPreviewProgram.mName = "Preview Physics Shader";
+ gPhysicsPreviewProgram.mFeatures.calculatesLighting = false;
+ gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false;
+ gPhysicsPreviewProgram.mFeatures.hasGamma = false;
+ gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false;
+ gPhysicsPreviewProgram.mFeatures.hasLighting = false;
+ gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
+ gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
+ gPhysicsPreviewProgram.mShaderFiles.clear();
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
+ gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gPhysicsPreviewProgram.createShader(NULL, NULL);
+ gPhysicsPreviewProgram.mFeatures.hasLighting = false;
+ }
if (!success)
{
@@ -2379,234 +2501,234 @@ BOOL LLViewerShaderMgr::loadShadersObject()
return FALSE;
}
- return TRUE;
+ return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersAvatar()
{
LL_PROFILE_ZONE_SCOPED;
#if 1 // DEPRECATED -- forward rendering is deprecated
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_AVATAR] == 0)
- {
- gAvatarProgram.unload();
- gAvatarEyeballProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gAvatarProgram.mName = "Avatar Shader";
- gAvatarProgram.mFeatures.hasSkinning = true;
- gAvatarProgram.mFeatures.calculatesAtmospherics = true;
- gAvatarProgram.mFeatures.calculatesLighting = true;
- gAvatarProgram.mFeatures.hasGamma = true;
- gAvatarProgram.mFeatures.hasAtmospherics = true;
- gAvatarProgram.mFeatures.hasLighting = true;
- gAvatarProgram.mFeatures.hasAlphaMask = true;
- gAvatarProgram.mFeatures.disableTextureIndex = true;
- gAvatarProgram.mShaderFiles.clear();
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
- gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
- success = gAvatarProgram.createShader(NULL, NULL);
-
- /// Keep track of avatar levels
- if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
- {
- mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
- }
- }
-
- if (success)
- {
- gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
- gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
- gAvatarEyeballProgram.mFeatures.isSpecular = true;
- gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
- gAvatarEyeballProgram.mFeatures.hasGamma = true;
- gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
- gAvatarEyeballProgram.mFeatures.hasLighting = true;
- gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
- gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
- gAvatarEyeballProgram.mShaderFiles.clear();
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
- gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
- success = gAvatarEyeballProgram.createShader(NULL, NULL);
- }
-
- if( !success )
- {
- mShaderLevel[SHADER_AVATAR] = 0;
- mMaxAvatarShaderLevel = 0;
- return FALSE;
- }
+ BOOL success = TRUE;
+
+ if (mShaderLevel[SHADER_AVATAR] == 0)
+ {
+ gAvatarProgram.unload();
+ gAvatarEyeballProgram.unload();
+ return TRUE;
+ }
+
+ if (success)
+ {
+ gAvatarProgram.mName = "Avatar Shader";
+ gAvatarProgram.mFeatures.hasSkinning = true;
+ gAvatarProgram.mFeatures.calculatesAtmospherics = true;
+ gAvatarProgram.mFeatures.calculatesLighting = true;
+ gAvatarProgram.mFeatures.hasGamma = true;
+ gAvatarProgram.mFeatures.hasAtmospherics = true;
+ gAvatarProgram.mFeatures.hasLighting = true;
+ gAvatarProgram.mFeatures.hasAlphaMask = true;
+ gAvatarProgram.mFeatures.disableTextureIndex = true;
+ gAvatarProgram.mShaderFiles.clear();
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
+ gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
+ success = gAvatarProgram.createShader(NULL, NULL);
+
+ /// Keep track of avatar levels
+ if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
+ {
+ mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
+ }
+ }
+
+ if (success)
+ {
+ gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
+ gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
+ gAvatarEyeballProgram.mFeatures.isSpecular = true;
+ gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
+ gAvatarEyeballProgram.mFeatures.hasGamma = true;
+ gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
+ gAvatarEyeballProgram.mFeatures.hasLighting = true;
+ gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
+ gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
+ gAvatarEyeballProgram.mShaderFiles.clear();
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
+ gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
+ success = gAvatarEyeballProgram.createShader(NULL, NULL);
+ }
+
+ if( !success )
+ {
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mMaxAvatarShaderLevel = 0;
+ return FALSE;
+ }
#endif
- return TRUE;
+ return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersInterface()
{
LL_PROFILE_ZONE_SCOPED;
- BOOL success = TRUE;
-
- if (success)
- {
- gHighlightProgram.mName = "Highlight Shader";
- gHighlightProgram.mShaderFiles.clear();
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ BOOL success = TRUE;
+
+ if (success)
+ {
+ gHighlightProgram.mName = "Highlight Shader";
+ gHighlightProgram.mShaderFiles.clear();
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
- success = success && gHighlightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gHighlightNormalProgram.mName = "Highlight Normals Shader";
- gHighlightNormalProgram.mShaderFiles.clear();
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightNormalProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gHighlightSpecularProgram.mName = "Highlight Spec Shader";
- gHighlightSpecularProgram.mShaderFiles.clear();
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightSpecularProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gUIProgram.mName = "UI Shader";
- gUIProgram.mShaderFiles.clear();
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
- gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gUIProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gPathfindingProgram.mName = "Pathfinding Shader";
- gPathfindingProgram.mShaderFiles.clear();
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
- gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gPathfindingProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
- gPathfindingNoNormalsProgram.mShaderFiles.clear();
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
- gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gGlowCombineProgram.mName = "Glow Combine Shader";
- gGlowCombineProgram.mShaderFiles.clear();
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
- gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gGlowCombineProgram.createShader(NULL, NULL);
- if (success)
- {
- gGlowCombineProgram.bind();
- gGlowCombineProgram.uniform1i(sGlowMap, 0);
- gGlowCombineProgram.uniform1i(sScreenMap, 1);
- gGlowCombineProgram.unbind();
- }
- }
-
- if (success)
- {
- gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
- gGlowCombineFXAAProgram.mShaderFiles.clear();
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
- gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
- if (success)
- {
- gGlowCombineFXAAProgram.bind();
- gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
- gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
- gGlowCombineFXAAProgram.unbind();
- }
- }
+ success = success && gHighlightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gHighlightNormalProgram.mName = "Highlight Normals Shader";
+ gHighlightNormalProgram.mShaderFiles.clear();
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gHighlightNormalProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gHighlightSpecularProgram.mName = "Highlight Spec Shader";
+ gHighlightSpecularProgram.mShaderFiles.clear();
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gHighlightSpecularProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gUIProgram.mName = "UI Shader";
+ gUIProgram.mShaderFiles.clear();
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
+ gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gUIProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gPathfindingProgram.mName = "Pathfinding Shader";
+ gPathfindingProgram.mShaderFiles.clear();
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
+ gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
+ gPathfindingNoNormalsProgram.mShaderFiles.clear();
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
+ gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gGlowCombineProgram.mName = "Glow Combine Shader";
+ gGlowCombineProgram.mShaderFiles.clear();
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
+ gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGlowCombineProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gGlowCombineProgram.bind();
+ gGlowCombineProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineProgram.uniform1i(sScreenMap, 1);
+ gGlowCombineProgram.unbind();
+ }
+ }
+
+ if (success)
+ {
+ gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
+ gGlowCombineFXAAProgram.mShaderFiles.clear();
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
+ gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gGlowCombineFXAAProgram.bind();
+ gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
+ gGlowCombineFXAAProgram.unbind();
+ }
+ }
#ifdef LL_WINDOWS
- if (success)
- {
- gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
- gTwoTextureCompareProgram.mShaderFiles.clear();
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
- gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gTwoTextureCompareProgram.createShader(NULL, NULL);
- if (success)
- {
- gTwoTextureCompareProgram.bind();
- gTwoTextureCompareProgram.uniform1i(sTex0, 0);
- gTwoTextureCompareProgram.uniform1i(sTex1, 1);
- gTwoTextureCompareProgram.uniform1i(sDitherTex, 2);
- }
- }
-
- if (success)
- {
- gOneTextureFilterProgram.mName = "One Texture Filter Shader";
- gOneTextureFilterProgram.mShaderFiles.clear();
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
- gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gOneTextureFilterProgram.createShader(NULL, NULL);
- if (success)
- {
- gOneTextureFilterProgram.bind();
- gOneTextureFilterProgram.uniform1i(sTex0, 0);
- }
- }
+ if (success)
+ {
+ gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
+ gTwoTextureCompareProgram.mShaderFiles.clear();
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
+ gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gTwoTextureCompareProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gTwoTextureCompareProgram.bind();
+ gTwoTextureCompareProgram.uniform1i(sTex0, 0);
+ gTwoTextureCompareProgram.uniform1i(sTex1, 1);
+ gTwoTextureCompareProgram.uniform1i(sDitherTex, 2);
+ }
+ }
+
+ if (success)
+ {
+ gOneTextureFilterProgram.mName = "One Texture Filter Shader";
+ gOneTextureFilterProgram.mShaderFiles.clear();
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
+ gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gOneTextureFilterProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gOneTextureFilterProgram.bind();
+ gOneTextureFilterProgram.uniform1i(sTex0, 0);
+ }
+ }
#endif
- if (success)
- {
- gSolidColorProgram.mName = "Solid Color Shader";
- gSolidColorProgram.mShaderFiles.clear();
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
- gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gSolidColorProgram.createShader(NULL, NULL);
- if (success)
- {
- gSolidColorProgram.bind();
- gSolidColorProgram.uniform1i(sTex0, 0);
- gSolidColorProgram.unbind();
- }
- }
-
- if (success)
- {
- gOcclusionProgram.mName = "Occlusion Shader";
- gOcclusionProgram.mShaderFiles.clear();
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
- gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ if (success)
+ {
+ gSolidColorProgram.mName = "Solid Color Shader";
+ gSolidColorProgram.mShaderFiles.clear();
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
+ gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gSolidColorProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gSolidColorProgram.bind();
+ gSolidColorProgram.uniform1i(sTex0, 0);
+ gSolidColorProgram.unbind();
+ }
+ }
+
+ if (success)
+ {
+ gOcclusionProgram.mName = "Occlusion Shader";
+ gOcclusionProgram.mShaderFiles.clear();
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
+ gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
- success = gOcclusionProgram.createShader(NULL, NULL);
- }
+ success = gOcclusionProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -2619,47 +2741,74 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
}
- if (success)
- {
- gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
- gOcclusionCubeProgram.mShaderFiles.clear();
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
- gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gOcclusionCubeProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDebugProgram.mName = "Debug Shader";
- gDebugProgram.mShaderFiles.clear();
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
+ if (success)
+ {
+ gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
+ gOcclusionCubeProgram.mShaderFiles.clear();
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
+ gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gOcclusionCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDebugProgram.mName = "Debug Shader";
+ gDebugProgram.mShaderFiles.clear();
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
- gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
- success = success && gDebugProgram.createShader(NULL, NULL);
- }
+ success = success && gDebugProgram.createShader(NULL, NULL);
+ }
- if (success)
- {
- gClipProgram.mName = "Clip Shader";
- gClipProgram.mShaderFiles.clear();
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
- gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gClipProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gBenchmarkProgram.mName = "Benchmark Shader";
- gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
- gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gBenchmarkProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ for (S32 variant = 0; variant < NORMAL_DEBUG_SHADER_COUNT; ++variant)
+ {
+ LLGLSLShader& shader = gNormalDebugProgram[variant];
+ LLGLSLShader& skinned_shader = gSkinnedNormalDebugProgram[variant];
+ shader.mName = "Normal Debug Shader";
+ shader.mShaderFiles.clear();
+ shader.mShaderFiles.push_back(make_pair("interface/normaldebugV.glsl", GL_VERTEX_SHADER));
+ // *NOTE: Geometry shaders have a reputation for being slow.
+ // Consider using compute shaders instead, which have a reputation
+ // for being fast. This geometry shader in particular seems to run
+ // fine on my machine, but I won't vouch for this in
+ // performance-critical areas. -Cosmic,2023-09-28
+ shader.mShaderFiles.push_back(make_pair("interface/normaldebugG.glsl", GL_GEOMETRY_SHADER));
+ shader.mShaderFiles.push_back(make_pair("interface/normaldebugF.glsl", GL_FRAGMENT_SHADER));
+ shader.mRiggedVariant = &skinned_shader;
+ shader.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ if (variant == NORMAL_DEBUG_SHADER_WITH_TANGENTS)
+ {
+ shader.addPermutation("HAS_ATTRIBUTE_TANGENT", "1");
+ }
+ success = make_rigged_variant(shader, skinned_shader);
+ success = success && shader.createShader(NULL, NULL);
+ }
+ }
+
+ if (success)
+ {
+ gClipProgram.mName = "Clip Shader";
+ gClipProgram.mShaderFiles.clear();
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
+ gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gClipProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gBenchmarkProgram.mName = "Benchmark Shader";
+ gBenchmarkProgram.mShaderFiles.clear();
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
+ gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gBenchmarkProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -2698,16 +2847,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCopyDepthProgram.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));
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
- gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gAlphaMaskProgram.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));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
+ gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gAlphaMaskProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -2744,8 +2893,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ gRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "32");
success = gRadianceGenProgram.createShader(NULL, NULL);
}
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gHeroRadianceGenProgram.mName = "Hero Radiance Gen Shader";
+ gHeroRadianceGenProgram.mShaderFiles.clear();
+ gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
+ gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gHeroRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ gHeroRadianceGenProgram.addPermutation("HERO_PROBES", "1");
+ gHeroRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "4");
+ success = gHeroRadianceGenProgram.createShader(NULL, NULL);
+ }
if (success && gGLManager.mHasCubeMapArray)
{
@@ -2757,19 +2919,19 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
success = gIrradianceGenProgram.createShader(NULL, NULL);
}
- if( !success )
- {
- mShaderLevel[SHADER_INTERFACE] = 0;
- return FALSE;
- }
-
- return TRUE;
+ if( !success )
+ {
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ return FALSE;
+ }
+
+ return TRUE;
}
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
+ return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
}
void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
@@ -2779,11 +2941,11 @@ void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const
{
- return mShaderList.begin();
+ return mShaderList.begin();
}
LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
{
- return mShaderList.end();
+ return mShaderList.end();
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index a6a70236cc..c51f583ebc 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewershadermgr.h
* @brief Viewer Shader Manager
*
* $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$
*/
@@ -35,241 +35,271 @@
class LLViewerShaderMgr: public LLShaderMgr
{
public:
- static BOOL sInitialized;
- static bool sSkipReload;
+ static BOOL sInitialized;
+ static bool sSkipReload;
+
+ LLViewerShaderMgr();
+ /* virtual */ ~LLViewerShaderMgr();
- LLViewerShaderMgr();
- /* virtual */ ~LLViewerShaderMgr();
+ // Add shaders to mShaderList for later uniform propagation
+ // Will assert on redundant shader entries in debug builds
+ void finalizeShaderList();
- // singleton pattern implementation
- static LLViewerShaderMgr * instance();
- static void releaseInstance();
+ // singleton pattern implementation
+ static LLViewerShaderMgr * instance();
+ static void releaseInstance();
- void initAttribsAndUniforms(void);
- void setShaders();
- void unloadShaders();
+ void initAttribsAndUniforms(void);
+ void setShaders();
+ void unloadShaders();
S32 getShaderLevel(S32 type);
// loadBasicShaders in case of a failure returns
// name of a file error happened at, otherwise
// returns an empty string
std::string loadBasicShaders();
- BOOL loadShadersEffects();
- BOOL loadShadersDeferred();
- BOOL loadShadersObject();
- BOOL loadShadersAvatar();
- BOOL loadShadersWater();
- BOOL loadShadersInterface();
-
- std::vector<S32> mShaderLevel;
- S32 mMaxAvatarShaderLevel;
-
- enum EShaderClass
- {
- SHADER_LIGHTING,
- SHADER_OBJECT,
- SHADER_AVATAR,
- SHADER_ENVIRONMENT,
- SHADER_INTERFACE,
- SHADER_EFFECT,
- SHADER_WINDLIGHT,
- SHADER_WATER,
- SHADER_DEFERRED,
- SHADER_COUNT
- };
-
- // simple model of forward iterator
- // http://www.sgi.com/tech/stl/ForwardIterator.html
- class shader_iter
- {
- private:
- friend bool operator == (shader_iter const & a, shader_iter const & b);
- friend bool operator != (shader_iter const & a, shader_iter const & b);
-
- typedef std::vector<LLGLSLShader *>::const_iterator base_iter_t;
- public:
- shader_iter()
- {
- }
-
- shader_iter(base_iter_t iter) : mIter(iter)
- {
- }
-
- LLGLSLShader & operator * () const
- {
- return **mIter;
- }
-
- LLGLSLShader * operator -> () const
- {
- return *mIter;
- }
-
- shader_iter & operator++ ()
- {
- ++mIter;
- return *this;
- }
-
- shader_iter operator++ (int)
- {
- return mIter++;
- }
-
- private:
- base_iter_t mIter;
- };
-
- shader_iter beginShaders() const;
- shader_iter endShaders() const;
-
- /* virtual */ std::string getShaderDirPrefix(void);
-
- /* virtual */ void updateShaderUniforms(LLGLSLShader * shader);
+ BOOL loadShadersEffects();
+ BOOL loadShadersDeferred();
+ BOOL loadShadersObject();
+ BOOL loadShadersAvatar();
+ BOOL loadShadersWater();
+ BOOL loadShadersInterface();
+
+ std::vector<S32> mShaderLevel;
+ S32 mMaxAvatarShaderLevel;
+
+ enum EShaderClass
+ {
+ SHADER_LIGHTING,
+ SHADER_OBJECT,
+ SHADER_AVATAR,
+ SHADER_ENVIRONMENT,
+ SHADER_INTERFACE,
+ SHADER_EFFECT,
+ SHADER_WINDLIGHT,
+ SHADER_WATER,
+ SHADER_DEFERRED,
+ SHADER_COUNT
+ };
+
+ // simple model of forward iterator
+ // http://www.sgi.com/tech/stl/ForwardIterator.html
+ class shader_iter
+ {
+ private:
+ friend bool operator == (shader_iter const & a, shader_iter const & b);
+ friend bool operator != (shader_iter const & a, shader_iter const & b);
+
+ typedef std::vector<LLGLSLShader *>::const_iterator base_iter_t;
+ public:
+ shader_iter()
+ {
+ }
+
+ shader_iter(base_iter_t iter) : mIter(iter)
+ {
+ }
+
+ LLGLSLShader & operator * () const
+ {
+ return **mIter;
+ }
+
+ LLGLSLShader * operator -> () const
+ {
+ return *mIter;
+ }
+
+ shader_iter & operator++ ()
+ {
+ ++mIter;
+ return *this;
+ }
+
+ shader_iter operator++ (int)
+ {
+ return mIter++;
+ }
+
+ private:
+ base_iter_t mIter;
+ };
+
+ shader_iter beginShaders() const;
+ shader_iter endShaders() const;
+
+ /* virtual */ std::string getShaderDirPrefix(void);
+
+ /* virtual */ void updateShaderUniforms(LLGLSLShader * shader);
private:
- // the list of shaders we need to propagate parameters to.
- std::vector<LLGLSLShader *> mShaderList;
+ // the list of shaders we need to propagate parameters to.
+ std::vector<LLGLSLShader *> mShaderList;
}; //LLViewerShaderMgr
inline bool operator == (LLViewerShaderMgr::shader_iter const & a, LLViewerShaderMgr::shader_iter const & b)
{
- return a.mIter == b.mIter;
+ return a.mIter == b.mIter;
}
inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShaderMgr::shader_iter const & b)
{
- return a.mIter != b.mIter;
+ return a.mIter != b.mIter;
}
-extern LLVector4 gShinyOrigin;
+extern LLVector4 gShinyOrigin;
//utility shaders
-extern LLGLSLShader gOcclusionProgram;
-extern LLGLSLShader gOcclusionCubeProgram;
-extern LLGLSLShader gGlowCombineProgram;
-extern LLGLSLShader gReflectionMipProgram;
+extern LLGLSLShader gOcclusionProgram;
+extern LLGLSLShader gOcclusionCubeProgram;
+extern LLGLSLShader gGlowCombineProgram;
+extern LLGLSLShader gReflectionMipProgram;
extern LLGLSLShader gGaussianProgram;
extern LLGLSLShader gRadianceGenProgram;
+extern LLGLSLShader gHeroRadianceGenProgram;
extern LLGLSLShader gIrradianceGenProgram;
-extern LLGLSLShader gGlowCombineFXAAProgram;
-extern LLGLSLShader gDebugProgram;
-extern LLGLSLShader gClipProgram;
-extern LLGLSLShader gBenchmarkProgram;
+extern LLGLSLShader gGlowCombineFXAAProgram;
+extern LLGLSLShader gDebugProgram;
+enum NormalDebugShaderVariant : S32
+{
+ NORMAL_DEBUG_SHADER_DEFAULT,
+ NORMAL_DEBUG_SHADER_WITH_TANGENTS,
+ NORMAL_DEBUG_SHADER_COUNT
+};
+extern LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
+extern LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT];
+extern LLGLSLShader gClipProgram;
+extern LLGLSLShader gBenchmarkProgram;
extern LLGLSLShader gReflectionProbeDisplayProgram;
extern LLGLSLShader gCopyProgram;
extern LLGLSLShader gCopyDepthProgram;
//output tex0[tc0] - tex1[tc1]
-extern LLGLSLShader gTwoTextureCompareProgram;
+extern LLGLSLShader gTwoTextureCompareProgram;
//discard some fragments based on user-set color tolerance
-extern LLGLSLShader gOneTextureFilterProgram;
-
+extern LLGLSLShader gOneTextureFilterProgram;
+
//object shaders
-extern LLGLSLShader gObjectPreviewProgram;
+extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gPhysicsPreviewProgram;
-extern LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
-extern LLGLSLShader gObjectBumpProgram;
+extern LLGLSLShader gObjectBumpProgram;
extern LLGLSLShader gSkinnedObjectBumpProgram;
-extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
+extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
-extern LLGLSLShader gWaterProgram;
-extern LLGLSLShader gWaterEdgeProgram;
-extern LLGLSLShader gUnderWaterProgram;
-extern LLGLSLShader gGlowProgram;
-extern LLGLSLShader gGlowExtractProgram;
+extern LLGLSLShader gWaterProgram;
+extern LLGLSLShader gWaterEdgeProgram;
+extern LLGLSLShader gUnderWaterProgram;
+extern LLGLSLShader gGlowProgram;
+extern LLGLSLShader gGlowExtractProgram;
//interface shaders
-extern LLGLSLShader gHighlightProgram;
-extern LLGLSLShader gHighlightNormalProgram;
-extern LLGLSLShader gHighlightSpecularProgram;
+extern LLGLSLShader gHighlightProgram;
+extern LLGLSLShader gHighlightNormalProgram;
+extern LLGLSLShader gHighlightSpecularProgram;
-extern LLGLSLShader gDeferredHighlightProgram;
+extern LLGLSLShader gDeferredHighlightProgram;
-extern LLGLSLShader gPathfindingProgram;
-extern LLGLSLShader gPathfindingNoNormalsProgram;
+extern LLGLSLShader gPathfindingProgram;
+extern LLGLSLShader gPathfindingNoNormalsProgram;
// avatar shader handles
-extern LLGLSLShader gAvatarProgram;
-extern LLGLSLShader gAvatarEyeballProgram;
-extern LLGLSLShader gImpostorProgram;
+extern LLGLSLShader gAvatarProgram;
+extern LLGLSLShader gAvatarEyeballProgram;
+extern LLGLSLShader gImpostorProgram;
// Post Process Shaders
extern LLGLSLShader gPostScreenSpaceReflectionProgram;
// Deferred rendering shaders
-extern LLGLSLShader gDeferredImpostorProgram;
-extern LLGLSLShader gDeferredDiffuseProgram;
-extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
-extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
-extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
-extern LLGLSLShader gDeferredNonIndexedDiffuseProgram;
-extern LLGLSLShader gDeferredBumpProgram;
-extern LLGLSLShader gDeferredTerrainProgram;
-extern LLGLSLShader gDeferredTreeProgram;
-extern LLGLSLShader gDeferredTreeShadowProgram;
-extern LLGLSLShader gDeferredLightProgram;
-extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
-extern LLGLSLShader gDeferredSpotLightProgram;
-extern LLGLSLShader gDeferredMultiSpotLightProgram;
-extern LLGLSLShader gDeferredSunProgram;
+extern LLGLSLShader gDeferredImpostorProgram;
+extern LLGLSLShader gDeferredDiffuseProgram;
+extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
+extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
+extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
+extern LLGLSLShader gDeferredNonIndexedDiffuseProgram;
+extern LLGLSLShader gDeferredBumpProgram;
+extern LLGLSLShader gDeferredTerrainProgram;
+extern LLGLSLShader gDeferredTreeProgram;
+extern LLGLSLShader gDeferredTreeShadowProgram;
+extern LLGLSLShader gDeferredLightProgram;
+extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
+extern LLGLSLShader gDeferredSpotLightProgram;
+extern LLGLSLShader gDeferredMultiSpotLightProgram;
+extern LLGLSLShader gDeferredSunProgram;
extern LLGLSLShader gHazeProgram;
extern LLGLSLShader gHazeWaterProgram;
-extern LLGLSLShader gDeferredBlurLightProgram;
-extern LLGLSLShader gDeferredAvatarProgram;
-extern LLGLSLShader gDeferredSoftenProgram;
-extern LLGLSLShader gDeferredShadowProgram;
-extern LLGLSLShader gDeferredShadowCubeProgram;
-extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
+extern LLGLSLShader gDeferredBlurLightProgram;
+extern LLGLSLShader gDeferredAvatarProgram;
+extern LLGLSLShader gDeferredSoftenProgram;
+extern LLGLSLShader gDeferredShadowProgram;
+extern LLGLSLShader gDeferredShadowCubeProgram;
+extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
extern LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
extern LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
-extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
-extern LLGLSLShader gDeferredPostProgram;
-extern LLGLSLShader gDeferredCoFProgram;
-extern LLGLSLShader gDeferredDoFCombineProgram;
-extern LLGLSLShader gFXAAProgram;
-extern LLGLSLShader gDeferredPostNoDoFProgram;
-extern LLGLSLShader gDeferredPostGammaCorrectProgram;
+extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
+extern LLGLSLShader gDeferredPostProgram;
+extern LLGLSLShader gDeferredCoFProgram;
+extern LLGLSLShader gDeferredDoFCombineProgram;
+extern LLGLSLShader gFXAAProgram;
+extern LLGLSLShader gDeferredPostNoDoFProgram;
+extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gNoPostGammaCorrectProgram;
extern LLGLSLShader gLegacyPostGammaCorrectProgram;
-extern LLGLSLShader gExposureProgram;
-extern LLGLSLShader gLuminanceProgram;
-extern LLGLSLShader gDeferredAvatarShadowProgram;
-extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
-extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
-extern LLGLSLShader gDeferredAlphaProgram;
-extern LLGLSLShader gHUDAlphaProgram;
-extern LLGLSLShader gDeferredAlphaImpostorProgram;
-extern LLGLSLShader gDeferredFullbrightProgram;
-extern LLGLSLShader gHUDFullbrightProgram;
-extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
-extern LLGLSLShader gHUDFullbrightAlphaMaskProgram;
-extern LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
-extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
-extern LLGLSLShader gDeferredEmissiveProgram;
-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 gExposureProgram;
+extern LLGLSLShader gExposureProgramNoFade;
+extern LLGLSLShader gLuminanceProgram;
+extern LLGLSLShader gDeferredAvatarShadowProgram;
+extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
+extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
+extern LLGLSLShader gDeferredAlphaProgram;
+extern LLGLSLShader gHUDAlphaProgram;
+extern LLGLSLShader gDeferredAlphaImpostorProgram;
+extern LLGLSLShader gDeferredFullbrightProgram;
+extern LLGLSLShader gHUDFullbrightProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+extern LLGLSLShader gHUDFullbrightAlphaMaskProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
+extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
+extern LLGLSLShader gDeferredEmissiveProgram;
+extern LLGLSLShader gDeferredAvatarEyesProgram;
+extern LLGLSLShader gDeferredAvatarAlphaProgram;
+extern LLGLSLShader gEnvironmentMapProgram;
+extern LLGLSLShader gDeferredWLSkyProgram;
+extern LLGLSLShader gDeferredWLCloudProgram;
+extern LLGLSLShader gDeferredWLSunProgram;
+extern LLGLSLShader gDeferredWLMoonProgram;
+extern LLGLSLShader gDeferredStarProgram;
+extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gHUDFullbrightShinyProgram;
-extern LLGLSLShader gNormalMapGenProgram;
+extern LLGLSLShader gNormalMapGenProgram;
extern LLGLSLShader gDeferredGenBrdfLutProgram;
-extern LLGLSLShader gDeferredBufferVisualProgram;
+extern LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
-extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
extern LLGLSLShader gHUDPBROpaqueProgram;
extern LLGLSLShader gPBRGlowProgram;
extern LLGLSLShader gDeferredPBROpaqueProgram;
extern LLGLSLShader gDeferredPBRAlphaProgram;
extern LLGLSLShader gHUDPBRAlphaProgram;
+
+// Encodes detail level for dropping textures, in accordance with the GLTF spec where possible
+// 0 is highest detail, -1 drops emissive, etc
+// Dropping metallic roughness is off-spec - Reserve for potato machines as needed
+// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
+enum TerrainPBRDetail : S32
+{
+ TERRAIN_PBR_DETAIL_MAX = 0,
+ TERRAIN_PBR_DETAIL_EMISSIVE = 0,
+ TERRAIN_PBR_DETAIL_OCCLUSION = -1,
+ TERRAIN_PBR_DETAIL_NORMAL = -2,
+ TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS = -3,
+ TERRAIN_PBR_DETAIL_BASE_COLOR = -4,
+ TERRAIN_PBR_DETAIL_MIN = -4,
+};
+extern LLGLSLShader gDeferredPBRTerrainProgram;
#endif
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 506ffce1ce..6b496cf658 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewertexture.cpp
* @brief Object which handles a received image (and associated texture(s))
*
* $LicenseInfo:firstyear=2000&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$
*/
@@ -115,24 +115,24 @@ const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_S
//----------------------------------------------------------------------------------------------
LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
- S32 discard_level,
- BOOL need_imageraw, // Needs image raw for the callback
- void* userdata,
- LLLoadedCallbackEntry::source_callback_list_t* src_callback_list,
- LLViewerFetchedTexture* target,
- BOOL pause)
- : mCallback(cb),
- mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
- mDesiredDiscard(discard_level),
- mNeedsImageRaw(need_imageraw),
- mUserData(userdata),
- mSourceCallbackList(src_callback_list),
- mPaused(pause)
-{
- if(mSourceCallbackList)
- {
+ S32 discard_level,
+ BOOL need_imageraw, // Needs image raw for the callback
+ void* userdata,
+ LLLoadedCallbackEntry::source_callback_list_t* src_callback_list,
+ LLViewerFetchedTexture* target,
+ BOOL pause)
+ : mCallback(cb),
+ mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
+ mDesiredDiscard(discard_level),
+ mNeedsImageRaw(need_imageraw),
+ mUserData(userdata),
+ mSourceCallbackList(src_callback_list),
+ mPaused(pause)
+{
+ if(mSourceCallbackList)
+ {
mSourceCallbackList->insert(LLTextureKey(target->getID(), (ETexListType)target->getTextureListType()));
- }
+ }
}
LLLoadedCallbackEntry::~LLLoadedCallbackEntry()
@@ -141,34 +141,34 @@ LLLoadedCallbackEntry::~LLLoadedCallbackEntry()
void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)
{
- if(mSourceCallbackList)
- {
- mSourceCallbackList->erase(LLTextureKey(tex->getID(), (ETexListType)tex->getTextureListType()));
- }
+ if(mSourceCallbackList)
+ {
+ mSourceCallbackList->erase(LLTextureKey(tex->getID(), (ETexListType)tex->getTextureListType()));
+ }
}
-//static
+//static
void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
- //clear texture callbacks.
- if(callback_list && !callback_list->empty())
- {
- for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();
- iter != callback_list->end(); ++iter)
- {
- LLViewerFetchedTexture* tex = gTextureList.findImage(*iter);
- if(tex)
- {
- tex->deleteCallbackEntry(callback_list);
- }
- }
- callback_list->clear();
- }
+ //clear texture callbacks.
+ if(callback_list && !callback_list->empty())
+ {
+ for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();
+ iter != callback_list->end(); ++iter)
+ {
+ LLViewerFetchedTexture* tex = gTextureList.findImage(*iter);
+ if(tex)
+ {
+ tex->deleteCallbackEntry(callback_list);
+ }
+ }
+ callback_list->clear();
+ }
}
LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image)
{
- return new LLViewerMediaTexture(media_id, usemipmaps, gl_image);
+ return new LLViewerMediaTexture(media_id, usemipmaps, gl_image);
}
void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output)
@@ -209,78 +209,78 @@ LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID&
LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
{
- return LLViewerMediaTexture::findMediaTexture(media_id);
+ return LLViewerMediaTexture::findMediaTexture(media_id);
}
-LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
+LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
{
- LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id);
- if(!tex)
- {
- tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image);
- }
+ LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id);
+ if(!tex)
+ {
+ tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image);
+ }
- tex->initVirtualSize();
+ tex->initVirtualSize();
- return tex;
+ return tex;
}
LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error)
{
- if(!tex)
- {
- return NULL;
- }
+ if(!tex)
+ {
+ return NULL;
+ }
- S8 type = tex->getType();
- if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
- {
- return static_cast<LLViewerFetchedTexture*>(tex);
- }
+ S8 type = tex->getType();
+ if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ return static_cast<LLViewerFetchedTexture*>(tex);
+ }
- if(report_error)
- {
- LL_ERRS() << "not a fetched texture type: " << type << LL_ENDL;
- }
+ if(report_error)
+ {
+ LL_ERRS() << "not a fetched texture type: " << type << LL_ENDL;
+ }
- return NULL;
+ return NULL;
}
LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex)
{
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps);
- if(generate_gl_tex)
- {
- tex->generateGLTexture();
- tex->setCategory(LLGLTexture::LOCAL);
- }
- return tex;
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps);
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture();
+ tex->setCategory(LLGLTexture::LOCAL);
+ }
+ return tex;
}
-LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex)
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex)
{
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps);
- if(generate_gl_tex)
- {
- tex->generateGLTexture();
- tex->setCategory(LLGLTexture::LOCAL);
- }
- return tex;
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps);
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture();
+ tex->setCategory(LLGLTexture::LOCAL);
+ }
+ return tex;
}
-LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
{
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps);
- tex->setCategory(LLGLTexture::LOCAL);
- return tex;
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps);
+ tex->setCategory(LLGLTexture::LOCAL);
+ return tex;
}
-LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
{
- LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height, components, usemipmaps);
- if(generate_gl_tex)
- {
- tex->generateGLTexture();
- tex->setCategory(LLGLTexture::LOCAL);
- }
- return tex;
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height, components, usemipmaps);
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture();
+ tex->setCategory(LLGLTexture::LOCAL);
+ }
+ return tex;
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
@@ -291,170 +291,170 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageR
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
- const LLUUID &image_id,
- FTType f_type,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- LLHost request_from_host)
-{
- return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host);
-}
-
+ const LLUUID &image_id,
+ FTType f_type,
+ BOOL usemipmaps,
+ LLViewerTexture::EBoostLevel boost_priority,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ LLHost request_from_host)
+{
+ return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host);
+}
+
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
- const std::string& filename,
- FTType f_type,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- const LLUUID& force_id)
+ const std::string& filename,
+ FTType f_type,
+ BOOL usemipmaps,
+ LLViewerTexture::EBoostLevel boost_priority,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ const LLUUID& force_id)
{
- return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
+ return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
}
-//static
+//static
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
- FTType f_type,
- BOOL usemipmaps,
- LLViewerTexture::EBoostLevel boost_priority,
- S8 texture_type,
- LLGLint internal_format,
- LLGLenum primary_format,
- const LLUUID& force_id
- )
+ FTType f_type,
+ BOOL usemipmaps,
+ LLViewerTexture::EBoostLevel boost_priority,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ const LLUUID& force_id
+ )
{
- return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
+ return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
}
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
{
- return gTextureList.getImageFromHost(image_id, f_type, host);
+ return gTextureList.getImageFromHost(image_id, f_type, host);
}
// Create a bridge to the viewer texture manager.
class LLViewerTextureManagerBridge : public LLTextureManagerBridge
{
- /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE)
- {
- return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex);
- }
+ /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE)
+ {
+ return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex);
+ }
- /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE)
- {
- return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex);
- }
+ /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE)
+ {
+ return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex);
+ }
- /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id)
- {
- return LLViewerTextureManager::getFetchedTexture(image_id);
- }
+ /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id)
+ {
+ return LLViewerTextureManager::getFetchedTexture(image_id);
+ }
};
void LLViewerTextureManager::init()
{
- {
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
- raw->clear(0x77, 0x77, 0x77, 0xFF);
- LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE);
- }
+ {
+ LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
+ raw->clear(0x77, 0x77, 0x77, 0xFF);
+ LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE);
+ }
- const S32 dim = 128;
- LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
- U8* data = image_raw->getData();
-
- memset(data, 0, dim * dim * 3);
- LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
+ const S32 dim = 128;
+ LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
+ U8* data = image_raw->getData();
+
+ memset(data, 0, dim * dim * 3);
+ LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
#if 1
- LLPointer<LLViewerFetchedTexture> imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT);
- LLViewerFetchedTexture::sDefaultImagep = imagep;
-
- for (S32 i = 0; i<dim; i++)
- {
- for (S32 j = 0; j<dim; j++)
- {
+ LLPointer<LLViewerFetchedTexture> imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT);
+ LLViewerFetchedTexture::sDefaultImagep = imagep;
+
+ for (S32 i = 0; i<dim; i++)
+ {
+ for (S32 j = 0; j<dim; j++)
+ {
#if 0
- const S32 border = 2;
- if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
- {
- *data++ = 0xff;
- *data++ = 0xff;
- *data++ = 0xff;
- }
- else
+ const S32 border = 2;
+ if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
+ {
+ *data++ = 0xff;
+ *data++ = 0xff;
+ *data++ = 0xff;
+ }
+ else
#endif
- {
- *data++ = 0x7f;
- *data++ = 0x7f;
- *data++ = 0x7f;
- }
- }
- }
- imagep->createGLTexture(0, image_raw);
- //cache the raw image
- imagep->setCachedRawImage(0, image_raw);
- image_raw = NULL;
+ {
+ *data++ = 0x7f;
+ *data++ = 0x7f;
+ *data++ = 0x7f;
+ }
+ }
+ }
+ imagep->createGLTexture(0, image_raw);
+ //cache the raw image
+ imagep->setCachedRawImage(0, image_raw);
+ image_raw = NULL;
#else
- LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
#endif
- LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
- LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER);
-
- image_raw = new LLImageRaw(32,32,3);
- data = image_raw->getData();
-
- for (S32 i = 0; i < (32*32*3); i+=3)
- {
- S32 x = (i % (32*3)) / (3*16);
- S32 y = i / (32*3*16);
- U8 color = ((x + y) % 2) * 255;
- data[i] = color;
- data[i+1] = color;
- data[i+2] = color;
- }
-
- LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
-
- LLViewerTexture::initClass();
-
- // Create a texture manager bridge.
- gTextureManagerBridgep = new LLViewerTextureManagerBridge;
-
- if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
- {
- sTesterp = new LLTexturePipelineTester();
- if (!sTesterp->isValid())
- {
- delete sTesterp;
- sTesterp = NULL;
- }
- }
+ LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
+ LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER);
+
+ image_raw = new LLImageRaw(32,32,3);
+ data = image_raw->getData();
+
+ for (S32 i = 0; i < (32*32*3); i+=3)
+ {
+ S32 x = (i % (32*3)) / (3*16);
+ S32 y = i / (32*3*16);
+ U8 color = ((x + y) % 2) * 255;
+ data[i] = color;
+ data[i+1] = color;
+ data[i+2] = color;
+ }
+
+ LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
+
+ LLViewerTexture::initClass();
+
+ // Create a texture manager bridge.
+ gTextureManagerBridgep = new LLViewerTextureManagerBridge;
+
+ if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
+ {
+ sTesterp = new LLTexturePipelineTester();
+ if (!sTesterp->isValid())
+ {
+ delete sTesterp;
+ sTesterp = NULL;
+ }
+ }
}
void LLViewerTextureManager::cleanup()
{
- stop_glerror();
+ stop_glerror();
- delete gTextureManagerBridgep;
- LLImageGL::sDefaultGLTexture = NULL;
- LLViewerTexture::sNullImagep = NULL;
- LLViewerTexture::sBlackImagep = NULL;
- LLViewerTexture::sCheckerBoardImagep = NULL;
- LLViewerFetchedTexture::sDefaultImagep = NULL;
- LLViewerFetchedTexture::sSmokeImagep = NULL;
- LLViewerFetchedTexture::sMissingAssetImagep = NULL;
- LLTexUnit::sWhiteTexture = 0;
- LLViewerFetchedTexture::sWhiteImagep = NULL;
+ delete gTextureManagerBridgep;
+ LLImageGL::sDefaultGLTexture = NULL;
+ LLViewerTexture::sNullImagep = NULL;
+ LLViewerTexture::sBlackImagep = NULL;
+ LLViewerTexture::sCheckerBoardImagep = NULL;
+ LLViewerFetchedTexture::sDefaultImagep = NULL;
+ LLViewerFetchedTexture::sSmokeImagep = NULL;
+ LLViewerFetchedTexture::sMissingAssetImagep = NULL;
+ LLTexUnit::sWhiteTexture = 0;
+ LLViewerFetchedTexture::sWhiteImagep = NULL;
+
+ LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
- LLViewerFetchedTexture::sFlatNormalImagep = NULL;
- LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
-
- LLViewerMediaTexture::cleanUpClass();
+ LLViewerMediaTexture::cleanUpClass();
}
//----------------------------------------------------------------------------------------------
@@ -464,7 +464,7 @@ void LLViewerTextureManager::cleanup()
// static
void LLViewerTexture::initClass()
{
- LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture();
+ LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture();
}
// tuning params
@@ -473,7 +473,7 @@ const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
-//static
+//static
bool LLViewerTexture::isMemoryForTextureLow()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -498,7 +498,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
-
+
if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
gpu = gpu_res;
@@ -509,7 +509,7 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
{
gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes();
-
+
//check main memory, only works for windows and macos.
LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
@@ -523,25 +523,25 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
void LLViewerTexture::updateClass()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- sCurrentTime = gFrameTimeSeconds;
+ sCurrentTime = gFrameTimeSeconds;
- LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
- if (tester)
- {
- tester->update();
- }
+ LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
+ if (tester)
+ {
+ tester->update();
+ }
- LLViewerMediaTexture::updateClass();
+ LLViewerMediaTexture::updateClass();
static LLCachedControl<U32> max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0);
- F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0;
- F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 512.0;
+ F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0;
+ F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 512.0;
- // get an estimate of how much video memory we're using
+ // get an estimate of how much video memory we're using
// NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number
- F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc);
-
+ F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc);
+
F32 budget = max_vram_budget == 0 ? gGLManager.mVRAM : max_vram_budget;
// try to leave half a GB for everyone else, but keep at least 768MB for ourselves
@@ -563,75 +563,75 @@ void LLViewerTexture::updateClass()
const U32 LLViewerTexture::sCurrentFileVersion = 1;
LLViewerTexture::LLViewerTexture(BOOL usemipmaps) :
- LLGLTexture(usemipmaps)
+ LLGLTexture(usemipmaps)
{
- init(true);
+ init(true);
- mID.generate();
- sImageCount++;
+ mID.generate();
+ sImageCount++;
}
LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) :
- LLGLTexture(usemipmaps),
- mID(id)
+ LLGLTexture(usemipmaps),
+ mID(id)
{
- init(true);
-
- sImageCount++;
+ init(true);
+
+ sImageCount++;
}
LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) :
- LLGLTexture(width, height, components, usemipmaps)
+ LLGLTexture(width, height, components, usemipmaps)
{
- init(true);
+ init(true);
- mID.generate();
- sImageCount++;
+ mID.generate();
+ sImageCount++;
}
LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) :
- LLGLTexture(raw, usemipmaps)
+ LLGLTexture(raw, usemipmaps)
{
- init(true);
-
- mID.generate();
- sImageCount++;
+ init(true);
+
+ mID.generate();
+ sImageCount++;
}
LLViewerTexture::~LLViewerTexture()
{
- // LL_DEBUGS("Avatar") << mID << LL_ENDL;
- cleanup();
- sImageCount--;
+ // LL_DEBUGS("Avatar") << mID << LL_ENDL;
+ cleanup();
+ sImageCount--;
}
// virtual
void LLViewerTexture::init(bool firstinit)
{
- mMaxVirtualSize = 0.f;
- mMaxVirtualSizeResetInterval = 1;
- mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
- mParcelMedia = NULL;
-
- memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
- mFaceList[LLRender::DIFFUSE_MAP].clear();
- mFaceList[LLRender::NORMAL_MAP].clear();
- mFaceList[LLRender::SPECULAR_MAP].clear();
- mNumFaces[LLRender::DIFFUSE_MAP] =
- mNumFaces[LLRender::NORMAL_MAP] =
- mNumFaces[LLRender::SPECULAR_MAP] = 0;
-
- mVolumeList[LLRender::LIGHT_TEX].clear();
- mVolumeList[LLRender::SCULPT_TEX].clear();
-
- mMainQueue = LL::WorkQueue::getInstance("mainloop");
- mImageQueue = LL::WorkQueue::getInstance("LLImageGL");
-}
-
-//virtual
+ mMaxVirtualSize = 0.f;
+ mMaxVirtualSizeResetInterval = 1;
+ mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
+ mParcelMedia = NULL;
+
+ memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
+ mFaceList[LLRender::DIFFUSE_MAP].clear();
+ mFaceList[LLRender::NORMAL_MAP].clear();
+ mFaceList[LLRender::SPECULAR_MAP].clear();
+ mNumFaces[LLRender::DIFFUSE_MAP] =
+ mNumFaces[LLRender::NORMAL_MAP] =
+ mNumFaces[LLRender::SPECULAR_MAP] = 0;
+
+ mVolumeList[LLRender::LIGHT_TEX].clear();
+ mVolumeList[LLRender::SCULPT_TEX].clear();
+
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
+ mImageQueue = LL::WorkQueue::getInstance("LLImageGL");
+}
+
+//virtual
S8 LLViewerTexture::getType() const
{
- return LLViewerTexture::LOCAL_TEXTURE;
+ return LLViewerTexture::LOCAL_TEXTURE;
}
void LLViewerTexture::cleanup()
@@ -641,37 +641,37 @@ void LLViewerTexture::cleanup()
LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f);
}
- mFaceList[LLRender::DIFFUSE_MAP].clear();
- mFaceList[LLRender::NORMAL_MAP].clear();
- mFaceList[LLRender::SPECULAR_MAP].clear();
- mVolumeList[LLRender::LIGHT_TEX].clear();
- mVolumeList[LLRender::SCULPT_TEX].clear();
+ mFaceList[LLRender::DIFFUSE_MAP].clear();
+ mFaceList[LLRender::NORMAL_MAP].clear();
+ mFaceList[LLRender::SPECULAR_MAP].clear();
+ mVolumeList[LLRender::LIGHT_TEX].clear();
+ mVolumeList[LLRender::SCULPT_TEX].clear();
}
// virtual
void LLViewerTexture::dump()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- LLGLTexture::dump();
+ LLGLTexture::dump();
- LL_INFOS() << "LLViewerTexture"
- << " mID " << mID
- << LL_ENDL;
+ LL_INFOS() << "LLViewerTexture"
+ << " mID " << mID
+ << LL_ENDL;
}
void LLViewerTexture::setBoostLevel(S32 level)
{
- if(mBoostLevel != level)
- {
- mBoostLevel = level;
- if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
- mBoostLevel != LLViewerTexture::BOOST_SELECTED &&
- mBoostLevel != LLViewerTexture::BOOST_ICON &&
+ if(mBoostLevel != level)
+ {
+ mBoostLevel = level;
+ if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
+ mBoostLevel != LLViewerTexture::BOOST_SELECTED &&
+ mBoostLevel != LLViewerTexture::BOOST_ICON &&
mBoostLevel != LLViewerTexture::BOOST_THUMBNAIL)
- {
- setNoDelete();
- }
- }
+ {
+ setNoDelete();
+ }
+ }
// strongly encourage anything boosted to load at full res
if (mBoostLevel >= LLViewerTexture::BOOST_HIGH)
@@ -682,159 +682,159 @@ void LLViewerTexture::setBoostLevel(S32 level)
bool LLViewerTexture::isActiveFetching()
{
- return false;
+ return false;
}
bool LLViewerTexture::bindDebugImage(const S32 stage)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (stage < 0) return false;
+ if (stage < 0) return false;
- bool res = true;
- if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get()))
- {
- res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep);
- }
+ bool res = true;
+ if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get()))
+ {
+ res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep);
+ }
- if(!res)
- {
- return bindDefaultImage(stage);
- }
+ if(!res)
+ {
+ return bindDefaultImage(stage);
+ }
- return res;
+ return res;
}
-bool LLViewerTexture::bindDefaultImage(S32 stage)
+bool LLViewerTexture::bindDefaultImage(S32 stage)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (stage < 0) return false;
+ if (stage < 0) return false;
- bool res = true;
- if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get()))
- {
- // use default if we've got it
- res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
- }
- if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))
- {
- res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep);
- }
- if (!res)
- {
- LL_WARNS() << "LLViewerTexture::bindDefaultImage failed." << LL_ENDL;
- }
- stop_glerror();
+ bool res = true;
+ if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get()))
+ {
+ // use default if we've got it
+ res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))
+ {
+ res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep);
+ }
+ if (!res)
+ {
+ LL_WARNS() << "LLViewerTexture::bindDefaultImage failed." << LL_ENDL;
+ }
+ stop_glerror();
- //check if there is cached raw image and switch to it if possible
- switchToCachedImage();
+ //check if there is cached raw image and switch to it if possible
+ switchToCachedImage();
- LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
- if (tester)
- {
- tester->updateGrayTextureBinding();
- }
- return res;
+ LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
+ if (tester)
+ {
+ tester->updateGrayTextureBinding();
+ }
+ return res;
}
-//virtual
-BOOL LLViewerTexture::isMissingAsset()const
-{
- return FALSE;
+//virtual
+BOOL LLViewerTexture::isMissingAsset()const
+{
+ return FALSE;
}
-//virtual
-void LLViewerTexture::forceImmediateUpdate()
+//virtual
+void LLViewerTexture::forceImmediateUpdate()
{
}
-void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
+void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(needs_gltexture)
- {
- mNeedsGLTexture = TRUE;
- }
+ if(needs_gltexture)
+ {
+ mNeedsGLTexture = TRUE;
+ }
virtual_size = llmin(virtual_size, LLViewerFetchedTexture::sMaxVirtualSize);
- if (virtual_size > mMaxVirtualSize)
- {
- mMaxVirtualSize = virtual_size;
- }
+ if (virtual_size > mMaxVirtualSize)
+ {
+ mMaxVirtualSize = virtual_size;
+ }
}
void LLViewerTexture::resetTextureStats()
{
- mMaxVirtualSize = 0.0f;
- mMaxVirtualSizeResetCounter = 0;
+ mMaxVirtualSize = 0.0f;
+ mMaxVirtualSizeResetCounter = 0;
}
-//virtual
+//virtual
F32 LLViewerTexture::getMaxVirtualSize()
{
- return mMaxVirtualSize;
+ return mMaxVirtualSize;
}
-//virtual
+//virtual
void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
{
- //nothing here.
+ //nothing here.
}
//virtual
-void LLViewerTexture::addFace(U32 ch, LLFace* facep)
+void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- if(mNumFaces[ch] >= mFaceList[ch].size())
- {
- mFaceList[ch].resize(2 * mNumFaces[ch] + 1);
- }
- mFaceList[ch][mNumFaces[ch]] = facep;
- facep->setIndexInTex(ch, mNumFaces[ch]);
- mNumFaces[ch]++;
- mLastFaceListUpdateTimer.reset();
+ if(mNumFaces[ch] >= mFaceList[ch].size())
+ {
+ mFaceList[ch].resize(2 * mNumFaces[ch] + 1);
+ }
+ mFaceList[ch][mNumFaces[ch]] = facep;
+ facep->setIndexInTex(ch, mNumFaces[ch]);
+ mNumFaces[ch]++;
+ mLastFaceListUpdateTimer.reset();
}
//virtual
-void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
+void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
-
- if(mNumFaces[ch] > 1)
- {
- S32 index = facep->getIndexInTex(ch);
- llassert(index < mFaceList[ch].size());
- llassert(index < mNumFaces[ch]);
- mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]];
- mFaceList[ch][index]->setIndexInTex(ch, index);
- }
- else
- {
- mFaceList[ch].clear();
- mNumFaces[ch] = 0;
- }
- mLastFaceListUpdateTimer.reset();
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mNumFaces[ch] > 1)
+ {
+ S32 index = facep->getIndexInTex(ch);
+ llassert(index < mFaceList[ch].size());
+ llassert(index < mNumFaces[ch]);
+ mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]];
+ mFaceList[ch][index]->setIndexInTex(ch, index);
+ }
+ else
+ {
+ mFaceList[ch].clear();
+ mNumFaces[ch] = 0;
+ }
+ mLastFaceListUpdateTimer.reset();
}
S32 LLViewerTexture::getTotalNumFaces() const
{
- S32 ret = 0;
+ S32 ret = 0;
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- ret += mNumFaces[i];
- }
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ ret += mNumFaces[i];
+ }
- return ret;
+ return ret;
}
S32 LLViewerTexture::getNumFaces(U32 ch) const
{
- llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- return mNumFaces[ch];
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ return mNumFaces[ch];
}
@@ -842,117 +842,117 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const
void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (mNumVolumes[ch] >= mVolumeList[ch].size())
- {
- mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
- }
- mVolumeList[ch][mNumVolumes[ch]] = volumep;
- volumep->setIndexInTex(ch, mNumVolumes[ch]);
- mNumVolumes[ch]++;
- mLastVolumeListUpdateTimer.reset();
+ if (mNumVolumes[ch] >= mVolumeList[ch].size())
+ {
+ mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
+ }
+ mVolumeList[ch][mNumVolumes[ch]] = volumep;
+ volumep->setIndexInTex(ch, mNumVolumes[ch]);
+ mNumVolumes[ch]++;
+ mLastVolumeListUpdateTimer.reset();
}
//virtual
void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (mNumVolumes[ch] > 1)
- {
- S32 index = volumep->getIndexInTex(ch);
- llassert(index < mVolumeList[ch].size());
- llassert(index < mNumVolumes[ch]);
- mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]];
- mVolumeList[ch][index]->setIndexInTex(ch, index);
- }
- else
- {
- mVolumeList[ch].clear();
- mNumVolumes[ch] = 0;
- }
- mLastVolumeListUpdateTimer.reset();
+ if (mNumVolumes[ch] > 1)
+ {
+ S32 index = volumep->getIndexInTex(ch);
+ llassert(index < mVolumeList[ch].size());
+ llassert(index < mNumVolumes[ch]);
+ mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]];
+ mVolumeList[ch][index]->setIndexInTex(ch, index);
+ }
+ else
+ {
+ mVolumeList[ch].clear();
+ mNumVolumes[ch] = 0;
+ }
+ mLastVolumeListUpdateTimer.reset();
}
S32 LLViewerTexture::getNumVolumes(U32 ch) const
{
- return mNumVolumes[ch];
+ return mNumVolumes[ch];
}
void LLViewerTexture::reorganizeFaceList()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static const F32 MAX_WAIT_TIME = 20.f; // seconds
- static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
-
- if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
- {
- return;
- }
+ static const F32 MAX_WAIT_TIME = 20.f; // seconds
+ static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
- for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
- {
- if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
- {
- return;
- }
+ if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
+ {
+ return;
+ }
- mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
- }
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
+ {
+ return;
+ }
- mLastFaceListUpdateTimer.reset();
+ mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
+ }
+
+ mLastFaceListUpdateTimer.reset();
}
void LLViewerTexture::reorganizeVolumeList()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static const F32 MAX_WAIT_TIME = 20.f; // seconds
- static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
+ static const F32 MAX_WAIT_TIME = 20.f; // seconds
+ static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
- for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
- {
- if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size())
- {
- return;
- }
- }
+ for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
+ {
+ if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size())
+ {
+ return;
+ }
+ }
- if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
- {
- return;
- }
+ if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
+ {
+ return;
+ }
- mLastVolumeListUpdateTimer.reset();
- for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
- {
- mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i], mVolumeList[i].end());
- }
+ mLastVolumeListUpdateTimer.reset();
+ for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
+ {
+ mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i], mVolumeList[i].end());
+ }
}
//virtual
void LLViewerTexture::switchToCachedImage()
{
- //nothing here.
+ //nothing here.
}
//virtual
void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
{
- //nothing here.
+ //nothing here.
}
BOOL LLViewerTexture::isLargeImage()
{
- return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize;
+ return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize;
}
-//virtual
+//virtual
void LLViewerTexture::updateBindStatsForTester()
{
- LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
- if (tester)
- {
- tester->updateTextureBindingStats(this);
- }
+ LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
+ if (tester)
+ {
+ tester->updateTextureBindingStats(this);
+ }
}
//----------------------------------------------------------------------------------------------
@@ -961,30 +961,30 @@ void LLViewerTexture::updateBindStatsForTester()
const std::string& fttype_to_string(const FTType& fttype)
{
- static const std::string ftt_unknown("FTT_UNKNOWN");
- static const std::string ftt_default("FTT_DEFAULT");
- static const std::string ftt_server_bake("FTT_SERVER_BAKE");
- static const std::string ftt_host_bake("FTT_HOST_BAKE");
- static const std::string ftt_map_tile("FTT_MAP_TILE");
- static const std::string ftt_local_file("FTT_LOCAL_FILE");
- static const std::string ftt_error("FTT_ERROR");
- switch(fttype)
- {
- case FTT_UNKNOWN: return ftt_unknown; break;
- case FTT_DEFAULT: return ftt_default; break;
- case FTT_SERVER_BAKE: return ftt_server_bake; break;
- case FTT_HOST_BAKE: return ftt_host_bake; break;
- case FTT_MAP_TILE: return ftt_map_tile; break;
- case FTT_LOCAL_FILE: return ftt_local_file; break;
- }
- return ftt_error;
+ static const std::string ftt_unknown("FTT_UNKNOWN");
+ static const std::string ftt_default("FTT_DEFAULT");
+ static const std::string ftt_server_bake("FTT_SERVER_BAKE");
+ static const std::string ftt_host_bake("FTT_HOST_BAKE");
+ static const std::string ftt_map_tile("FTT_MAP_TILE");
+ static const std::string ftt_local_file("FTT_LOCAL_FILE");
+ static const std::string ftt_error("FTT_ERROR");
+ switch(fttype)
+ {
+ case FTT_UNKNOWN: return ftt_unknown; break;
+ case FTT_DEFAULT: return ftt_default; break;
+ case FTT_SERVER_BAKE: return ftt_server_bake; break;
+ case FTT_HOST_BAKE: return ftt_host_bake; break;
+ case FTT_MAP_TILE: return ftt_map_tile; break;
+ case FTT_LOCAL_FILE: return ftt_local_file; break;
+ }
+ return ftt_error;
}
//----------------------------------------------------------------------------------------------
//start of LLViewerFetchedTexture
//----------------------------------------------------------------------------------------------
-//static
+//static
LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage()
{
if (sSmokeImagep.isNull())
@@ -998,186 +998,186 @@ LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage()
}
LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
- : LLViewerTexture(id, usemipmaps),
- mTargetHost(host)
-{
- init(TRUE);
- mFTType = f_type;
- if (mFTType == FTT_HOST_BAKE)
- {
- LL_WARNS() << "Unsupported fetch type " << mFTType << LL_ENDL;
- }
- generateGLTexture();
-}
-
+ : LLViewerTexture(id, usemipmaps),
+ mTargetHost(host)
+{
+ init(TRUE);
+ mFTType = f_type;
+ if (mFTType == FTT_HOST_BAKE)
+ {
+ LL_WARNS() << "Unsupported fetch type " << mFTType << LL_ENDL;
+ }
+ generateGLTexture();
+}
+
LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps)
- : LLViewerTexture(raw, usemipmaps)
+ : LLViewerTexture(raw, usemipmaps)
{
- init(TRUE);
- mFTType = f_type;
+ init(TRUE);
+ mFTType = f_type;
}
-
+
LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
- : LLViewerTexture(id, usemipmaps),
- mUrl(url)
+ : LLViewerTexture(id, usemipmaps),
+ mUrl(url)
{
- init(TRUE);
- mFTType = f_type;
- generateGLTexture();
+ init(TRUE);
+ mFTType = f_type;
+ generateGLTexture();
}
void LLViewerFetchedTexture::init(bool firstinit)
{
- mOrigWidth = 0;
- mOrigHeight = 0;
- mHasAux = FALSE;
- mNeedsAux = FALSE;
- mRequestedDiscardLevel = -1;
- mRequestedDownloadPriority = 0.f;
- mFullyLoaded = FALSE;
- mCanUseHTTP = true;
- mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
- mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
-
- mDecodingAux = FALSE;
-
- mKnownDrawWidth = 0;
- mKnownDrawHeight = 0;
- mKnownDrawSizeChanged = FALSE;
-
- if (firstinit)
- {
- mInImageList = 0;
- }
-
- // Only set mIsMissingAsset true when we know for certain that the database
- // does not contain this image.
- mIsMissingAsset = FALSE;
-
- mLoadedCallbackDesiredDiscardLevel = S8_MAX;
- mPauseLoadedCallBacks = FALSE;
-
- mNeedsCreateTexture = false;
-
- mIsRawImageValid = FALSE;
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- mMinDiscardLevel = 0;
-
- mHasFetcher = FALSE;
- mIsFetching = FALSE;
- mFetchState = 0;
- mFetchPriority = 0;
- mDownloadProgress = 0.f;
- mFetchDeltaTime = 999999.f;
- mRequestDeltaTime = 0.f;
- mForSculpt = FALSE;
- mIsFetched = FALSE;
- mInFastCacheList = FALSE;
-
- mCachedRawImage = NULL;
- mCachedRawDiscardLevel = -1;
- mCachedRawImageReady = FALSE;
-
- mSavedRawImage = NULL;
- mForceToSaveRawImage = FALSE;
- mSaveRawImage = FALSE;
- mSavedRawDiscardLevel = -1;
- mDesiredSavedRawDiscardLevel = -1;
- mLastReferencedSavedRawImageTime = 0.0f;
- mKeptSavedRawImageTime = 0.f;
- mLastCallBackActiveTime = 0.f;
- mForceCallbackFetch = FALSE;
- mInDebug = FALSE;
- mUnremovable = FALSE;
-
- mFTType = FTT_UNKNOWN;
+ mOrigWidth = 0;
+ mOrigHeight = 0;
+ mHasAux = FALSE;
+ mNeedsAux = FALSE;
+ mRequestedDiscardLevel = -1;
+ mRequestedDownloadPriority = 0.f;
+ mFullyLoaded = FALSE;
+ mCanUseHTTP = true;
+ mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+ mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+
+ mDecodingAux = FALSE;
+
+ mKnownDrawWidth = 0;
+ mKnownDrawHeight = 0;
+ mKnownDrawSizeChanged = FALSE;
+
+ if (firstinit)
+ {
+ mInImageList = 0;
+ }
+
+ // Only set mIsMissingAsset true when we know for certain that the database
+ // does not contain this image.
+ mIsMissingAsset = FALSE;
+
+ mLoadedCallbackDesiredDiscardLevel = S8_MAX;
+ mPauseLoadedCallBacks = FALSE;
+
+ mNeedsCreateTexture = false;
+
+ mIsRawImageValid = FALSE;
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ mMinDiscardLevel = 0;
+
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE;
+ mFetchState = 0;
+ mFetchPriority = 0;
+ mDownloadProgress = 0.f;
+ mFetchDeltaTime = 999999.f;
+ mRequestDeltaTime = 0.f;
+ mForSculpt = FALSE;
+ mIsFetched = FALSE;
+ mInFastCacheList = FALSE;
+
+ mCachedRawImage = NULL;
+ mCachedRawDiscardLevel = -1;
+ mCachedRawImageReady = FALSE;
+
+ mSavedRawImage = NULL;
+ mForceToSaveRawImage = FALSE;
+ mSaveRawImage = FALSE;
+ mSavedRawDiscardLevel = -1;
+ mDesiredSavedRawDiscardLevel = -1;
+ mLastReferencedSavedRawImageTime = 0.0f;
+ mKeptSavedRawImageTime = 0.f;
+ mLastCallBackActiveTime = 0.f;
+ mForceCallbackFetch = FALSE;
+ mInDebug = FALSE;
+ mUnremovable = FALSE;
+
+ mFTType = FTT_UNKNOWN;
}
LLViewerFetchedTexture::~LLViewerFetchedTexture()
{
assert_main_thread();
- //*NOTE getTextureFetch can return NULL when Viewer is shutting down.
- // This is due to LLWearableList is singleton and is destroyed after
- // LLAppViewer::cleanup() was called. (see ticket EXT-177)
- if (mHasFetcher && LLAppViewer::getTextureFetch())
- {
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- }
- cleanup();
+ //*NOTE getTextureFetch can return NULL when Viewer is shutting down.
+ // This is due to LLWearableList is singleton and is destroyed after
+ // LLAppViewer::cleanup() was called. (see ticket EXT-177)
+ if (mHasFetcher && LLAppViewer::getTextureFetch())
+ {
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ }
+ cleanup();
}
-//virtual
+//virtual
S8 LLViewerFetchedTexture::getType() const
{
- return LLViewerTexture::FETCHED_TEXTURE;
+ return LLViewerTexture::FETCHED_TEXTURE;
}
FTType LLViewerFetchedTexture::getFTType() const
{
- return mFTType;
+ return mFTType;
}
void LLViewerFetchedTexture::cleanup()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
- entryp->removeTexture(this);
- delete entryp;
- }
- mLoadedCallbackList.clear();
- mNeedsAux = FALSE;
-
- // Clean up image data
- destroyRawImage();
- mCachedRawImage = NULL;
- mCachedRawDiscardLevel = -1;
- mCachedRawImageReady = FALSE;
- mSavedRawImage = NULL;
- mSavedRawDiscardLevel = -1;
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
+ entryp->removeTexture(this);
+ delete entryp;
+ }
+ mLoadedCallbackList.clear();
+ mNeedsAux = FALSE;
+
+ // Clean up image data
+ destroyRawImage();
+ mCachedRawImage = NULL;
+ mCachedRawDiscardLevel = -1;
+ mCachedRawImageReady = FALSE;
+ mSavedRawImage = NULL;
+ mSavedRawDiscardLevel = -1;
}
//access the fast cache
void LLViewerFetchedTexture::loadFromFastCache()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(!mInFastCacheList)
- {
- return; //no need to access the fast cache.
- }
- mInFastCacheList = FALSE;
+ if(!mInFastCacheList)
+ {
+ return; //no need to access the fast cache.
+ }
+ mInFastCacheList = FALSE;
add(LLTextureFetch::sCacheAttempt, 1.0);
LLTimer fastCacheTimer;
- mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel);
- if(mRawImage.notNull())
- {
+ mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel);
+ if(mRawImage.notNull())
+ {
F32 cachReadTime = fastCacheTimer.getElapsedTimeF32();
add(LLTextureFetch::sCacheHit, 1.0);
record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
sample(LLTextureFetch::sCacheReadLatency, cachReadTime);
- mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
- mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
- setTexelsPerImage();
-
- if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
- {
- //discard all oversized textures.
- destroyRawImage();
- LL_WARNS() << "oversized, setting as missing" << LL_ENDL;
- setIsMissingAsset();
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- }
- else
- {
+ mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
+ mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
+ setTexelsPerImage();
+
+ if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
+ {
+ //discard all oversized textures.
+ destroyRawImage();
+ LL_WARNS() << "oversized, setting as missing" << LL_ENDL;
+ setIsMissingAsset();
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ }
+ else
+ {
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
// Shouldn't do anything usefull since texures in fast cache are 16x16,
@@ -1202,11 +1202,11 @@ void LLViewerFetchedTexture::loadFromFastCache()
}
}
- mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
- mIsRawImageValid = TRUE;
- addToCreateTexture();
- }
- }
+ mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
+ mIsRawImageValid = TRUE;
+ addToCreateTexture();
+ }
+ }
else
{
record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
@@ -1215,197 +1215,197 @@ void LLViewerFetchedTexture::loadFromFastCache()
void LLViewerFetchedTexture::setForSculpt()
{
- static const S32 MAX_INTERVAL = 8; //frames
+ static const S32 MAX_INTERVAL = 8; //frames
- mForSculpt = TRUE;
- if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())
- {
- destroyGLTexture(); //sculpt image does not need gl texture.
- mTextureState = ACTIVE;
- }
- checkCachedRawSculptImage();
- setMaxVirtualSizeResetInterval(MAX_INTERVAL);
+ mForSculpt = TRUE;
+ if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())
+ {
+ destroyGLTexture(); //sculpt image does not need gl texture.
+ mTextureState = ACTIVE;
+ }
+ checkCachedRawSculptImage();
+ setMaxVirtualSizeResetInterval(MAX_INTERVAL);
}
BOOL LLViewerFetchedTexture::isForSculptOnly() const
{
- return mForSculpt && !mNeedsGLTexture;
+ return mForSculpt && !mNeedsGLTexture;
}
-BOOL LLViewerFetchedTexture::isDeleted()
-{
- return mTextureState == DELETED;
+BOOL LLViewerFetchedTexture::isDeleted()
+{
+ return mTextureState == DELETED;
}
-BOOL LLViewerFetchedTexture::isInactive()
-{
- return mTextureState == INACTIVE;
+BOOL LLViewerFetchedTexture::isInactive()
+{
+ return mTextureState == INACTIVE;
}
-BOOL LLViewerFetchedTexture::isDeletionCandidate()
-{
- return mTextureState == DELETION_CANDIDATE;
+BOOL LLViewerFetchedTexture::isDeletionCandidate()
+{
+ return mTextureState == DELETION_CANDIDATE;
}
-void LLViewerFetchedTexture::setDeletionCandidate()
-{
- if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE))
- {
- mTextureState = DELETION_CANDIDATE;
- }
+void LLViewerFetchedTexture::setDeletionCandidate()
+{
+ if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE))
+ {
+ mTextureState = DELETION_CANDIDATE;
+ }
}
//set the texture inactive
void LLViewerFetchedTexture::setInactive()
{
- if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently())
- {
- mTextureState = INACTIVE;
- }
+ if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently())
+ {
+ mTextureState = INACTIVE;
+ }
}
BOOL LLViewerFetchedTexture::isFullyLoaded() const
{
- // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic
- // to check if the texture is there and completely downloaded
- return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher;
+ // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic
+ // to check if the texture is there and completely downloaded
+ return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher;
}
// virtual
void LLViewerFetchedTexture::dump()
{
- LLViewerTexture::dump();
-
- LL_INFOS() << "Dump : " << mID
- << ", mIsMissingAsset = " << (S32)mIsMissingAsset
- << ", mFullWidth = " << (S32)mFullWidth
- << ", mFullHeight = " << (S32)mFullHeight
- << ", mOrigWidth = " << (S32)mOrigWidth
- << ", mOrigHeight = " << (S32)mOrigHeight
- << LL_ENDL;
- LL_INFOS() << " : "
- << " mFullyLoaded = " << (S32)mFullyLoaded
- << ", mFetchState = " << (S32)mFetchState
- << ", mFetchPriority = " << (S32)mFetchPriority
- << ", mDownloadProgress = " << (F32)mDownloadProgress
- << LL_ENDL;
- LL_INFOS() << " : "
- << " mHasFetcher = " << (S32)mHasFetcher
- << ", mIsFetching = " << (S32)mIsFetching
- << ", mIsFetched = " << (S32)mIsFetched
- << ", mBoostLevel = " << (S32)mBoostLevel
- << LL_ENDL;
+ LLViewerTexture::dump();
+
+ LL_INFOS() << "Dump : " << mID
+ << ", mIsMissingAsset = " << (S32)mIsMissingAsset
+ << ", mFullWidth = " << (S32)mFullWidth
+ << ", mFullHeight = " << (S32)mFullHeight
+ << ", mOrigWidth = " << (S32)mOrigWidth
+ << ", mOrigHeight = " << (S32)mOrigHeight
+ << LL_ENDL;
+ LL_INFOS() << " : "
+ << " mFullyLoaded = " << (S32)mFullyLoaded
+ << ", mFetchState = " << (S32)mFetchState
+ << ", mFetchPriority = " << (S32)mFetchPriority
+ << ", mDownloadProgress = " << (F32)mDownloadProgress
+ << LL_ENDL;
+ LL_INFOS() << " : "
+ << " mHasFetcher = " << (S32)mHasFetcher
+ << ", mIsFetching = " << (S32)mIsFetching
+ << ", mIsFetched = " << (S32)mIsFetched
+ << ", mBoostLevel = " << (S32)mBoostLevel
+ << LL_ENDL;
}
///////////////////////////////////////////////////////////////////////////////
// ONLY called from LLViewerFetchedTextureList
-void LLViewerFetchedTexture::destroyTexture()
+void LLViewerFetchedTexture::destroyTexture()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (mNeedsCreateTexture)//return if in the process of generating a new texture.
- {
- return;
- }
+ if (mNeedsCreateTexture)//return if in the process of generating a new texture.
+ {
+ return;
+ }
- //LL_DEBUGS("Avatar") << mID << LL_ENDL;
- destroyGLTexture();
- mFullyLoaded = FALSE;
+ //LL_DEBUGS("Avatar") << mID << LL_ENDL;
+ destroyGLTexture();
+ mFullyLoaded = FALSE;
}
void LLViewerFetchedTexture::addToCreateTexture()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- bool force_update = false;
- if (getComponents() != mRawImage->getComponents())
- {
- // We've changed the number of components, so we need to move any
- // objects using this pool to a different pool.
- mComponents = mRawImage->getComponents();
- mGLTexturep->setComponents(mComponents);
- force_update = true;
-
- for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
- {
- llassert(mNumFaces[j] <= mFaceList[j].size());
-
- for(U32 i = 0; i < mNumFaces[j]; i++)
- {
- mFaceList[j][i]->dirtyTexture();
- }
- }
-
- //discard the cached raw image and the saved raw image
- mCachedRawImageReady = FALSE;
- mCachedRawDiscardLevel = -1;
- mCachedRawImage = NULL;
- mSavedRawDiscardLevel = -1;
- mSavedRawImage = NULL;
- }
-
- if(isForSculptOnly())
- {
- //just update some variables, not to create a real GL texture.
- createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE);
- mNeedsCreateTexture = false;
- destroyRawImage();
- }
- else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel)
- {
- mNeedsCreateTexture = false;
- destroyRawImage();
- }
- else
- {
+ bool force_update = false;
+ if (getComponents() != mRawImage->getComponents())
+ {
+ // We've changed the number of components, so we need to move any
+ // objects using this pool to a different pool.
+ mComponents = mRawImage->getComponents();
+ mGLTexturep->setComponents(mComponents);
+ force_update = true;
+
+ for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
+ {
+ llassert(mNumFaces[j] <= mFaceList[j].size());
+
+ for(U32 i = 0; i < mNumFaces[j]; i++)
+ {
+ mFaceList[j][i]->dirtyTexture();
+ }
+ }
+
+ //discard the cached raw image and the saved raw image
+ mCachedRawImageReady = FALSE;
+ mCachedRawDiscardLevel = -1;
+ mCachedRawImage = NULL;
+ mSavedRawDiscardLevel = -1;
+ mSavedRawImage = NULL;
+ }
+
+ if(isForSculptOnly())
+ {
+ //just update some variables, not to create a real GL texture.
+ createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE);
+ mNeedsCreateTexture = false;
+ destroyRawImage();
+ }
+ else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel)
+ {
+ mNeedsCreateTexture = false;
+ destroyRawImage();
+ }
+ else
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
#if 1
- //
- //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
- //so do not scale down the over qualified image.
- //Note: scaling down image is expensensive. Do it only when very necessary.
- //
- if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !mForceToSaveRawImage)
- {
- S32 w = mFullWidth >> mRawDiscardLevel;
- S32 h = mFullHeight >> mRawDiscardLevel;
-
- //if big image, do not load extra data
- //scale it down to size >= LLViewerTexture::sMinLargeImageSize
- if(w * h > LLViewerTexture::sMinLargeImageSize)
- {
- S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel;
-
- if(d_level > 0)
- {
- S32 i = 0;
- while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize))
- {
- i++;
- d_level--;
- }
- if(i > 0)
- {
- mRawDiscardLevel += i;
- if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
- {
- mNeedsCreateTexture = false;
- destroyRawImage();
- return;
- }
-
- {
- //make a duplicate in case somebody else is using this raw image
- mRawImage = mRawImage->scaled(w >> i, h >> i);
- }
- }
- }
- }
- }
+ //
+ //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
+ //so do not scale down the over qualified image.
+ //Note: scaling down image is expensensive. Do it only when very necessary.
+ //
+ if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !mForceToSaveRawImage)
+ {
+ S32 w = mFullWidth >> mRawDiscardLevel;
+ S32 h = mFullHeight >> mRawDiscardLevel;
+
+ //if big image, do not load extra data
+ //scale it down to size >= LLViewerTexture::sMinLargeImageSize
+ if(w * h > LLViewerTexture::sMinLargeImageSize)
+ {
+ S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel;
+
+ if(d_level > 0)
+ {
+ S32 i = 0;
+ while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize))
+ {
+ i++;
+ d_level--;
+ }
+ if(i > 0)
+ {
+ mRawDiscardLevel += i;
+ if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
+ {
+ mNeedsCreateTexture = false;
+ destroyRawImage();
+ return;
+ }
+
+ {
+ //make a duplicate in case somebody else is using this raw image
+ mRawImage = mRawImage->scaled(w >> i, h >> i);
+ }
+ }
+ }
+ }
+ }
#endif
scheduleCreateTexture();
- }
- return;
+ }
+ return;
}
// ONLY called from LLViewerTextureList
@@ -1433,10 +1433,10 @@ BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
destroyRawImage();
return FALSE;
}
- // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
- // mRawDiscardLevel,
- // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
- // << mID.getString() << LL_ENDL;
+ // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
+ // mRawDiscardLevel,
+ // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
+ // << mID.getString() << LL_ENDL;
BOOL res = TRUE;
// store original size only for locally-sourced images
@@ -1532,9 +1532,9 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
- BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
-
- return res;
+ BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
+ return res;
}
void LLViewerFetchedTexture::postCreateTexture()
@@ -1640,15 +1640,15 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(mKnownDrawWidth < width || mKnownDrawHeight < height)
- {
- mKnownDrawWidth = llmax(mKnownDrawWidth, width);
- mKnownDrawHeight = llmax(mKnownDrawHeight, height);
+ if(mKnownDrawWidth < width || mKnownDrawHeight < height)
+ {
+ mKnownDrawWidth = llmax(mKnownDrawWidth, width);
+ mKnownDrawHeight = llmax(mKnownDrawHeight, height);
- mKnownDrawSizeChanged = TRUE;
- mFullyLoaded = FALSE;
- }
- addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
+ mKnownDrawSizeChanged = TRUE;
+ mFullyLoaded = FALSE;
+ }
+ addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
}
void LLViewerFetchedTexture::setDebugText(const std::string& text)
@@ -1676,126 +1676,126 @@ void LLViewerFetchedTexture::setDebugText(const std::string& text)
void LLViewerFetchedTexture::processTextureStats()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(mFullyLoaded)
- {
- if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
- {
- mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
- mFullyLoaded = FALSE;
- }
+ if(mFullyLoaded)
+ {
+ if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
+ {
+ mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
+ mFullyLoaded = FALSE;
+ }
//setDebugText("fully loaded");
- }
- else
- {
- updateVirtualSize();
-
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
-
- if (textures_fullres)
- {
- mDesiredDiscardLevel = 0;
- }
+ }
+ else
+ {
+ updateVirtualSize();
+
+ static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
+
+ if (textures_fullres)
+ {
+ mDesiredDiscardLevel = 0;
+ }
else if (mDontDiscard && (mBoostLevel == LLGLTexture::BOOST_ICON || mBoostLevel == LLGLTexture::BOOST_THUMBNAIL))
{
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
{
- mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+ mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
}
else
{
mDesiredDiscardLevel = 0;
}
}
- else if(!mFullWidth || !mFullHeight)
- {
- mDesiredDiscardLevel = llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel);
- }
- else
- {
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
- {
- if (mFullWidth > desired_size || mFullHeight > desired_size)
- {
- mDesiredDiscardLevel = 1;
- }
- else
- {
- mDesiredDiscardLevel = 0;
- }
- }
- else if(mKnownDrawSizeChanged)//known draw size is set
- {
- mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2,
- log((F32)mFullHeight / mKnownDrawHeight) / log_2);
- mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel());
- mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
- }
- mKnownDrawSizeChanged = FALSE;
-
- if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
- {
- mFullyLoaded = TRUE;
- }
- }
- }
-
- if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
- {
- mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
- if(getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel)
- {
- mFullyLoaded = FALSE;
- }
- }
+ else if(!mFullWidth || !mFullHeight)
+ {
+ mDesiredDiscardLevel = llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel);
+ }
+ else
+ {
+ U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
+ if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
+ {
+ if (mFullWidth > desired_size || mFullHeight > desired_size)
+ {
+ mDesiredDiscardLevel = 1;
+ }
+ else
+ {
+ mDesiredDiscardLevel = 0;
+ }
+ }
+ else if(mKnownDrawSizeChanged)//known draw size is set
+ {
+ mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2,
+ log((F32)mFullHeight / mKnownDrawHeight) / log_2);
+ mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel());
+ mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
+ }
+ mKnownDrawSizeChanged = FALSE;
+
+ if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
+ {
+ mFullyLoaded = TRUE;
+ }
+ }
+ }
+
+ if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
+ {
+ mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
+ if(getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel)
+ {
+ mFullyLoaded = FALSE;
+ }
+ }
}
//============================================================================
-void LLViewerFetchedTexture::updateVirtualSize()
-{
+void LLViewerFetchedTexture::updateVirtualSize()
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- reorganizeFaceList();
- reorganizeVolumeList();
+ reorganizeFaceList();
+ reorganizeVolumeList();
}
S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()
{
- S32 current_discard = getDiscardLevel();
- if(mForceToSaveRawImage)
- {
- if(mSavedRawDiscardLevel < 0 || current_discard < 0)
- {
- current_discard = -1;
- }
- else
- {
- current_discard = llmax(current_discard, mSavedRawDiscardLevel);
- }
- }
+ S32 current_discard = getDiscardLevel();
+ if(mForceToSaveRawImage)
+ {
+ if(mSavedRawDiscardLevel < 0 || current_discard < 0)
+ {
+ current_discard = -1;
+ }
+ else
+ {
+ current_discard = llmax(current_discard, mSavedRawDiscardLevel);
+ }
+ }
- return current_discard;
+ return current_discard;
}
bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level)
{
- if(debug_level < 0)
- {
- mInDebug = FALSE;
- return false;
- }
- mInDebug = TRUE;
+ if(debug_level < 0)
+ {
+ mInDebug = FALSE;
+ return false;
+ }
+ mInDebug = TRUE;
- mDesiredDiscardLevel = debug_level;
+ mDesiredDiscardLevel = debug_level;
- return true;
+ return true;
}
bool LLViewerFetchedTexture::isActiveFetching()
{
- static LLCachedControl<bool> monitor_enabled(gSavedSettings,"DebugShowTextureInfo");
+ static LLCachedControl<bool> monitor_enabled(gSavedSettings,"DebugShowTextureInfo");
- return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.
+ return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.
}
void LLViewerFetchedTexture::setBoostLevel(S32 level)
@@ -1811,121 +1811,121 @@ void LLViewerFetchedTexture::setBoostLevel(S32 level)
bool LLViewerFetchedTexture::updateFetch()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
-
- if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
- {
- return false;
- }
-
- mFetchState = 0;
- mFetchPriority = 0;
- mFetchDeltaTime = 999999.f;
- mRequestDeltaTime = 999999.f;
+ static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
+
+ if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
+ {
+ return false;
+ }
+
+ mFetchState = 0;
+ mFetchPriority = 0;
+ mFetchDeltaTime = 999999.f;
+ mRequestDeltaTime = 999999.f;
#ifndef LL_RELEASE_FOR_DOWNLOAD
- if (mID == LLAppViewer::getTextureFetch()->mDebugID)
- {
- LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
- }
+ if (mID == LLAppViewer::getTextureFetch()->mDebugID)
+ {
+ LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
+ }
#endif
- if (mNeedsCreateTexture)
- {
+ if (mNeedsCreateTexture)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create");
- // We may be fetching still (e.g. waiting on write)
- // but don't check until we've processed the raw data we have
- return false;
- }
- if (mIsMissingAsset)
- {
+ // We may be fetching still (e.g. waiting on write)
+ // but don't check until we've processed the raw data we have
+ return false;
+ }
+ if (mIsMissingAsset)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset");
- llassert(!mHasFetcher);
- return false; // skip
- }
- if (!mLoadedCallbackList.empty() && mRawImage.notNull())
- {
+ llassert(!mHasFetcher);
+ return false; // skip
+ }
+ if (!mLoadedCallbackList.empty() && mRawImage.notNull())
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");
- return false; // process any raw image data in callbacks before replacing
- }
- if(mInFastCacheList)
- {
+ return false; // process any raw image data in callbacks before replacing
+ }
+ if(mInFastCacheList)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");
- return false;
- }
+ return false;
+ }
if (mGLTexturep.isNull())
{ // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening)
llassert(false);
return false;
}
+
+ S32 current_discard = getCurrentDiscardLevelForFetching();
+ S32 desired_discard = getDesiredDiscardLevel();
+ F32 decode_priority = mMaxVirtualSize;
- S32 current_discard = getCurrentDiscardLevelForFetching();
- S32 desired_discard = getDesiredDiscardLevel();
- F32 decode_priority = mMaxVirtualSize;
-
- if (mIsFetching)
- {
+ if (mIsFetching)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching");
- // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
- S32 fetch_discard = current_discard;
-
- if (mRawImage.notNull()) sRawCount--;
- if (mAuxRawImage.notNull()) sAuxCount--;
- // keep in mind that fetcher still might need raw image, don't modify original
- bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage,
- mLastHttpGetStatus);
- if (mRawImage.notNull()) sRawCount++;
- if (mAuxRawImage.notNull())
- {
- mHasAux = TRUE;
- sAuxCount++;
- }
- if (finished)
- {
- mIsFetching = FALSE;
+ // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
+ S32 fetch_discard = current_discard;
+
+ if (mRawImage.notNull()) sRawCount--;
+ if (mAuxRawImage.notNull()) sAuxCount--;
+ // keep in mind that fetcher still might need raw image, don't modify original
+ bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage,
+ mLastHttpGetStatus);
+ if (mRawImage.notNull()) sRawCount++;
+ if (mAuxRawImage.notNull())
+ {
+ mHasAux = TRUE;
+ sAuxCount++;
+ }
+ if (finished)
+ {
+ mIsFetching = FALSE;
mLastFetchState = -1;
- mLastPacketTimer.reset();
- }
- else
- {
- mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
- }
-
- // We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
- if (mRawImage.notNull())
- {
+ mLastPacketTimer.reset();
+ }
+ else
+ {
+ mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
+ }
+
+ // We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
+ if (mRawImage.notNull())
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image");
- LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
- if (tester)
- {
- mIsFetched = TRUE;
- tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID));
- }
- mRawDiscardLevel = fetch_discard;
- if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
- (current_discard < 0 || mRawDiscardLevel < current_discard))
- {
+ LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
+ if (tester)
+ {
+ mIsFetched = TRUE;
+ tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID));
+ }
+ mRawDiscardLevel = fetch_discard;
+ if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
+ (current_discard < 0 || mRawDiscardLevel < current_discard))
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good");
- mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
- mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
- setTexelsPerImage();
-
- if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
- {
- //discard all oversized textures.
- destroyRawImage();
- LL_WARNS() << "oversize, setting as missing" << LL_ENDL;
- setIsMissingAsset();
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- mIsFetching = FALSE;
- mLastPacketTimer.reset();
- }
- else
- {
- mIsRawImageValid = TRUE;
- addToCreateTexture();
- }
+ mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
+ mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
+ setTexelsPerImage();
+
+ if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
+ {
+ //discard all oversized textures.
+ destroyRawImage();
+ LL_WARNS() << "oversize, setting as missing" << LL_ENDL;
+ setIsMissingAsset();
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ mIsFetching = FALSE;
+ mLastPacketTimer.reset();
+ }
+ else
+ {
+ mIsRawImageValid = TRUE;
+ addToCreateTexture();
+ }
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
@@ -1951,802 +1951,802 @@ bool LLViewerFetchedTexture::updateFetch()
}
}
- return TRUE;
- }
- else
- {
+ return TRUE;
+ }
+ else
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed");
- // Data is ready but we don't need it
- // (received it already while fetcher was writing to disk)
- destroyRawImage();
- return false; // done
- }
- }
-
- if (!mIsFetching)
- {
- if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
- {
- // We finished but received no data
- if (getDiscardLevel() < 0)
- {
- if (getFTType() != FTT_MAP_TILE)
- {
- LL_WARNS() << mID
- << " Fetch failure, setting as missing, decode_priority " << decode_priority
- << " mRawDiscardLevel " << mRawDiscardLevel
- << " current_discard " << current_discard
- << " stats " << mLastHttpGetStatus.toHex()
- << LL_ENDL;
- }
- setIsMissingAsset();
- desired_discard = -1;
- }
- else
- {
- //LL_WARNS() << mID << ": Setting min discard to " << current_discard << LL_ENDL;
- if(current_discard >= 0)
- {
- mMinDiscardLevel = current_discard;
- //desired_discard = current_discard;
- }
- else
- {
- S32 dis_level = getDiscardLevel();
- mMinDiscardLevel = dis_level;
- //desired_discard = dis_level;
- }
- }
- destroyRawImage();
- }
- else if (mRawImage.notNull())
- {
- // We have data, but our fetch failed to return raw data
- // *TODO: FIgure out why this is happening and fix it
- destroyRawImage();
- }
- }
- else
- {
- static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
- if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
- {
- mStopFetchingTimer.reset();
- LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
- }
- }
- }
+ // Data is ready but we don't need it
+ // (received it already while fetcher was writing to disk)
+ destroyRawImage();
+ return false; // done
+ }
+ }
+
+ if (!mIsFetching)
+ {
+ if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
+ {
+ // We finished but received no data
+ if (getDiscardLevel() < 0)
+ {
+ if (getFTType() != FTT_MAP_TILE)
+ {
+ LL_WARNS() << mID
+ << " Fetch failure, setting as missing, decode_priority " << decode_priority
+ << " mRawDiscardLevel " << mRawDiscardLevel
+ << " current_discard " << current_discard
+ << " stats " << mLastHttpGetStatus.toHex()
+ << LL_ENDL;
+ }
+ setIsMissingAsset();
+ desired_discard = -1;
+ }
+ else
+ {
+ //LL_WARNS() << mID << ": Setting min discard to " << current_discard << LL_ENDL;
+ if(current_discard >= 0)
+ {
+ mMinDiscardLevel = current_discard;
+ //desired_discard = current_discard;
+ }
+ else
+ {
+ S32 dis_level = getDiscardLevel();
+ mMinDiscardLevel = dis_level;
+ //desired_discard = dis_level;
+ }
+ }
+ destroyRawImage();
+ }
+ else if (mRawImage.notNull())
+ {
+ // We have data, but our fetch failed to return raw data
+ // *TODO: FIgure out why this is happening and fix it
+ destroyRawImage();
+ }
+ }
+ else
+ {
+ static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
+ if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
+ {
+ mStopFetchingTimer.reset();
+ LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
+ }
+ }
+ }
desired_discard = llmin(desired_discard, getMaxDiscardLevel());
- bool make_request = true;
- if (decode_priority <= 0)
- {
+ bool make_request = true;
+ if (decode_priority <= 0)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
- make_request = false;
- }
- else if(mDesiredDiscardLevel > getMaxDiscardLevel())
- {
+ make_request = false;
+ }
+ else if(mDesiredDiscardLevel > getMaxDiscardLevel())
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
- make_request = false;
- }
- else if (mNeedsCreateTexture || mIsMissingAsset)
- {
+ make_request = false;
+ }
+ else if (mNeedsCreateTexture || mIsMissingAsset)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
- make_request = false;
- }
- else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
- {
+ make_request = false;
+ }
+ else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");
- make_request = false;
- }
- else if(mCachedRawImage.notNull() // can be empty
- && mCachedRawImageReady
- && (current_discard < 0 || current_discard > mCachedRawDiscardLevel))
- {
- make_request = false;
- switchToCachedImage(); //use the cached raw data first
- }
-
- if (make_request)
- {
- if (mIsFetching)
- {
+ make_request = false;
+ }
+ else if(mCachedRawImage.notNull() // can be empty
+ && mCachedRawImageReady
+ && (current_discard < 0 || current_discard > mCachedRawDiscardLevel))
+ {
+ make_request = false;
+ switchToCachedImage(); //use the cached raw data first
+ }
+
+ if (make_request)
+ {
+ if (mIsFetching)
+ {
// already requested a higher resolution mip
- if (mRequestedDiscardLevel <= desired_discard)
- {
+ if (mRequestedDiscardLevel <= desired_discard)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired");
- make_request = false;
- }
- }
- else
- {
+ make_request = false;
+ }
+ }
+ else
+ {
// already at a higher resolution mip, don't discard
- if (current_discard >= 0 && current_discard <= desired_discard)
- {
+ if (current_discard >= 0 && current_discard <= desired_discard)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired");
- make_request = false;
- }
- }
- }
-
- if (make_request)
- {
+ make_request = false;
+ }
+ }
+ }
+
+ if (make_request)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");
- S32 w=0, h=0, c=0;
- if (getDiscardLevel() >= 0)
- {
- w = mGLTexturep->getWidth(0);
- h = mGLTexturep->getHeight(0);
- c = mComponents;
- }
-
- const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
- if (override_tex_discard_level != 0)
- {
- desired_discard = override_tex_discard_level;
- }
-
- // bypass texturefetch directly by pulling from LLTextureCache
- S32 fetch_request_discard = -1;
+ S32 w=0, h=0, c=0;
+ if (getDiscardLevel() >= 0)
+ {
+ w = mGLTexturep->getWidth(0);
+ h = mGLTexturep->getHeight(0);
+ c = mComponents;
+ }
+
+ const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
+ if (override_tex_discard_level != 0)
+ {
+ desired_discard = override_tex_discard_level;
+ }
+
+ // bypass texturefetch directly by pulling from LLTextureCache
+ S32 fetch_request_discard = -1;
fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
- w, h, c, desired_discard, needsAux(), mCanUseHTTP);
-
- if (fetch_request_discard >= 0)
- {
+ w, h, c, desired_discard, needsAux(), mCanUseHTTP);
+
+ if (fetch_request_discard >= 0)
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
- mHasFetcher = TRUE;
- mIsFetching = TRUE;
+ mHasFetcher = TRUE;
+ mIsFetching = TRUE;
// in some cases createRequest can modify discard, as an example
// bake textures are always at discard 0
mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard);
- mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
- mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
- }
+ mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
+ }
// If createRequest() failed, that means one of two things:
// 1. We're finishing up a request for this UUID, so we
// should wait for it to complete
// 2. We've failed a request for this UUID, so there is
// no need to create another request
- }
- else if (mHasFetcher && !mIsFetching)
- {
- // Only delete requests that haven't received any network data
- // for a while. Note - this is the normal mechanism for
- // deleting requests, not just a place to handle timeouts.
- const F32 FETCH_IDLE_TIME = 0.1f;
- if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
- {
- LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL;
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- mHasFetcher = FALSE;
- }
- }
-
- return mIsFetching ? true : false;
+ }
+ else if (mHasFetcher && !mIsFetching)
+ {
+ // Only delete requests that haven't received any network data
+ // for a while. Note - this is the normal mechanism for
+ // deleting requests, not just a place to handle timeouts.
+ const F32 FETCH_IDLE_TIME = 0.1f;
+ if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
+ {
+ LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL;
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ mHasFetcher = FALSE;
+ }
+ }
+
+ return mIsFetching ? true : false;
}
void LLViewerFetchedTexture::clearFetchedResults()
{
- if(mNeedsCreateTexture || mIsFetching)
- {
- return;
- }
+ if(mNeedsCreateTexture || mIsFetching)
+ {
+ return;
+ }
+
+ cleanup();
+ destroyGLTexture();
- cleanup();
- destroyGLTexture();
-
- if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate
- {
- mGLTexturep->forceToInvalidateGLTexture();
- }
+ if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate
+ {
+ mGLTexturep->forceToInvalidateGLTexture();
+ }
}
void LLViewerFetchedTexture::forceToDeleteRequest()
{
- if (mHasFetcher)
- {
- mHasFetcher = FALSE;
- mIsFetching = FALSE;
- }
-
- resetTextureStats();
+ if (mHasFetcher)
+ {
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE;
+ }
+
+ resetTextureStats();
- mDesiredDiscardLevel = getMaxDiscardLevel() + 1;
+ mDesiredDiscardLevel = getMaxDiscardLevel() + 1;
}
void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
{
- if (is_missing == mIsMissingAsset)
- {
- return;
- }
- if (is_missing)
- {
- if (mUrl.empty())
- {
- LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
- }
- else
- {
- // This may or may not be an error - it is normal to have no
- // map tile on an empty region, but bad if we're failing on a
- // server bake texture.
- if (getFTType() != FTT_MAP_TILE)
- {
- LL_WARNS() << mUrl << ": Marking image as missing" << LL_ENDL;
- }
- }
- if (mHasFetcher)
- {
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
- mHasFetcher = FALSE;
- mIsFetching = FALSE;
- mLastPacketTimer.reset();
- mFetchState = 0;
- mFetchPriority = 0;
- }
- }
- else
- {
- LL_INFOS() << mID << ": un-flagging missing asset" << LL_ENDL;
- }
- mIsMissingAsset = is_missing;
+ if (is_missing == mIsMissingAsset)
+ {
+ return;
+ }
+ if (is_missing)
+ {
+ if (mUrl.empty())
+ {
+ LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
+ }
+ else
+ {
+ // This may or may not be an error - it is normal to have no
+ // map tile on an empty region, but bad if we're failing on a
+ // server bake texture.
+ if (getFTType() != FTT_MAP_TILE)
+ {
+ LL_WARNS() << mUrl << ": Marking image as missing" << LL_ENDL;
+ }
+ }
+ if (mHasFetcher)
+ {
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE;
+ mLastPacketTimer.reset();
+ mFetchState = 0;
+ mFetchPriority = 0;
+ }
+ }
+ else
+ {
+ LL_INFOS() << mID << ": un-flagging missing asset" << LL_ENDL;
+ }
+ mIsMissingAsset = is_missing;
}
void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
- S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,
- LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)
-{
- //
- // Don't do ANYTHING here, just add it to the global callback list
- //
- if (mLoadedCallbackList.empty())
- {
- // Put in list to call this->doLoadedCallbacks() periodically
- gTextureList.mCallbackList.insert(this);
- mLoadedCallbackDesiredDiscardLevel = (S8)discard_level;
- }
- else
- {
- mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level);
- }
-
- if(mPauseLoadedCallBacks)
- {
- if(!pause)
- {
- unpauseLoadedCallbacks(src_callback_list);
- }
- }
- else if(pause)
- {
- pauseLoadedCallbacks(src_callback_list);
- }
-
- LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
- mLoadedCallbackList.push_back(entryp);
-
- mNeedsAux |= needs_aux;
- if(keep_imageraw)
- {
- mSaveRawImage = TRUE;
- }
- if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
- {
- if(mHasAux)
- {
- //trigger a refetch
- forceToRefetchTexture();
- }
- else
- {
- // We need aux data, but we've already loaded the image, and it didn't have any
- LL_WARNS() << "No aux data available for callback for image:" << getID() << LL_ENDL;
- }
- }
- mLastCallBackActiveTime = sCurrentTime ;
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,
+ LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)
+{
+ //
+ // Don't do ANYTHING here, just add it to the global callback list
+ //
+ if (mLoadedCallbackList.empty())
+ {
+ // Put in list to call this->doLoadedCallbacks() periodically
+ gTextureList.mCallbackList.insert(this);
+ mLoadedCallbackDesiredDiscardLevel = (S8)discard_level;
+ }
+ else
+ {
+ mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level);
+ }
+
+ if(mPauseLoadedCallBacks)
+ {
+ if(!pause)
+ {
+ unpauseLoadedCallbacks(src_callback_list);
+ }
+ }
+ else if(pause)
+ {
+ pauseLoadedCallbacks(src_callback_list);
+ }
+
+ LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
+ mLoadedCallbackList.push_back(entryp);
+
+ mNeedsAux |= needs_aux;
+ if(keep_imageraw)
+ {
+ mSaveRawImage = TRUE;
+ }
+ if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
+ {
+ if(mHasAux)
+ {
+ //trigger a refetch
+ forceToRefetchTexture();
+ }
+ else
+ {
+ // We need aux data, but we've already loaded the image, and it didn't have any
+ LL_WARNS() << "No aux data available for callback for image:" << getID() << LL_ENDL;
+ }
+ }
+ mLastCallBackActiveTime = sCurrentTime ;
mLastReferencedSavedRawImageTime = sCurrentTime;
}
void LLViewerFetchedTexture::clearCallbackEntryList()
{
- if(mLoadedCallbackList.empty())
- {
- return;
- }
-
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter;
-
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
- iter = mLoadedCallbackList.erase(iter);
- delete entryp;
- }
- gTextureList.mCallbackList.erase(this);
-
- mLoadedCallbackDesiredDiscardLevel = S8_MAX;
- if(needsToSaveRawImage())
- {
- destroySavedRawImage();
- }
-
- return;
+ if(mLoadedCallbackList.empty())
+ {
+ return;
+ }
+
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter;
+
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
+ iter = mLoadedCallbackList.erase(iter);
+ delete entryp;
+ }
+ gTextureList.mCallbackList.erase(this);
+
+ mLoadedCallbackDesiredDiscardLevel = S8_MAX;
+ if(needsToSaveRawImage())
+ {
+ destroySavedRawImage();
+ }
+
+ return;
}
void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
- if(mLoadedCallbackList.empty() || !callback_list)
- {
- return;
- }
-
- S32 desired_discard = S8_MAX;
- S32 desired_raw_discard = INVALID_DISCARD_LEVEL;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter;
- if(entryp->mSourceCallbackList == callback_list)
- {
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
- iter = mLoadedCallbackList.erase(iter);
- delete entryp;
- }
- else
- {
- ++iter;
-
- desired_discard = llmin(desired_discard, entryp->mDesiredDiscard);
- if(entryp->mNeedsImageRaw)
- {
- desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard);
- }
- }
- }
-
- mLoadedCallbackDesiredDiscardLevel = desired_discard;
- if (mLoadedCallbackList.empty())
- {
- // If we have no callbacks, take us off of the image callback list.
- gTextureList.mCallbackList.erase(this);
-
- if(needsToSaveRawImage())
- {
- destroySavedRawImage();
- }
- }
- else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW)
- {
- if(desired_raw_discard != INVALID_DISCARD_LEVEL)
- {
- mDesiredSavedRawDiscardLevel = desired_raw_discard;
- }
- else
- {
- destroySavedRawImage();
- }
- }
+ if(mLoadedCallbackList.empty() || !callback_list)
+ {
+ return;
+ }
+
+ S32 desired_discard = S8_MAX;
+ S32 desired_raw_discard = INVALID_DISCARD_LEVEL;
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter;
+ if(entryp->mSourceCallbackList == callback_list)
+ {
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
+ iter = mLoadedCallbackList.erase(iter);
+ delete entryp;
+ }
+ else
+ {
+ ++iter;
+
+ desired_discard = llmin(desired_discard, entryp->mDesiredDiscard);
+ if(entryp->mNeedsImageRaw)
+ {
+ desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard);
+ }
+ }
+ }
+
+ mLoadedCallbackDesiredDiscardLevel = desired_discard;
+ if (mLoadedCallbackList.empty())
+ {
+ // If we have no callbacks, take us off of the image callback list.
+ gTextureList.mCallbackList.erase(this);
+
+ if(needsToSaveRawImage())
+ {
+ destroySavedRawImage();
+ }
+ }
+ else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW)
+ {
+ if(desired_raw_discard != INVALID_DISCARD_LEVEL)
+ {
+ mDesiredSavedRawDiscardLevel = desired_raw_discard;
+ }
+ else
+ {
+ destroySavedRawImage();
+ }
+ }
}
void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
- if(!callback_list)
-{
- mPauseLoadedCallBacks = FALSE;
- return;
- }
-
- BOOL need_raw = FALSE;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- if(entryp->mSourceCallbackList == callback_list)
- {
- entryp->mPaused = FALSE;
- if(entryp->mNeedsImageRaw)
- {
- need_raw = TRUE;
- }
- }
- }
- mPauseLoadedCallBacks = FALSE ;
- mLastCallBackActiveTime = sCurrentTime ;
- mForceCallbackFetch = TRUE;
- if(need_raw)
- {
- mSaveRawImage = TRUE;
- }
+ if(!callback_list)
+{
+ mPauseLoadedCallBacks = FALSE;
+ return;
+ }
+
+ BOOL need_raw = FALSE;
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ if(entryp->mSourceCallbackList == callback_list)
+ {
+ entryp->mPaused = FALSE;
+ if(entryp->mNeedsImageRaw)
+ {
+ need_raw = TRUE;
+ }
+ }
+ }
+ mPauseLoadedCallBacks = FALSE ;
+ mLastCallBackActiveTime = sCurrentTime ;
+ mForceCallbackFetch = TRUE;
+ if(need_raw)
+ {
+ mSaveRawImage = TRUE;
+ }
}
void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
- if(!callback_list)
+ if(!callback_list)
{
- return;
- }
+ return;
+ }
- bool paused = true;
+ bool paused = true;
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- if(entryp->mSourceCallbackList == callback_list)
- {
- entryp->mPaused = TRUE;
- }
- else if(!entryp->mPaused)
- {
- paused = false;
- }
- }
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ if(entryp->mSourceCallbackList == callback_list)
+ {
+ entryp->mPaused = TRUE;
+ }
+ else if(!entryp->mPaused)
+ {
+ paused = false;
+ }
+ }
- if(paused)
- {
- mPauseLoadedCallBacks = TRUE;//when set, loaded callback is paused.
- resetTextureStats();
- mSaveRawImage = FALSE;
- }
+ if(paused)
+ {
+ mPauseLoadedCallBacks = TRUE;//when set, loaded callback is paused.
+ resetTextureStats();
+ mSaveRawImage = FALSE;
+ }
}
bool LLViewerFetchedTexture::doLoadedCallbacks()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds
- static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds
-
- if (mNeedsCreateTexture)
- {
- return false;
- }
- if(mPauseLoadedCallBacks)
- {
- destroyRawImage();
- return false; //paused
- }
- if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching)
- {
- if (mFTType == FTT_SERVER_BAKE)
- {
- //output some debug info
- LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;
- LL_INFOS() << mUrl << LL_ENDL;
- LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() <<
- " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;
- }
-
- clearCallbackEntryList() ; //remove all callbacks.
- return false ;
- }
-
- bool res = false;
-
- if (isMissingAsset())
- {
- if (mFTType == FTT_SERVER_BAKE)
- {
- //output some debug info
- LL_INFOS() << "baked texture: " << mID << "is missing." << LL_ENDL;
- LL_INFOS() << mUrl << LL_ENDL;
- }
-
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
- // We never finished loading the image. Indicate failure.
- // Note: this allows mLoadedCallbackUserData to be cleaned up.
- entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
- delete entryp;
- }
- mLoadedCallbackList.clear();
-
- // Remove ourself from the global list of textures with callbacks
- gTextureList.mCallbackList.erase(this);
- return false;
- }
-
- S32 gl_discard = getDiscardLevel();
-
- // If we don't have a legit GL image, set it to be lower than the worst discard level
- if (gl_discard == -1)
- {
- gl_discard = MAX_DISCARD_LEVEL + 1;
- }
-
- //
- // Determine the quality levels of textures that we can provide to callbacks
- // and whether we need to do decompression/readback to get it
- //
- S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard
- S32 best_raw_discard = gl_discard; // Current GL quality level
- S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
- S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
-
- if (mIsRawImageValid)
- {
- // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
- best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
- best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
- current_aux_discard = llmin(current_aux_discard, best_aux_discard);
- }
- else
- {
- // We have no data at all, we need to get it
- // Do this by forcing the best aux discard to be 0.
- best_aux_discard = 0;
- }
-
-
- //
- // See if any of the callbacks would actually run using the data that we can provide,
- // and also determine if we need to perform any readbacks or decodes.
- //
- bool run_gl_callbacks = false;
- bool run_raw_callbacks = false;
- bool need_readback = false;
-
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- LLLoadedCallbackEntry *entryp = *iter++;
-
- if (entryp->mNeedsImageRaw)
- {
- if (mNeedsAux)
- {
- //
- // Need raw and auxiliary channels
- //
- if (entryp->mLastUsedDiscard > current_aux_discard)
- {
- // We have useful data, run the callbacks
- run_raw_callbacks = true;
- }
- }
- else
- {
- if (entryp->mLastUsedDiscard > current_raw_discard)
- {
- // We have useful data, just run the callbacks
- run_raw_callbacks = true;
- }
- else if (entryp->mLastUsedDiscard > best_raw_discard)
- {
- // We can readback data, and then run the callbacks
- need_readback = true;
- run_raw_callbacks = true;
- }
- }
- }
- else
- {
- // Needs just GL
- if (entryp->mLastUsedDiscard > gl_discard)
- {
- // We have enough data, run this callback requiring GL data
- run_gl_callbacks = true;
- }
- }
- }
-
- //
- // Do a readback if required, OR start off a texture decode
- //
- if (need_readback && (getMaxDiscardLevel() > gl_discard))
- {
- // Do a readback to get the GL data into the raw image
- // We have GL data.
-
- destroyRawImage();
- reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
- llassert(mRawImage.notNull());
- llassert(!mNeedsAux || mAuxRawImage.notNull());
- }
-
- //
- // Run raw/auxiliary data callbacks
- //
- if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel()))
- {
- // Do callbacks which require raw image data.
- //LL_INFOS() << "doLoadedCallbacks raw for " << getID() << LL_ENDL;
-
- // Call each party interested in the raw data.
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLLoadedCallbackEntry *entryp = *curiter;
- if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel))
- {
- // If we've loaded all the data there is to load or we've loaded enough
- // to satisfy the interested party, then this is the last time that
- // we're going to call them.
-
- mLastCallBackActiveTime = sCurrentTime;
- if(mNeedsAux && mAuxRawImage.isNull())
- {
- LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL;
- }
- BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
- //LL_INFOS() << "Running callback for " << getID() << LL_ENDL;
- //LL_INFOS() << mRawImage->getWidth() << "x" << mRawImage->getHeight() << LL_ENDL;
- entryp->mLastUsedDiscard = mRawDiscardLevel;
- entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
- if (final)
- {
- iter = mLoadedCallbackList.erase(curiter);
- delete entryp;
- }
- res = true;
- }
- }
- }
-
- //
- // Run GL callbacks
- //
- if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel()))
- {
- //LL_INFOS() << "doLoadedCallbacks GL for " << getID() << LL_ENDL;
-
- // Call the callbacks interested in GL data.
- for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
- iter != mLoadedCallbackList.end(); )
- {
- callback_list_t::iterator curiter = iter++;
- LLLoadedCallbackEntry *entryp = *curiter;
- if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard))
- {
- mLastCallBackActiveTime = sCurrentTime;
- BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE;
- entryp->mLastUsedDiscard = gl_discard;
- entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData);
- if (final)
- {
- iter = mLoadedCallbackList.erase(curiter);
- delete entryp;
- }
- res = true;
- }
- }
- }
-
- // Done with any raw image data at this point (will be re-created if we still have callbacks)
- destroyRawImage();
-
- //
- // If we have no callbacks, take us off of the image callback list.
- //
- if (mLoadedCallbackList.empty())
- {
- gTextureList.mCallbackList.erase(this);
- }
- else if(!res && mForceCallbackFetch && sCurrentTime - mLastCallBackActiveTime > MAX_IDLE_WAIT_TIME && !mIsFetching)
- {
- //wait for long enough but no fetching request issued, force one.
- forceToRefetchTexture(mLoadedCallbackDesiredDiscardLevel, 5.f);
- mForceCallbackFetch = FALSE; //fire once.
- }
-
- return res;
+ static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds
+ static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds
+
+ if (mNeedsCreateTexture)
+ {
+ return false;
+ }
+ if(mPauseLoadedCallBacks)
+ {
+ destroyRawImage();
+ return false; //paused
+ }
+ if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching)
+ {
+ if (mFTType == FTT_SERVER_BAKE)
+ {
+ //output some debug info
+ LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;
+ LL_INFOS() << mUrl << LL_ENDL;
+ LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() <<
+ " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;
+ }
+
+ clearCallbackEntryList() ; //remove all callbacks.
+ return false ;
+ }
+
+ bool res = false;
+
+ if (isMissingAsset())
+ {
+ if (mFTType == FTT_SERVER_BAKE)
+ {
+ //output some debug info
+ LL_INFOS() << "baked texture: " << mID << "is missing." << LL_ENDL;
+ LL_INFOS() << mUrl << LL_ENDL;
+ }
+
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
+ delete entryp;
+ }
+ mLoadedCallbackList.clear();
+
+ // Remove ourself from the global list of textures with callbacks
+ gTextureList.mCallbackList.erase(this);
+ return false;
+ }
+
+ S32 gl_discard = getDiscardLevel();
+
+ // If we don't have a legit GL image, set it to be lower than the worst discard level
+ if (gl_discard == -1)
+ {
+ gl_discard = MAX_DISCARD_LEVEL + 1;
+ }
+
+ //
+ // Determine the quality levels of textures that we can provide to callbacks
+ // and whether we need to do decompression/readback to get it
+ //
+ S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard
+ S32 best_raw_discard = gl_discard; // Current GL quality level
+ S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
+ S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
+
+ if (mIsRawImageValid)
+ {
+ // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
+ best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
+ best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
+ current_aux_discard = llmin(current_aux_discard, best_aux_discard);
+ }
+ else
+ {
+ // We have no data at all, we need to get it
+ // Do this by forcing the best aux discard to be 0.
+ best_aux_discard = 0;
+ }
+
+
+ //
+ // See if any of the callbacks would actually run using the data that we can provide,
+ // and also determine if we need to perform any readbacks or decodes.
+ //
+ bool run_gl_callbacks = false;
+ bool run_raw_callbacks = false;
+ bool need_readback = false;
+
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+
+ if (entryp->mNeedsImageRaw)
+ {
+ if (mNeedsAux)
+ {
+ //
+ // Need raw and auxiliary channels
+ //
+ if (entryp->mLastUsedDiscard > current_aux_discard)
+ {
+ // We have useful data, run the callbacks
+ run_raw_callbacks = true;
+ }
+ }
+ else
+ {
+ if (entryp->mLastUsedDiscard > current_raw_discard)
+ {
+ // We have useful data, just run the callbacks
+ run_raw_callbacks = true;
+ }
+ else if (entryp->mLastUsedDiscard > best_raw_discard)
+ {
+ // We can readback data, and then run the callbacks
+ need_readback = true;
+ run_raw_callbacks = true;
+ }
+ }
+ }
+ else
+ {
+ // Needs just GL
+ if (entryp->mLastUsedDiscard > gl_discard)
+ {
+ // We have enough data, run this callback requiring GL data
+ run_gl_callbacks = true;
+ }
+ }
+ }
+
+ //
+ // Do a readback if required, OR start off a texture decode
+ //
+ if (need_readback && (getMaxDiscardLevel() > gl_discard))
+ {
+ // Do a readback to get the GL data into the raw image
+ // We have GL data.
+
+ destroyRawImage();
+ reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
+ llassert(mRawImage.notNull());
+ llassert(!mNeedsAux || mAuxRawImage.notNull());
+ }
+
+ //
+ // Run raw/auxiliary data callbacks
+ //
+ if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel()))
+ {
+ // Do callbacks which require raw image data.
+ //LL_INFOS() << "doLoadedCallbacks raw for " << getID() << LL_ENDL;
+
+ // Call each party interested in the raw data.
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLLoadedCallbackEntry *entryp = *curiter;
+ if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel))
+ {
+ // If we've loaded all the data there is to load or we've loaded enough
+ // to satisfy the interested party, then this is the last time that
+ // we're going to call them.
+
+ mLastCallBackActiveTime = sCurrentTime;
+ if(mNeedsAux && mAuxRawImage.isNull())
+ {
+ LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL;
+ }
+ BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
+ //LL_INFOS() << "Running callback for " << getID() << LL_ENDL;
+ //LL_INFOS() << mRawImage->getWidth() << "x" << mRawImage->getHeight() << LL_ENDL;
+ entryp->mLastUsedDiscard = mRawDiscardLevel;
+ entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
+ if (final)
+ {
+ iter = mLoadedCallbackList.erase(curiter);
+ delete entryp;
+ }
+ res = true;
+ }
+ }
+ }
+
+ //
+ // Run GL callbacks
+ //
+ if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel()))
+ {
+ //LL_INFOS() << "doLoadedCallbacks GL for " << getID() << LL_ENDL;
+
+ // Call the callbacks interested in GL data.
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLLoadedCallbackEntry *entryp = *curiter;
+ if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard))
+ {
+ mLastCallBackActiveTime = sCurrentTime;
+ BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE;
+ entryp->mLastUsedDiscard = gl_discard;
+ entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData);
+ if (final)
+ {
+ iter = mLoadedCallbackList.erase(curiter);
+ delete entryp;
+ }
+ res = true;
+ }
+ }
+ }
+
+ // Done with any raw image data at this point (will be re-created if we still have callbacks)
+ destroyRawImage();
+
+ //
+ // If we have no callbacks, take us off of the image callback list.
+ //
+ if (mLoadedCallbackList.empty())
+ {
+ gTextureList.mCallbackList.erase(this);
+ }
+ else if(!res && mForceCallbackFetch && sCurrentTime - mLastCallBackActiveTime > MAX_IDLE_WAIT_TIME && !mIsFetching)
+ {
+ //wait for long enough but no fetching request issued, force one.
+ forceToRefetchTexture(mLoadedCallbackDesiredDiscardLevel, 5.f);
+ mForceCallbackFetch = FALSE; //fire once.
+ }
+
+ return res;
}
//virtual
void LLViewerFetchedTexture::forceImmediateUpdate()
{
- //only immediately update a deleted texture which is now being re-used.
- if(!isDeleted())
- {
- return;
- }
- //if already called forceImmediateUpdate()
- if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)
- {
- return;
- }
+ //only immediately update a deleted texture which is now being re-used.
+ if(!isDeleted())
+ {
+ return;
+ }
+ //if already called forceImmediateUpdate()
+ if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)
+ {
+ return;
+ }
- gTextureList.forceImmediateUpdate(this);
- return;
+ gTextureList.forceImmediateUpdate(this);
+ return;
}
LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
{
- llassert(mGLTexturep.notNull());
- llassert(discard_level >= 0);
- llassert(mComponents > 0);
+ llassert(mGLTexturep.notNull());
+ llassert(discard_level >= 0);
+ llassert(mComponents > 0);
- if (mRawImage.notNull())
- {
- //mRawImage is in use by somebody else, do not delete it.
- return NULL;
- }
+ if (mRawImage.notNull())
+ {
+ //mRawImage is in use by somebody else, do not delete it.
+ return NULL;
+ }
- if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
- {
- if (mSavedRawDiscardLevel != discard_level
+ if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
+ {
+ if (mSavedRawDiscardLevel != discard_level
&& mBoostLevel != BOOST_ICON
&& mBoostLevel != BOOST_THUMBNAIL)
- {
- mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
- mRawImage->copy(getSavedRawImage());
- }
- else
- {
- mRawImage = getSavedRawImage();
- }
- mRawDiscardLevel = discard_level;
- }
- else
- {
- //force to fetch raw image again if cached raw image is not good enough.
- if(mCachedRawDiscardLevel > discard_level)
- {
- mRawImage = mCachedRawImage;
- mRawDiscardLevel = mCachedRawDiscardLevel;
- }
- else //cached raw image is good enough, copy it.
- {
- if(mCachedRawDiscardLevel != discard_level)
- {
- mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
- mRawImage->copy(mCachedRawImage);
- }
- else
- {
- mRawImage = mCachedRawImage;
- }
- mRawDiscardLevel = discard_level;
- }
- }
- mIsRawImageValid = TRUE;
- sRawCount++;
-
- return mRawImage;
+ {
+ mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
+ mRawImage->copy(getSavedRawImage());
+ }
+ else
+ {
+ mRawImage = getSavedRawImage();
+ }
+ mRawDiscardLevel = discard_level;
+ }
+ else
+ {
+ //force to fetch raw image again if cached raw image is not good enough.
+ if(mCachedRawDiscardLevel > discard_level)
+ {
+ mRawImage = mCachedRawImage;
+ mRawDiscardLevel = mCachedRawDiscardLevel;
+ }
+ else //cached raw image is good enough, copy it.
+ {
+ if(mCachedRawDiscardLevel != discard_level)
+ {
+ mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
+ mRawImage->copy(mCachedRawImage);
+ }
+ else
+ {
+ mRawImage = mCachedRawImage;
+ }
+ mRawDiscardLevel = discard_level;
+ }
+ }
+ mIsRawImageValid = TRUE;
+ sRawCount++;
+
+ return mRawImage;
}
bool LLViewerFetchedTexture::needsToSaveRawImage()
{
- return mForceToSaveRawImage || mSaveRawImage;
+ return mForceToSaveRawImage || mSaveRawImage;
}
void LLViewerFetchedTexture::destroyRawImage()
-{
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (mAuxRawImage.notNull() && !needsToSaveRawImage())
- {
- sAuxCount--;
- mAuxRawImage = NULL;
- }
-
- if (mRawImage.notNull())
- {
- sRawCount--;
-
- if(mIsRawImageValid)
- {
- if(needsToSaveRawImage())
- {
- saveRawImage();
- }
- setCachedRawImage();
- }
-
- mRawImage = NULL;
-
- mIsRawImageValid = FALSE;
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- }
+ if (mAuxRawImage.notNull() && !needsToSaveRawImage())
+ {
+ sAuxCount--;
+ mAuxRawImage = NULL;
+ }
+
+ if (mRawImage.notNull())
+ {
+ sRawCount--;
+
+ if(mIsRawImageValid)
+ {
+ if(needsToSaveRawImage())
+ {
+ saveRawImage();
+ }
+ setCachedRawImage();
+ }
+
+ mRawImage = NULL;
+
+ mIsRawImageValid = FALSE;
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ }
}
//use the mCachedRawImage to (re)generate the gl texture.
@@ -2754,32 +2754,32 @@ void LLViewerFetchedTexture::destroyRawImage()
void LLViewerFetchedTexture::switchToCachedImage()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(mCachedRawImage.notNull() &&
+ if(mCachedRawImage.notNull() &&
!mNeedsCreateTexture) // <--- texture creation is pending, don't step on it
- {
- mRawImage = mCachedRawImage;
-
- if (getComponents() != mRawImage->getComponents())
- {
- // We've changed the number of components, so we need to move any
- // objects using this pool to a different pool.
- mComponents = mRawImage->getComponents();
- mGLTexturep->setComponents(mComponents);
- gTextureList.dirtyImage(this);
- }
-
- mIsRawImageValid = TRUE;
- mRawDiscardLevel = mCachedRawDiscardLevel;
+ {
+ mRawImage = mCachedRawImage;
+
+ if (getComponents() != mRawImage->getComponents())
+ {
+ // We've changed the number of components, so we need to move any
+ // objects using this pool to a different pool.
+ mComponents = mRawImage->getComponents();
+ mGLTexturep->setComponents(mComponents);
+ gTextureList.dirtyImage(this);
+ }
+
+ mIsRawImageValid = TRUE;
+ mRawDiscardLevel = mCachedRawDiscardLevel;
scheduleCreateTexture();
- }
+ }
}
//cache the imageraw forcefully.
-//virtual
-void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
+//virtual
+void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
{
- if(imageraw != mRawImage.get())
+ if(imageraw != mRawImage.get())
{
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
@@ -2813,96 +2813,96 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
{
mCachedRawImage = imageraw;
}
- mCachedRawDiscardLevel = discard_level;
- mCachedRawImageReady = TRUE;
- }
+ mCachedRawDiscardLevel = discard_level;
+ mCachedRawImageReady = TRUE;
+ }
}
void LLViewerFetchedTexture::setCachedRawImage()
-{
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(mRawImage == mCachedRawImage)
- {
- return;
- }
- if(!mIsRawImageValid)
- {
- return;
- }
-
- if(mCachedRawImageReady)
- {
- return;
- }
-
- if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel)
- {
- S32 i = 0;
- S32 w = mRawImage->getWidth();
- S32 h = mRawImage->getHeight();
-
- S32 max_size = MAX_CACHED_RAW_IMAGE_AREA;
- if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
- {
- max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA;
- }
- if(mForSculpt)
- {
- max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA;
- mCachedRawImageReady = !mRawDiscardLevel;
- }
- else
- {
- mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size));
- }
-
- while(((w >> i) * (h >> i)) > max_size)
- {
- ++i;
- }
-
- if(i)
- {
- if(!(w >> i) || !(h >> i))
- {
- --i;
- }
-
- {
- //make a duplicate in case somebody else is using this raw image
- mRawImage = mRawImage->scaled(w >> i, h >> i);
- }
- }
- mCachedRawImage = mRawImage;
- mRawDiscardLevel += i;
- mCachedRawDiscardLevel = mRawDiscardLevel;
- }
+ if(mRawImage == mCachedRawImage)
+ {
+ return;
+ }
+ if(!mIsRawImageValid)
+ {
+ return;
+ }
+
+ if(mCachedRawImageReady)
+ {
+ return;
+ }
+
+ if(mCachedRawDiscardLevel < 0 || mCachedRawDiscardLevel > mRawDiscardLevel)
+ {
+ S32 i = 0;
+ S32 w = mRawImage->getWidth();
+ S32 h = mRawImage->getHeight();
+
+ S32 max_size = MAX_CACHED_RAW_IMAGE_AREA;
+ if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
+ {
+ max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA;
+ }
+ if(mForSculpt)
+ {
+ max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA;
+ mCachedRawImageReady = !mRawDiscardLevel;
+ }
+ else
+ {
+ mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size));
+ }
+
+ while(((w >> i) * (h >> i)) > max_size)
+ {
+ ++i;
+ }
+
+ if(i)
+ {
+ if(!(w >> i) || !(h >> i))
+ {
+ --i;
+ }
+
+ {
+ //make a duplicate in case somebody else is using this raw image
+ mRawImage = mRawImage->scaled(w >> i, h >> i);
+ }
+ }
+ mCachedRawImage = mRawImage;
+ mRawDiscardLevel += i;
+ mCachedRawDiscardLevel = mRawDiscardLevel;
+ }
}
void LLViewerFetchedTexture::checkCachedRawSculptImage()
{
- if(mCachedRawImageReady && mCachedRawDiscardLevel > 0)
- {
- if(getDiscardLevel() != 0)
- {
- mCachedRawImageReady = FALSE;
- }
- else if(isForSculptOnly())
- {
- resetTextureStats(); //do not update this image any more.
- }
- }
+ if(mCachedRawImageReady && mCachedRawDiscardLevel > 0)
+ {
+ if(getDiscardLevel() != 0)
+ {
+ mCachedRawImageReady = FALSE;
+ }
+ else if(isForSculptOnly())
+ {
+ resetTextureStats(); //do not update this image any more.
+ }
+ }
}
-void LLViewerFetchedTexture::saveRawImage()
+void LLViewerFetchedTexture::saveRawImage()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))
- {
- return;
- }
+ if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))
+ {
+ return;
+ }
- mSavedRawDiscardLevel = mRawDiscardLevel;
+ mSavedRawDiscardLevel = mRawDiscardLevel;
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
@@ -2936,102 +2936,102 @@ void LLViewerFetchedTexture::saveRawImage()
mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
}
- if(mForceToSaveRawImage && mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel)
- {
- mForceToSaveRawImage = FALSE;
- }
+ if(mForceToSaveRawImage && mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel)
+ {
+ mForceToSaveRawImage = FALSE;
+ }
- mLastReferencedSavedRawImageTime = sCurrentTime;
+ mLastReferencedSavedRawImageTime = sCurrentTime;
}
-//force to refetch the texture to the discard level
+//force to refetch the texture to the discard level
void LLViewerFetchedTexture::forceToRefetchTexture(S32 desired_discard, F32 kept_time)
{
- if(mForceToSaveRawImage)
- {
- desired_discard = llmin(desired_discard, mDesiredSavedRawDiscardLevel);
- kept_time = llmax(kept_time, mKeptSavedRawImageTime);
- }
-
- //trigger a new fetch.
- mForceToSaveRawImage = TRUE ;
- mDesiredSavedRawDiscardLevel = desired_discard ;
- mKeptSavedRawImageTime = kept_time ;
- mLastReferencedSavedRawImageTime = sCurrentTime ;
- mSavedRawImage = NULL ;
- mSavedRawDiscardLevel = -1 ;
-}
-
-void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time)
-{
- mKeptSavedRawImageTime = kept_time;
- mLastReferencedSavedRawImageTime = sCurrentTime;
-
- if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard)
- {
- return; //raw imge is ready.
- }
-
- if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard)
- {
- mForceToSaveRawImage = TRUE;
- mDesiredSavedRawDiscardLevel = desired_discard;
-
- //copy from the cached raw image if exists.
- if(mCachedRawImage.notNull() && mRawImage.isNull() )
- {
- mRawImage = mCachedRawImage;
- mRawDiscardLevel = mCachedRawDiscardLevel;
-
- saveRawImage();
-
- mRawImage = NULL;
- mRawDiscardLevel = INVALID_DISCARD_LEVEL;
- }
- }
+ if(mForceToSaveRawImage)
+ {
+ desired_discard = llmin(desired_discard, mDesiredSavedRawDiscardLevel);
+ kept_time = llmax(kept_time, mKeptSavedRawImageTime);
+ }
+
+ //trigger a new fetch.
+ mForceToSaveRawImage = TRUE ;
+ mDesiredSavedRawDiscardLevel = desired_discard ;
+ mKeptSavedRawImageTime = kept_time ;
+ mLastReferencedSavedRawImageTime = sCurrentTime ;
+ mSavedRawImage = NULL ;
+ mSavedRawDiscardLevel = -1 ;
+}
+
+void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time)
+{
+ mKeptSavedRawImageTime = kept_time;
+ mLastReferencedSavedRawImageTime = sCurrentTime;
+
+ if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard)
+ {
+ return; //raw imge is ready.
+ }
+
+ if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard)
+ {
+ mForceToSaveRawImage = TRUE;
+ mDesiredSavedRawDiscardLevel = desired_discard;
+
+ //copy from the cached raw image if exists.
+ if(mCachedRawImage.notNull() && mRawImage.isNull() )
+ {
+ mRawImage = mCachedRawImage;
+ mRawDiscardLevel = mCachedRawDiscardLevel;
+
+ saveRawImage();
+
+ mRawImage = NULL;
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ }
+ }
}
void LLViewerFetchedTexture::destroySavedRawImage()
{
- if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime)
- {
- return; //keep the saved raw image.
- }
-
- mForceToSaveRawImage = FALSE;
- mSaveRawImage = FALSE;
-
- clearCallbackEntryList();
+ if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime)
+ {
+ return; //keep the saved raw image.
+ }
- mSavedRawImage = NULL ;
- mForceToSaveRawImage = FALSE ;
- mSaveRawImage = FALSE ;
- mSavedRawDiscardLevel = -1 ;
- mDesiredSavedRawDiscardLevel = -1 ;
- mLastReferencedSavedRawImageTime = 0.0f ;
- mKeptSavedRawImageTime = 0.f ;
+ mForceToSaveRawImage = FALSE;
+ mSaveRawImage = FALSE;
- if(mAuxRawImage.notNull())
- {
- sAuxCount--;
- mAuxRawImage = NULL;
- }
+ clearCallbackEntryList();
+
+ mSavedRawImage = NULL ;
+ mForceToSaveRawImage = FALSE ;
+ mSaveRawImage = FALSE ;
+ mSavedRawDiscardLevel = -1 ;
+ mDesiredSavedRawDiscardLevel = -1 ;
+ mLastReferencedSavedRawImageTime = 0.0f ;
+ mKeptSavedRawImageTime = 0.f ;
+
+ if(mAuxRawImage.notNull())
+ {
+ sAuxCount--;
+ mAuxRawImage = NULL;
+ }
}
-LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()
+LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()
{
- mLastReferencedSavedRawImageTime = sCurrentTime;
+ mLastReferencedSavedRawImageTime = sCurrentTime;
- return mSavedRawImage;
+ return mSavedRawImage;
}
-
+
BOOL LLViewerFetchedTexture::hasSavedRawImage() const
{
- return mSavedRawImage.notNull();
+ return mSavedRawImage.notNull();
}
-
+
F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
-{
- return sCurrentTime - mLastReferencedSavedRawImageTime;
+{
+ return sCurrentTime - mLastReferencedSavedRawImageTime;
}
//----------------------------------------------------------------------------------------------
@@ -3042,33 +3042,33 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
//start of LLViewerLODTexture
//----------------------------------------------------------------------------------------------
LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
- : LLViewerFetchedTexture(id, f_type, host, usemipmaps)
+ : LLViewerFetchedTexture(id, f_type, host, usemipmaps)
{
- init(TRUE);
+ init(TRUE);
}
LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
- : LLViewerFetchedTexture(url, f_type, id, usemipmaps)
+ : LLViewerFetchedTexture(url, f_type, id, usemipmaps)
{
- init(TRUE);
+ init(TRUE);
}
void LLViewerLODTexture::init(bool firstinit)
{
- mTexelsPerImage = 64.f*64.f;
- mDiscardVirtualSize = 0.f;
- mCalculatedDiscardLevel = -1.f;
+ mTexelsPerImage = 64.f*64.f;
+ mDiscardVirtualSize = 0.f;
+ mCalculatedDiscardLevel = -1.f;
}
-//virtual
+//virtual
S8 LLViewerLODTexture::getType() const
{
- return LLViewerTexture::LOD_TEXTURE;
+ return LLViewerTexture::LOD_TEXTURE;
}
bool LLViewerLODTexture::isUpdateFrozen()
{
- return LLViewerTexture::sFreezeImageUpdates;
+ return LLViewerTexture::sFreezeImageUpdates;
}
// This is gauranteed to get called periodically for every texture
@@ -3076,30 +3076,38 @@ bool LLViewerLODTexture::isUpdateFrozen()
void LLViewerLODTexture::processTextureStats()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- updateVirtualSize();
-
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
-
- if (textures_fullres)
- {
- mDesiredDiscardLevel = 0;
- }
- // Generate the request priority and render priority
- else if (mDontDiscard || !mUseMipMaps)
- {
- mDesiredDiscardLevel = 0;
- if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
- mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- }
- else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
- {
- // If the image has not been significantly visible in a while, we don't want it
- mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
- }
- else if (!mFullWidth || !mFullHeight)
- {
- mDesiredDiscardLevel = getMaxDiscardLevel();
- }
+ updateVirtualSize();
+
+ static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
+
+ { // restrict texture resolution to download based on RenderMaxTextureResolution
+ static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
+ // sanity clamp debug setting to avoid settings hack shenanigans
+ F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048);
+ tex_res *= tex_res;
+ mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res);
+ }
+
+ if (textures_fullres)
+ {
+ mDesiredDiscardLevel = 0;
+ }
+ // Generate the request priority and render priority
+ else if (mDontDiscard || !mUseMipMaps)
+ {
+ mDesiredDiscardLevel = 0;
+ if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+ mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
+ }
+ else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
+ {
+ // If the image has not been significantly visible in a while, we don't want it
+ mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
+ }
+ else if (!mFullWidth || !mFullHeight)
+ {
+ mDesiredDiscardLevel = getMaxDiscardLevel();
+ }
else
{
//static const F64 log_2 = log(2.0);
@@ -3134,7 +3142,7 @@ void LLViewerLODTexture::processTextureStats()
discard_level = floorf(discard_level);
F32 min_discard = 0.f;
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+ U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
{
desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
@@ -3156,7 +3164,7 @@ void LLViewerLODTexture::processTextureStats()
//
S32 current_discard = getDiscardLevel();
- if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED &&
+ if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED &&
current_discard >= 0)
{
if (current_discard < (mDesiredDiscardLevel-1) && !mForceToSaveRawImage)
@@ -3165,19 +3173,19 @@ void LLViewerLODTexture::processTextureStats()
}
}
- if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
- && mBoostLevel < LLGLTexture::BOOST_SCULPTED
- && mDesiredDiscardLevel < current_discard)
- {
- // stop requesting more
- mDesiredDiscardLevel = current_discard;
- }
- }
+ if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
+ && mBoostLevel < LLGLTexture::BOOST_SCULPTED
+ && mDesiredDiscardLevel < current_discard)
+ {
+ // stop requesting more
+ mDesiredDiscardLevel = current_discard;
+ }
+ }
- if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
- {
- mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
- }
+ if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
+ {
+ mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
+ }
// decay max virtual size over time
mMaxVirtualSize *= 0.8f;
@@ -3192,19 +3200,19 @@ void LLViewerLODTexture::processTextureStats()
bool LLViewerLODTexture::scaleDown()
{
- if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
- {
- switchToCachedImage();
+ if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
+ {
+ switchToCachedImage();
- LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
- if (tester)
- {
- tester->setStablizingTime();
- }
+ LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
+ if (tester)
+ {
+ tester->setStablizingTime();
+ }
- return true;
- }
- return false;
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------------------------------------
//end of LLViewerLODTexture
@@ -3217,182 +3225,182 @@ bool LLViewerLODTexture::scaleDown()
void LLViewerMediaTexture::updateClass()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static const F32 MAX_INACTIVE_TIME = 30.f;
+ static const F32 MAX_INACTIVE_TIME = 30.f;
#if 0
- //force to play media.
- gSavedSettings.setBOOL("AudioStreamingMedia", true);
+ //force to play media.
+ gSavedSettings.setBOOL("AudioStreamingMedia", true);
#endif
- for(media_map_t::iterator iter = sMediaMap.begin(); iter != sMediaMap.end(); )
- {
- LLViewerMediaTexture* mediap = iter->second;
-
- if(mediap->getNumRefs() == 1) //one reference by sMediaMap
- {
- //
- //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
- //
- if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
- {
- media_map_t::iterator cur = iter++;
- sMediaMap.erase(cur);
- continue;
- }
- }
- ++iter;
- }
-}
-
-//static
-void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
-{
- LLViewerMediaTexture* media_tex = findMediaTexture(media_id);
- if(media_tex)
- {
- media_tex->invalidateMediaImpl();
- }
+ for(media_map_t::iterator iter = sMediaMap.begin(); iter != sMediaMap.end(); )
+ {
+ LLViewerMediaTexture* mediap = iter->second;
+
+ if(mediap->getNumRefs() == 1) //one reference by sMediaMap
+ {
+ //
+ //Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
+ //
+ if(mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
+ {
+ media_map_t::iterator cur = iter++;
+ sMediaMap.erase(cur);
+ continue;
+ }
+ }
+ ++iter;
+ }
+}
+
+//static
+void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
+{
+ LLViewerMediaTexture* media_tex = findMediaTexture(media_id);
+ if(media_tex)
+ {
+ media_tex->invalidateMediaImpl();
+ }
}
//static
void LLViewerMediaTexture::cleanUpClass()
{
- sMediaMap.clear();
+ sMediaMap.clear();
}
//static
LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
{
- media_map_t::iterator iter = sMediaMap.find(media_id);
- if(iter == sMediaMap.end())
- {
- return NULL;
- }
+ media_map_t::iterator iter = sMediaMap.find(media_id);
+ if(iter == sMediaMap.end())
+ {
+ return NULL;
+ }
- LLViewerMediaTexture* media_tex = iter->second;
- media_tex->setMediaImpl();
- media_tex->getLastReferencedTimer()->reset();
+ LLViewerMediaTexture* media_tex = iter->second;
+ media_tex->setMediaImpl();
+ media_tex->getLastReferencedTimer()->reset();
- return media_tex;
+ return media_tex;
}
-LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
- : LLViewerTexture(id, usemipmaps),
- mMediaImplp(NULL),
- mUpdateVirtualSizeTime(0)
+LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
+ : LLViewerTexture(id, usemipmaps),
+ mMediaImplp(NULL),
+ mUpdateVirtualSizeTime(0)
{
- sMediaMap.insert(std::make_pair(id, this));
+ sMediaMap.insert(std::make_pair(id, this));
- mGLTexturep = gl_image;
+ mGLTexturep = gl_image;
- if(mGLTexturep.isNull())
- {
- generateGLTexture();
- }
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture();
+ }
- mGLTexturep->setAllowCompression(false);
+ mGLTexturep->setAllowCompression(false);
- mGLTexturep->setNeedsAlphaAndPickMask(FALSE);
+ mGLTexturep->setNeedsAlphaAndPickMask(FALSE);
- mIsPlaying = FALSE;
+ mIsPlaying = FALSE;
- setMediaImpl();
+ setMediaImpl();
- setCategory(LLGLTexture::MEDIA);
-
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
- if(tex) //this media is a parcel media for tex.
- {
- tex->setParcelMedia(this);
- }
+ setCategory(LLGLTexture::MEDIA);
+
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
+ if(tex) //this media is a parcel media for tex.
+ {
+ tex->setParcelMedia(this);
+ }
}
-//virtual
-LLViewerMediaTexture::~LLViewerMediaTexture()
-{
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
- if(tex) //this media is a parcel media for tex.
- {
- tex->setParcelMedia(NULL);
- }
+//virtual
+LLViewerMediaTexture::~LLViewerMediaTexture()
+{
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
+ if(tex) //this media is a parcel media for tex.
+ {
+ tex->setParcelMedia(NULL);
+ }
}
void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
{
- llassert(mGLTexturep.notNull());
+ llassert(mGLTexturep.notNull());
- mUseMipMaps = usemipmaps;
- getLastReferencedTimer()->reset();
- mGLTexturep->setUseMipMaps(mUseMipMaps);
- mGLTexturep->setNeedsAlphaAndPickMask(FALSE);
+ mUseMipMaps = usemipmaps;
+ getLastReferencedTimer()->reset();
+ mGLTexturep->setUseMipMaps(mUseMipMaps);
+ mGLTexturep->setNeedsAlphaAndPickMask(FALSE);
}
-void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap)
+void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap)
{
- mUseMipMaps = mipmap;
+ mUseMipMaps = mipmap;
- if(mGLTexturep.notNull())
- {
- mGLTexturep->setUseMipMaps(mipmap);
- }
+ if(mGLTexturep.notNull())
+ {
+ mGLTexturep->setUseMipMaps(mipmap);
+ }
}
-//virtual
+//virtual
S8 LLViewerMediaTexture::getType() const
{
- return LLViewerTexture::MEDIA_TEXTURE;
+ return LLViewerTexture::MEDIA_TEXTURE;
}
-void LLViewerMediaTexture::invalidateMediaImpl()
+void LLViewerMediaTexture::invalidateMediaImpl()
{
- mMediaImplp = NULL;
+ mMediaImplp = NULL;
}
void LLViewerMediaTexture::setMediaImpl()
{
- if(!mMediaImplp)
- {
- mMediaImplp = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mID);
- }
+ if(!mMediaImplp)
+ {
+ mMediaImplp = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mID);
+ }
}
//return true if all faces to reference to this media texture are found
-//Note: mMediaFaceList is valid only for the current instant
+//Note: mMediaFaceList is valid only for the current instant
// because it does not check the face validity after the current frame.
BOOL LLViewerMediaTexture::findFaces()
-{
- mMediaFaceList.clear();
-
- BOOL ret = TRUE;
-
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
- if(tex) //this media is a parcel media for tex.
- {
- for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- const ll_face_list_t* face_list = tex->getFaceList(ch);
- U32 end = tex->getNumFaces(ch);
- for(U32 i = 0; i < end; i++)
- {
- if ((*face_list)[i]->isMediaAllowed())
- {
- mMediaFaceList.push_back((*face_list)[i]);
- }
- }
- }
- }
-
- if(!mMediaImplp)
- {
- return TRUE;
- }
-
- //for media on a face.
- const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList();
- std::list< LLVOVolume* >::const_iterator iter = obj_list->begin();
- for(; iter != obj_list->end(); ++iter)
- {
- LLVOVolume* obj = *iter;
+{
+ mMediaFaceList.clear();
+
+ BOOL ret = TRUE;
+
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
+ if(tex) //this media is a parcel media for tex.
+ {
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ const ll_face_list_t* face_list = tex->getFaceList(ch);
+ U32 end = tex->getNumFaces(ch);
+ for(U32 i = 0; i < end; i++)
+ {
+ if ((*face_list)[i]->isMediaAllowed())
+ {
+ mMediaFaceList.push_back((*face_list)[i]);
+ }
+ }
+ }
+ }
+
+ if(!mMediaImplp)
+ {
+ return TRUE;
+ }
+
+ //for media on a face.
+ const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList();
+ std::list< LLVOVolume* >::const_iterator iter = obj_list->begin();
+ for(; iter != obj_list->end(); ++iter)
+ {
+ LLVOVolume* obj = *iter;
if (obj->isDead())
{
// Isn't supposed to happen, objects are supposed to detach
@@ -3410,343 +3418,343 @@ BOOL LLViewerMediaTexture::findFaces()
continue;
}
- S32 face_id = -1;
- S32 num_faces = obj->mDrawable->getNumFaces();
- while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces)
- {
- LLFace* facep = obj->mDrawable->getFace(face_id);
- if(facep)
- {
- mMediaFaceList.push_back(facep);
- }
- else
- {
- ret = FALSE;
- }
- }
- }
-
- return ret;
+ S32 face_id = -1;
+ S32 num_faces = obj->mDrawable->getNumFaces();
+ while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces)
+ {
+ LLFace* facep = obj->mDrawable->getFace(face_id);
+ if(facep)
+ {
+ mMediaFaceList.push_back(facep);
+ }
+ else
+ {
+ ret = FALSE;
+ }
+ }
+ }
+
+ return ret;
}
void LLViewerMediaTexture::initVirtualSize()
{
- if(mIsPlaying)
- {
- return;
- }
-
- findFaces();
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- addTextureStats((*iter)->getVirtualSize());
- }
-}
-
-void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
-{
- if(facep)
- {
- facep->setHasMedia(true);
- }
- if(!mIsPlaying)
- {
- return; //no need to add the face because the media is not in playing.
- }
-
- switchTexture(LLRender::DIFFUSE_MAP, facep);
-}
-
-void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
-{
- if(!facep)
- {
- return;
- }
- facep->setHasMedia(false);
-
- if(!mIsPlaying)
- {
- return; //no need to remove the face because the media is not in playing.
- }
-
- mIsPlaying = FALSE; //set to remove the media from the face.
- switchTexture(LLRender::DIFFUSE_MAP, facep);
- mIsPlaying = TRUE; //set the flag back.
-
- if(getTotalNumFaces() < 1) //no face referencing to this media
- {
- stopPlaying();
- }
-}
-
-//virtual
-void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
-{
- LLViewerTexture::addFace(ch, facep);
-
- const LLTextureEntry* te = facep->getTextureEntry();
- if(te && te->getID().notNull())
- {
- LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
- if(tex)
- {
- mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it.
- return;
- }
- }
-
- //check if it is a parcel media
- if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID)
- {
- mTextureList.push_back(facep->getTexture()); //a parcel media.
- return;
- }
-
- if(te && te->getID().notNull()) //should have a texture
- {
+ if(mIsPlaying)
+ {
+ return;
+ }
+
+ findFaces();
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ addTextureStats((*iter)->getVirtualSize());
+ }
+}
+
+void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
+{
+ if(facep)
+ {
+ facep->setHasMedia(true);
+ }
+ if(!mIsPlaying)
+ {
+ return; //no need to add the face because the media is not in playing.
+ }
+
+ switchTexture(LLRender::DIFFUSE_MAP, facep);
+}
+
+void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
+{
+ if(!facep)
+ {
+ return;
+ }
+ facep->setHasMedia(false);
+
+ if(!mIsPlaying)
+ {
+ return; //no need to remove the face because the media is not in playing.
+ }
+
+ mIsPlaying = FALSE; //set to remove the media from the face.
+ switchTexture(LLRender::DIFFUSE_MAP, facep);
+ mIsPlaying = TRUE; //set the flag back.
+
+ if(getTotalNumFaces() < 1) //no face referencing to this media
+ {
+ stopPlaying();
+ }
+}
+
+//virtual
+void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
+{
+ LLViewerTexture::addFace(ch, facep);
+
+ const LLTextureEntry* te = facep->getTextureEntry();
+ if(te && te->getID().notNull())
+ {
+ LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
+ if(tex)
+ {
+ mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it.
+ return;
+ }
+ }
+
+ //check if it is a parcel media
+ if(facep->getTexture() && facep->getTexture() != this && facep->getTexture()->getID() == mID)
+ {
+ mTextureList.push_back(facep->getTexture()); //a parcel media.
+ return;
+ }
+
+ if(te && te->getID().notNull()) //should have a texture
+ {
LL_WARNS_ONCE() << "The face's texture " << te->getID() << " is not valid. Face must have a valid texture before media texture." << LL_ENDL;
// This might break the object, but it likely isn't a 'recoverable' situation.
LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(te->getID());
mTextureList.push_back(tex);
- }
-}
-
-//virtual
-void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
-{
- LLViewerTexture::removeFace(ch, facep);
-
- const LLTextureEntry* te = facep->getTextureEntry();
- if(te && te->getID().notNull())
- {
- LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
- if(tex)
- {
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- if(*iter == tex)
- {
- mTextureList.erase(iter); //decrease the reference number for tex by one.
- return;
- }
- }
-
- std::vector<const LLTextureEntry*> te_list;
-
- for (U32 ch = 0; ch < 3; ++ch)
- {
- //
- //we have some trouble here: the texture of the face is changed.
- //we need to find the former texture, and remove it from the list to avoid memory leaking.
-
- llassert(mNumFaces[ch] <= mFaceList[ch].size());
-
- for(U32 j = 0; j < mNumFaces[ch]; j++)
- {
- te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use.
- }
- }
-
- if (te_list.empty())
- {
- mTextureList.clear();
- return;
- }
-
- S32 end = te_list.size();
-
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- S32 i = 0;
-
- for(i = 0; i < end; i++)
- {
- if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
- {
- te_list[i] = NULL;
- break;
- }
- }
- if(i == end) //no hit for this texture, remove it.
- {
- mTextureList.erase(iter); //decrease the reference number for tex by one.
- return;
- }
- }
- }
- }
-
- //check if it is a parcel media
- for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
- iter != mTextureList.end(); ++iter)
- {
- if((*iter)->getID() == mID)
- {
- mTextureList.erase(iter); //decrease the reference number for tex by one.
- return;
- }
- }
-
- if(te && te->getID().notNull()) //should have a texture but none found
- {
- LL_ERRS() << "mTextureList texture reference number is corrupted. Texture id: " << te->getID() << " List size: " << (U32)mTextureList.size() << LL_ENDL;
- }
+ }
+}
+
+//virtual
+void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
+{
+ LLViewerTexture::removeFace(ch, facep);
+
+ const LLTextureEntry* te = facep->getTextureEntry();
+ if(te && te->getID().notNull())
+ {
+ LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
+ if(tex)
+ {
+ for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+ iter != mTextureList.end(); ++iter)
+ {
+ if(*iter == tex)
+ {
+ mTextureList.erase(iter); //decrease the reference number for tex by one.
+ return;
+ }
+ }
+
+ std::vector<const LLTextureEntry*> te_list;
+
+ for (U32 ch = 0; ch < 3; ++ch)
+ {
+ //
+ //we have some trouble here: the texture of the face is changed.
+ //we need to find the former texture, and remove it from the list to avoid memory leaking.
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for(U32 j = 0; j < mNumFaces[ch]; j++)
+ {
+ te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use.
+ }
+ }
+
+ if (te_list.empty())
+ {
+ mTextureList.clear();
+ return;
+ }
+
+ S32 end = te_list.size();
+
+ for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+ iter != mTextureList.end(); ++iter)
+ {
+ S32 i = 0;
+
+ for(i = 0; i < end; i++)
+ {
+ if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
+ {
+ te_list[i] = NULL;
+ break;
+ }
+ }
+ if(i == end) //no hit for this texture, remove it.
+ {
+ mTextureList.erase(iter); //decrease the reference number for tex by one.
+ return;
+ }
+ }
+ }
+ }
+
+ //check if it is a parcel media
+ for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
+ iter != mTextureList.end(); ++iter)
+ {
+ if((*iter)->getID() == mID)
+ {
+ mTextureList.erase(iter); //decrease the reference number for tex by one.
+ return;
+ }
+ }
+
+ if(te && te->getID().notNull()) //should have a texture but none found
+ {
+ LL_ERRS() << "mTextureList texture reference number is corrupted. Texture id: " << te->getID() << " List size: " << (U32)mTextureList.size() << LL_ENDL;
+ }
}
void LLViewerMediaTexture::stopPlaying()
{
- // Don't stop the media impl playing here -- this breaks non-inworld media (login screen, search, and media browser).
-// if(mMediaImplp)
-// {
-// mMediaImplp->stop();
-// }
- mIsPlaying = FALSE;
+ // Don't stop the media impl playing here -- this breaks non-inworld media (login screen, search, and media browser).
+// if(mMediaImplp)
+// {
+// mMediaImplp->stop();
+// }
+ mIsPlaying = FALSE;
}
void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
{
- if(facep)
- {
- //check if another media is playing on this face.
- if(facep->getTexture() && facep->getTexture() != this
- && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
- {
- if(mID == facep->getTexture()->getID()) //this is a parcel media
- {
- return; //let the prim media win.
- }
- }
-
- if(mIsPlaying) //old textures switch to the media texture
- {
- facep->switchTexture(ch, this);
- }
- else //switch to old textures.
- {
- const LLTextureEntry* te = facep->getTextureEntry();
- if(te)
- {
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
- if(!tex && te->getID() != mID)//try parcel media.
- {
- tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
- }
- if(!tex)
- {
- tex = LLViewerFetchedTexture::sDefaultImagep;
- }
- facep->switchTexture(ch, tex);
- }
- }
- }
-}
-
-void LLViewerMediaTexture::setPlaying(BOOL playing)
-{
- if(!mMediaImplp)
- {
- return;
- }
- if(!playing && !mIsPlaying)
- {
- return; //media is already off
- }
-
- if(playing == mIsPlaying && !mMediaImplp->isUpdated())
- {
- return; //nothing has changed since last time.
- }
-
- mIsPlaying = playing;
- if(mIsPlaying) //is about to play this media
- {
- if(findFaces())
- {
- //about to update all faces.
- mMediaImplp->setUpdated(FALSE);
- }
-
- if(mMediaFaceList.empty())//no face pointing to this media
- {
- stopPlaying();
- return;
- }
-
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- switchTexture(LLRender::DIFFUSE_MAP, *iter);
- }
- }
- else //stop playing this media
- {
- U32 ch = LLRender::DIFFUSE_MAP;
-
- llassert(mNumFaces[ch] <= mFaceList[ch].size());
- for(U32 i = mNumFaces[ch]; i; i--)
- {
- switchTexture(ch, mFaceList[ch][i - 1]); //current face could be removed in this function.
- }
- }
- return;
-}
-
-//virtual
-F32 LLViewerMediaTexture::getMaxVirtualSize()
-{
- if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
- {
- return mMaxVirtualSize;
- }
- mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount();
-
- if(!mMaxVirtualSizeResetCounter)
- {
- addTextureStats(0.f, FALSE);//reset
- }
-
- if(mIsPlaying) //media is playing
- {
- for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- llassert(mNumFaces[ch] <= mFaceList[ch].size());
- for(U32 i = 0; i < mNumFaces[ch]; i++)
- {
- LLFace* facep = mFaceList[ch][i];
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize());
- }
- }
- }
- }
- else //media is not in playing
- {
- findFaces();
-
- if(!mMediaFaceList.empty())
- {
- for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
- {
- LLFace* facep = *iter;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize());
- }
- }
- }
- }
-
- if(mMaxVirtualSizeResetCounter > 0)
- {
- mMaxVirtualSizeResetCounter--;
- }
- reorganizeFaceList();
- reorganizeVolumeList();
-
- return mMaxVirtualSize;
+ if(facep)
+ {
+ //check if another media is playing on this face.
+ if(facep->getTexture() && facep->getTexture() != this
+ && facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
+ {
+ if(mID == facep->getTexture()->getID()) //this is a parcel media
+ {
+ return; //let the prim media win.
+ }
+ }
+
+ if(mIsPlaying) //old textures switch to the media texture
+ {
+ facep->switchTexture(ch, this);
+ }
+ else //switch to old textures.
+ {
+ const LLTextureEntry* te = facep->getTextureEntry();
+ if(te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
+ if(!tex && te->getID() != mID)//try parcel media.
+ {
+ tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
+ }
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ facep->switchTexture(ch, tex);
+ }
+ }
+ }
+}
+
+void LLViewerMediaTexture::setPlaying(BOOL playing)
+{
+ if(!mMediaImplp)
+ {
+ return;
+ }
+ if(!playing && !mIsPlaying)
+ {
+ return; //media is already off
+ }
+
+ if(playing == mIsPlaying && !mMediaImplp->isUpdated())
+ {
+ return; //nothing has changed since last time.
+ }
+
+ mIsPlaying = playing;
+ if(mIsPlaying) //is about to play this media
+ {
+ if(findFaces())
+ {
+ //about to update all faces.
+ mMediaImplp->setUpdated(FALSE);
+ }
+
+ if(mMediaFaceList.empty())//no face pointing to this media
+ {
+ stopPlaying();
+ return;
+ }
+
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ switchTexture(LLRender::DIFFUSE_MAP, *iter);
+ }
+ }
+ else //stop playing this media
+ {
+ U32 ch = LLRender::DIFFUSE_MAP;
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = mNumFaces[ch]; i; i--)
+ {
+ switchTexture(ch, mFaceList[ch][i - 1]); //current face could be removed in this function.
+ }
+ }
+ return;
+}
+
+//virtual
+F32 LLViewerMediaTexture::getMaxVirtualSize()
+{
+ if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
+ {
+ return mMaxVirtualSize;
+ }
+ mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount();
+
+ if(!mMaxVirtualSizeResetCounter)
+ {
+ addTextureStats(0.f, FALSE);//reset
+ }
+
+ if(mIsPlaying) //media is playing
+ {
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = 0; i < mNumFaces[ch]; i++)
+ {
+ LLFace* facep = mFaceList[ch][i];
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize());
+ }
+ }
+ }
+ }
+ else //media is not in playing
+ {
+ findFaces();
+
+ if(!mMediaFaceList.empty())
+ {
+ for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
+ {
+ LLFace* facep = *iter;
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize());
+ }
+ }
+ }
+ }
+
+ if(mMaxVirtualSizeResetCounter > 0)
+ {
+ mMaxVirtualSizeResetCounter--;
+ }
+ reorganizeFaceList();
+ reorganizeVolumeList();
+
+ return mMaxVirtualSize;
}
//----------------------------------------------------------------------------------------------
//end of LLViewerMediaTexture
@@ -3755,391 +3763,391 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
//----------------------------------------------------------------------------------------------
//start of LLTexturePipelineTester
//----------------------------------------------------------------------------------------------
-LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName)
-{
- addMetric("TotalBytesLoaded");
- addMetric("TotalBytesLoadedFromCache");
- addMetric("TotalBytesLoadedForLargeImage");
- addMetric("TotalBytesLoadedForSculpties");
- addMetric("StartFetchingTime");
- addMetric("TotalGrayTime");
- addMetric("TotalStablizingTime");
- addMetric("StartTimeLoadingSculpties");
- addMetric("EndTimeLoadingSculpties");
-
- addMetric("Time");
- addMetric("TotalBytesBound");
- addMetric("TotalBytesBoundForLargeImage");
- addMetric("PercentageBytesBound");
-
- mTotalBytesLoaded = (S32Bytes)0;
- mTotalBytesLoadedFromCache = (S32Bytes)0;
- mTotalBytesLoadedForLargeImage = (S32Bytes)0;
- mTotalBytesLoadedForSculpties = (S32Bytes)0;
-
- reset();
+LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName)
+{
+ addMetric("TotalBytesLoaded");
+ addMetric("TotalBytesLoadedFromCache");
+ addMetric("TotalBytesLoadedForLargeImage");
+ addMetric("TotalBytesLoadedForSculpties");
+ addMetric("StartFetchingTime");
+ addMetric("TotalGrayTime");
+ addMetric("TotalStablizingTime");
+ addMetric("StartTimeLoadingSculpties");
+ addMetric("EndTimeLoadingSculpties");
+
+ addMetric("Time");
+ addMetric("TotalBytesBound");
+ addMetric("TotalBytesBoundForLargeImage");
+ addMetric("PercentageBytesBound");
+
+ mTotalBytesLoaded = (S32Bytes)0;
+ mTotalBytesLoadedFromCache = (S32Bytes)0;
+ mTotalBytesLoadedForLargeImage = (S32Bytes)0;
+ mTotalBytesLoadedForSculpties = (S32Bytes)0;
+
+ reset();
}
LLTexturePipelineTester::~LLTexturePipelineTester()
{
- LLViewerTextureManager::sTesterp = NULL;
+ LLViewerTextureManager::sTesterp = NULL;
}
void LLTexturePipelineTester::update()
{
- mLastTotalBytesUsed = mTotalBytesUsed;
- mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage;
- mTotalBytesUsed = (S32Bytes)0;
- mTotalBytesUsedForLargeImage = (S32Bytes)0;
-
- if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty
- {
- if(mPause)
- {
- //start a new fetching session
- reset();
- mStartFetchingTime = LLImageGL::sLastFrameTime;
- mPause = FALSE;
- }
-
- //update total gray time
- if(mUsingDefaultTexture)
- {
- mUsingDefaultTexture = FALSE;
- mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime;
- }
-
- //update the stablizing timer.
- updateStablizingTime();
-
- outputTestResults();
- }
- else if(!mPause)
- {
- //stop the current fetching session
- mPause = TRUE;
- outputTestResults();
- reset();
- }
-}
-
-void LLTexturePipelineTester::reset()
-{
- mPause = TRUE;
-
- mUsingDefaultTexture = FALSE;
- mStartStablizingTime = 0.0f;
- mEndStablizingTime = 0.0f;
-
- mTotalBytesUsed = (S32Bytes)0;
- mTotalBytesUsedForLargeImage = (S32Bytes)0;
- mLastTotalBytesUsed = (S32Bytes)0;
- mLastTotalBytesUsedForLargeImage = (S32Bytes)0;
-
- mStartFetchingTime = 0.0f;
-
- mTotalGrayTime = 0.0f;
- mTotalStablizingTime = 0.0f;
-
- mStartTimeLoadingSculpties = 1.0f;
- mEndTimeLoadingSculpties = 0.0f;
-}
-
-//virtual
-void LLTexturePipelineTester::outputTestRecord(LLSD *sd)
-{
- std::string currentLabel = getCurrentLabelName();
- (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value();
- (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value();
- (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value();
- (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value();
-
- (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime;
- (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime;
- (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime;
-
- (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties;
- (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties;
-
- (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime;
- (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value();
- (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value();
- (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded);
-}
-
-void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep)
-{
- U32Bytes mem_size = imagep->getTextureMemory();
- mTotalBytesUsed += mem_size;
-
- if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents()))
- {
- mTotalBytesUsedForLargeImage += mem_size;
- }
-}
-
-void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache)
-{
- U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize();
- mTotalBytesLoaded += data_size;
-
- if(from_cache)
- {
- mTotalBytesLoadedFromCache += data_size;
- }
-
- if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents()))
- {
- mTotalBytesLoadedForLargeImage += data_size;
- }
-
- if(imagep->forSculpt())
- {
- mTotalBytesLoadedForSculpties += data_size;
-
- if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties)
- {
- mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime;
- }
- mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime;
- }
+ mLastTotalBytesUsed = mTotalBytesUsed;
+ mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage;
+ mTotalBytesUsed = (S32Bytes)0;
+ mTotalBytesUsedForLargeImage = (S32Bytes)0;
+
+ if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty
+ {
+ if(mPause)
+ {
+ //start a new fetching session
+ reset();
+ mStartFetchingTime = LLImageGL::sLastFrameTime;
+ mPause = FALSE;
+ }
+
+ //update total gray time
+ if(mUsingDefaultTexture)
+ {
+ mUsingDefaultTexture = FALSE;
+ mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime;
+ }
+
+ //update the stablizing timer.
+ updateStablizingTime();
+
+ outputTestResults();
+ }
+ else if(!mPause)
+ {
+ //stop the current fetching session
+ mPause = TRUE;
+ outputTestResults();
+ reset();
+ }
+}
+
+void LLTexturePipelineTester::reset()
+{
+ mPause = TRUE;
+
+ mUsingDefaultTexture = FALSE;
+ mStartStablizingTime = 0.0f;
+ mEndStablizingTime = 0.0f;
+
+ mTotalBytesUsed = (S32Bytes)0;
+ mTotalBytesUsedForLargeImage = (S32Bytes)0;
+ mLastTotalBytesUsed = (S32Bytes)0;
+ mLastTotalBytesUsedForLargeImage = (S32Bytes)0;
+
+ mStartFetchingTime = 0.0f;
+
+ mTotalGrayTime = 0.0f;
+ mTotalStablizingTime = 0.0f;
+
+ mStartTimeLoadingSculpties = 1.0f;
+ mEndTimeLoadingSculpties = 0.0f;
+}
+
+//virtual
+void LLTexturePipelineTester::outputTestRecord(LLSD *sd)
+{
+ std::string currentLabel = getCurrentLabelName();
+ (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value();
+ (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value();
+ (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value();
+ (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value();
+
+ (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime;
+ (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime;
+ (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime;
+
+ (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties;
+ (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties;
+
+ (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime;
+ (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value();
+ (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value();
+ (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded);
+}
+
+void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep)
+{
+ U32Bytes mem_size = imagep->getTextureMemory();
+ mTotalBytesUsed += mem_size;
+
+ if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents()))
+ {
+ mTotalBytesUsedForLargeImage += mem_size;
+ }
+}
+
+void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache)
+{
+ U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize();
+ mTotalBytesLoaded += data_size;
+
+ if(from_cache)
+ {
+ mTotalBytesLoadedFromCache += data_size;
+ }
+
+ if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents()))
+ {
+ mTotalBytesLoadedForLargeImage += data_size;
+ }
+
+ if(imagep->forSculpt())
+ {
+ mTotalBytesLoadedForSculpties += data_size;
+
+ if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties)
+ {
+ mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime;
+ }
+ mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime;
+ }
}
void LLTexturePipelineTester::updateGrayTextureBinding()
{
- mUsingDefaultTexture = TRUE;
+ mUsingDefaultTexture = TRUE;
}
void LLTexturePipelineTester::setStablizingTime()
{
- if(mStartStablizingTime <= mStartFetchingTime)
- {
- mStartStablizingTime = LLImageGL::sLastFrameTime;
- }
- mEndStablizingTime = LLImageGL::sLastFrameTime;
+ if(mStartStablizingTime <= mStartFetchingTime)
+ {
+ mStartStablizingTime = LLImageGL::sLastFrameTime;
+ }
+ mEndStablizingTime = LLImageGL::sLastFrameTime;
}
void LLTexturePipelineTester::updateStablizingTime()
{
- if(mStartStablizingTime > mStartFetchingTime)
- {
- F32 t = mEndStablizingTime - mStartStablizingTime;
-
- if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO)
- {
- //already stablized
- mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime;
-
- //cancel the timer
- mStartStablizingTime = 0.f;
- mEndStablizingTime = 0.f;
- }
- else
- {
- mTotalStablizingTime = t;
- }
- }
- mTotalStablizingTime = 0.f;
-}
-
-//virtual
-void LLTexturePipelineTester::compareTestSessions(llofstream* os)
-{
- LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mBaseSessionp);
- LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mCurrentSessionp);
- if(!base_sessionp || !current_sessionp)
- {
- LL_ERRS() << "type of test session does not match!" << LL_ENDL;
- }
-
- //compare and output the comparison
- *os << llformat("%s\n", getTesterName().c_str());
- *os << llformat("AggregateResults\n");
-
- compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime);
- compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);
- compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties);
- compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties);
-
- compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded);
- compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache);
- compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage);
- compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties);
-
- *os << llformat("InstantResults\n");
- S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter);
- for(S32 i = 0; i < size; i++)
- {
- *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime);
-
- compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond,
- current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
-
- compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond,
- current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
-
- compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond,
- current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
- }
-
- if(size < base_sessionp->mInstantPerformanceListCounter)
- {
- for(S32 i = size; i < base_sessionp->mInstantPerformanceListCounter; i++)
- {
- *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime);
-
- *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
- *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
- *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
- }
- }
- else if(size < current_sessionp->mInstantPerformanceListCounter)
- {
- for(S32 i = size; i < current_sessionp->mInstantPerformanceListCounter; i++)
- {
- *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime);
-
- *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
- *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
- *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
- }
- }
-}
-
-//virtual
+ if(mStartStablizingTime > mStartFetchingTime)
+ {
+ F32 t = mEndStablizingTime - mStartStablizingTime;
+
+ if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO)
+ {
+ //already stablized
+ mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime;
+
+ //cancel the timer
+ mStartStablizingTime = 0.f;
+ mEndStablizingTime = 0.f;
+ }
+ else
+ {
+ mTotalStablizingTime = t;
+ }
+ }
+ mTotalStablizingTime = 0.f;
+}
+
+//virtual
+void LLTexturePipelineTester::compareTestSessions(llofstream* os)
+{
+ LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mBaseSessionp);
+ LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mCurrentSessionp);
+ if(!base_sessionp || !current_sessionp)
+ {
+ LL_ERRS() << "type of test session does not match!" << LL_ENDL;
+ }
+
+ //compare and output the comparison
+ *os << llformat("%s\n", getTesterName().c_str());
+ *os << llformat("AggregateResults\n");
+
+ compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime);
+ compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);
+ compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties);
+ compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties);
+
+ compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded);
+ compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache);
+ compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage);
+ compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties);
+
+ *os << llformat("InstantResults\n");
+ S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter);
+ for(S32 i = 0; i < size; i++)
+ {
+ *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime);
+
+ compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
+
+ compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
+
+ compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
+ }
+
+ if(size < base_sessionp->mInstantPerformanceListCounter)
+ {
+ for(S32 i = size; i < base_sessionp->mInstantPerformanceListCounter; i++)
+ {
+ *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime);
+
+ *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
+ *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
+ *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
+ }
+ }
+ else if(size < current_sessionp->mInstantPerformanceListCounter)
+ {
+ for(S32 i = size; i < current_sessionp->mInstantPerformanceListCounter; i++)
+ {
+ *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime);
+
+ *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond);
+ *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond);
+ *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond);
+ }
+ }
+}
+
+//virtual
LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log)
{
- LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession();
- if(!sessionp)
- {
- return NULL;
- }
-
- F32 total_gray_time = 0.f;
- F32 total_stablizing_time = 0.f;
- F32 total_loading_sculpties_time = 0.f;
-
- F32 start_fetching_time = -1.f;
- F32 start_fetching_sculpties_time = 0.f;
-
- F32 last_time = 0.0f;
- S32 frame_count = 0;
-
- sessionp->mInstantPerformanceListCounter = 0;
- sessionp->mInstantPerformanceList.resize(128);
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f;
-
- //load a session
- std::string currentLabel = getCurrentLabelName();
- BOOL in_log = (*log).has(currentLabel);
- while (in_log)
- {
- LLSD::String label = currentLabel;
-
- if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size())
- {
- sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128);
- }
-
- //time
- F32 start_time = (*log)[label]["StartFetchingTime"].asReal();
- F32 cur_time = (*log)[label]["Time"].asReal();
- if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
- {
- sessionp->mTotalGrayTime += total_gray_time;
- sessionp->mTotalStablizingTime += total_stablizing_time;
-
- sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time;
- sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
-
- start_fetching_time = start_time;
- total_gray_time = 0.f;
- total_stablizing_time = 0.f;
- total_loading_sculpties_time = 0.f;
- }
- else
- {
- total_gray_time = (*log)[label]["TotalGrayTime"].asReal();
- total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal();
-
- total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal();
- if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f)
- {
- start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal();
- }
- }
-
- //total loaded bytes
- sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger();
- sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger();
- sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger();
- sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger();
-
- //instant metrics
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond +=
- (*log)[label]["TotalBytesBound"].asInteger();
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond +=
- (*log)[label]["TotalBytesBoundForLargeImage"].asInteger();
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond +=
- (*log)[label]["PercentageBytesBound"].asReal();
- frame_count++;
- if(cur_time - last_time >= 1.0f)
- {
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time;
-
- frame_count = 0;
- last_time = cur_time;
- sessionp->mInstantPerformanceListCounter++;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f;
- sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f;
- }
- // Next label
- incrementCurrentCount();
- currentLabel = getCurrentLabelName();
- in_log = (*log).has(currentLabel);
- }
-
- sessionp->mTotalGrayTime += total_gray_time;
- sessionp->mTotalStablizingTime += total_stablizing_time;
-
- if(sessionp->mStartTimeLoadingSculpties < 0.f)
- {
- sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time;
- }
- sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
-
- return sessionp;
-}
-
-LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession()
-{
- reset();
-}
-LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
-{
-}
-void LLTexturePipelineTester::LLTextureTestSession::reset()
-{
- mTotalGrayTime = 0.0f;
- mTotalStablizingTime = 0.0f;
-
- mStartTimeLoadingSculpties = 0.0f;
- mTotalTimeLoadingSculpties = 0.0f;
-
- mTotalBytesLoaded = 0;
- mTotalBytesLoadedFromCache = 0;
- mTotalBytesLoadedForLargeImage = 0;
- mTotalBytesLoadedForSculpties = 0;
-
- mInstantPerformanceListCounter = 0;
+ LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession();
+ if(!sessionp)
+ {
+ return NULL;
+ }
+
+ F32 total_gray_time = 0.f;
+ F32 total_stablizing_time = 0.f;
+ F32 total_loading_sculpties_time = 0.f;
+
+ F32 start_fetching_time = -1.f;
+ F32 start_fetching_sculpties_time = 0.f;
+
+ F32 last_time = 0.0f;
+ S32 frame_count = 0;
+
+ sessionp->mInstantPerformanceListCounter = 0;
+ sessionp->mInstantPerformanceList.resize(128);
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f;
+
+ //load a session
+ std::string currentLabel = getCurrentLabelName();
+ BOOL in_log = (*log).has(currentLabel);
+ while (in_log)
+ {
+ LLSD::String label = currentLabel;
+
+ if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size())
+ {
+ sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128);
+ }
+
+ //time
+ F32 start_time = (*log)[label]["StartFetchingTime"].asReal();
+ F32 cur_time = (*log)[label]["Time"].asReal();
+ if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
+ {
+ sessionp->mTotalGrayTime += total_gray_time;
+ sessionp->mTotalStablizingTime += total_stablizing_time;
+
+ sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time;
+ sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
+
+ start_fetching_time = start_time;
+ total_gray_time = 0.f;
+ total_stablizing_time = 0.f;
+ total_loading_sculpties_time = 0.f;
+ }
+ else
+ {
+ total_gray_time = (*log)[label]["TotalGrayTime"].asReal();
+ total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal();
+
+ total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal();
+ if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f)
+ {
+ start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal();
+ }
+ }
+
+ //total loaded bytes
+ sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger();
+ sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger();
+ sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger();
+ sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger();
+
+ //instant metrics
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond +=
+ (*log)[label]["TotalBytesBound"].asInteger();
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond +=
+ (*log)[label]["TotalBytesBoundForLargeImage"].asInteger();
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond +=
+ (*log)[label]["PercentageBytesBound"].asReal();
+ frame_count++;
+ if(cur_time - last_time >= 1.0f)
+ {
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time;
+
+ frame_count = 0;
+ last_time = cur_time;
+ sessionp->mInstantPerformanceListCounter++;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f;
+ }
+ // Next label
+ incrementCurrentCount();
+ currentLabel = getCurrentLabelName();
+ in_log = (*log).has(currentLabel);
+ }
+
+ sessionp->mTotalGrayTime += total_gray_time;
+ sessionp->mTotalStablizingTime += total_stablizing_time;
+
+ if(sessionp->mStartTimeLoadingSculpties < 0.f)
+ {
+ sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time;
+ }
+ sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
+
+ return sessionp;
+}
+
+LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession()
+{
+ reset();
+}
+LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
+{
+}
+void LLTexturePipelineTester::LLTextureTestSession::reset()
+{
+ mTotalGrayTime = 0.0f;
+ mTotalStablizingTime = 0.0f;
+
+ mStartTimeLoadingSculpties = 0.0f;
+ mTotalTimeLoadingSculpties = 0.0f;
+
+ mTotalBytesLoaded = 0;
+ mTotalBytesLoadedFromCache = 0;
+ mTotalBytesLoadedForLargeImage = 0;
+ mTotalBytesLoadedForSculpties = 0;
+
+ mInstantPerformanceListCounter = 0;
}
//----------------------------------------------------------------------------------------------
//end of LLTexturePipelineTester
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 8c44f6e6c0..52b2f19ada 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -1,30 +1,30 @@
-/**
+/**
* @file llviewertexture.h
* @brief Object for managing images and their textures
*
* $LicenseInfo:firstyear=2000&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_LLVIEWERTEXTURE_H
+#ifndef LL_LLVIEWERTEXTURE_H
#define LL_LLVIEWERTEXTURE_H
#include "llatomic.h"
@@ -54,7 +54,7 @@ class LLViewerMediaTexture ;
class LLTexturePipelineTester ;
-typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
+typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
class LLFileSystem;
class LLMessageSystem;
@@ -68,26 +68,26 @@ public:
typedef std::set< LLTextureKey > source_callback_list_t;
public:
- LLLoadedCallbackEntry(loaded_callback_func cb,
- S32 discard_level,
- BOOL need_imageraw, // Needs image raw for the callback
- void* userdata,
- source_callback_list_t* src_callback_list,
- LLViewerFetchedTexture* target,
- BOOL pause);
- ~LLLoadedCallbackEntry();
- void removeTexture(LLViewerFetchedTexture* tex) ;
-
- loaded_callback_func mCallback;
- S32 mLastUsedDiscard;
- S32 mDesiredDiscard;
- BOOL mNeedsImageRaw;
- BOOL mPaused;
- void* mUserData;
- source_callback_list_t* mSourceCallbackList;
-
+ LLLoadedCallbackEntry(loaded_callback_func cb,
+ S32 discard_level,
+ BOOL need_imageraw, // Needs image raw for the callback
+ void* userdata,
+ source_callback_list_t* src_callback_list,
+ LLViewerFetchedTexture* target,
+ BOOL pause);
+ ~LLLoadedCallbackEntry();
+ void removeTexture(LLViewerFetchedTexture* tex) ;
+
+ loaded_callback_func mCallback;
+ S32 mLastUsedDiscard;
+ S32 mDesiredDiscard;
+ BOOL mNeedsImageRaw;
+ BOOL mPaused;
+ void* mUserData;
+ source_callback_list_t* mSourceCallbackList;
+
public:
- static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;
+ static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;
};
class LLTextureBar;
@@ -95,163 +95,163 @@ class LLTextureBar;
class LLViewerTexture : public LLGLTexture
{
public:
- enum
- {
- LOCAL_TEXTURE,
- MEDIA_TEXTURE,
- DYNAMIC_TEXTURE,
- FETCHED_TEXTURE,
- LOD_TEXTURE,
- ATLAS_TEXTURE,
- INVALID_TEXTURE_TYPE
- };
+ enum
+ {
+ LOCAL_TEXTURE,
+ MEDIA_TEXTURE,
+ DYNAMIC_TEXTURE,
+ FETCHED_TEXTURE,
+ LOD_TEXTURE,
+ ATLAS_TEXTURE,
+ INVALID_TEXTURE_TYPE
+ };
- typedef std::vector<class LLFace*> ll_face_list_t;
- typedef std::vector<LLVOVolume*> ll_volume_list_t;
+ typedef std::vector<class LLFace*> ll_face_list_t;
+ typedef std::vector<LLVOVolume*> ll_volume_list_t;
protected:
- virtual ~LLViewerTexture();
- LOG_CLASS(LLViewerTexture);
-
-public:
- static void initClass();
- static void updateClass();
-
- LLViewerTexture(BOOL usemipmaps = TRUE);
- LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ;
- LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
- LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
-
- virtual S8 getType() const;
- virtual BOOL isMissingAsset() const ;
- virtual void dump(); // debug info to LL_INFOS()
-
+ virtual ~LLViewerTexture();
+ LOG_CLASS(LLViewerTexture);
+
+public:
+ static void initClass();
+ static void updateClass();
+
+ LLViewerTexture(BOOL usemipmaps = TRUE);
+ LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ;
+ LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+
+ virtual S8 getType() const;
+ virtual BOOL isMissingAsset() const ;
+ virtual void dump(); // debug info to LL_INFOS()
+
virtual bool isViewerMediaTexture() const { return false; }
- /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
- /*virtual*/ bool bindDebugImage(const S32 stage = 0) ;
- /*virtual*/ void forceImmediateUpdate() ;
- /*virtual*/ bool isActiveFetching();
-
- /*virtual*/ const LLUUID& getID() const { return mID; }
- virtual void setBoostLevel(S32 level);
- S32 getBoostLevel() { return mBoostLevel; }
- void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }
- S32 getTextureListType() { return mTextureListType; }
-
- void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;
- void resetTextureStats();
- void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
- void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
- S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
-
- virtual F32 getMaxVirtualSize() ;
-
- LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
-
- S32 getFullWidth() const { return mFullWidth; }
- S32 getFullHeight() const { return mFullHeight; }
- /*virtual*/ void setKnownDrawSize(S32 width, S32 height);
-
- virtual void addFace(U32 channel, LLFace* facep) ;
- virtual void removeFace(U32 channel, LLFace* facep) ;
- S32 getTotalNumFaces() const;
- S32 getNumFaces(U32 ch) const;
- const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
-
- virtual void addVolume(U32 channel, LLVOVolume* volumep);
- virtual void removeVolume(U32 channel, LLVOVolume* volumep);
- S32 getNumVolumes(U32 channel) const;
- const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; }
-
-
- virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
- BOOL isLargeImage() ;
-
- void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
- BOOL hasParcelMedia() const { return mParcelMedia != NULL;}
- LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;}
-
- /*virtual*/ void updateBindStatsForTester() ;
+ /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
+ /*virtual*/ bool bindDebugImage(const S32 stage = 0) ;
+ /*virtual*/ void forceImmediateUpdate() ;
+ /*virtual*/ bool isActiveFetching();
+
+ /*virtual*/ const LLUUID& getID() const { return mID; }
+ virtual void setBoostLevel(S32 level);
+ S32 getBoostLevel() { return mBoostLevel; }
+ void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }
+ S32 getTextureListType() { return mTextureListType; }
+
+ void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;
+ void resetTextureStats();
+ void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
+ void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
+ S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
+
+ virtual F32 getMaxVirtualSize() ;
+
+ LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
+
+ S32 getFullWidth() const { return mFullWidth; }
+ S32 getFullHeight() const { return mFullHeight; }
+ /*virtual*/ void setKnownDrawSize(S32 width, S32 height);
+
+ virtual void addFace(U32 channel, LLFace* facep) ;
+ virtual void removeFace(U32 channel, LLFace* facep) ;
+ S32 getTotalNumFaces() const;
+ S32 getNumFaces(U32 ch) const;
+ const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
+
+ virtual void addVolume(U32 channel, LLVOVolume* volumep);
+ virtual void removeVolume(U32 channel, LLVOVolume* volumep);
+ S32 getNumVolumes(U32 channel) const;
+ const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; }
+
+
+ virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
+ BOOL isLargeImage() ;
+
+ void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
+ BOOL hasParcelMedia() const { return mParcelMedia != NULL;}
+ LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;}
+
+ /*virtual*/ void updateBindStatsForTester() ;
protected:
- void cleanup() ;
- void init(bool firstinit) ;
- void reorganizeFaceList() ;
- void reorganizeVolumeList();
+ void cleanup() ;
+ void init(bool firstinit) ;
+ void reorganizeFaceList() ;
+ void reorganizeVolumeList();
private:
- friend class LLBumpImageList;
- friend class LLUIImageList;
+ friend class LLBumpImageList;
+ friend class LLUIImageList;
- virtual void switchToCachedImage();
-
- static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
+ virtual void switchToCachedImage();
+
+ static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
public:
static bool isMemoryForTextureLow();
protected:
friend class LLViewerTextureList;
- LLUUID mID;
- S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
+ LLUUID mID;
+ S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
- mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need?
- mutable S32 mMaxVirtualSizeResetCounter;
- mutable S32 mMaxVirtualSizeResetInterval;
- LLFrameTimer mLastReferencedTimer;
+ mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need?
+ mutable S32 mMaxVirtualSizeResetCounter;
+ mutable S32 mMaxVirtualSizeResetInterval;
+ LLFrameTimer mLastReferencedTimer;
- ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
- U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
- LLFrameTimer mLastFaceListUpdateTimer ;
+ ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
+ U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
+ LLFrameTimer mLastFaceListUpdateTimer ;
- ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
- U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
- LLFrameTimer mLastVolumeListUpdateTimer;
+ ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
+ U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
+ LLFrameTimer mLastVolumeListUpdateTimer;
- //do not use LLPointer here.
- LLViewerMediaTexture* mParcelMedia ;
+ //do not use LLPointer here.
+ LLViewerMediaTexture* mParcelMedia ;
- LL::WorkQueue::weak_t mMainQueue;
- LL::WorkQueue::weak_t mImageQueue;
+ LL::WorkQueue::weak_t mMainQueue;
+ LL::WorkQueue::weak_t mImageQueue;
public:
- static const U32 sCurrentFileVersion;
- static S32 sImageCount;
- static S32 sRawCount;
- static S32 sAuxCount;
- static LLFrameTimer sEvaluationTimer;
- static F32 sDesiredDiscardBias;
- static F32 sDesiredDiscardScale;
- static S32 sMaxSculptRez ;
- static U32 sMinLargeImageSize ;
- static U32 sMaxSmallImageSize ;
- static bool sFreezeImageUpdates;
- static F32 sCurrentTime ;
-
- enum EDebugTexels
- {
- DEBUG_TEXELS_OFF,
- DEBUG_TEXELS_CURRENT,
- DEBUG_TEXELS_DESIRED,
- DEBUG_TEXELS_FULL
- };
-
- static EDebugTexels sDebugTexelsMode;
-
- static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
- static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black)
- static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black)
+ static const U32 sCurrentFileVersion;
+ static S32 sImageCount;
+ static S32 sRawCount;
+ static S32 sAuxCount;
+ static LLFrameTimer sEvaluationTimer;
+ static F32 sDesiredDiscardBias;
+ static F32 sDesiredDiscardScale;
+ static S32 sMaxSculptRez ;
+ static U32 sMinLargeImageSize ;
+ static U32 sMaxSmallImageSize ;
+ static bool sFreezeImageUpdates;
+ static F32 sCurrentTime ;
+
+ enum EDebugTexels
+ {
+ DEBUG_TEXELS_OFF,
+ DEBUG_TEXELS_CURRENT,
+ DEBUG_TEXELS_DESIRED,
+ DEBUG_TEXELS_FULL
+ };
+
+ static EDebugTexels sDebugTexelsMode;
+
+ static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
+ static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black)
+ static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black)
};
enum FTType
{
- FTT_UNKNOWN = -1,
- FTT_DEFAULT = 0, // standard texture fetched by id.
- FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
- FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
- FTT_MAP_TILE, // tiles are fetched from map server directly.
- FTT_LOCAL_FILE // fetch directly from a local file.
+ FTT_UNKNOWN = -1,
+ FTT_DEFAULT = 0, // standard texture fetched by id.
+ FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
+ FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
+ FTT_MAP_TILE, // tiles are fetched from map server directly.
+ FTT_LOCAL_FILE // fetch directly from a local file.
};
const std::string& fttype_to_string(const FTType& fttype);
@@ -263,269 +263,269 @@ const std::string& fttype_to_string(const FTType& fttype);
//
class LLViewerFetchedTexture : public LLViewerTexture
{
- friend class LLTextureBar; // debug info only
- friend class LLTextureView; // debug info only
+ friend class LLTextureBar; // debug info only
+ friend class LLTextureView; // debug info only
protected:
- /*virtual*/ ~LLViewerFetchedTexture();
+ /*virtual*/ ~LLViewerFetchedTexture();
public:
- LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
- LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
- LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
+ LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
+ LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
public:
-
- struct Compare
- {
- // lhs < rhs
- bool operator()(const LLPointer<LLViewerFetchedTexture> &lhs, const LLPointer<LLViewerFetchedTexture> &rhs) const
- {
- const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
- const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
-
- // greater priority is "less"
- const F32 lpriority = lhsp->mMaxVirtualSize;
- const F32 rpriority = rhsp->mMaxVirtualSize;
- if (lpriority > rpriority) // higher priority
- return true;
- if (lpriority < rpriority)
- return false;
- return lhsp < rhsp;
- }
- };
+
+ struct Compare
+ {
+ // lhs < rhs
+ bool operator()(const LLPointer<LLViewerFetchedTexture> &lhs, const LLPointer<LLViewerFetchedTexture> &rhs) const
+ {
+ const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
+ const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
+
+ // greater priority is "less"
+ const F32 lpriority = lhsp->mMaxVirtualSize;
+ const F32 rpriority = rhsp->mMaxVirtualSize;
+ if (lpriority > rpriority) // higher priority
+ return true;
+ if (lpriority < rpriority)
+ return false;
+ return lhsp < rhsp;
+ }
+ };
public:
- /*virtual*/ S8 getType() const override;
- FTType getFTType() const;
- /*virtual*/ void forceImmediateUpdate() override;
- /*virtual*/ void dump() override;
-
- // Set callbacks to get called when the image gets updated with higher
- // resolution versions.
- void setLoadedCallback(loaded_callback_func cb,
- S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
- void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);
- bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
- void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
- void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
- bool doLoadedCallbacks();
- void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
- void clearCallbackEntryList() ;
-
- void addToCreateTexture();
+ /*virtual*/ S8 getType() const override;
+ FTType getFTType() const;
+ /*virtual*/ void forceImmediateUpdate() override;
+ /*virtual*/ void dump() override;
+
+ // Set callbacks to get called when the image gets updated with higher
+ // resolution versions.
+ void setLoadedCallback(loaded_callback_func cb,
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
+ void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);
+ bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
+ void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
+ void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
+ bool doLoadedCallbacks();
+ void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
+ void clearCallbackEntryList() ;
+
+ void addToCreateTexture();
//call to determine if createTexture is necessary
BOOL preCreateTexture(S32 usename = 0);
- // ONLY call from LLViewerTextureList or ImageGL background thread
- BOOL createTexture(S32 usename = 0);
+ // ONLY call from LLViewerTextureList or ImageGL background thread
+ BOOL createTexture(S32 usename = 0);
void postCreateTexture();
void scheduleCreateTexture();
- void destroyTexture() ;
+ void destroyTexture() ;
- virtual void processTextureStats() ;
+ virtual void processTextureStats() ;
- BOOL needsAux() const { return mNeedsAux; }
+ BOOL needsAux() const { return mNeedsAux; }
- // Host we think might have this image, used for baked av textures.
- void setTargetHost(LLHost host) { mTargetHost = host; }
- LLHost getTargetHost() const { return mTargetHost; }
+ // Host we think might have this image, used for baked av textures.
+ void setTargetHost(LLHost host) { mTargetHost = host; }
+ LLHost getTargetHost() const { return mTargetHost; }
+
+ void updateVirtualSize() ;
- void updateVirtualSize() ;
-
- S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
- void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
+ S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
+ void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
void setBoostLevel(S32 level) override;
- bool updateFetch();
- bool setDebugFetching(S32 debug_level);
- bool isInDebug() const { return mInDebug; }
-
- void setUnremovable(BOOL value) { mUnremovable = value; }
- bool isUnremovable() const { return mUnremovable; }
+ bool updateFetch();
+ bool setDebugFetching(S32 debug_level);
+ bool isInDebug() const { return mInDebug; }
- void clearFetchedResults(); //clear all fetched results, for debug use.
+ void setUnremovable(BOOL value) { mUnremovable = value; }
+ bool isUnremovable() const { return mUnremovable; }
+
+ void clearFetchedResults(); //clear all fetched results, for debug use.
- // Override the computation of discard levels if we know the exact output
- // size of the image. Used for UI textures to not decode, even if we have
- // more data.
- /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override;
+ // Override the computation of discard levels if we know the exact output
+ // size of the image. Used for UI textures to not decode, even if we have
+ // more data.
+ /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override;
// Set the debug text of all Viewer Objects associated with this texture
// to the specified text
void setDebugText(const std::string& text);
- void setIsMissingAsset(BOOL is_missing = true);
- /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; }
-
- // returns dimensions of original image for local files (before power of two scaling)
- // and returns 0 for all asset system images
- S32 getOriginalWidth() { return mOrigWidth; }
- S32 getOriginalHeight() { return mOrigHeight; }
-
- BOOL isInImageList() const {return mInImageList ;}
- void setInImageList(BOOL flag) {mInImageList = flag ;}
-
- LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;}
-
- U32 getFetchPriority() const { return mFetchPriority ;}
- F32 getDownloadProgress() const {return mDownloadProgress ;}
-
- LLImageRaw* reloadRawImage(S8 discard_level) ;
- void destroyRawImage();
- bool needsToSaveRawImage();
-
- const std::string& getUrl() const {return mUrl;}
- //---------------
- BOOL isDeleted() ;
- BOOL isInactive() ;
- BOOL isDeletionCandidate();
- void setDeletionCandidate() ;
- void setInactive() ;
- BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }
- //---------------
-
- void setForSculpt();
- BOOL forSculpt() const {return mForSculpt;}
- BOOL isForSculptOnly() const;
-
- //raw image management
- void checkCachedRawSculptImage() ;
- LLImageRaw* getRawImage()const { return mRawImage ;}
- S32 getRawImageLevel() const {return mRawDiscardLevel;}
- LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;}
- S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
- BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;}
- BOOL isRawImageValid()const { return mIsRawImageValid ; }
- void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
- void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
- /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
- void destroySavedRawImage() ;
- LLImageRaw* getSavedRawImage() ;
- BOOL hasSavedRawImage() const ;
- F32 getElapsedLastReferencedSavedRawImageTime() const ;
- BOOL isFullyLoaded() const;
-
- BOOL hasFetcher() const { return mHasFetcher;}
- bool isFetching() const { return mIsFetching;}
- void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
-
- void forceToDeleteRequest();
- void loadFromFastCache();
- void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
- bool isInFastCacheList() { return mInFastCacheList; }
-
- /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
+ void setIsMissingAsset(BOOL is_missing = true);
+ /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; }
+
+ // returns dimensions of original image for local files (before power of two scaling)
+ // and returns 0 for all asset system images
+ S32 getOriginalWidth() { return mOrigWidth; }
+ S32 getOriginalHeight() { return mOrigHeight; }
+
+ BOOL isInImageList() const {return mInImageList ;}
+ void setInImageList(BOOL flag) {mInImageList = flag ;}
+
+ LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;}
+
+ U32 getFetchPriority() const { return mFetchPriority ;}
+ F32 getDownloadProgress() const {return mDownloadProgress ;}
+
+ LLImageRaw* reloadRawImage(S8 discard_level) ;
+ void destroyRawImage();
+ bool needsToSaveRawImage();
+
+ const std::string& getUrl() const {return mUrl;}
+ //---------------
+ BOOL isDeleted() ;
+ BOOL isInactive() ;
+ BOOL isDeletionCandidate();
+ void setDeletionCandidate() ;
+ void setInactive() ;
+ BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }
+ //---------------
+
+ void setForSculpt();
+ BOOL forSculpt() const {return mForSculpt;}
+ BOOL isForSculptOnly() const;
+
+ //raw image management
+ void checkCachedRawSculptImage() ;
+ LLImageRaw* getRawImage()const { return mRawImage ;}
+ S32 getRawImageLevel() const {return mRawDiscardLevel;}
+ LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;}
+ S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
+ BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;}
+ BOOL isRawImageValid()const { return mIsRawImageValid ; }
+ void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
+ /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
+ void destroySavedRawImage() ;
+ LLImageRaw* getSavedRawImage() ;
+ BOOL hasSavedRawImage() const ;
+ F32 getElapsedLastReferencedSavedRawImageTime() const ;
+ BOOL isFullyLoaded() const;
+
+ BOOL hasFetcher() const { return mHasFetcher;}
+ bool isFetching() const { return mIsFetching;}
+ void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
+
+ void forceToDeleteRequest();
+ void loadFromFastCache();
+ void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
+ bool isInFastCacheList() { return mInFastCacheList; }
+
+ /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
protected:
- /*virtual*/ void switchToCachedImage() override;
- S32 getCurrentDiscardLevelForFetching() ;
+ /*virtual*/ void switchToCachedImage() override;
+ S32 getCurrentDiscardLevelForFetching() ;
+ void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
private:
- void init(bool firstinit) ;
- void cleanup() ;
+ void init(bool firstinit) ;
+ void cleanup() ;
- void saveRawImage() ;
- void setCachedRawImage() ;
+ void saveRawImage() ;
+ void setCachedRawImage() ;
- //for atlas
- void resetFaceAtlas() ;
- void invalidateAtlas(BOOL rebuild_geom) ;
- BOOL insertToAtlas() ;
+ //for atlas
+ void resetFaceAtlas() ;
+ void invalidateAtlas(BOOL rebuild_geom) ;
+ BOOL insertToAtlas() ;
private:
- BOOL mFullyLoaded;
- BOOL mInDebug;
- BOOL mUnremovable;
- BOOL mInFastCacheList;
- BOOL mForceCallbackFetch;
-
-protected:
- std::string mLocalFileName;
-
- S32 mOrigWidth;
- S32 mOrigHeight;
-
- // Override the computation of discard levels if we know the exact output size of the image.
- // Used for UI textures to not decode, even if we have more data.
- S32 mKnownDrawWidth;
- S32 mKnownDrawHeight;
- BOOL mKnownDrawSizeChanged ;
- std::string mUrl;
-
- S32 mRequestedDiscardLevel;
- F32 mRequestedDownloadPriority;
- S32 mFetchState;
+ BOOL mFullyLoaded;
+ BOOL mInDebug;
+ BOOL mUnremovable;
+ BOOL mInFastCacheList;
+ BOOL mForceCallbackFetch;
+
+protected:
+ std::string mLocalFileName;
+
+ S32 mOrigWidth;
+ S32 mOrigHeight;
+
+ // Override the computation of discard levels if we know the exact output size of the image.
+ // Used for UI textures to not decode, even if we have more data.
+ S32 mKnownDrawWidth;
+ S32 mKnownDrawHeight;
+ BOOL mKnownDrawSizeChanged ;
+ std::string mUrl;
+
+ S32 mRequestedDiscardLevel;
+ F32 mRequestedDownloadPriority;
+ S32 mFetchState;
S32 mLastFetchState = -1; // DEBUG
- U32 mFetchPriority;
- F32 mDownloadProgress;
- F32 mFetchDeltaTime;
- F32 mRequestDeltaTime;
- S32 mMinDiscardLevel;
- S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
- S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
-
- S8 mNeedsAux; // We need to decode the auxiliary channels
- S8 mHasAux; // We have aux channels
- S8 mDecodingAux; // Are we decoding high components
- S8 mIsRawImageValid;
- S8 mHasFetcher; // We've made a fecth request
- S8 mIsFetching; // Fetch request is active
- bool mCanUseHTTP; //This texture can be fetched through http if true.
- LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture.
-
- FTType mFTType; // What category of image is this - map tile, server bake, etc?
- mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
-
- typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
- S8 mLoadedCallbackDesiredDiscardLevel;
- BOOL mPauseLoadedCallBacks;
- callback_list_t mLoadedCallbackList;
- F32 mLastCallBackActiveTime;
-
- LLPointer<LLImageRaw> mRawImage;
- S32 mRawDiscardLevel = -1;
-
- // Used ONLY for cloth meshes right now. Make SURE you know what you're
- // doing if you use it for anything else! - djs
- LLPointer<LLImageRaw> mAuxRawImage;
-
- //keep a copy of mRawImage for some special purposes
- //when mForceToSaveRawImage is set.
- BOOL mForceToSaveRawImage ;
- BOOL mSaveRawImage;
- LLPointer<LLImageRaw> mSavedRawImage;
- S32 mSavedRawDiscardLevel;
- S32 mDesiredSavedRawDiscardLevel;
- F32 mLastReferencedSavedRawImageTime ;
- F32 mKeptSavedRawImageTime ;
-
- //a small version of the copy of the raw image (<= 64 * 64)
- LLPointer<LLImageRaw> mCachedRawImage;
- S32 mCachedRawDiscardLevel;
- BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.
-
- LLHost mTargetHost; // if invalid, just request from agent's simulator
-
- // Timers
- LLFrameTimer mLastPacketTimer; // Time since last packet.
- LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f.
-
- BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!)
- // This needs to be atomic, since it is written both in the main thread
- // and in the GL image worker thread... HB
- LLAtomicBool mNeedsCreateTexture;
-
- BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
- BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
+ U32 mFetchPriority;
+ F32 mDownloadProgress;
+ F32 mFetchDeltaTime;
+ F32 mRequestDeltaTime;
+ S32 mMinDiscardLevel;
+ S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
+ S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
+
+ S8 mNeedsAux; // We need to decode the auxiliary channels
+ S8 mHasAux; // We have aux channels
+ S8 mDecodingAux; // Are we decoding high components
+ S8 mIsRawImageValid;
+ S8 mHasFetcher; // We've made a fecth request
+ S8 mIsFetching; // Fetch request is active
+ bool mCanUseHTTP; //This texture can be fetched through http if true.
+ LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture.
+
+ FTType mFTType; // What category of image is this - map tile, server bake, etc?
+ mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
+
+ typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
+ S8 mLoadedCallbackDesiredDiscardLevel;
+ BOOL mPauseLoadedCallBacks;
+ callback_list_t mLoadedCallbackList;
+ F32 mLastCallBackActiveTime;
+
+ LLPointer<LLImageRaw> mRawImage;
+ S32 mRawDiscardLevel = -1;
+
+ // Used ONLY for cloth meshes right now. Make SURE you know what you're
+ // doing if you use it for anything else! - djs
+ LLPointer<LLImageRaw> mAuxRawImage;
+
+ //keep a copy of mRawImage for some special purposes
+ //when mForceToSaveRawImage is set.
+ BOOL mForceToSaveRawImage ;
+ BOOL mSaveRawImage;
+ LLPointer<LLImageRaw> mSavedRawImage;
+ S32 mSavedRawDiscardLevel;
+ S32 mDesiredSavedRawDiscardLevel;
+ F32 mLastReferencedSavedRawImageTime ;
+ F32 mKeptSavedRawImageTime ;
+
+ //a small version of the copy of the raw image (<= 64 * 64)
+ LLPointer<LLImageRaw> mCachedRawImage;
+ S32 mCachedRawDiscardLevel;
+ BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.
+
+ LLHost mTargetHost; // if invalid, just request from agent's simulator
+
+ // Timers
+ LLFrameTimer mLastPacketTimer; // Time since last packet.
+ LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f.
+
+ BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!)
+ // This needs to be atomic, since it is written both in the main thread
+ // and in the GL image worker thread... HB
+ LLAtomicBool mNeedsCreateTexture;
+
+ BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
+ BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
public:
static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize
- static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
- static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
- static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
- static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
- static LLPointer<LLViewerFetchedTexture> sDefaultIrradiancePBRp; // PBR: irradiance
+ static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
+ static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
+ static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
+ static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
+ static LLPointer<LLViewerFetchedTexture> sDefaultIrradiancePBRp; // PBR: irradiance
// not sure why, but something is iffy about the loading of this particular texture, use the accessor instead of accessing directly
static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
@@ -539,24 +539,24 @@ public:
class LLViewerLODTexture : public LLViewerFetchedTexture
{
protected:
- /*virtual*/ ~LLViewerLODTexture(){}
+ /*virtual*/ ~LLViewerLODTexture(){}
public:
- LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
- LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
+ LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
- /*virtual*/ S8 getType() const;
- // Process image stats to determine priority/quality requirements.
- /*virtual*/ void processTextureStats();
- bool isUpdateFrozen() ;
+ /*virtual*/ S8 getType() const;
+ // Process image stats to determine priority/quality requirements.
+ /*virtual*/ void processTextureStats();
+ bool isUpdateFrozen() ;
private:
- void init(bool firstinit) ;
- bool scaleDown() ;
+ void init(bool firstinit) ;
+ bool scaleDown() ;
private:
- F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
- F32 mCalculatedDiscardLevel; // Last calculated discard level
+ F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
+ F32 mCalculatedDiscardLevel; // Last calculated discard level
};
//
@@ -566,135 +566,135 @@ private:
class LLViewerMediaTexture : public LLViewerTexture
{
protected:
- /*virtual*/ ~LLViewerMediaTexture() ;
+ /*virtual*/ ~LLViewerMediaTexture() ;
public:
- LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+ LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
- /*virtual*/ S8 getType() const;
- void reinit(BOOL usemipmaps = TRUE);
+ /*virtual*/ S8 getType() const;
+ void reinit(BOOL usemipmaps = TRUE);
- BOOL getUseMipMaps() {return mUseMipMaps ; }
- void setUseMipMaps(BOOL mipmap) ;
-
- void setPlaying(BOOL playing) ;
- BOOL isPlaying() const {return mIsPlaying;}
- void setMediaImpl() ;
+ BOOL getUseMipMaps() {return mUseMipMaps ; }
+ void setUseMipMaps(BOOL mipmap) ;
+
+ void setPlaying(BOOL playing) ;
+ BOOL isPlaying() const {return mIsPlaying;}
+ void setMediaImpl() ;
virtual bool isViewerMediaTexture() const { return true; }
- void initVirtualSize() ;
- void invalidateMediaImpl() ;
+ void initVirtualSize() ;
+ void invalidateMediaImpl() ;
- void addMediaToFace(LLFace* facep) ;
- void removeMediaFromFace(LLFace* facep) ;
+ void addMediaToFace(LLFace* facep) ;
+ void removeMediaFromFace(LLFace* facep) ;
- /*virtual*/ void addFace(U32 ch, LLFace* facep) ;
- /*virtual*/ void removeFace(U32 ch, LLFace* facep) ;
+ /*virtual*/ void addFace(U32 ch, LLFace* facep) ;
+ /*virtual*/ void removeFace(U32 ch, LLFace* facep) ;
- /*virtual*/ F32 getMaxVirtualSize() ;
+ /*virtual*/ F32 getMaxVirtualSize() ;
private:
- void switchTexture(U32 ch, LLFace* facep) ;
- BOOL findFaces() ;
- void stopPlaying() ;
+ void switchTexture(U32 ch, LLFace* facep) ;
+ BOOL findFaces() ;
+ void stopPlaying() ;
private:
- //
- //an instant list, recording all faces referencing or can reference to this media texture.
- //NOTE: it is NOT thread safe.
- //
- std::list< LLFace* > mMediaFaceList ;
+ //
+ //an instant list, recording all faces referencing or can reference to this media texture.
+ //NOTE: it is NOT thread safe.
+ //
+ std::list< LLFace* > mMediaFaceList ;
- //an instant list keeping all textures which are replaced by the current media texture,
- //is only used to avoid the removal of those textures from memory.
- std::list< LLPointer<LLViewerTexture> > mTextureList ;
+ //an instant list keeping all textures which are replaced by the current media texture,
+ //is only used to avoid the removal of those textures from memory.
+ std::list< LLPointer<LLViewerTexture> > mTextureList ;
- LLViewerMediaImpl* mMediaImplp ;
- BOOL mIsPlaying ;
- U32 mUpdateVirtualSizeTime ;
+ LLViewerMediaImpl* mMediaImplp ;
+ BOOL mIsPlaying ;
+ U32 mUpdateVirtualSizeTime ;
public:
- static void updateClass() ;
- static void cleanUpClass() ;
+ static void updateClass() ;
+ static void cleanUpClass() ;
- static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
- static void removeMediaImplFromTexture(const LLUUID& media_id) ;
+ static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
+ static void removeMediaImplFromTexture(const LLUUID& media_id) ;
private:
- typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
- static media_map_t sMediaMap ;
+ typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
+ static media_map_t sMediaMap ;
};
//just an interface class, do not create instance from this class.
class LLViewerTextureManager
{
private:
- //make the constructor private to preclude creating instances from this class.
- LLViewerTextureManager(){}
+ //make the constructor private to preclude creating instances from this class.
+ LLViewerTextureManager(){}
public:
//texture pipeline tester
- static LLTexturePipelineTester* sTesterp ;
-
- //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture.
- static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ;
-
- //
- //"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
- //
- static void findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output);
- static void findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output);
- static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type);
- static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ;
-
- static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
-
- //
- //"get-texture" will create a new texture if the texture does not exist.
- //
- static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
-
- static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE);
- static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
- static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
- static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLTexturePipelineTester* sTesterp ;
+
+ //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture.
+ static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ;
+
+ //
+ //"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
+ //
+ static void findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output);
+ static void findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output);
+ static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type);
+ static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ;
+
+ static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+
+ //
+ //"get-texture" will create a new texture if the texture does not exist.
+ //
+ static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+
+ static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE);
+ static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps);
- static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
- FTType f_type = FTT_DEFAULT,
- BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
- S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
- LLGLint internal_format = 0,
- LLGLenum primary_format = 0,
- LLHost request_from_host = LLHost()
- );
-
- static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,
- FTType f_type = FTT_LOCAL_FILE,
- BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
- S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
- LLGLint internal_format = 0,
- LLGLenum primary_format = 0,
- const LLUUID& force_id = LLUUID::null
- );
-
- static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,
- FTType f_type,
- BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
- S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
- LLGLint internal_format = 0,
- LLGLenum primary_format = 0,
- const LLUUID& force_id = LLUUID::null
- );
-
- static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
-
- static void init() ;
- static void cleanup() ;
+ static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
+ FTType f_type = FTT_DEFAULT,
+ BOOL usemipmap = TRUE,
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ LLHost request_from_host = LLHost()
+ );
+
+ static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,
+ FTType f_type = FTT_LOCAL_FILE,
+ BOOL usemipmap = TRUE,
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ const LLUUID& force_id = LLUUID::null
+ );
+
+ static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,
+ FTType f_type,
+ BOOL usemipmap = TRUE,
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ const LLUUID& force_id = LLUUID::null
+ );
+
+ static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
+
+ static void init() ;
+ static void cleanup() ;
};
//
//this class is used for test/debug only
@@ -703,91 +703,91 @@ public:
//
class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession
{
- enum
- {
- MIN_LARGE_IMAGE_AREA = 262144 //512 * 512
- };
+ enum
+ {
+ MIN_LARGE_IMAGE_AREA = 262144 //512 * 512
+ };
public:
- LLTexturePipelineTester() ;
- ~LLTexturePipelineTester() ;
+ LLTexturePipelineTester() ;
+ ~LLTexturePipelineTester() ;
- void update();
- void updateTextureBindingStats(const LLViewerTexture* imagep) ;
- void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ;
- void updateGrayTextureBinding() ;
- void setStablizingTime() ;
+ void update();
+ void updateTextureBindingStats(const LLViewerTexture* imagep) ;
+ void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ;
+ void updateGrayTextureBinding() ;
+ void setStablizingTime() ;
private:
- void reset() ;
- void updateStablizingTime() ;
+ void reset() ;
+ void updateStablizingTime() ;
- /*virtual*/ void outputTestRecord(LLSD* sd) ;
+ /*virtual*/ void outputTestRecord(LLSD* sd) ;
private:
- BOOL mPause ;
+ BOOL mPause ;
private:
- BOOL mUsingDefaultTexture; //if set, some textures are still gray.
-
- U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame.
- U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256.
- U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame.
- U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256.
-
- //
- //data size
- //
- U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline
- U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache
- U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256.
- U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties
-
- //
- //time
- //NOTE: the error tolerances of the following timers is one frame time.
- //
- F32 mStartFetchingTime ;
- F32 mTotalGrayTime ; //total loading time when no gray textures.
- F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows
- F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images.
- F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images.
- F32 mStartStablizingTime ;
- F32 mEndStablizingTime ;
+ BOOL mUsingDefaultTexture; //if set, some textures are still gray.
+
+ U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame.
+ U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256.
+ U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame.
+ U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256.
+
+ //
+ //data size
+ //
+ U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline
+ U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache
+ U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256.
+ U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties
+
+ //
+ //time
+ //NOTE: the error tolerances of the following timers is one frame time.
+ //
+ F32 mStartFetchingTime ;
+ F32 mTotalGrayTime ; //total loading time when no gray textures.
+ F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows
+ F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images.
+ F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images.
+ F32 mStartStablizingTime ;
+ F32 mEndStablizingTime ;
private:
- //
- //The following members are used for performance analyzing
- //
- class LLTextureTestSession : public LLTestSession
- {
- public:
- LLTextureTestSession() ;
- /*virtual*/ ~LLTextureTestSession() ;
-
- void reset() ;
-
- F32 mTotalGrayTime ;
- F32 mTotalStablizingTime ;
- F32 mStartTimeLoadingSculpties ;
- F32 mTotalTimeLoadingSculpties ;
-
- S32 mTotalBytesLoaded ;
- S32 mTotalBytesLoadedFromCache ;
- S32 mTotalBytesLoadedForLargeImage ;
- S32 mTotalBytesLoadedForSculpties ;
-
- typedef struct _texture_instant_preformance_t
- {
- S32 mAverageBytesUsedPerSecond ;
- S32 mAverageBytesUsedForLargeImagePerSecond ;
- F32 mAveragePercentageBytesUsedPerSecond ;
- F32 mTime ;
- }texture_instant_preformance_t ;
- std::vector<texture_instant_preformance_t> mInstantPerformanceList ;
- S32 mInstantPerformanceListCounter ;
- };
-
- /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ;
- /*virtual*/ void compareTestSessions(llofstream* os) ;
+ //
+ //The following members are used for performance analyzing
+ //
+ class LLTextureTestSession : public LLTestSession
+ {
+ public:
+ LLTextureTestSession() ;
+ /*virtual*/ ~LLTextureTestSession() ;
+
+ void reset() ;
+
+ F32 mTotalGrayTime ;
+ F32 mTotalStablizingTime ;
+ F32 mStartTimeLoadingSculpties ;
+ F32 mTotalTimeLoadingSculpties ;
+
+ S32 mTotalBytesLoaded ;
+ S32 mTotalBytesLoadedFromCache ;
+ S32 mTotalBytesLoadedForLargeImage ;
+ S32 mTotalBytesLoadedForSculpties ;
+
+ typedef struct _texture_instant_preformance_t
+ {
+ S32 mAverageBytesUsedPerSecond ;
+ S32 mAverageBytesUsedForLargeImagePerSecond ;
+ F32 mAveragePercentageBytesUsedPerSecond ;
+ F32 mTime ;
+ }texture_instant_preformance_t ;
+ std::vector<texture_instant_preformance_t> mInstantPerformanceList ;
+ S32 mInstantPerformanceListCounter ;
+ };
+
+ /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ;
+ /*virtual*/ void compareTestSessions(llofstream* os) ;
};
#endif
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ce144f67c7..a0b0fabb66 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerwindow.cpp
* @brief Implementation of the LLViewerWindow class.
*
* $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$
*/
@@ -62,7 +62,7 @@
//
// linden library includes
-#include "llaudioengine.h" // mute on minimize
+#include "llaudioengine.h" // mute on minimize
#include "llchatentry.h"
#include "indra_constants.h"
#include "llassetstorage.h"
@@ -166,7 +166,7 @@
#include "lltoolselectland.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
-#include "llurldispatcher.h" // SLURL from other app instance
+#include "llurldispatcher.h" // SLURL from other app instance
#include "llversioninfo.h"
#include "llvieweraudio.h"
#include "llviewercamera.h"
@@ -231,29 +231,31 @@ extern BOOL gResizeScreenTexture;
extern BOOL gCubeSnapshot;
extern BOOL gSnapshotNoPost;
-LLViewerWindow *gViewerWindow = NULL;
+LLViewerWindow *gViewerWindow = NULL;
-LLFrameTimer gAwayTimer;
-LLFrameTimer gAwayTriggerTimer;
+LLFrameTimer gAwayTimer;
+LLFrameTimer gAwayTriggerTimer;
-BOOL gShowOverlayTitle = FALSE;
+BOOL gShowOverlayTitle = FALSE;
LLViewerObject* gDebugRaycastObject = NULL;
LLVOPartGroup* gDebugRaycastParticle = NULL;
LLVector4a gDebugRaycastIntersection;
-LLVector4a gDebugRaycastParticleIntersection;
+LLVector4a gDebugRaycastParticleIntersection;
LLVector2 gDebugRaycastTexCoord;
LLVector4a gDebugRaycastNormal;
LLVector4a gDebugRaycastTangent;
-S32 gDebugRaycastFaceHit;
-LLVector4a gDebugRaycastStart;
-LLVector4a gDebugRaycastEnd;
+S32 gDebugRaycastFaceHit;
+S32 gDebugRaycastGLTFNodeHit;
+S32 gDebugRaycastGLTFPrimitiveHit;
+LLVector4a gDebugRaycastStart;
+LLVector4a gDebugRaycastEnd;
// HUD display lines in lower right
-BOOL gDisplayWindInfo = FALSE;
-BOOL gDisplayCameraPos = FALSE;
-BOOL gDisplayFOV = FALSE;
-BOOL gDisplayBadge = FALSE;
+BOOL gDisplayWindInfo = FALSE;
+BOOL gDisplayCameraPos = FALSE;
+BOOL gDisplayFOV = FALSE;
+BOOL gDisplayBadge = FALSE;
static const U8 NO_FACE = 255;
BOOL gQuietSnapshot = FALSE;
@@ -267,8 +269,8 @@ static const F32 MIN_DISPLAY_SCALE = 0.75f;
static const char KEY_MOUSELOOK = 'M';
-static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"));
-static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", ""));
+static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"));
+static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", ""));
LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity");
@@ -276,40 +278,40 @@ LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity")
class RecordToChatConsoleRecorder : public LLError::Recorder
{
public:
- virtual void recordMessage(LLError::ELevel level,
- const std::string& message)
- {
- //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread
-
- // only log warnings to chat console
- //if (level == LLError::LEVEL_WARN)
- //{
- //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
- //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat"))
- //{
- // LLChat chat;
- // chat.mText = message;
- // chat.mSourceType = CHAT_SOURCE_SYSTEM;
-
- // chat_floater->addChat(chat, FALSE, FALSE);
- //}
- //}
- }
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ //FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread
+
+ // only log warnings to chat console
+ //if (level == LLError::LEVEL_WARN)
+ //{
+ //LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
+ //if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat"))
+ //{
+ // LLChat chat;
+ // chat.mText = message;
+ // chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+ // chat_floater->addChat(chat, FALSE, FALSE);
+ //}
+ //}
+ }
};
class RecordToChatConsole : public LLSingleton<RecordToChatConsole>
{
- LLSINGLETON(RecordToChatConsole);
+ LLSINGLETON(RecordToChatConsole);
public:
- void startRecorder() { LLError::addRecorder(mRecorder); }
- void stopRecorder() { LLError::removeRecorder(mRecorder); }
+ void startRecorder() { LLError::addRecorder(mRecorder); }
+ void stopRecorder() { LLError::removeRecorder(mRecorder); }
private:
- LLError::RecorderPtr mRecorder;
+ LLError::RecorderPtr mRecorder;
};
RecordToChatConsole::RecordToChatConsole():
- mRecorder(new RecordToChatConsoleRecorder())
+ mRecorder(new RecordToChatConsoleRecorder())
{
mRecorder->showTags(false);
mRecorder->showLocation(false);
@@ -419,214 +421,214 @@ static LLTrace::BlockTimerStatHandle FTM_DISPLAY_DEBUG_TEXT("Display Debug Text"
class LLDebugText
{
private:
- struct Line
- {
- Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
- std::string text;
- S32 x,y;
- };
-
- LLViewerWindow *mWindow;
-
- typedef std::vector<Line> line_list_t;
- line_list_t mLineList;
- LLColor4 mTextColor;
-
- LLColor4 mBackColor;
- LLRect mBackRectCamera1;
- LLRect mBackRectCamera2;
-
- void addText(S32 x, S32 y, const std::string &text)
- {
- mLineList.push_back(Line(text, x, y));
- }
-
- void clearText() { mLineList.clear(); }
-
+ struct Line
+ {
+ Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
+ std::string text;
+ S32 x,y;
+ };
+
+ LLViewerWindow *mWindow;
+
+ typedef std::vector<Line> line_list_t;
+ line_list_t mLineList;
+ LLColor4 mTextColor;
+
+ LLColor4 mBackColor;
+ LLRect mBackRectCamera1;
+ LLRect mBackRectCamera2;
+
+ void addText(S32 x, S32 y, const std::string &text)
+ {
+ mLineList.push_back(Line(text, x, y));
+ }
+
+ void clearText() { mLineList.clear(); }
+
public:
- LLDebugText(LLViewerWindow* window) : mWindow(window) {}
-
- void update()
- {
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- clearText();
- return;
- }
-
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
- std::string wind_vel_text;
- std::string wind_vector_text;
- std::string rwind_vel_text;
- std::string rwind_vector_text;
- std::string audio_text;
-
- static const std::string beacon_particle = LLTrans::getString("BeaconParticle");
- static const std::string beacon_physical = LLTrans::getString("BeaconPhysical");
- static const std::string beacon_scripted = LLTrans::getString("BeaconScripted");
- static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
- static const std::string beacon_sound = LLTrans::getString("BeaconSound");
- static const std::string beacon_media = LLTrans::getString("BeaconMedia");
- static const std::string beacon_sun = LLTrans::getString("BeaconSun");
- static const std::string beacon_moon = LLTrans::getString("BeaconMoon");
- static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
-
- // Draw the statistics in a light gray
- // and in a thin font
- mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
-
- // Draw stuff growing up from right lower corner of screen
- S32 x_right = mWindow->getWorldViewWidthScaled();
- S32 xpos = x_right - 400;
- xpos = llmax(xpos, 0);
- S32 ypos = 64;
- const S32 y_inc = 20;
-
- // Camera matrix text is hard to see again a white background
- // Add a dark background underneath the matrices for readability (contrast)
- mBackRectCamera1.mLeft = xpos;
- mBackRectCamera1.mRight = x_right;
- mBackRectCamera1.mTop = -1;
- mBackRectCamera1.mBottom = -1;
- mBackRectCamera2 = mBackRectCamera1;
-
- mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
-
- clearText();
-
- if (gSavedSettings.getBOOL("DebugShowTime"))
- {
- F32 time = gFrameTimeSeconds;
- S32 hours = (S32)(time / (60*60));
- S32 mins = (S32)((time - hours*(60*60)) / 60);
- S32 secs = (S32)((time - hours*(60*60) - mins*60));
- addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
- }
-
- if (gSavedSettings.getBOOL("DebugShowMemory"))
- {
- addText(xpos, ypos,
- STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)"));
- ypos += y_inc;
- }
-
- if (gDisplayCameraPos)
- {
- std::string camera_view_text;
- std::string camera_center_text;
- std::string agent_view_text;
- std::string agent_left_text;
- std::string agent_center_text;
- std::string agent_root_center_text;
-
- LLVector3d tvector; // Temporary vector to hold data for printing.
-
- // Update camera center, camera view, wind info every other frame
- tvector = gAgent.getPositionGlobal();
- agent_center_text = llformat("AgentCenter %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
-
- if (isAgentAvatarValid())
- {
- tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
- agent_root_center_text = llformat("AgentRootCenter %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
- }
- else
- {
- agent_root_center_text = "---";
- }
-
-
- tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
- agent_view_text = llformat("AgentAtAxis %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
-
- tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
- agent_left_text = llformat("AgentLeftAxis %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
-
- tvector = gAgentCamera.getCameraPositionGlobal();
- camera_center_text = llformat("CameraCenter %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
-
- tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
- camera_view_text = llformat("CameraAtAxis %f %f %f",
- (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
-
- addText(xpos, ypos, agent_center_text); ypos += y_inc;
- addText(xpos, ypos, agent_root_center_text); ypos += y_inc;
- addText(xpos, ypos, agent_view_text); ypos += y_inc;
- addText(xpos, ypos, agent_left_text); ypos += y_inc;
- addText(xpos, ypos, camera_center_text); ypos += y_inc;
- addText(xpos, ypos, camera_view_text); ypos += y_inc;
- }
-
- if (gDisplayWindInfo)
- {
- wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec());
- wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]);
- rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec());
- rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]);
-
- addText(xpos, ypos, wind_vel_text); ypos += y_inc;
- addText(xpos, ypos, wind_vector_text); ypos += y_inc;
- addText(xpos, ypos, rwind_vel_text); ypos += y_inc;
- addText(xpos, ypos, rwind_vector_text); ypos += y_inc;
- }
- if (gDisplayWindInfo)
- {
- audio_text = llformat("Audio for wind: %d", gAudiop ? gAudiop->isWindEnabled() : -1);
- addText(xpos, ypos, audio_text); ypos += y_inc;
- }
- if (gDisplayFOV)
- {
- addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
- ypos += y_inc;
- }
- if (gDisplayBadge)
- {
- addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
- ypos += y_inc * 2;
- }
-
- /*if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- addText(xpos + 200, ypos, llformat("Flycam"));
- ypos += y_inc;
- }*/
-
- if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
- {
- LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
-
- //show streaming cost/triangle count of known prims in current region OR selection
- {
- F32 cost = 0.f;
- S32 count = 0;
- S32 vcount = 0;
- S32 object_count = 0;
- S32 total_bytes = 0;
- S32 visible_bytes = 0;
-
- const char* label = "Region";
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)
- { //region
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- for (U32 i = 0; i < gObjectList.getNumObjects(); ++i)
- {
- LLViewerObject* object = gObjectList.getObject(i);
- if (object &&
- object->getRegion() == region &&
- object->getVolume())
- {
- object_count++;
- S32 bytes = 0;
- S32 visible = 0;
- cost += object->getStreamingCost();
+ LLDebugText(LLViewerWindow* window) : mWindow(window) {}
+
+ void update()
+ {
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ clearText();
+ return;
+ }
+
+ static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
+
+ std::string wind_vel_text;
+ std::string wind_vector_text;
+ std::string rwind_vel_text;
+ std::string rwind_vector_text;
+ std::string audio_text;
+
+ static const std::string beacon_particle = LLTrans::getString("BeaconParticle");
+ static const std::string beacon_physical = LLTrans::getString("BeaconPhysical");
+ static const std::string beacon_scripted = LLTrans::getString("BeaconScripted");
+ static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
+ static const std::string beacon_sound = LLTrans::getString("BeaconSound");
+ static const std::string beacon_media = LLTrans::getString("BeaconMedia");
+ static const std::string beacon_sun = LLTrans::getString("BeaconSun");
+ static const std::string beacon_moon = LLTrans::getString("BeaconMoon");
+ static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
+
+ // Draw the statistics in a light gray
+ // and in a thin font
+ mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
+
+ // Draw stuff growing up from right lower corner of screen
+ S32 x_right = mWindow->getWorldViewWidthScaled();
+ S32 xpos = x_right - 400;
+ xpos = llmax(xpos, 0);
+ S32 ypos = 64;
+ const S32 y_inc = 20;
+
+ // Camera matrix text is hard to see again a white background
+ // Add a dark background underneath the matrices for readability (contrast)
+ mBackRectCamera1.mLeft = xpos;
+ mBackRectCamera1.mRight = x_right;
+ mBackRectCamera1.mTop = -1;
+ mBackRectCamera1.mBottom = -1;
+ mBackRectCamera2 = mBackRectCamera1;
+
+ mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
+
+ clearText();
+
+ if (gSavedSettings.getBOOL("DebugShowTime"))
+ {
+ F32 time = gFrameTimeSeconds;
+ S32 hours = (S32)(time / (60*60));
+ S32 mins = (S32)((time - hours*(60*60)) / 60);
+ S32 secs = (S32)((time - hours*(60*60) - mins*60));
+ addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
+ }
+
+ if (gSavedSettings.getBOOL("DebugShowMemory"))
+ {
+ addText(xpos, ypos,
+ STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)"));
+ ypos += y_inc;
+ }
+
+ if (gDisplayCameraPos)
+ {
+ std::string camera_view_text;
+ std::string camera_center_text;
+ std::string agent_view_text;
+ std::string agent_left_text;
+ std::string agent_center_text;
+ std::string agent_root_center_text;
+
+ LLVector3d tvector; // Temporary vector to hold data for printing.
+
+ // Update camera center, camera view, wind info every other frame
+ tvector = gAgent.getPositionGlobal();
+ agent_center_text = llformat("AgentCenter %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+
+ if (isAgentAvatarValid())
+ {
+ tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
+ agent_root_center_text = llformat("AgentRootCenter %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+ }
+ else
+ {
+ agent_root_center_text = "---";
+ }
+
+
+ tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
+ agent_view_text = llformat("AgentAtAxis %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+
+ tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
+ agent_left_text = llformat("AgentLeftAxis %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+
+ tvector = gAgentCamera.getCameraPositionGlobal();
+ camera_center_text = llformat("CameraCenter %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+
+ tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
+ camera_view_text = llformat("CameraAtAxis %f %f %f",
+ (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
+
+ addText(xpos, ypos, agent_center_text); ypos += y_inc;
+ addText(xpos, ypos, agent_root_center_text); ypos += y_inc;
+ addText(xpos, ypos, agent_view_text); ypos += y_inc;
+ addText(xpos, ypos, agent_left_text); ypos += y_inc;
+ addText(xpos, ypos, camera_center_text); ypos += y_inc;
+ addText(xpos, ypos, camera_view_text); ypos += y_inc;
+ }
+
+ if (gDisplayWindInfo)
+ {
+ wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec());
+ wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]);
+ rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec());
+ rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]);
+
+ addText(xpos, ypos, wind_vel_text); ypos += y_inc;
+ addText(xpos, ypos, wind_vector_text); ypos += y_inc;
+ addText(xpos, ypos, rwind_vel_text); ypos += y_inc;
+ addText(xpos, ypos, rwind_vector_text); ypos += y_inc;
+ }
+ if (gDisplayWindInfo)
+ {
+ audio_text = llformat("Audio for wind: %d", gAudiop ? gAudiop->isWindEnabled() : -1);
+ addText(xpos, ypos, audio_text); ypos += y_inc;
+ }
+ if (gDisplayFOV)
+ {
+ addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
+ ypos += y_inc;
+ }
+ if (gDisplayBadge)
+ {
+ addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
+ ypos += y_inc * 2;
+ }
+
+ /*if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ addText(xpos + 200, ypos, llformat("Flycam"));
+ ypos += y_inc;
+ }*/
+
+ if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
+ {
+ LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
+
+ //show streaming cost/triangle count of known prims in current region OR selection
+ {
+ F32 cost = 0.f;
+ S32 count = 0;
+ S32 vcount = 0;
+ S32 object_count = 0;
+ S32 total_bytes = 0;
+ S32 visible_bytes = 0;
+
+ const char* label = "Region";
+ if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)
+ { //region
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ for (U32 i = 0; i < gObjectList.getNumObjects(); ++i)
+ {
+ LLViewerObject* object = gObjectList.getObject(i);
+ if (object &&
+ object->getRegion() == region &&
+ object->getVolume())
+ {
+ object_count++;
+ S32 bytes = 0;
+ S32 visible = 0;
+ cost += object->getStreamingCost();
LLMeshCostData costs;
if (object->getCostData(costs))
{
@@ -634,96 +636,96 @@ public:
visible = costs.getSizeByLOD(object->getLOD());
}
- S32 vt = 0;
- count += object->getTriangleCount(&vt);
- vcount += vt;
- total_bytes += bytes;
- visible_bytes += visible;
- }
- }
- }
- }
- else
- {
- label = "Selection";
- cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);
- count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount);
- object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
- }
-
- addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects",
- count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));
- ypos += y_inc;
-
- }
-
- addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount));
+ S32 vt = 0;
+ count += object->getTriangleCount(&vt);
+ vcount += vt;
+ total_bytes += bytes;
+ visible_bytes += visible;
+ }
+ }
+ }
+ }
+ else
+ {
+ label = "Selection";
+ cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);
+ count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount);
+ object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ }
+
+ addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects",
+ count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));
+ ypos += y_inc;
+
+ }
+
+ addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d Render Calls", (U32)last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize)));
ypos += y_inc;
- addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
- ypos += y_inc;
-
- 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()));
+ ypos += y_inc;
- addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects()));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
- ypos += y_inc;
+ addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
+ ypos += y_inc;
- addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps));
- ypos += y_inc;
+ addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps));
+ ypos += y_inc;
- gPipeline.mTextureMatrixOps = 0;
- gPipeline.mMatrixOpCount = 0;
+ gPipeline.mTextureMatrixOps = 0;
+ gPipeline.mMatrixOpCount = 0;
- if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0)
- {
+ if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0)
+ {
addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", (U32)last_frame_recording.getMin(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMax(LLPipeline::sStatBatchSize), (U32)last_frame_recording.getMean(LLPipeline::sStatBatchSize)));
- }
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls));
- LLRender::sUICalls = LLRender::sUIVerts = 0;
- ypos += y_inc;
-
- addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount));
-
+ }
ypos += y_inc;
- if (!LLOcclusionCullingGroup::sPendingQueries.empty())
- {
- addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size()));
- ypos += y_inc;
- }
-
+ addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls));
+ LLRender::sUICalls = LLRender::sUIVerts = 0;
+ ypos += y_inc;
- addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));
+ addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount));
+
+ ypos += y_inc;
- ypos += y_inc;
+ if (!LLOcclusionCullingGroup::sPendingQueries.empty())
+ {
+ addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size()));
+ ypos += y_inc;
+ }
- addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount));
- ypos += y_inc;
+ addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));
+
+ ypos += y_inc;
- if (gMeshRepo.meshRezEnabled())
- {
- addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
+ addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount));
+
+ ypos += y_inc;
- ypos += y_inc;
+ if (gMeshRepo.meshRezEnabled())
+ {
+ addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
+
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
+ LLMeshRepository::sHTTPRetryCount));
+ ypos += y_inc;
- addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
- LLMeshRepository::sHTTPRetryCount));
- ypos += y_inc;
+ addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
+ ypos += y_inc;
- addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
+ addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
@@ -731,72 +733,72 @@ public:
addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
- ypos += y_inc;
- }
+ ypos += y_inc;
+ }
gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
- }
- if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo"))
- {
- std::map<std::string, LLVOAvatar*> sorted_avs;
-
- std::vector<LLCharacter*>::iterator sort_iter = LLCharacter::sInstances.begin();
- while (sort_iter != LLCharacter::sInstances.end())
- {
- LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*sort_iter);
- if (avatar &&
- !avatar->isDead()) // Not dead yet
- {
- // Stuff into a sorted map so the display is ordered
- sorted_avs[avatar->getFullname()] = avatar;
- }
- sort_iter++;
- }
-
- std::string trunc_name;
- std::map<std::string, LLVOAvatar*>::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top
- while (av_iter != sorted_avs.rend())
- {
- LLVOAvatar* avatar = av_iter->second;
-
- avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date
-
- trunc_name = utf8str_truncate(avatar->getFullname(), 16);
- addText(xpos, ypos, llformat("%s : %s, complexity %d, area %.2f",
- trunc_name.c_str(),
+ }
+ if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo"))
+ {
+ std::map<std::string, LLVOAvatar*> sorted_avs;
+
+ std::vector<LLCharacter*>::iterator sort_iter = LLCharacter::sInstances.begin();
+ while (sort_iter != LLCharacter::sInstances.end())
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*sort_iter);
+ if (avatar &&
+ !avatar->isDead()) // Not dead yet
+ {
+ // Stuff into a sorted map so the display is ordered
+ sorted_avs[avatar->getFullname()] = avatar;
+ }
+ sort_iter++;
+ }
+
+ std::string trunc_name;
+ std::map<std::string, LLVOAvatar*>::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top
+ while (av_iter != sorted_avs.rend())
+ {
+ LLVOAvatar* avatar = av_iter->second;
+
+ avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date
+
+ trunc_name = utf8str_truncate(avatar->getFullname(), 16);
+ addText(xpos, ypos, llformat("%s : %s, complexity %d, area %.2f",
+ trunc_name.c_str(),
LLVOAvatar::rezStatusToString(avatar->getRezzedStatus()).c_str(),
- avatar->getVisualComplexity(),
- avatar->getAttachmentSurfaceArea()));
- ypos += y_inc;
- av_iter++;
- }
- }
- if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
- {
- char camera_lines[8][32];
- memset(camera_lines, ' ', sizeof(camera_lines));
-
- // Projection last column is always <0,0,-1.0001,0>
- // Projection last row is always <0,0,-0.2>
- mBackRectCamera1.mBottom = ypos - y_inc + 2;
- MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc;
- MATRIX_ROW_N32_TO_STR(gGLProjection, 8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc;
- MATRIX_ROW_N32_TO_STR(gGLProjection, 4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop = ypos + 2;
- MATRIX_ROW_N32_TO_STR(gGLProjection, 0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2;
-
- addText(xpos, ypos, "Projection Matrix");
- ypos += y_inc;
-
- // View last column is always <0,0,0,1>
- MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc;
- MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc;
- MATRIX_ROW_N32_TO_STR(gGLModelView, 4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2;
- MATRIX_ROW_N32_TO_STR(gGLModelView, 0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc;
-
- addText(xpos, ypos, "View Matrix");
- ypos += y_inc;
- }
- // disable use of glReadPixels which messes up nVidia nSight graphics debugging
+ avatar->getVisualComplexity(),
+ avatar->getAttachmentSurfaceArea()));
+ ypos += y_inc;
+ av_iter++;
+ }
+ }
+ if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
+ {
+ char camera_lines[8][32];
+ memset(camera_lines, ' ', sizeof(camera_lines));
+
+ // Projection last column is always <0,0,-1.0001,0>
+ // Projection last row is always <0,0,-0.2>
+ mBackRectCamera1.mBottom = ypos - y_inc + 2;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop = ypos + 2;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2;
+
+ addText(xpos, ypos, "Projection Matrix");
+ ypos += y_inc;
+
+ // View last column is always <0,0,0,1>
+ MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc;
+
+ addText(xpos, ypos, "View Matrix");
+ ypos += y_inc;
+ }
+ // disable use of glReadPixels which messes up nVidia nSight graphics debugging
if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
{
U8 color[4];
@@ -805,165 +807,165 @@ public:
// Convert x,y to raw pixel coords
S32 x_raw = llround(coord.mX * gViewerWindow->getWindowWidthRaw() / (F32) gViewerWindow->getWindowWidthScaled());
S32 y_raw = llround(coord.mY * gViewerWindow->getWindowHeightRaw() / (F32) gViewerWindow->getWindowHeightScaled());
-
+
glReadPixels(x_raw, y_raw, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
addText(xpos, ypos, llformat("Pixel <%1d, %1d> R:%1d G:%1d B:%1d A:%1d", x_raw, y_raw, color[0], color[1], color[2], color[3]));
ypos += y_inc;
}
// only display these messages if we are actually rendering beacons at this moment
- if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
- {
- if (LLPipeline::getRenderMOAPBeacons())
- {
- addText(xpos, ypos, "Viewing media beacons (white)");
- ypos += y_inc;
- }
-
- if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES))
- {
- addText(xpos, ypos, particle_hiding);
- ypos += y_inc;
- }
-
- if (LLPipeline::getRenderParticleBeacons())
- {
- addText(xpos, ypos, "Viewing particle beacons (blue)");
- ypos += y_inc;
- }
-
- if (LLPipeline::getRenderSoundBeacons())
- {
- addText(xpos, ypos, "Viewing sound beacons (yellow)");
- ypos += y_inc;
- }
-
- if (LLPipeline::getRenderScriptedBeacons())
- {
- addText(xpos, ypos, beacon_scripted);
- ypos += y_inc;
- }
- else
- if (LLPipeline::getRenderScriptedTouchBeacons())
- {
- addText(xpos, ypos, beacon_scripted_touch);
- ypos += y_inc;
- }
-
- if (LLPipeline::getRenderPhysicalBeacons())
- {
- addText(xpos, ypos, "Viewing physical object beacons (green)");
- ypos += y_inc;
- }
- }
-
- static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
- static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
-
- if (show_sun_beacon)
- {
- addText(xpos, ypos, beacon_sun);
- ypos += y_inc;
- }
- if (show_moon_beacon)
- {
- addText(xpos, ypos, beacon_moon);
- ypos += y_inc;
- }
-
- if(log_texture_traffic)
- {
- U32 old_y = ypos ;
- for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++)
- {
- if(gTotalTextureBytesPerBoostLevel[i] > (S32Bytes)0)
- {
- addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, F32Megabytes(gTotalTextureBytesPerBoostLevel[i]).value()));
- ypos += y_inc;
- }
- }
- if(ypos != old_y)
- {
- addText(xpos, ypos, "Network traffic for textures:");
- ypos += y_inc;
- }
- }
-
- if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
- {
- LLViewerObject* objectp = NULL ;
-
- LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
- if (nodep)
- {
- objectp = nodep->getObject();
- }
-
- if (objectp && !objectp->isDead())
- {
- S32 num_faces = objectp->mDrawable->getNumFaces() ;
- std::set<LLViewerFetchedTexture*> tex_list;
-
- for(S32 i = 0 ; i < num_faces; i++)
- {
- LLFace* facep = objectp->mDrawable->getFace(i) ;
- if(facep)
- {
- LLViewerFetchedTexture* tex = dynamic_cast<LLViewerFetchedTexture*>(facep->getTexture()) ;
- if(tex)
- {
- if(tex_list.find(tex) != tex_list.end())
- {
- continue ; //already displayed.
- }
- tex_list.insert(tex);
-
- std::string uuid_str;
- tex->getID().toString(uuid_str);
- uuid_str = uuid_str.substr(0,7);
-
- addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize()));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(),
- tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N"));
- ypos += y_inc;
- }
- }
- }
- }
- }
- }
-
- void draw()
- {
- LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT);
-
- // Camera matrix text is hard to see again a white background
- // Add a dark background underneath the matrices for readability (contrast)
- if (mBackRectCamera1.mTop >= 0)
- {
- mBackColor.setAlpha( 0.75f );
- gl_rect_2d(mBackRectCamera1, mBackColor, true);
-
- mBackColor.setAlpha( 0.66f );
- gl_rect_2d(mBackRectCamera2, mBackColor, true);
- }
-
- for (line_list_t::iterator iter = mLineList.begin();
- iter != mLineList.end(); ++iter)
- {
- const Line& line = *iter;
- LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
- LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
- }
- }
+ if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
+ {
+ if (LLPipeline::getRenderMOAPBeacons())
+ {
+ addText(xpos, ypos, "Viewing media beacons (white)");
+ ypos += y_inc;
+ }
+
+ if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES))
+ {
+ addText(xpos, ypos, particle_hiding);
+ ypos += y_inc;
+ }
+
+ if (LLPipeline::getRenderParticleBeacons())
+ {
+ addText(xpos, ypos, "Viewing particle beacons (blue)");
+ ypos += y_inc;
+ }
+
+ if (LLPipeline::getRenderSoundBeacons())
+ {
+ addText(xpos, ypos, "Viewing sound beacons (yellow)");
+ ypos += y_inc;
+ }
+
+ if (LLPipeline::getRenderScriptedBeacons())
+ {
+ addText(xpos, ypos, beacon_scripted);
+ ypos += y_inc;
+ }
+ else
+ if (LLPipeline::getRenderScriptedTouchBeacons())
+ {
+ addText(xpos, ypos, beacon_scripted_touch);
+ ypos += y_inc;
+ }
+
+ if (LLPipeline::getRenderPhysicalBeacons())
+ {
+ addText(xpos, ypos, "Viewing physical object beacons (green)");
+ ypos += y_inc;
+ }
+ }
+
+ static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
+ static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
+
+ if (show_sun_beacon)
+ {
+ addText(xpos, ypos, beacon_sun);
+ ypos += y_inc;
+ }
+ if (show_moon_beacon)
+ {
+ addText(xpos, ypos, beacon_moon);
+ ypos += y_inc;
+ }
+
+ if(log_texture_traffic)
+ {
+ U32 old_y = ypos ;
+ for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++)
+ {
+ if(gTotalTextureBytesPerBoostLevel[i] > (S32Bytes)0)
+ {
+ addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, F32Megabytes(gTotalTextureBytesPerBoostLevel[i]).value()));
+ ypos += y_inc;
+ }
+ }
+ if(ypos != old_y)
+ {
+ addText(xpos, ypos, "Network traffic for textures:");
+ ypos += y_inc;
+ }
+ }
+
+ if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
+ {
+ LLViewerObject* objectp = NULL ;
+
+ LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
+ if (nodep)
+ {
+ objectp = nodep->getObject();
+ }
+
+ if (objectp && !objectp->isDead())
+ {
+ S32 num_faces = objectp->mDrawable->getNumFaces() ;
+ std::set<LLViewerFetchedTexture*> tex_list;
+
+ for(S32 i = 0 ; i < num_faces; i++)
+ {
+ LLFace* facep = objectp->mDrawable->getFace(i) ;
+ if(facep)
+ {
+ LLViewerFetchedTexture* tex = dynamic_cast<LLViewerFetchedTexture*>(facep->getTexture()) ;
+ if(tex)
+ {
+ if(tex_list.find(tex) != tex_list.end())
+ {
+ continue ; //already displayed.
+ }
+ tex_list.insert(tex);
+
+ std::string uuid_str;
+ tex->getID().toString(uuid_str);
+ uuid_str = uuid_str.substr(0,7);
+
+ addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize()));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(),
+ tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N"));
+ ypos += y_inc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void draw()
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT);
+
+ // Camera matrix text is hard to see again a white background
+ // Add a dark background underneath the matrices for readability (contrast)
+ if (mBackRectCamera1.mTop >= 0)
+ {
+ mBackColor.setAlpha( 0.75f );
+ gl_rect_2d(mBackRectCamera1, mBackColor, true);
+
+ mBackColor.setAlpha( 0.66f );
+ gl_rect_2d(mBackRectCamera2, mBackColor, true);
+ }
+
+ for (line_list_t::iterator iter = mLineList.begin();
+ iter != mLineList.end(); ++iter)
+ {
+ const Line& line = *iter;
+ LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
+ LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW);
+ }
+ }
};
void LLViewerWindow::updateDebugText()
{
- mDebugText->update();
+ mDebugText->update();
}
////////////////////////////////////////////////////////////////////////////
@@ -972,16 +974,16 @@ void LLViewerWindow::updateDebugText()
//
LLViewerWindow::Params::Params()
-: title("title"),
- name("name"),
- x("x"),
- y("y"),
- width("width"),
- height("height"),
- min_width("min_width"),
- min_height("min_height"),
- fullscreen("fullscreen", false),
- ignore_pixel_depth("ignore_pixel_depth", false)
+: title("title"),
+ name("name"),
+ x("x"),
+ y("y"),
+ width("width"),
+ height("height"),
+ min_width("min_width"),
+ min_height("min_height"),
+ fullscreen("fullscreen", false),
+ ignore_pixel_depth("ignore_pixel_depth", false)
{}
@@ -998,167 +1000,167 @@ void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask)
BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool& is_toolmgr_action)
{
- const char* buttonname = "";
- const char* buttonstatestr = "";
- S32 x = pos.mX;
- S32 y = pos.mY;
- x = ll_round((F32)x / mDisplayScale.mV[VX]);
- y = ll_round((F32)y / mDisplayScale.mV[VY]);
+ const char* buttonname = "";
+ const char* buttonstatestr = "";
+ S32 x = pos.mX;
+ S32 y = pos.mY;
+ x = ll_round((F32)x / mDisplayScale.mV[VX]);
+ y = ll_round((F32)y / mDisplayScale.mV[VY]);
- // Handle non-consuming global keybindings, like voice
+ // Handle non-consuming global keybindings, like voice
gViewerInput.handleGlobalBindsMouse(clicktype, mask, down);
- // only send mouse clicks to UI if UI is visible
- if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
-
- if (down)
- {
- buttonstatestr = "down" ;
- }
- else
- {
- buttonstatestr = "up" ;
- }
-
- switch (clicktype)
- {
- case CLICK_LEFT:
- mLeftMouseDown = down;
- buttonname = "Left";
- break;
- case CLICK_RIGHT:
- mRightMouseDown = down;
- buttonname = "Right";
- break;
- case CLICK_MIDDLE:
- mMiddleMouseDown = down;
- buttonname = "Middle";
- break;
- case CLICK_DOUBLELEFT:
- mLeftMouseDown = down;
- buttonname = "Left Double Click";
- break;
- case CLICK_BUTTON4:
- buttonname = "Button 4";
- break;
- case CLICK_BUTTON5:
- buttonname = "Button 5";
- break;
- default:
- break; // COUNT and NONE
- }
-
- LLView::sMouseHandlerMessage.clear();
-
- if (gMenuBarView)
- {
- // stop ALT-key access to menu
- gMenuBarView->resetMenuTrigger();
- }
-
- if (gDebugClicks)
- {
- LL_INFOS() << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << LL_ENDL;
- }
-
- // Make sure we get a corresponding mouseup event, even if the mouse leaves the window
- if (down)
- mWindow->captureMouse();
- else
- mWindow->releaseMouse();
-
- // Indicate mouse was active
- LLUI::getInstance()->resetMouseIdleTimer();
-
- // Don't let the user move the mouse out of the window until mouse up.
- if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
- {
- mWindow->setMouseClipping(down);
- }
-
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << LL_ENDL;
- }
-
- BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
- if (r) {
-
- LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << LL_ENDL;
-
- LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
- LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
-
- }
- else if (down && clicktype == CLICK_RIGHT)
- {
- handlePieMenu(x, y, mask);
- r = TRUE;
- }
- return r;
- }
-
- // Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
- if( !mRootView->pointInView(x, y) )
- {
- return TRUE;
- }
- // Give the UI views a chance to process the click
-
- BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ;
- if (r)
- {
-
- LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << LL_ENDL;
-
- LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
-
- // Clear local coords - this was a click on root window so these are not needed
- // By not including them, this allows the test skeleton generation tool to be smarter when generating code
- // the code generator can be smarter because when local coords are present it can try the xui path with local coords
- // and fallback to global coordinates only if needed.
- // The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element
- // (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA)
- // For this reason it's best to provide hints where possible here by leaving out local coordinates
- LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1);
- LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname);
-
- if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << LL_ENDL;
- }
- return TRUE;
- } else if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " not handled by view" << LL_ENDL;
- }
- }
-
- // Do not allow tool manager to handle mouseclicks if we have disconnected
- if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
- {
- LLViewerEventRecorder::instance().clear_xui();
+ // only send mouse clicks to UI if UI is visible
+ if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+
+ if (down)
+ {
+ buttonstatestr = "down" ;
+ }
+ else
+ {
+ buttonstatestr = "up" ;
+ }
+
+ switch (clicktype)
+ {
+ case CLICK_LEFT:
+ mLeftMouseDown = down;
+ buttonname = "Left";
+ break;
+ case CLICK_RIGHT:
+ mRightMouseDown = down;
+ buttonname = "Right";
+ break;
+ case CLICK_MIDDLE:
+ mMiddleMouseDown = down;
+ buttonname = "Middle";
+ break;
+ case CLICK_DOUBLELEFT:
+ mLeftMouseDown = down;
+ buttonname = "Left Double Click";
+ break;
+ case CLICK_BUTTON4:
+ buttonname = "Button 4";
+ break;
+ case CLICK_BUTTON5:
+ buttonname = "Button 5";
+ break;
+ default:
+ break; // COUNT and NONE
+ }
+
+ LLView::sMouseHandlerMessage.clear();
+
+ if (gMenuBarView)
+ {
+ // stop ALT-key access to menu
+ gMenuBarView->resetMenuTrigger();
+ }
+
+ if (gDebugClicks)
+ {
+ LL_INFOS() << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << LL_ENDL;
+ }
+
+ // Make sure we get a corresponding mouseup event, even if the mouse leaves the window
+ if (down)
+ mWindow->captureMouse();
+ else
+ mWindow->releaseMouse();
+
+ // Indicate mouse was active
+ LLUI::getInstance()->resetMouseIdleTimer();
+
+ // Don't let the user move the mouse out of the window until mouse up.
+ if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
+ {
+ mWindow->setMouseClipping(down);
+ }
+
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ if( mouse_captor )
+ {
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << LL_ENDL;
+ }
+
+ BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
+ if (r) {
+
+ LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << LL_ENDL;
+
+ LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
+ LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
+
+ }
+ else if (down && clicktype == CLICK_RIGHT)
+ {
+ handlePieMenu(x, y, mask);
+ r = TRUE;
+ }
+ return r;
+ }
+
+ // Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
+ if( !mRootView->pointInView(x, y) )
+ {
+ return TRUE;
+ }
+ // Give the UI views a chance to process the click
+
+ BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ;
+ if (r)
+ {
+
+ LL_DEBUGS() << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << LL_ENDL;
+
+ LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
+
+ // Clear local coords - this was a click on root window so these are not needed
+ // By not including them, this allows the test skeleton generation tool to be smarter when generating code
+ // the code generator can be smarter because when local coords are present it can try the xui path with local coords
+ // and fallback to global coordinates only if needed.
+ // The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element
+ // (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA)
+ // For this reason it's best to provide hints where possible here by leaving out local coordinates
+ LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1);
+ LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname);
+
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << LL_ENDL;
+ }
+ return TRUE;
+ } else if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << buttonname << " Mouse " << buttonstatestr << " not handled by view" << LL_ENDL;
+ }
+ }
+
+ // Do not allow tool manager to handle mouseclicks if we have disconnected
+ if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
+ {
+ LLViewerEventRecorder::instance().clear_xui();
is_toolmgr_action = true;
- return TRUE;
- }
+ return TRUE;
+ }
- if (down && clicktype == CLICK_RIGHT)
- {
- handlePieMenu(x, y, mask);
- return TRUE;
- }
+ if (down && clicktype == CLICK_RIGHT)
+ {
+ handlePieMenu(x, y, mask);
+ return TRUE;
+ }
- // If we got this far on a down-click, it wasn't handled.
- // Up-clicks, though, are always handled as far as the OS is concerned.
- BOOL default_rtn = !down;
- return default_rtn;
+ // If we got this far on a down-click, it wasn't handled.
+ // Up-clicks, though, are always handled as far as the OS is concerned.
+ BOOL default_rtn = !down;
+ return default_rtn;
}
BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
@@ -1171,7 +1173,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
else
{
mMouseDownTimer.reset();
- }
+ }
BOOL down = TRUE;
//handleMouse() loops back to LLViewerWindow::handleAnyMouseClick
return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
@@ -1179,14 +1181,14 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
{
- // try handling as a double-click first, then a single-click if that
- // wasn't handled.
- BOOL down = TRUE;
- if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down))
- {
- return TRUE;
- }
- return handleMouseDown(window, pos, mask);
+ // try handling as a double-click first, then a single-click if that
+ // wasn't handled.
+ BOOL down = TRUE;
+ if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down))
+ {
+ return TRUE;
+ }
+ return handleMouseDown(window, pos, mask);
}
BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
@@ -1200,177 +1202,177 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
}
BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = TRUE;
- return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
+ BOOL down = TRUE;
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
}
BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = FALSE;
- return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
+ BOOL down = FALSE;
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
}
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = TRUE;
- gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
-
- // Always handled as far as the OS is concerned.
- return TRUE;
+ BOOL down = TRUE;
+ gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
+
+ // Always handled as far as the OS is concerned.
+ return TRUE;
}
LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data)
{
- LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE;
-
- const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop");
- const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop");
-
- if ( prim_media_dnd_enabled || slurl_dnd_enabled )
- {
- switch(action)
- {
- // Much of the handling for these two cases is the same.
- case LLWindowCallbacks::DNDA_TRACK:
- case LLWindowCallbacks::DNDA_DROPPED:
- case LLWindowCallbacks::DNDA_START_TRACKING:
- {
- bool drop = (LLWindowCallbacks::DNDA_DROPPED == action);
-
- if (slurl_dnd_enabled)
- {
- LLSLURL dropped_slurl(data);
- if(dropped_slurl.isSpatial())
- {
- if (drop)
- {
- LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), LLCommandHandler::NAV_TYPE_CLICKED, NULL, true );
- return LLWindowCallbacks::DND_MOVE;
- }
- return LLWindowCallbacks::DND_COPY;
- }
- }
-
- if (prim_media_dnd_enabled)
- {
- LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY,
- TRUE /* pick_transparent */,
+ LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE;
+
+ const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop");
+ const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop");
+
+ if ( prim_media_dnd_enabled || slurl_dnd_enabled )
+ {
+ switch(action)
+ {
+ // Much of the handling for these two cases is the same.
+ case LLWindowCallbacks::DNDA_TRACK:
+ case LLWindowCallbacks::DNDA_DROPPED:
+ case LLWindowCallbacks::DNDA_START_TRACKING:
+ {
+ bool drop = (LLWindowCallbacks::DNDA_DROPPED == action);
+
+ if (slurl_dnd_enabled)
+ {
+ LLSLURL dropped_slurl(data);
+ if(dropped_slurl.isSpatial())
+ {
+ if (drop)
+ {
+ LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), LLCommandHandler::NAV_TYPE_CLICKED, NULL, true );
+ return LLWindowCallbacks::DND_MOVE;
+ }
+ return LLWindowCallbacks::DND_COPY;
+ }
+ }
+
+ if (prim_media_dnd_enabled)
+ {
+ LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY,
+ TRUE /* pick_transparent */,
FALSE /* pick_rigged */);
- S32 object_face = pick_info.mObjectFace;
- std::string url = data;
-
- LL_DEBUGS() << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << LL_ENDL;
-
- LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject()));
-
- if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty())
- {
- LLTextureEntry *te = obj->getTE(object_face);
-
- // can modify URL if we can modify the object or we have navigate permissions
- bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT );
-
- if (te && allow_modify_url )
- {
- if (drop)
- {
- // object does NOT have media already
- if ( ! te->hasMedia() )
- {
- // we are allowed to modify the object
- if ( obj->permModify() )
- {
- // Create new media entry
- LLSD media_data;
- // XXX Should we really do Home URL too?
- media_data[LLMediaEntry::HOME_URL_KEY] = url;
- media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
- media_data[LLMediaEntry::AUTO_PLAY_KEY] = true;
- obj->syncMediaData(object_face, media_data, true, true);
- // XXX This shouldn't be necessary, should it ?!?
- if (obj->getMediaImpl(object_face))
- obj->getMediaImpl(object_face)->navigateReload();
- obj->sendMediaDataUpdate();
-
- result = LLWindowCallbacks::DND_COPY;
- }
- }
- else
- // object HAS media already
- {
- // URL passes the whitelist
- if (te->getMediaData()->checkCandidateUrl( url ) )
- {
- // just navigate to the URL
- if (obj->getMediaImpl(object_face))
- {
- obj->getMediaImpl(object_face)->navigateTo(url);
- }
- else
- {
- // This is very strange. Navigation should
- // happen via the Impl, but we don't have one.
- // This sends it to the server, which /should/
- // trigger us getting it. Hopefully.
- LLSD media_data;
- media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
- obj->syncMediaData(object_face, media_data, true, true);
- obj->sendMediaDataUpdate();
- }
- result = LLWindowCallbacks::DND_LINK;
-
- }
- }
- LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
- mDragHoveredObject = NULL;
-
- }
- else
- {
- // Check the whitelist, if there's media (otherwise just show it)
- if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
- {
- if ( obj != mDragHoveredObject)
- {
- // Highlight the dragged object
- LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
- mDragHoveredObject = obj;
- LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject);
- }
- result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK;
-
- }
- }
- }
- }
- }
- }
- break;
-
- case LLWindowCallbacks::DNDA_STOP_TRACKING:
- // The cleanup case below will make sure things are unhilighted if necessary.
- break;
- }
-
- if (prim_media_dnd_enabled &&
- result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull())
- {
- LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
- mDragHoveredObject = NULL;
- }
- }
-
- return result;
+ S32 object_face = pick_info.mObjectFace;
+ std::string url = data;
+
+ LL_DEBUGS() << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << LL_ENDL;
+
+ LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject()));
+
+ if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty())
+ {
+ LLTextureEntry *te = obj->getTE(object_face);
+
+ // can modify URL if we can modify the object or we have navigate permissions
+ bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT );
+
+ if (te && allow_modify_url )
+ {
+ if (drop)
+ {
+ // object does NOT have media already
+ if ( ! te->hasMedia() )
+ {
+ // we are allowed to modify the object
+ if ( obj->permModify() )
+ {
+ // Create new media entry
+ LLSD media_data;
+ // XXX Should we really do Home URL too?
+ media_data[LLMediaEntry::HOME_URL_KEY] = url;
+ media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
+ media_data[LLMediaEntry::AUTO_PLAY_KEY] = true;
+ obj->syncMediaData(object_face, media_data, true, true);
+ // XXX This shouldn't be necessary, should it ?!?
+ if (obj->getMediaImpl(object_face))
+ obj->getMediaImpl(object_face)->navigateReload();
+ obj->sendMediaDataUpdate();
+
+ result = LLWindowCallbacks::DND_COPY;
+ }
+ }
+ else
+ // object HAS media already
+ {
+ // URL passes the whitelist
+ if (te->getMediaData()->checkCandidateUrl( url ) )
+ {
+ // just navigate to the URL
+ if (obj->getMediaImpl(object_face))
+ {
+ obj->getMediaImpl(object_face)->navigateTo(url);
+ }
+ else
+ {
+ // This is very strange. Navigation should
+ // happen via the Impl, but we don't have one.
+ // This sends it to the server, which /should/
+ // trigger us getting it. Hopefully.
+ LLSD media_data;
+ media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
+ obj->syncMediaData(object_face, media_data, true, true);
+ obj->sendMediaDataUpdate();
+ }
+ result = LLWindowCallbacks::DND_LINK;
+
+ }
+ }
+ LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
+ mDragHoveredObject = NULL;
+
+ }
+ else
+ {
+ // Check the whitelist, if there's media (otherwise just show it)
+ if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
+ {
+ if ( obj != mDragHoveredObject)
+ {
+ // Highlight the dragged object
+ LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
+ mDragHoveredObject = obj;
+ LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject);
+ }
+ result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK;
+
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case LLWindowCallbacks::DNDA_STOP_TRACKING:
+ // The cleanup case below will make sure things are unhilighted if necessary.
+ break;
+ }
+
+ if (prim_media_dnd_enabled &&
+ result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull())
+ {
+ LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
+ mDragHoveredObject = NULL;
+ }
+ }
+
+ return result;
}
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = FALSE;
- gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
-
- // Always handled as far as the OS is concerned.
- return TRUE;
+ BOOL down = FALSE;
+ gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
+
+ // Always handled as far as the OS is concerned.
+ return TRUE;
}
BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down)
@@ -1404,32 +1406,32 @@ BOOL LLViewerWindow::handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK ma
// WARNING: this is potentially called multiple times per frame
void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
{
- S32 x = pos.mX;
- S32 y = pos.mY;
+ S32 x = pos.mX;
+ S32 y = pos.mY;
- x = ll_round((F32)x / mDisplayScale.mV[VX]);
- y = ll_round((F32)y / mDisplayScale.mV[VY]);
+ x = ll_round((F32)x / mDisplayScale.mV[VX]);
+ y = ll_round((F32)y / mDisplayScale.mV[VY]);
- mMouseInWindow = TRUE;
+ mMouseInWindow = TRUE;
- // Save mouse point for access during idle() and display()
+ // Save mouse point for access during idle() and display()
- LLCoordGL mouse_point(x, y);
+ LLCoordGL mouse_point(x, y);
- if (mouse_point != mCurrentMousePoint)
- {
- LLUI::getInstance()->resetMouseIdleTimer();
- }
+ if (mouse_point != mCurrentMousePoint)
+ {
+ LLUI::getInstance()->resetMouseIdleTimer();
+ }
- saveLastMouse(mouse_point);
+ saveLastMouse(mouse_point);
- mWindow->showCursorFromMouseMove();
+ mWindow->showCursorFromMouseMove();
- if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME
- && !gDisconnected)
- {
- gAgent.clearAFK();
- }
+ if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME
+ && !gDisconnected)
+ {
+ gAgent.clearAFK();
+ }
}
void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask)
@@ -1450,114 +1452,114 @@ void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK m
void LLViewerWindow::handleMouseLeave(LLWindow *window)
{
- // Note: we won't get this if we have captured the mouse.
- llassert( gFocusMgr.getMouseCapture() == NULL );
- mMouseInWindow = FALSE;
- LLToolTipMgr::instance().blockToolTips();
+ // Note: we won't get this if we have captured the mouse.
+ llassert( gFocusMgr.getMouseCapture() == NULL );
+ mMouseInWindow = FALSE;
+ LLToolTipMgr::instance().blockToolTips();
}
BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
{
- // User has indicated they want to close, but we may need to ask
- // about modified documents.
- LLAppViewer::instance()->userQuit();
- // Don't quit immediately
- return FALSE;
+ // User has indicated they want to close, but we may need to ask
+ // about modified documents.
+ LLAppViewer::instance()->userQuit();
+ // Don't quit immediately
+ return FALSE;
}
void LLViewerWindow::handleQuit(LLWindow *window)
{
- if (gNonInteractive)
- {
- LLAppViewer::instance()->requestQuit();
- }
- else
- {
- LL_INFOS() << "Window forced quit" << LL_ENDL;
- LLAppViewer::instance()->forceQuit();
- }
+ if (gNonInteractive)
+ {
+ LLAppViewer::instance()->requestQuit();
+ }
+ else
+ {
+ LL_INFOS() << "Window forced quit" << LL_ENDL;
+ LLAppViewer::instance()->forceQuit();
+ }
}
void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height)
{
- reshape(width, height);
- mResDirty = true;
+ reshape(width, height);
+ mResDirty = true;
}
// The top-level window has gained focus (e.g. via ALT-TAB)
void LLViewerWindow::handleFocus(LLWindow *window)
{
- gFocusMgr.setAppHasFocus(TRUE);
- LLModalDialog::onAppFocusGained();
+ gFocusMgr.setAppHasFocus(TRUE);
+ LLModalDialog::onAppFocusGained();
- gAgent.onAppFocusGained();
- LLToolMgr::getInstance()->onAppFocusGained();
+ gAgent.onAppFocusGained();
+ LLToolMgr::getInstance()->onAppFocusGained();
- // See if we're coming in with modifier keys held down
- if (gKeyboard)
- {
- gKeyboard->resetMaskKeys();
- }
+ // See if we're coming in with modifier keys held down
+ if (gKeyboard)
+ {
+ gKeyboard->resetMaskKeys();
+ }
- // resume foreground running timer
- // since we artifically limit framerate when not frontmost
- gForegroundTime.unpause();
+ // resume foreground running timer
+ // since we artifically limit framerate when not frontmost
+ gForegroundTime.unpause();
}
// The top-level window has lost focus (e.g. via ALT-TAB)
void LLViewerWindow::handleFocusLost(LLWindow *window)
{
- gFocusMgr.setAppHasFocus(FALSE);
- //LLModalDialog::onAppFocusLost();
- LLToolMgr::getInstance()->onAppFocusLost();
- gFocusMgr.setMouseCapture( NULL );
+ gFocusMgr.setAppHasFocus(FALSE);
+ //LLModalDialog::onAppFocusLost();
+ LLToolMgr::getInstance()->onAppFocusLost();
+ gFocusMgr.setMouseCapture( NULL );
- if (gMenuBarView)
- {
- // stop ALT-key access to menu
- gMenuBarView->resetMenuTrigger();
- }
+ if (gMenuBarView)
+ {
+ // stop ALT-key access to menu
+ gMenuBarView->resetMenuTrigger();
+ }
- // restore mouse cursor
- showCursor();
- getWindow()->setMouseClipping(FALSE);
+ // restore mouse cursor
+ showCursor();
+ getWindow()->setMouseClipping(FALSE);
- // If losing focus while keys are down, handle them as
+ // If losing focus while keys are down, handle them as
// an 'up' to correctly release states, then reset states
- if (gKeyboard)
- {
+ if (gKeyboard)
+ {
gKeyboard->resetKeyDownAndHandle();
- gKeyboard->resetKeys();
- }
+ gKeyboard->resetKeys();
+ }
- // pause timer that tracks total foreground running time
- gForegroundTime.pause();
+ // pause timer that tracks total foreground running time
+ gForegroundTime.pause();
}
BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
{
- // Handle non-consuming global keybindings, like voice
+ // Handle non-consuming global keybindings, like voice
// Never affects event processing.
gViewerInput.handleGlobalBindsKeyDown(key, mask);
- if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
- {
- gAgent.clearAFK();
- }
-
- // *NOTE: We want to interpret KEY_RETURN later when it arrives as
- // a Unicode char, not as a keydown. Otherwise when client frame
- // rate is really low, hitting return sends your chat text before
- // it's all entered/processed.
- if (key == KEY_RETURN && mask == MASK_NONE)
- {
+ if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+ {
+ gAgent.clearAFK();
+ }
+
+ // *NOTE: We want to interpret KEY_RETURN later when it arrives as
+ // a Unicode char, not as a keydown. Otherwise when client frame
+ // rate is really low, hitting return sends your chat text before
+ // it's all entered/processed.
+ if (key == KEY_RETURN && mask == MASK_NONE)
+ {
// RIDER: although, at times some of the controlls (in particular the CEF viewer
// would like to know about the KEYDOWN for an enter key... so ask and pass it along.
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if (keyboard_focus && !keyboard_focus->wantsReturnKey())
- return FALSE;
- }
+ return FALSE;
+ }
// remaps, handles ignored cases and returns back to viewer window.
return gViewerInput.handleKey(key, mask, repeated);
@@ -1565,25 +1567,25 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
{
- // Handle non-consuming global keybindings, like voice
+ // Handle non-consuming global keybindings, like voice
// Never affects event processing.
gViewerInput.handleGlobalBindsKeyUp(key, mask);
- // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera
- LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance();
- if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp)
- {
- tool_inspectp->keyUp(key, mask);
- }
+ // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera
+ LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance();
+ if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp)
+ {
+ tool_inspectp->keyUp(key, mask);
+ }
- return gViewerInput.handleKeyUp(key, mask);
+ return gViewerInput.handleKeyUp(key, mask);
}
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
- LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
- gViewerInput.scanKey(key, key_down, key_up, key_level);
- return; // Be clear this function returns nothing
+ LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
+ gViewerInput.scanKey(key, key_down, key_up, key_level);
+ return; // Be clear this function returns nothing
}
@@ -1591,45 +1593,45 @@ void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key
BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
{
- if (activated)
- {
- mActive = true;
- send_agent_resume();
- gAgent.clearAFK();
-
- // Unmute audio
- audio_update_volume();
- }
- else
- {
- mActive = false;
-
- // if the user has chosen to go Away automatically after some time, then go Away when minimizing
- if (gSavedSettings.getS32("AFKTimeout"))
- {
- gAgent.setAFK();
- }
-
- // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
- if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
- {
- gAgentCamera.changeCameraToDefault();
- }
-
- send_agent_pause();
-
- // Mute audio
- audio_update_volume();
- }
- return TRUE;
+ if (activated)
+ {
+ mActive = true;
+ send_agent_resume();
+ gAgent.clearAFK();
+
+ // Unmute audio
+ audio_update_volume();
+ }
+ else
+ {
+ mActive = false;
+
+ // if the user has chosen to go Away automatically after some time, then go Away when minimizing
+ if (gSavedSettings.getS32("AFKTimeout"))
+ {
+ gAgent.setAFK();
+ }
+
+ // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
+ if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+
+ send_agent_pause();
+
+ // Mute audio
+ audio_update_volume();
+ }
+ return TRUE;
}
BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
{
- //if (!activating) gAgentCamera.changeCameraToDefault();
+ //if (!activating) gAgentCamera.changeCameraToDefault();
- LLViewerJoystick::getInstance()->setNeedsReset(true);
- return FALSE;
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+ return FALSE;
}
@@ -1640,108 +1642,108 @@ void LLViewerWindow::handleMenuSelect(LLWindow *window, S32 menu_item)
BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height)
{
- // *TODO: Enable similar information output for other platforms? DK 2011-02-18
+ // *TODO: Enable similar information output for other platforms? DK 2011-02-18
#if LL_WINDOWS
- if (gHeadlessClient)
- {
- HWND window_handle = (HWND)window->getPlatformWindow();
- PAINTSTRUCT ps;
- HDC hdc;
-
- RECT wnd_rect;
- wnd_rect.left = 0;
- wnd_rect.top = 0;
- wnd_rect.bottom = 200;
- wnd_rect.right = 500;
-
- hdc = BeginPaint(window_handle, &ps);
- //SetBKColor(hdc, RGB(255, 255, 255));
- FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
-
- std::string temp_str;
- LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
- temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
- recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(),
- recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS),
- recording.getLastValue(LLStatViewer::SIM_TIME_DILATION));
- S32 len = temp_str.length();
- TextOutA(hdc, 0, 0, temp_str.c_str(), len);
-
-
- LLVector3d pos_global = gAgent.getPositionGlobal();
- temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
- len = temp_str.length();
- TextOutA(hdc, 0, 25, temp_str.c_str(), len);
-
- TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
- EndPaint(window_handle, &ps);
- return TRUE;
- }
+ if (gHeadlessClient)
+ {
+ HWND window_handle = (HWND)window->getPlatformWindow();
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ RECT wnd_rect;
+ wnd_rect.left = 0;
+ wnd_rect.top = 0;
+ wnd_rect.bottom = 200;
+ wnd_rect.right = 500;
+
+ hdc = BeginPaint(window_handle, &ps);
+ //SetBKColor(hdc, RGB(255, 255, 255));
+ FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
+
+ std::string temp_str;
+ LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
+ temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
+ recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(),
+ recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS),
+ recording.getLastValue(LLStatViewer::SIM_TIME_DILATION));
+ S32 len = temp_str.length();
+ TextOutA(hdc, 0, 0, temp_str.c_str(), len);
+
+
+ LLVector3d pos_global = gAgent.getPositionGlobal();
+ temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
+ len = temp_str.length();
+ TextOutA(hdc, 0, 25, temp_str.c_str(), len);
+
+ TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
+ EndPaint(window_handle, &ps);
+ return TRUE;
+ }
#endif
- return FALSE;
+ return FALSE;
}
void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
{
- handleScrollWheel( clicks );
+ handleScrollWheel( clicks );
}
void LLViewerWindow::handleScrollHWheel(LLWindow *window, S32 clicks)
{
- handleScrollHWheel(clicks);
+ handleScrollHWheel(clicks);
}
void LLViewerWindow::handleWindowBlock(LLWindow *window)
{
- send_agent_pause();
+ send_agent_pause();
}
void LLViewerWindow::handleWindowUnblock(LLWindow *window)
{
- send_agent_resume();
+ send_agent_resume();
}
void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
{
- const S32 SLURL_MESSAGE_TYPE = 0;
- switch (data_type)
- {
- case SLURL_MESSAGE_TYPE:
- // received URL
- std::string url = (const char*)data;
- LLMediaCtrl* web = NULL;
- const bool trusted_browser = false;
- // don't treat slapps coming from external browsers as "clicks" as this would bypass throttling
- if (LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_EXTERNAL, web, trusted_browser))
- {
- // bring window to foreground, as it has just been "launched" from a URL
- mWindow->bringToFront();
- }
- break;
- }
+ const S32 SLURL_MESSAGE_TYPE = 0;
+ switch (data_type)
+ {
+ case SLURL_MESSAGE_TYPE:
+ // received URL
+ std::string url = (const char*)data;
+ LLMediaCtrl* web = NULL;
+ const bool trusted_browser = false;
+ // don't treat slapps coming from external browsers as "clicks" as this would bypass throttling
+ if (LLURLDispatcher::dispatch(url, LLCommandHandler::NAV_TYPE_EXTERNAL, web, trusted_browser))
+ {
+ // bring window to foreground, as it has just been "launched" from a URL
+ mWindow->bringToFront();
+ }
+ break;
+ }
}
BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
{
//TODO: just call this every frame from gatherInput instead of using a convoluted 30fps timer callback
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- LLViewerJoystick::getInstance()->updateStatus();
- return TRUE;
- }
- return FALSE;
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ LLViewerJoystick::getInstance()->updateStatus();
+ return TRUE;
+ }
+ return FALSE;
}
BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
{
- // give a chance to use a joystick after startup (hot-plugging)
- if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
- {
- LLViewerJoystick::getInstance()->init(true);
- return TRUE;
- }
- return FALSE;
+ // give a chance to use a joystick after startup (hot-plugging)
+ if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
+ {
+ LLViewerJoystick::getInstance()->init(true);
+ return TRUE;
+ }
+ return FALSE;
}
BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
@@ -1761,157 +1763,157 @@ BOOL LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
BOOL LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window)
{
- LLCoordScreen window_rect;
- mWindow->getSize(&window_rect);
- reshape(window_rect.mX, window_rect.mY);
- return TRUE;
+ LLCoordScreen window_rect;
+ mWindow->getSize(&window_rect);
+ reshape(window_rect.mX, window_rect.mY);
+ return TRUE;
}
void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
{
- LLAppViewer::instance()->pingMainloopTimeout(msg);
+ LLAppViewer::instance()->pingMainloopTimeout(msg);
}
void LLViewerWindow::handleResumeWatchdog(LLWindow *window)
{
- LLAppViewer::instance()->resumeMainloopTimeout();
+ LLAppViewer::instance()->resumeMainloopTimeout();
}
void LLViewerWindow::handlePauseWatchdog(LLWindow *window)
{
- LLAppViewer::instance()->pauseMainloopTimeout();
+ LLAppViewer::instance()->pauseMainloopTimeout();
}
//virtual
std::string LLViewerWindow::translateString(const char* tag)
{
- return LLTrans::getString( std::string(tag) );
+ return LLTrans::getString( std::string(tag) );
}
//virtual
std::string LLViewerWindow::translateString(const char* tag,
- const std::map<std::string, std::string>& args)
-{
- // LLTrans uses a special subclass of std::string for format maps,
- // but we must use std::map<> in these callbacks, otherwise we create
- // a dependency between LLWindow and LLFormatMapString. So copy the data.
- LLStringUtil::format_map_t args_copy;
- std::map<std::string,std::string>::const_iterator it = args.begin();
- for ( ; it != args.end(); ++it)
- {
- args_copy[it->first] = it->second;
- }
- return LLTrans::getString( std::string(tag), args_copy);
+ const std::map<std::string, std::string>& args)
+{
+ // LLTrans uses a special subclass of std::string for format maps,
+ // but we must use std::map<> in these callbacks, otherwise we create
+ // a dependency between LLWindow and LLFormatMapString. So copy the data.
+ LLStringUtil::format_map_t args_copy;
+ std::map<std::string,std::string>::const_iterator it = args.begin();
+ for ( ; it != args.end(); ++it)
+ {
+ args_copy[it->first] = it->second;
+ }
+ return LLTrans::getString( std::string(tag), args_copy);
}
//
// Classes
//
LLViewerWindow::LLViewerWindow(const Params& p)
-: mWindow(NULL),
- mActive(true),
- mUIVisible(true),
- mWindowRectRaw(0, p.height, p.width, 0),
- mWindowRectScaled(0, p.height, p.width, 0),
- mWorldViewRectRaw(0, p.height, p.width, 0),
- mLeftMouseDown(FALSE),
- mMiddleMouseDown(FALSE),
- mRightMouseDown(FALSE),
- mMouseInWindow( FALSE ),
+: mWindow(NULL),
+ mActive(true),
+ mUIVisible(true),
+ mWindowRectRaw(0, p.height, p.width, 0),
+ mWindowRectScaled(0, p.height, p.width, 0),
+ mWorldViewRectRaw(0, p.height, p.width, 0),
+ mLeftMouseDown(FALSE),
+ mMiddleMouseDown(FALSE),
+ mRightMouseDown(FALSE),
+ mMouseInWindow( FALSE ),
mAllowMouseDragging(TRUE),
mMouseDownTimer(),
- mLastMask( MASK_NONE ),
- mToolStored( NULL ),
- mHideCursorPermanent( FALSE ),
- mCursorHidden(FALSE),
- mIgnoreActivate( FALSE ),
- mResDirty(false),
- mStatesDirty(false),
- mCurrResolutionIndex(0),
- mProgressView(NULL)
-{
- // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
- // pass its value right now. Instead, pass it a nullary function that
- // will, when we later need it, return the value of gKeyboard.
- // boost::lambda::var() constructs such a functor on the fly.
- mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
- mViewerWindowListener.reset(new LLViewerWindowListener(this));
-
- mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
- mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
- mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
- mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
-
- bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
- LLNotifications::instance().setIgnoreAllNotifications(ignore);
- if (ignore)
- {
- LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL;
- }
-
-
- /*
- LLWindowCallbacks* callbacks,
- const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
- BOOL fullscreen,
- BOOL clearBg,
- BOOL disable_vsync,
- BOOL ignore_pixel_depth,
- U32 fsaa_samples)
- */
- // create window
+ mLastMask( MASK_NONE ),
+ mToolStored( NULL ),
+ mHideCursorPermanent( FALSE ),
+ mCursorHidden(FALSE),
+ mIgnoreActivate( FALSE ),
+ mResDirty(false),
+ mStatesDirty(false),
+ mCurrResolutionIndex(0),
+ mProgressView(NULL)
+{
+ // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
+ // pass its value right now. Instead, pass it a nullary function that
+ // will, when we later need it, return the value of gKeyboard.
+ // boost::lambda::var() constructs such a functor on the fly.
+ mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
+ mViewerWindowListener.reset(new LLViewerWindowListener(this));
+
+ mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+ mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
+ mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+ mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
+
+ bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
+ LLNotifications::instance().setIgnoreAllNotifications(ignore);
+ if (ignore)
+ {
+ LL_INFOS() << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << LL_ENDL;
+ }
+
+
+ /*
+ LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
+ BOOL fullscreen,
+ BOOL clearBg,
+ BOOL disable_vsync,
+ BOOL ignore_pixel_depth,
+ U32 fsaa_samples)
+ */
+ // create window
U32 max_core_count = gSavedSettings.getU32("EmulateCoreCount");
U32 max_vram = gSavedSettings.getU32("RenderMaxVRAMBudget");
F32 max_gl_version = gSavedSettings.getF32("RenderMaxOpenGLVersion");
-
- mWindow = LLWindowManager::createWindow(this,
- p.title, p.name, p.x, p.y, p.width, p.height, 0,
- p.fullscreen,
- gHeadlessClient,
- gSavedSettings.getBOOL("RenderVSyncEnable"),
- !gHeadlessClient,
- p.ignore_pixel_depth,
- 0,
+
+ mWindow = LLWindowManager::createWindow(this,
+ p.title, p.name, p.x, p.y, p.width, p.height, 0,
+ p.fullscreen,
+ gHeadlessClient,
+ gSavedSettings.getBOOL("RenderVSyncEnable"),
+ !gHeadlessClient,
+ p.ignore_pixel_depth,
+ 0,
max_core_count,
max_vram,
max_gl_version); //don't use window level anti-aliasing
- if (NULL == mWindow)
- {
- LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
-
- LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << LL_ENDL ;
+ if (NULL == mWindow)
+ {
+ LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
+
+ LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << LL_ENDL ;
- ms_sleep(5000) ; //wait for 5 seconds.
+ ms_sleep(5000) ; //wait for 5 seconds.
- LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
+ LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
#if LL_LINUX
- LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information."
- << LL_ENDL;
+ LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information."
+ << LL_ENDL;
#else
- LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
- << LL_ENDL;
+ LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
+ << LL_ENDL;
#endif
LLAppViewer::instance()->fastQuit(1);
- }
+ }
else if (!LLViewerShaderMgr::sInitialized)
{
//immediately initialize shaders
LLViewerShaderMgr::sInitialized = TRUE;
LLViewerShaderMgr::instance()->setShaders();
}
-
- if (!LLAppViewer::instance()->restoreErrorTrap())
- {
+
+ if (!LLAppViewer::instance()->restoreErrorTrap())
+ {
// this always happens, so downgrading it to INFO
- LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL;
- }
+ LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL;
+ }
- const bool do_not_enforce = false;
- mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set
- LLCoordScreen scr;
+ const bool do_not_enforce = false;
+ mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce); // root view not set
+ LLCoordScreen scr;
mWindow->getSize(&scr);
// Reset UI scale factor on first run if OS's display scaling is not 100%
@@ -1924,90 +1926,90 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.setBOOL("ResetUIScaleOnFirstRun", FALSE);
}
- // Get the real window rect the window was created with (since there are various OS-dependent reasons why
- // the size of a window or fullscreen context may have been adjusted slightly...)
- F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE);
-
- mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
- mDisplayScale *= ui_scale_factor;
- LLUI::setScaleFactor(mDisplayScale);
-
- {
- LLCoordWindow size;
- mWindow->getSize(&size);
- mWindowRectRaw.set(0, size.mY, size.mX, 0);
- mWindowRectScaled.set(0, ll_round((F32)size.mY / mDisplayScale.mV[VY]), ll_round((F32)size.mX / mDisplayScale.mV[VX]), 0);
- }
-
- LLFontManager::initClass();
- // Init font system, load default fonts and generate basic glyphs
- // currently it takes aprox. 0.5 sec and we would load these fonts anyway
- // before login screen.
- LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
- mDisplayScale.mV[VX],
- mDisplayScale.mV[VY],
- gDirUtilp->getAppRODataDir());
-
- //
- // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
- // stuff like AGP if we think that it'll crash the viewer.
- //
- LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
-
- // Initialize OpenGL Renderer
- LLVertexBuffer::initClass(mWindow);
- LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- if (!gGL.init(true))
+ // Get the real window rect the window was created with (since there are various OS-dependent reasons why
+ // the size of a window or fullscreen context may have been adjusted slightly...)
+ F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE);
+
+ mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
+ mDisplayScale *= ui_scale_factor;
+ LLUI::setScaleFactor(mDisplayScale);
+
+ {
+ LLCoordWindow size;
+ mWindow->getSize(&size);
+ mWindowRectRaw.set(0, size.mY, size.mX, 0);
+ mWindowRectScaled.set(0, ll_round((F32)size.mY / mDisplayScale.mV[VY]), ll_round((F32)size.mX / mDisplayScale.mV[VX]), 0);
+ }
+
+ LLFontManager::initClass();
+ // Init font system, load default fonts and generate basic glyphs
+ // currently it takes aprox. 0.5 sec and we would load these fonts anyway
+ // before login screen.
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
+ mDisplayScale.mV[VX],
+ mDisplayScale.mV[VY],
+ gDirUtilp->getAppRODataDir());
+
+ //
+ // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
+ // stuff like AGP if we think that it'll crash the viewer.
+ //
+ LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
+
+ // Initialize OpenGL Renderer
+ LLVertexBuffer::initClass(mWindow);
+ LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
+ if (!gGL.init(true))
{
LLError::LLUserWarningMsg::show(LLTrans::getString("MBVideoDrvErr"));
LL_ERRS() << "gGL not initialized" << LL_ENDL;
}
- if (LLFeatureManager::getInstance()->isSafe()
- || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
- || (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString())
- || (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
- {
- LLFeatureManager::getInstance()->applyRecommendedSettings();
- gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
- }
-
- // If we crashed while initializng GL stuff last time, disable certain features
- if (gSavedSettings.getBOOL("RenderInitError"))
- {
- mInitAlert = "DisplaySettingsNoShaders";
- LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
- gSavedSettings.setU32("RenderQualityPerformance", 0);
- }
-
- // Init the image list. Must happen after GL is initialized and before the images that
- // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images.
+ if (LLFeatureManager::getInstance()->isSafe()
+ || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
+ || (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString())
+ || (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
+ {
+ LLFeatureManager::getInstance()->applyRecommendedSettings();
+ gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
+ }
+
+ // If we crashed while initializng GL stuff last time, disable certain features
+ if (gSavedSettings.getBOOL("RenderInitError"))
+ {
+ mInitAlert = "DisplaySettingsNoShaders";
+ LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
+ gSavedSettings.setU32("RenderQualityPerformance", 0);
+ }
+
+ // Init the image list. Must happen after GL is initialized and before the images that
+ // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images.
LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreadedTextures"), gSavedSettings.getBOOL("RenderGLMultiThreadedMedia"));
- gTextureList.init();
- LLViewerTextureManager::init() ;
- gBumpImageList.init();
-
+ gTextureList.init();
+ LLViewerTextureManager::init() ;
+ gBumpImageList.init();
+
// Create container for all sub-views
- LLView::Params rvp;
- rvp.name("root");
- rvp.rect(mWindowRectScaled);
- rvp.mouse_opaque(false);
- rvp.follows.flags(FOLLOWS_NONE);
- mRootView = LLUICtrlFactory::create<LLRootView>(rvp);
- LLUI::getInstance()->setRootView(mRootView);
+ LLView::Params rvp;
+ rvp.name("root");
+ rvp.rect(mWindowRectScaled);
+ rvp.mouse_opaque(false);
+ rvp.follows.flags(FOLLOWS_NONE);
+ mRootView = LLUICtrlFactory::create<LLRootView>(rvp);
+ LLUI::getInstance()->setRootView(mRootView);
- // Make avatar head look forward at start
- mCurrentMousePoint.mX = getWindowWidthScaled() / 2;
- mCurrentMousePoint.mY = getWindowHeightScaled() / 2;
+ // Make avatar head look forward at start
+ mCurrentMousePoint.mX = getWindowWidthScaled() / 2;
+ mCurrentMousePoint.mY = getWindowHeightScaled() / 2;
- gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
- mOverlayTitle = gSavedSettings.getString("OverlayTitle");
- // Can't have spaces in settings.ini strings, so use underscores instead and convert them.
- LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
+ gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
+ mOverlayTitle = gSavedSettings.getString("OverlayTitle");
+ // Can't have spaces in settings.ini strings, so use underscores instead and convert them.
+ LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
- mDebugText = new LLDebugText(this);
+ mDebugText = new LLDebugText(this);
- mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
}
std::string LLViewerWindow::getLastSnapshotDir()
@@ -2017,8 +2019,8 @@ std::string LLViewerWindow::getLastSnapshotDir()
void LLViewerWindow::initGLDefaults()
{
- // RN: Need this for translation and stretch manip.
- gBox.prerender();
+ // RN: Need this for translation and stretch manip.
+ gBox.prerender();
}
struct MainPanel : public LLPanel
@@ -2027,550 +2029,550 @@ struct MainPanel : public LLPanel
void LLViewerWindow::initBase()
{
- S32 height = getWindowHeightScaled();
- S32 width = getWindowWidthScaled();
+ S32 height = getWindowHeightScaled();
+ S32 width = getWindowWidthScaled();
- LLRect full_window(0, height, width, 0);
+ LLRect full_window(0, height, width, 0);
- ////////////////////
- //
- // Set the gamma
- //
+ ////////////////////
+ //
+ // Set the gamma
+ //
- F32 gamma = gSavedSettings.getF32("RenderGamma");
- if (gamma != 0.0f)
- {
- getWindow()->setGamma(gamma);
- }
+ F32 gamma = gSavedSettings.getF32("RenderGamma");
+ if (gamma != 0.0f)
+ {
+ getWindow()->setGamma(gamma);
+ }
- // Create global views
+ // Create global views
- // Login screen and main_view.xml need edit menus for preferences and browser
- LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL;
- initialize_edit_menu();
+ // Login screen and main_view.xml need edit menus for preferences and browser
+ LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL;
+ initialize_edit_menu();
LLFontGL::loadCommonFonts();
- // Create the floater view at the start so that other views can add children to it.
- // (But wait to add it as a child of the root view so that it will be in front of the
- // other views.)
- MainPanel* main_view = new MainPanel();
- if (!main_view->buildFromFile("main_view.xml"))
- {
- LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file main_view.xml, "
- << "if this problem happens again, please validate your installation." << LL_ENDL;
- }
- main_view->setShape(full_window);
- getRootView()->addChild(main_view);
-
- // placeholder widget that controls where "world" is rendered
- mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
- mPopupView = main_view->getChild<LLPopupView>("popup_holder");
- mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
- mLoginPanelHolder = main_view->getChild<LLView>("login_panel_holder")->getHandle();
-
- // Create the toolbar view
- // Get a pointer to the toolbar view holder
- LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");
- // Load the toolbar view from file
- gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance());
- if (!gToolBarView)
- {
- LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, "
- << "if this problem happens again, please validate your installation." << LL_ENDL;
- }
- gToolBarView->setShape(panel_holder->getLocalRect());
- // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())
- gToolBarView->setVisible(FALSE);
-
- // Constrain floaters to inside the menu and status bar regions.
- gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
- for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; ++i)
- {
- LLToolBar * toolbarp = gToolBarView->getToolbar((LLToolBarEnums::EToolBarLocation)i);
- if (toolbarp)
- {
- toolbarp->getCenterLayoutPanel()->setReshapeCallback(boost::bind(&LLFloaterView::setToolbarRect, gFloaterView, _1, _2));
- }
- }
- gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
- gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
-
- // Console
- llassert( !gConsole );
- LLConsole::Params cp;
- cp.name("console");
- cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
- cp.rect(getChatConsoleRect());
- cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
- cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
- cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
- gConsole = LLUICtrlFactory::create<LLConsole>(cp);
- getRootView()->addChild(gConsole);
-
- // optionally forward warnings to chat console/chat floater
- // for qa runs and dev builds
+ // Create the floater view at the start so that other views can add children to it.
+ // (But wait to add it as a child of the root view so that it will be in front of the
+ // other views.)
+ MainPanel* main_view = new MainPanel();
+ if (!main_view->buildFromFile("main_view.xml"))
+ {
+ LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file main_view.xml, "
+ << "if this problem happens again, please validate your installation." << LL_ENDL;
+ }
+ main_view->setShape(full_window);
+ getRootView()->addChild(main_view);
+
+ // placeholder widget that controls where "world" is rendered
+ mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
+ mPopupView = main_view->getChild<LLPopupView>("popup_holder");
+ mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
+ mLoginPanelHolder = main_view->getChild<LLView>("login_panel_holder")->getHandle();
+
+ // Create the toolbar view
+ // Get a pointer to the toolbar view holder
+ LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");
+ // Load the toolbar view from file
+ gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance());
+ if (!gToolBarView)
+ {
+ LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, "
+ << "if this problem happens again, please validate your installation." << LL_ENDL;
+ }
+ gToolBarView->setShape(panel_holder->getLocalRect());
+ // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())
+ gToolBarView->setVisible(FALSE);
+
+ // Constrain floaters to inside the menu and status bar regions.
+ gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
+ for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; ++i)
+ {
+ LLToolBar * toolbarp = gToolBarView->getToolbar((LLToolBarEnums::EToolBarLocation)i);
+ if (toolbarp)
+ {
+ toolbarp->getCenterLayoutPanel()->setReshapeCallback(boost::bind(&LLFloaterView::setToolbarRect, gFloaterView, _1, _2));
+ }
+ }
+ gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
+ gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
+
+ // Console
+ llassert( !gConsole );
+ LLConsole::Params cp;
+ cp.name("console");
+ cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
+ cp.rect(getChatConsoleRect());
+ cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
+ cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
+ cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ gConsole = LLUICtrlFactory::create<LLConsole>(cp);
+ getRootView()->addChild(gConsole);
+
+ // optionally forward warnings to chat console/chat floater
+ // for qa runs and dev builds
#if !LL_RELEASE_FOR_DOWNLOAD
- RecordToChatConsole::getInstance()->startRecorder();
+ RecordToChatConsole::getInstance()->startRecorder();
#else
- if(gSavedSettings.getBOOL("QAMode"))
- {
- RecordToChatConsole::getInstance()->startRecorder();
- }
+ if(gSavedSettings.getBOOL("QAMode"))
+ {
+ RecordToChatConsole::getInstance()->startRecorder();
+ }
#endif
- gDebugView = getRootView()->getChild<LLDebugView>("DebugView");
- gDebugView->init();
- gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
+ gDebugView = getRootView()->getChild<LLDebugView>("DebugView");
+ gDebugView->init();
+ gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
- // Initialize do not disturb response message when logged in
- LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse));
+ // Initialize do not disturb response message when logged in
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse));
- // Add the progress bar view (startup view), which overrides everything
- mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
- setShowProgress(FALSE);
- setProgressCancelButtonVisible(FALSE);
+ // Add the progress bar view (startup view), which overrides everything
+ mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
+ setShowProgress(FALSE);
+ setProgressCancelButtonVisible(FALSE);
- gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
- LLMenuGL::sMenuContainer = gMenuHolder;
+ gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
+ LLMenuGL::sMenuContainer = gMenuHolder;
}
void LLViewerWindow::initWorldUI()
{
- if (gNonInteractive)
- {
- gIMMgr = LLIMMgr::getInstance();
- LLNavigationBar::getInstance();
- gFloaterView->pushVisibleAll(FALSE);
- return;
- }
-
- S32 height = mRootView->getRect().getHeight();
- S32 width = mRootView->getRect().getWidth();
- LLRect full_window(0, height, width, 0);
-
-
- gIMMgr = LLIMMgr::getInstance();
-
- //getRootView()->sendChildToFront(gFloaterView);
- //getRootView()->sendChildToFront(gSnapshotFloaterView);
-
- if (!gNonInteractive)
- {
- LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
- LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
- chiclet_bar->setShape(chiclet_container->getLocalRect());
- chiclet_bar->setFollowsAll();
- chiclet_container->addChild(chiclet_bar);
- chiclet_container->setVisible(TRUE);
- }
-
- LLRect morph_view_rect = full_window;
- morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
- morph_view_rect.mTop = full_window.mTop - 32;
- LLMorphView::Params mvp;
- mvp.name("MorphView");
- mvp.rect(morph_view_rect);
- mvp.visible(false);
- gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
- getRootView()->addChild(gMorphView);
-
- LLWorldMapView::initClass();
-
- // Force gFloaterWorldMap to initialize
- LLFloaterReg::getInstance("world_map");
-
- // Force gFloaterTools to initialize
- LLFloaterReg::getInstance("build");
-
- // Status bar
- LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
- gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
- gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT);
- gStatusBar->setShape(status_bar_container->getLocalRect());
- // sync bg color with menu bar
- gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
+ if (gNonInteractive)
+ {
+ gIMMgr = LLIMMgr::getInstance();
+ LLNavigationBar::getInstance();
+ gFloaterView->pushVisibleAll(FALSE);
+ return;
+ }
+
+ S32 height = mRootView->getRect().getHeight();
+ S32 width = mRootView->getRect().getWidth();
+ LLRect full_window(0, height, width, 0);
+
+
+ gIMMgr = LLIMMgr::getInstance();
+
+ //getRootView()->sendChildToFront(gFloaterView);
+ //getRootView()->sendChildToFront(gSnapshotFloaterView);
+
+ if (!gNonInteractive)
+ {
+ LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
+ LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
+ chiclet_bar->setShape(chiclet_container->getLocalRect());
+ chiclet_bar->setFollowsAll();
+ chiclet_container->addChild(chiclet_bar);
+ chiclet_container->setVisible(TRUE);
+ }
+
+ LLRect morph_view_rect = full_window;
+ morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
+ morph_view_rect.mTop = full_window.mTop - 32;
+ LLMorphView::Params mvp;
+ mvp.name("MorphView");
+ mvp.rect(morph_view_rect);
+ mvp.visible(false);
+ gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
+ getRootView()->addChild(gMorphView);
+
+ LLWorldMapView::initClass();
+
+ // Force gFloaterWorldMap to initialize
+ LLFloaterReg::getInstance("world_map");
+
+ // Force gFloaterTools to initialize
+ LLFloaterReg::getInstance("build");
+
+ // Status bar
+ LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
+ gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
+ gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT);
+ gStatusBar->setShape(status_bar_container->getLocalRect());
+ // sync bg color with menu bar
+ gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
// add InBack so that gStatusBar won't be drawn over menu
status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/);
status_bar_container->setVisible(TRUE);
- // Navigation bar
- LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
+ // Navigation bar
+ LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
- LLNavigationBar* navbar = LLNavigationBar::getInstance();
- navbar->setShape(nav_bar_container->getLocalRect());
- navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
- nav_bar_container->addChild(navbar);
- nav_bar_container->setVisible(TRUE);
+ LLNavigationBar* navbar = LLNavigationBar::getInstance();
+ navbar->setShape(nav_bar_container->getLocalRect());
+ navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
+ nav_bar_container->addChild(navbar);
+ nav_bar_container->setVisible(TRUE);
- if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
- {
- navbar->setVisible(FALSE);
- }
+ if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
+ {
+ navbar->setVisible(FALSE);
+ }
else
{
reshapeStatusBarContainer();
}
- // Top Info bar
- LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
- LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance();
-
- topinfo_bar->setShape(topinfo_bar_container->getLocalRect());
-
- topinfo_bar_container->addChild(topinfo_bar);
- topinfo_bar_container->setVisible(TRUE);
-
- if (!gSavedSettings.getBOOL("ShowMiniLocationPanel"))
- {
- topinfo_bar->setVisible(FALSE);
- }
-
- if ( gHUDView == NULL )
- {
- LLRect hud_rect = full_window;
- hud_rect.mBottom += 50;
- if (gMenuBarView && gMenuBarView->isInVisibleChain())
- {
- hud_rect.mTop -= gMenuBarView->getRect().getHeight();
- }
- gHUDView = new LLHUDView(hud_rect);
- getRootView()->addChild(gHUDView);
- getRootView()->sendChildToBack(gHUDView);
- }
-
- LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
-
- LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance();
- panel_ssf_container->addChild(panel_stand_stop_flying);
-
- LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance();
- panel_ssf_container->addChild(panel_hide_beacon);
-
- panel_ssf_container->setVisible(TRUE);
-
- LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize();
-
- // Load and make the toolbars visible
- // Note: we need to load the toolbars only *after* the user is logged in and IW
- if (gToolBarView)
- {
- gToolBarView->loadToolbars();
- gToolBarView->setVisible(TRUE);
- }
-
- if (!gNonInteractive)
- {
- LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
- if (destinations)
- {
- destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("DestinationGuideURL");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
- LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
- if (avatar_picker)
- {
- avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("AvatarPickerURL");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
- }
+ // Top Info bar
+ LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
+ LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance();
+
+ topinfo_bar->setShape(topinfo_bar_container->getLocalRect());
+
+ topinfo_bar_container->addChild(topinfo_bar);
+ topinfo_bar_container->setVisible(TRUE);
+
+ if (!gSavedSettings.getBOOL("ShowMiniLocationPanel"))
+ {
+ topinfo_bar->setVisible(FALSE);
+ }
+
+ if ( gHUDView == NULL )
+ {
+ LLRect hud_rect = full_window;
+ hud_rect.mBottom += 50;
+ if (gMenuBarView && gMenuBarView->isInVisibleChain())
+ {
+ hud_rect.mTop -= gMenuBarView->getRect().getHeight();
+ }
+ gHUDView = new LLHUDView(hud_rect);
+ getRootView()->addChild(gHUDView);
+ getRootView()->sendChildToBack(gHUDView);
+ }
+
+ LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
+
+ LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance();
+ panel_ssf_container->addChild(panel_stand_stop_flying);
+
+ LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance();
+ panel_ssf_container->addChild(panel_hide_beacon);
+
+ panel_ssf_container->setVisible(TRUE);
+
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize();
+
+ // Load and make the toolbars visible
+ // Note: we need to load the toolbars only *after* the user is logged in and IW
+ if (gToolBarView)
+ {
+ gToolBarView->loadToolbars();
+ gToolBarView->setVisible(TRUE);
+ }
+
+ if (!gNonInteractive)
+ {
+ LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
+ if (destinations)
+ {
+ destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("DestinationGuideURL");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
+ LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
+ if (avatar_picker)
+ {
+ avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("AvatarPickerURL");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
+ }
}
// Destroy the UI
void LLViewerWindow::shutdownViews()
{
- // clean up warning logger
- RecordToChatConsole::getInstance()->stopRecorder();
- LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ;
-
- gFocusMgr.unlockFocus();
- gFocusMgr.setMouseCapture(NULL);
- gFocusMgr.setKeyboardFocus(NULL);
- gFocusMgr.setTopCtrl(NULL);
- if (mWindow)
- {
- mWindow->allowLanguageTextInput(NULL, FALSE);
- }
-
- delete mDebugText;
- mDebugText = NULL;
-
- LL_INFOS() << "DebugText deleted." << LL_ENDL ;
-
- // Cleanup global views
- if (gMorphView)
- {
- gMorphView->setVisible(FALSE);
- }
- LL_INFOS() << "Global views cleaned." << LL_ENDL ;
-
- LLNotificationsUI::LLToast::cleanupToasts();
- LL_INFOS() << "Leftover toast cleaned up." << LL_ENDL;
-
- // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
- // will crump with LL_ERRS.
- LLModalDialog::shutdownModals();
- LL_INFOS() << "LLModalDialog shut down." << LL_ENDL;
-
- // destroy the nav bar, not currently part of gViewerWindow
- // *TODO: Make LLNavigationBar part of gViewerWindow
- LLNavigationBar::deleteSingleton();
- LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ;
-
- // destroy menus after instantiating navbar above, as it needs
- // access to gMenuHolder
- cleanup_menus();
- LL_INFOS() << "menus destroyed." << LL_ENDL ;
-
- view_listener_t::cleanup();
- LL_INFOS() << "view listeners destroyed." << LL_ENDL ;
-
- // Clean up pointers that are going to be invalid. (todo: check sMenuContainer)
- mProgressView = NULL;
- mPopupView = NULL;
-
- // Delete all child views.
- delete mRootView;
- mRootView = NULL;
- LL_INFOS() << "RootView deleted." << LL_ENDL ;
-
- LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit();
-
- // Automatically deleted as children of mRootView. Fix the globals.
- gStatusBar = NULL;
- gIMMgr = NULL;
- gToolTipView = NULL;
-
- gToolBarView = NULL;
- gFloaterView = NULL;
- gMorphView = NULL;
-
- gHUDView = NULL;
+ // clean up warning logger
+ RecordToChatConsole::getInstance()->stopRecorder();
+ LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ;
+
+ gFocusMgr.unlockFocus();
+ gFocusMgr.setMouseCapture(NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
+ gFocusMgr.setTopCtrl(NULL);
+ if (mWindow)
+ {
+ mWindow->allowLanguageTextInput(NULL, FALSE);
+ }
+
+ delete mDebugText;
+ mDebugText = NULL;
+
+ LL_INFOS() << "DebugText deleted." << LL_ENDL ;
+
+ // Cleanup global views
+ if (gMorphView)
+ {
+ gMorphView->setVisible(FALSE);
+ }
+ LL_INFOS() << "Global views cleaned." << LL_ENDL ;
+
+ LLNotificationsUI::LLToast::cleanupToasts();
+ LL_INFOS() << "Leftover toast cleaned up." << LL_ENDL;
+
+ // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
+ // will crump with LL_ERRS.
+ LLModalDialog::shutdownModals();
+ LL_INFOS() << "LLModalDialog shut down." << LL_ENDL;
+
+ // destroy the nav bar, not currently part of gViewerWindow
+ // *TODO: Make LLNavigationBar part of gViewerWindow
+ LLNavigationBar::deleteSingleton();
+ LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ;
+
+ // destroy menus after instantiating navbar above, as it needs
+ // access to gMenuHolder
+ cleanup_menus();
+ LL_INFOS() << "menus destroyed." << LL_ENDL ;
+
+ view_listener_t::cleanup();
+ LL_INFOS() << "view listeners destroyed." << LL_ENDL ;
+
+ // Clean up pointers that are going to be invalid. (todo: check sMenuContainer)
+ mProgressView = NULL;
+ mPopupView = NULL;
+
+ // Delete all child views.
+ delete mRootView;
+ mRootView = NULL;
+ LL_INFOS() << "RootView deleted." << LL_ENDL ;
+
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit();
+
+ // Automatically deleted as children of mRootView. Fix the globals.
+ gStatusBar = NULL;
+ gIMMgr = NULL;
+ gToolTipView = NULL;
+
+ gToolBarView = NULL;
+ gFloaterView = NULL;
+ gMorphView = NULL;
+
+ gHUDView = NULL;
}
void LLViewerWindow::shutdownGL()
{
- //--------------------------------------------------------
- // Shutdown GL cleanly. Order is very important here.
- //--------------------------------------------------------
- LLFontGL::destroyDefaultFonts();
- SUBSYSTEM_CLEANUP(LLFontManager);
- stop_glerror();
-
- gSky.cleanup();
- stop_glerror();
+ //--------------------------------------------------------
+ // Shutdown GL cleanly. Order is very important here.
+ //--------------------------------------------------------
+ LLFontGL::destroyDefaultFonts();
+ SUBSYSTEM_CLEANUP(LLFontManager);
+ stop_glerror();
- LL_INFOS() << "Cleaning up pipeline" << LL_ENDL;
- gPipeline.cleanup();
- stop_glerror();
+ gSky.cleanup();
+ stop_glerror();
- //MUST clean up pipeline before cleaning up wearables
- LL_INFOS() << "Cleaning up wearables" << LL_ENDL;
- LLWearableList::instance().cleanup() ;
+ LL_INFOS() << "Cleaning up pipeline" << LL_ENDL;
+ gPipeline.cleanup();
+ stop_glerror();
- gTextureList.shutdown();
- stop_glerror();
+ //MUST clean up pipeline before cleaning up wearables
+ LL_INFOS() << "Cleaning up wearables" << LL_ENDL;
+ LLWearableList::instance().cleanup() ;
- gBumpImageList.shutdown();
- stop_glerror();
+ gTextureList.shutdown();
+ stop_glerror();
- LLWorldMapView::cleanupTextures();
+ gBumpImageList.shutdown();
+ stop_glerror();
- LLViewerTextureManager::cleanup() ;
- SUBSYSTEM_CLEANUP(LLImageGL) ;
+ LLWorldMapView::cleanupTextures();
- LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
+ LLViewerTextureManager::cleanup() ;
+ SUBSYSTEM_CLEANUP(LLImageGL) ;
+
+ LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
- LL_INFOS() << "Cleaning up select manager" << LL_ENDL;
- LLSelectMgr::getInstance()->cleanup();
+ LL_INFOS() << "Cleaning up select manager" << LL_ENDL;
+ LLSelectMgr::getInstance()->cleanup();
- LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL;
- stopGL(FALSE);
- stop_glerror();
+ LL_INFOS() << "Stopping GL during shutdown" << LL_ENDL;
+ stopGL(FALSE);
+ stop_glerror();
- gGL.shutdown();
+ gGL.shutdown();
- SUBSYSTEM_CLEANUP(LLVertexBuffer);
+ SUBSYSTEM_CLEANUP(LLVertexBuffer);
- LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ;
+ LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ;
}
// shutdownViews() and shutdownGL() need to be called first
LLViewerWindow::~LLViewerWindow()
{
- LL_INFOS() << "Destroying Window" << LL_ENDL;
- destroyWindow();
+ LL_INFOS() << "Destroying Window" << LL_ENDL;
+ destroyWindow();
- delete mDebugText;
- mDebugText = NULL;
+ delete mDebugText;
+ mDebugText = NULL;
- if (LLViewerShaderMgr::sInitialized)
- {
- LLViewerShaderMgr::releaseInstance();
- LLViewerShaderMgr::sInitialized = FALSE;
- }
+ if (LLViewerShaderMgr::sInitialized)
+ {
+ LLViewerShaderMgr::releaseInstance();
+ LLViewerShaderMgr::sInitialized = FALSE;
+ }
}
void LLViewerWindow::setCursor( ECursorType c )
{
- mWindow->setCursor( c );
+ mWindow->setCursor( c );
}
void LLViewerWindow::showCursor()
{
- mWindow->showCursor();
-
- mCursorHidden = FALSE;
+ mWindow->showCursor();
+
+ mCursorHidden = FALSE;
}
void LLViewerWindow::hideCursor()
{
- // And hide the cursor
- mWindow->hideCursor();
+ // And hide the cursor
+ mWindow->hideCursor();
- mCursorHidden = TRUE;
+ mCursorHidden = TRUE;
}
void LLViewerWindow::sendShapeToSim()
{
- LLMessageSystem* msg = gMessageSystem;
- if(!msg) return;
- msg->newMessageFast(_PREHASH_AgentHeightWidth);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
- msg->nextBlockFast(_PREHASH_HeightWidthBlock);
- msg->addU32Fast(_PREHASH_GenCounter, 0);
- U16 height16 = (U16) mWorldViewRectRaw.getHeight();
- U16 width16 = (U16) mWorldViewRectRaw.getWidth();
- msg->addU16Fast(_PREHASH_Height, height16);
- msg->addU16Fast(_PREHASH_Width, width16);
- gAgent.sendReliableMessage();
+ LLMessageSystem* msg = gMessageSystem;
+ if(!msg) return;
+ msg->newMessageFast(_PREHASH_AgentHeightWidth);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
+ msg->nextBlockFast(_PREHASH_HeightWidthBlock);
+ msg->addU32Fast(_PREHASH_GenCounter, 0);
+ U16 height16 = (U16) mWorldViewRectRaw.getHeight();
+ U16 width16 = (U16) mWorldViewRectRaw.getWidth();
+ msg->addU16Fast(_PREHASH_Height, height16);
+ msg->addU16Fast(_PREHASH_Width, width16);
+ gAgent.sendReliableMessage();
}
// Must be called after window is created to set up agent
// camera variables and UI variables.
void LLViewerWindow::reshape(S32 width, S32 height)
{
- // Destroying the window at quit time generates spurious
- // reshape messages. We don't care about these, and we
- // don't want to send messages because the message system
- // may have been destructed.
- if (!LLApp::isExiting())
- {
- gWindowResized = TRUE;
+ // Destroying the window at quit time generates spurious
+ // reshape messages. We don't care about these, and we
+ // don't want to send messages because the message system
+ // may have been destructed.
+ if (!LLApp::isExiting())
+ {
+ gWindowResized = TRUE;
- // update our window rectangle
- mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width;
- mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height;
+ // update our window rectangle
+ mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width;
+ mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height;
- //glViewport(0, 0, width, height );
+ //glViewport(0, 0, width, height );
LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist
- if (height > 0 && camera)
- {
+ if (height > 0 && camera)
+ {
camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
camera->setAspect( getWorldViewAspectRatio() );
- }
-
- calcDisplayScale();
+ }
- BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
- LLUI::setScaleFactor(mDisplayScale);
+ calcDisplayScale();
+
+ BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
+ LLUI::setScaleFactor(mDisplayScale);
- // update our window rectangle
- mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]);
- mWindowRectScaled.mTop = mWindowRectScaled.mBottom + ll_round((F32)height / mDisplayScale.mV[VY]);
+ // update our window rectangle
+ mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]);
+ mWindowRectScaled.mTop = mWindowRectScaled.mBottom + ll_round((F32)height / mDisplayScale.mV[VY]);
- setup2DViewport();
+ setup2DViewport();
- // Inform lower views of the change
- // round up when converting coordinates to make sure there are no gaps at edge of window
- LLView::sForceReshape = display_scale_changed;
- mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
+ // Inform lower views of the change
+ // round up when converting coordinates to make sure there are no gaps at edge of window
+ LLView::sForceReshape = display_scale_changed;
+ mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
if (display_scale_changed)
{
// Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass()
LLPanelLogin::reshapePanel();
}
- LLView::sForceReshape = FALSE;
+ LLView::sForceReshape = FALSE;
- // clear font width caches
- if (display_scale_changed)
- {
- LLHUDObject::reshapeAll();
- }
+ // clear font width caches
+ if (display_scale_changed)
+ {
+ LLHUDObject::reshapeAll();
+ }
- sendShapeToSim();
+ sendShapeToSim();
- // store new settings for the mode we are in, regardless
- BOOL maximized = mWindow->getMaximized();
- gSavedSettings.setBOOL("WindowMaximized", maximized);
+ // store new settings for the mode we are in, regardless
+ BOOL maximized = mWindow->getMaximized();
+ gSavedSettings.setBOOL("WindowMaximized", maximized);
- if (!maximized)
- {
- U32 min_window_width=gSavedSettings.getU32("MinWindowWidth");
- U32 min_window_height=gSavedSettings.getU32("MinWindowHeight");
- // tell the OS specific window code about min window size
- mWindow->setMinSize(min_window_width, min_window_height);
+ if (!maximized)
+ {
+ U32 min_window_width=gSavedSettings.getU32("MinWindowWidth");
+ U32 min_window_height=gSavedSettings.getU32("MinWindowHeight");
+ // tell the OS specific window code about min window size
+ mWindow->setMinSize(min_window_width, min_window_height);
- LLCoordScreen window_rect;
- if (!gNonInteractive && mWindow->getSize(&window_rect))
- {
- // Only save size if not maximized
- gSavedSettings.setU32("WindowWidth", window_rect.mX);
- gSavedSettings.setU32("WindowHeight", window_rect.mY);
- }
- }
+ LLCoordScreen window_rect;
+ if (!gNonInteractive && mWindow->getSize(&window_rect))
+ {
+ // Only save size if not maximized
+ gSavedSettings.setU32("WindowWidth", window_rect.mX);
+ gSavedSettings.setU32("WindowHeight", window_rect.mY);
+ }
+ }
- sample(LLStatViewer::WINDOW_WIDTH, width);
- sample(LLStatViewer::WINDOW_HEIGHT, height);
+ sample(LLStatViewer::WINDOW_WIDTH, width);
+ sample(LLStatViewer::WINDOW_HEIGHT, height);
- LLLayoutStack::updateClass();
- }
+ LLLayoutStack::updateClass();
+ }
}
// Hide normal UI when a logon fails
void LLViewerWindow::setNormalControlsVisible( BOOL visible )
{
- if(LLChicletBar::instanceExists())
- {
- LLChicletBar::getInstance()->setVisible(visible);
- LLChicletBar::getInstance()->setEnabled(visible);
- }
-
- if ( gMenuBarView )
- {
- gMenuBarView->setVisible( visible );
- gMenuBarView->setEnabled( visible );
-
- // ...and set the menu color appropriately.
- setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT,
- LLGridManager::getInstance()->isInProductionGrid());
- }
-
- if ( gStatusBar )
- {
- gStatusBar->setVisible( visible );
- gStatusBar->setEnabled( visible );
- }
-
- LLNavigationBar* navbarp = LLUI::getInstance()->getRootView()->findChild<LLNavigationBar>("navigation_bar");
- if (navbarp)
- {
- // when it's time to show navigation bar we need to ensure that the user wants to see it
- // i.e. ShowNavbarNavigationPanel option is true
- navbarp->setVisible( visible && gSavedSettings.getBOOL("ShowNavbarNavigationPanel") );
- }
+ if(LLChicletBar::instanceExists())
+ {
+ LLChicletBar::getInstance()->setVisible(visible);
+ LLChicletBar::getInstance()->setEnabled(visible);
+ }
+
+ if ( gMenuBarView )
+ {
+ gMenuBarView->setVisible( visible );
+ gMenuBarView->setEnabled( visible );
+
+ // ...and set the menu color appropriately.
+ setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT,
+ LLGridManager::getInstance()->isInProductionGrid());
+ }
+
+ if ( gStatusBar )
+ {
+ gStatusBar->setVisible( visible );
+ gStatusBar->setEnabled( visible );
+ }
+
+ LLNavigationBar* navbarp = LLUI::getInstance()->getRootView()->findChild<LLNavigationBar>("navigation_bar");
+ if (navbarp)
+ {
+ // when it's time to show navigation bar we need to ensure that the user wants to see it
+ // i.e. ShowNavbarNavigationPanel option is true
+ navbarp->setVisible( visible && gSavedSettings.getBOOL("ShowNavbarNavigationPanel") );
+ }
}
void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
@@ -2578,17 +2580,17 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
LLSD args;
LLColor4 new_bg_color;
- // god more important than project, proj more important than grid
- if ( god_mode )
+ // god more important than project, proj more important than grid
+ if ( god_mode )
{
- if ( LLGridManager::getInstance()->isInProductionGrid() )
- {
- new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
- }
- else
- {
- new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
- }
+ if ( LLGridManager::getInstance()->isInProductionGrid() )
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
+ }
+ else
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
+ }
}
else
{
@@ -2601,24 +2603,24 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
case LLVersionInfo::PROJECT_VIEWER:
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" );
break;
-
+
case LLVersionInfo::BETA_VIEWER:
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" );
break;
-
+
case LLVersionInfo::RELEASE_VIEWER:
if(!LLGridManager::getInstance()->isInProductionGrid())
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
- else
+ else
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
break;
}
}
-
+
if(gMenuBarView)
{
gMenuBarView->setBackgroundColor( new_bg_color );
@@ -2633,144 +2635,144 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
void LLViewerWindow::drawDebugText()
{
gUIProgram.bind();
- gGL.color4f(1,1,1,1);
- gGL.pushMatrix();
- gGL.pushUIMatrix();
- {
- // scale view by UI global scale factor and aspect ratio correction factor
- gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
- mDebugText->draw();
- }
- gGL.popUIMatrix();
- gGL.popMatrix();
+ gGL.color4f(1,1,1,1);
+ gGL.pushMatrix();
+ gGL.pushUIMatrix();
+ {
+ // scale view by UI global scale factor and aspect ratio correction factor
+ gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
+ mDebugText->draw();
+ }
+ gGL.popUIMatrix();
+ gGL.popMatrix();
- gGL.flush();
- gUIProgram.unbind();
+ gGL.flush();
+ gUIProgram.unbind();
}
void LLViewerWindow::draw()
{
-
+
//#if LL_DEBUG
- LLView::sIsDrawing = TRUE;
+ LLView::sIsDrawing = TRUE;
//#endif
- stop_glerror();
-
- LLUI::setLineWidth(1.f);
-
- LLUI::setLineWidth(1.f);
- // Reset any left-over transforms
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.loadIdentity();
-
- //S32 screen_x, screen_y;
-
- if (!gSavedSettings.getBOOL("RenderUIBuffer"))
- {
- LLView::sDirtyRect = getWindowRectScaled();
- }
-
- // HACK for timecode debugging
- if (gSavedSettings.getBOOL("DisplayTimecode"))
- {
- // draw timecode block
- std::string text;
-
- gGL.loadIdentity();
-
- microsecondsToTimecodeString(gFrameTime,text);
- const LLFontGL* font = LLFontGL::getFontSansSerif();
- font->renderUTF8(text, 0,
- ll_round((getWindowWidthScaled()/2)-100.f),
- ll_round((getWindowHeightScaled()-60.f)),
- LLColor4( 1.f, 1.f, 1.f, 1.f ),
- LLFontGL::LEFT, LLFontGL::TOP);
- }
-
- // Draw all nested UI views.
- // No translation needed, this view is glued to 0,0
-
- gUIProgram.bind();
+ stop_glerror();
+
+ LLUI::setLineWidth(1.f);
+
+ LLUI::setLineWidth(1.f);
+ // Reset any left-over transforms
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ gGL.loadIdentity();
+
+ //S32 screen_x, screen_y;
+
+ if (!gSavedSettings.getBOOL("RenderUIBuffer"))
+ {
+ LLView::sDirtyRect = getWindowRectScaled();
+ }
+
+ // HACK for timecode debugging
+ if (gSavedSettings.getBOOL("DisplayTimecode"))
+ {
+ // draw timecode block
+ std::string text;
+
+ gGL.loadIdentity();
+
+ microsecondsToTimecodeString(gFrameTime,text);
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ font->renderUTF8(text, 0,
+ ll_round((getWindowWidthScaled()/2)-100.f),
+ ll_round((getWindowHeightScaled()-60.f)),
+ LLColor4( 1.f, 1.f, 1.f, 1.f ),
+ LLFontGL::LEFT, LLFontGL::TOP);
+ }
+
+ // Draw all nested UI views.
+ // No translation needed, this view is glued to 0,0
+
+ gUIProgram.bind();
gGL.color4f(1, 1, 1, 1);
- gGL.pushMatrix();
- LLUI::pushMatrix();
- {
-
- // scale view by UI global scale factor and aspect ratio correction factor
- gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
-
- LLVector2 old_scale_factor = LLUI::getScaleFactor();
- // apply camera zoom transform (for high res screenshots)
- F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
- S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
- if (zoom_factor > 1.f)
- {
- //decompose subregion number to x and y values
- int pos_y = sub_region / llceil(zoom_factor);
- int pos_x = sub_region - (pos_y*llceil(zoom_factor));
- // offset for this tile
- gGL.translatef((F32)getWindowWidthScaled() * -(F32)pos_x,
- (F32)getWindowHeightScaled() * -(F32)pos_y,
- 0.f);
- gGL.scalef(zoom_factor, zoom_factor, 1.f);
- LLUI::getScaleFactor() *= zoom_factor;
- }
-
- // Draw tool specific overlay on world
- LLToolMgr::getInstance()->getCurrentTool()->draw();
-
- if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() )
- {
- drawMouselookInstructions();
- stop_glerror();
- }
-
- // Draw all nested UI views.
- // No translation needed, this view is glued to 0,0
- mRootView->draw();
-
- if (LLView::sDebugRects)
- {
- gToolTipView->drawStickyRect();
- }
-
- // Draw optional on-top-of-everyone view
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- if (top_ctrl && top_ctrl->getVisible())
- {
- S32 screen_x, screen_y;
- top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- LLUI::pushMatrix();
- LLUI::translate( (F32) screen_x, (F32) screen_y);
- top_ctrl->draw();
- LLUI::popMatrix();
- }
-
-
- if( gShowOverlayTitle && !mOverlayTitle.empty() )
- {
- // Used for special titles such as "Second Life - Special E3 2003 Beta"
- const S32 DIST_FROM_TOP = 20;
- LLFontGL::getFontSansSerifBig()->renderUTF8(
- mOverlayTitle, 0,
- ll_round( getWindowWidthScaled() * 0.5f),
- getWindowHeightScaled() - DIST_FROM_TOP,
- LLColor4(1, 1, 1, 0.4f),
- LLFontGL::HCENTER, LLFontGL::TOP);
- }
-
- LLUI::setScaleFactor(old_scale_factor);
- }
- LLUI::popMatrix();
- gGL.popMatrix();
-
- gUIProgram.unbind();
-
- LLView::sIsDrawing = FALSE;
+ gGL.pushMatrix();
+ LLUI::pushMatrix();
+ {
+
+ // scale view by UI global scale factor and aspect ratio correction factor
+ gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
+
+ LLVector2 old_scale_factor = LLUI::getScaleFactor();
+ // apply camera zoom transform (for high res screenshots)
+ F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
+ S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
+ if (zoom_factor > 1.f)
+ {
+ //decompose subregion number to x and y values
+ int pos_y = sub_region / llceil(zoom_factor);
+ int pos_x = sub_region - (pos_y*llceil(zoom_factor));
+ // offset for this tile
+ gGL.translatef((F32)getWindowWidthScaled() * -(F32)pos_x,
+ (F32)getWindowHeightScaled() * -(F32)pos_y,
+ 0.f);
+ gGL.scalef(zoom_factor, zoom_factor, 1.f);
+ LLUI::getScaleFactor() *= zoom_factor;
+ }
+
+ // Draw tool specific overlay on world
+ LLToolMgr::getInstance()->getCurrentTool()->draw();
+
+ if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() )
+ {
+ drawMouselookInstructions();
+ stop_glerror();
+ }
+
+ // Draw all nested UI views.
+ // No translation needed, this view is glued to 0,0
+ mRootView->draw();
+
+ if (LLView::sDebugRects)
+ {
+ gToolTipView->drawStickyRect();
+ }
+
+ // Draw optional on-top-of-everyone view
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ if (top_ctrl && top_ctrl->getVisible())
+ {
+ S32 screen_x, screen_y;
+ top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ LLUI::pushMatrix();
+ LLUI::translate( (F32) screen_x, (F32) screen_y);
+ top_ctrl->draw();
+ LLUI::popMatrix();
+ }
+
+
+ if( gShowOverlayTitle && !mOverlayTitle.empty() )
+ {
+ // Used for special titles such as "Second Life - Special E3 2003 Beta"
+ const S32 DIST_FROM_TOP = 20;
+ LLFontGL::getFontSansSerifBig()->renderUTF8(
+ mOverlayTitle, 0,
+ ll_round( getWindowWidthScaled() * 0.5f),
+ getWindowHeightScaled() - DIST_FROM_TOP,
+ LLColor4(1, 1, 1, 0.4f),
+ LLFontGL::HCENTER, LLFontGL::TOP);
+ }
+
+ LLUI::setScaleFactor(old_scale_factor);
+ }
+ LLUI::popMatrix();
+ gGL.popMatrix();
+
+ gUIProgram.unbind();
+
+ LLView::sIsDrawing = FALSE;
}
// Takes a single keyup event, usually when UI is visible
@@ -2786,45 +2788,45 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if (keyboard_focus
- && !(mask & (MASK_CONTROL | MASK_ALT))
- && !gFocusMgr.getKeystrokesOnly())
- {
- // We have keyboard focus, and it's not an accelerator
+ && !(mask & (MASK_CONTROL | MASK_ALT))
+ && !gFocusMgr.getKeystrokesOnly())
+ {
+ // We have keyboard focus, and it's not an accelerator
if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
{
return keyboard_focus->handleKeyUp(key, mask, FALSE);
}
else if (key < 0x80)
- {
- // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
- return (gFocusMgr.getKeyboardFocus() != NULL);
- }
- }
-
- if (keyboard_focus)
- {
- if (keyboard_focus->handleKeyUp(key, mask, FALSE))
- {
- LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key, mask);
- return TRUE;
- }
- else {
- LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL;
- }
- }
-
- // don't pass keys on to world when something in ui has focus
- return gFocusMgr.childHasKeyboardFocus(mRootView)
- || LLMenuGL::getKeyboardMode()
- || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
+ {
+ // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
+ return (gFocusMgr.getKeyboardFocus() != NULL);
+ }
+ }
+
+ if (keyboard_focus)
+ {
+ if (keyboard_focus->handleKeyUp(key, mask, FALSE))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+ return TRUE;
+ }
+ else {
+ LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL;
+ }
+ }
+
+ // don't pass keys on to world when something in ui has focus
+ return gFocusMgr.childHasKeyboardFocus(mRootView)
+ || LLMenuGL::getKeyboardMode()
+ || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
}
// Takes a single keydown event, usually when UI is visible
BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
{
- // hide tooltips on keypress
- LLToolTipMgr::instance().blockToolTips();
+ // hide tooltips on keypress
+ LLToolTipMgr::instance().blockToolTips();
// Menus get handled on key down instead of key up
// so keybindings have to be recorded before that
@@ -2836,7 +2838,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
-
+
if (keyboard_focus
&& !gFocusMgr.getKeystrokesOnly())
{
@@ -2909,279 +2911,279 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
}
- // let menus handle navigation keys for navigation
- if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
- ||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
- ||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
- {
- LL_DEBUGS() << "LLviewerWindow::handleKey handle nav keys for nav" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
-
- // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus
- // as long as focus isn't locked
- if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked())
- {
- // Check the current floater's menu first, if it has one.
- if (gFocusMgr.keyboardFocusHasAccelerators()
- && keyboard_focus
- && keyboard_focus->handleKey(key,mask,FALSE))
- {
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
- if (gAgent.isInitialized()
- && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
- && gMenuBarView
- && gMenuBarView->handleAcceleratorKey(key, mask))
- {
- LLViewerEventRecorder::instance().logKeyEvent(key, mask);
- return TRUE;
- }
-
- if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
- {
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
- }
-
- // give floaters first chance to handle TAB key
- // so frontmost floater gets focus
- // if nothing has focus, go to first or last UI element as appropriate
+ // let menus handle navigation keys for navigation
+ if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
+ ||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
+ ||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey handle nav keys for nav" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+
+ // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus
+ // as long as focus isn't locked
+ if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked())
+ {
+ // Check the current floater's menu first, if it has one.
+ if (gFocusMgr.keyboardFocusHasAccelerators()
+ && keyboard_focus
+ && keyboard_focus->handleKey(key,mask,FALSE))
+ {
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+ if (gAgent.isInitialized()
+ && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+ && gMenuBarView
+ && gMenuBarView->handleAcceleratorKey(key, mask))
+ {
+ LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+ return TRUE;
+ }
+
+ if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
+ {
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+ }
+
+ // give floaters first chance to handle TAB key
+ // so frontmost floater gets focus
+ // if nothing has focus, go to first or last UI element as appropriate
if (key == KEY_TAB && (mask & MASK_CONTROL || keyboard_focus == NULL))
- {
- LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL;
- if (gMenuHolder) gMenuHolder->hideMenus();
-
- // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
- gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0);
-
- // do CTRL-TAB and CTRL-SHIFT-TAB logic
- if (mask & MASK_SHIFT)
- {
- mRootView->focusPrevRoot();
- }
- else
- {
- mRootView->focusNextRoot();
- }
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
- // hidden edit menu for cut/copy/paste
- if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
- {
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
- LLFloater* focused_floaterp = gFloaterView->getFocusedFloater();
- std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : "");
-
- if( keyboard_focus )
- {
- if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
- {
- if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
- {
- // let Control-Up and Control-Down through for chat line history,
- if (!(key == KEY_UP && mask == MASK_CONTROL)
- && !(key == KEY_DOWN && mask == MASK_CONTROL)
- && !(key == KEY_UP && mask == MASK_ALT)
- && !(key == KEY_DOWN && mask == MASK_ALT))
- {
- switch(key)
- {
- case KEY_LEFT:
- case KEY_RIGHT:
- case KEY_UP:
- case KEY_DOWN:
- case KEY_PAGE_UP:
- case KEY_PAGE_DOWN:
- case KEY_HOME:
- case KEY_END:
- // when chatbar is empty or ArrowKeysAlwaysMove set,
- // pass arrow keys on to avatar...
- return FALSE;
- default:
- break;
- }
- }
- }
- }
-
- if (keyboard_focus->handleKey(key, mask, FALSE))
- {
-
- LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- } else {
- LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << LL_ENDL;
- }
- }
-
- if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
- {
- LL_DEBUGS() << "LLviewerWindow::handleKey toolbar handling?" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
- // Try for a new-format gesture
- if (LLGestureMgr::instance().triggerGesture(key, mask))
- {
- LL_DEBUGS() << "LLviewerWindow::handleKey new gesture feature" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
- // See if this is a gesture trigger. If so, eat the key and
- // don't pass it down to the menus.
- if (gGestureList.trigger(key, mask))
- {
- LL_DEBUGS() << "LLviewerWindow::handleKey check gesture trigger" << LL_ENDL;
- LLViewerEventRecorder::instance().logKeyEvent(key,mask);
- return TRUE;
- }
-
- // If "Pressing letter keys starts local chat" option is selected, we are not in mouselook,
- // no view has keyboard focus, this is a printable character key (and no modifier key is
- // pressed except shift), then give focus to nearby chat (STORM-560)
- if ( LLStartUp::getStartupState() >= STATE_STARTED &&
- gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
- !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
- {
- // Initialize nearby chat if it's missing
- LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
- if (!nearby_chat)
- {
- LLSD name("im_container");
- LLFloaterReg::toggleInstanceOrBringToFront(name);
- }
-
- LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox();
- if (chat_editor)
- {
- // passing NULL here, character will be added later when it is handled by character handler.
- nearby_chat->startChat(NULL);
- return TRUE;
- }
- }
-
- // give menus a chance to handle unmodified accelerator keys
- if (gAgent.isInitialized()
- && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
- && gMenuBarView
- && gMenuBarView->handleAcceleratorKey(key, mask))
- {
- LLViewerEventRecorder::instance().logKeyEvent(key, mask);
- return TRUE;
- }
-
- if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
- {
- return TRUE;
- }
-
- // don't pass keys on to world when something in ui has focus
- return gFocusMgr.childHasKeyboardFocus(mRootView)
- || LLMenuGL::getKeyboardMode()
- || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
+ {
+ LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL;
+ if (gMenuHolder) gMenuHolder->hideMenus();
+
+ // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
+ gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0);
+
+ // do CTRL-TAB and CTRL-SHIFT-TAB logic
+ if (mask & MASK_SHIFT)
+ {
+ mRootView->focusPrevRoot();
+ }
+ else
+ {
+ mRootView->focusNextRoot();
+ }
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+ // hidden edit menu for cut/copy/paste
+ if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
+ {
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+ LLFloater* focused_floaterp = gFloaterView->getFocusedFloater();
+ std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : "");
+
+ if( keyboard_focus )
+ {
+ if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
+ {
+ if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
+ {
+ // let Control-Up and Control-Down through for chat line history,
+ if (!(key == KEY_UP && mask == MASK_CONTROL)
+ && !(key == KEY_DOWN && mask == MASK_CONTROL)
+ && !(key == KEY_UP && mask == MASK_ALT)
+ && !(key == KEY_DOWN && mask == MASK_ALT))
+ {
+ switch(key)
+ {
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGE_UP:
+ case KEY_PAGE_DOWN:
+ case KEY_HOME:
+ case KEY_END:
+ // when chatbar is empty or ArrowKeysAlwaysMove set,
+ // pass arrow keys on to avatar...
+ return FALSE;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ if (keyboard_focus->handleKey(key, mask, FALSE))
+ {
+
+ LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ } else {
+ LL_DEBUGS() << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << LL_ENDL;
+ }
+ }
+
+ if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey toolbar handling?" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+ // Try for a new-format gesture
+ if (LLGestureMgr::instance().triggerGesture(key, mask))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey new gesture feature" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+ // See if this is a gesture trigger. If so, eat the key and
+ // don't pass it down to the menus.
+ if (gGestureList.trigger(key, mask))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey check gesture trigger" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+
+ // If "Pressing letter keys starts local chat" option is selected, we are not in mouselook,
+ // no view has keyboard focus, this is a printable character key (and no modifier key is
+ // pressed except shift), then give focus to nearby chat (STORM-560)
+ if ( LLStartUp::getStartupState() >= STATE_STARTED &&
+ gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
+ !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
+ {
+ // Initialize nearby chat if it's missing
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (!nearby_chat)
+ {
+ LLSD name("im_container");
+ LLFloaterReg::toggleInstanceOrBringToFront(name);
+ }
+
+ LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox();
+ if (chat_editor)
+ {
+ // passing NULL here, character will be added later when it is handled by character handler.
+ nearby_chat->startChat(NULL);
+ return TRUE;
+ }
+ }
+
+ // give menus a chance to handle unmodified accelerator keys
+ if (gAgent.isInitialized()
+ && (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+ && gMenuBarView
+ && gMenuBarView->handleAcceleratorKey(key, mask))
+ {
+ LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+ return TRUE;
+ }
+
+ if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
+ {
+ return TRUE;
+ }
+
+ // don't pass keys on to world when something in ui has focus
+ return gFocusMgr.childHasKeyboardFocus(mRootView)
+ || LLMenuGL::getKeyboardMode()
+ || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
}
BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
{
- // HACK: We delay processing of return keys until they arrive as a Unicode char,
- // so that if you're typing chat text at low frame rate, we don't send the chat
- // until all keystrokes have been entered. JC
- // HACK: Numeric keypad <enter> on Mac is Unicode 3
- // HACK: Control-M on Windows is Unicode 13
- if ((uni_char == 13 && mask != MASK_CONTROL)
- || (uni_char == 3 && mask == MASK_NONE) )
- {
- if (mask != MASK_ALT)
- {
- // remaps, handles ignored cases and returns back to viewer window.
- return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
- }
- }
+ // HACK: We delay processing of return keys until they arrive as a Unicode char,
+ // so that if you're typing chat text at low frame rate, we don't send the chat
+ // until all keystrokes have been entered. JC
+ // HACK: Numeric keypad <enter> on Mac is Unicode 3
+ // HACK: Control-M on Windows is Unicode 13
+ if ((uni_char == 13 && mask != MASK_CONTROL)
+ || (uni_char == 3 && mask == MASK_NONE) )
+ {
+ if (mask != MASK_ALT)
+ {
+ // remaps, handles ignored cases and returns back to viewer window.
+ return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+ }
+ }
+
+ // let menus handle navigation (jump) keys
+ if (gMenuBarView && gMenuBarView->handleUnicodeChar(uni_char, TRUE))
+ {
+ return TRUE;
+ }
+
+ // Traverses up the hierarchy
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ if( keyboard_focus )
+ {
+ if (keyboard_focus->handleUnicodeChar(uni_char, FALSE))
+ {
+ return TRUE;
+ }
- // let menus handle navigation (jump) keys
- if (gMenuBarView && gMenuBarView->handleUnicodeChar(uni_char, TRUE))
- {
return TRUE;
- }
-
- // Traverses up the hierarchy
- LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
- if( keyboard_focus )
- {
- if (keyboard_focus->handleUnicodeChar(uni_char, FALSE))
- {
- return TRUE;
- }
+ }
- return TRUE;
- }
-
- return FALSE;
+ return FALSE;
}
void LLViewerWindow::handleScrollWheel(S32 clicks)
{
- LLUI::getInstance()->resetMouseIdleTimer();
-
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if( mouse_captor )
- {
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
- mouse_captor->handleScrollWheel(local_x, local_y, clicks);
- if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << "Scroll Wheel handled by captor " << mouse_captor->getName() << LL_ENDL;
- }
- return;
- }
-
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- if (top_ctrl)
- {
- S32 local_x;
- S32 local_y;
- top_ctrl->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
- if (top_ctrl->handleScrollWheel(local_x, local_y, clicks)) return;
- }
-
- if (mRootView->handleScrollWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks) )
- {
- if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << "Scroll Wheel" << LLView::sMouseHandlerMessage << LL_ENDL;
- }
- return;
- }
- else if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << "Scroll Wheel not handled by view" << LL_ENDL;
- }
-
- // Zoom the camera in and out behavior
-
- if(top_ctrl == 0
- && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY)
- && gAgentCamera.isInitialized())
- gAgentCamera.handleScrollWheel(clicks);
-
- return;
+ LLUI::getInstance()->resetMouseIdleTimer();
+
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ if( mouse_captor )
+ {
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
+ mouse_captor->handleScrollWheel(local_x, local_y, clicks);
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Wheel handled by captor " << mouse_captor->getName() << LL_ENDL;
+ }
+ return;
+ }
+
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ if (top_ctrl)
+ {
+ S32 local_x;
+ S32 local_y;
+ top_ctrl->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
+ if (top_ctrl->handleScrollWheel(local_x, local_y, clicks)) return;
+ }
+
+ if (mRootView->handleScrollWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks) )
+ {
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Wheel" << LLView::sMouseHandlerMessage << LL_ENDL;
+ }
+ return;
+ }
+ else if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Wheel not handled by view" << LL_ENDL;
+ }
+
+ // Zoom the camera in and out behavior
+
+ if(top_ctrl == 0
+ && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY)
+ && gAgentCamera.isInitialized())
+ gAgentCamera.handleScrollWheel(clicks);
+
+ return;
}
void LLViewerWindow::handleScrollHWheel(S32 clicks)
@@ -3190,7 +3192,7 @@ void LLViewerWindow::handleScrollHWheel(S32 clicks)
{
return;
}
-
+
LLUI::getInstance()->resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
@@ -3234,42 +3236,42 @@ void LLViewerWindow::handleScrollHWheel(S32 clicks)
void LLViewerWindow::addPopup(LLView* popup)
{
- if (mPopupView)
- {
- mPopupView->addPopup(popup);
- }
+ if (mPopupView)
+ {
+ mPopupView->addPopup(popup);
+ }
}
void LLViewerWindow::removePopup(LLView* popup)
{
- if (mPopupView)
- {
- mPopupView->removePopup(popup);
- }
+ if (mPopupView)
+ {
+ mPopupView->removePopup(popup);
+ }
}
void LLViewerWindow::clearPopups()
{
- if (mPopupView)
- {
- mPopupView->clearPopups();
- }
+ if (mPopupView)
+ {
+ mPopupView->clearPopups();
+ }
}
void LLViewerWindow::moveCursorToCenter()
{
- if (! gSavedSettings.getBOOL("DisableMouseWarp"))
- {
- S32 x = getWorldViewWidthScaled() / 2;
- S32 y = getWorldViewHeightScaled() / 2;
-
- LLUI::getInstance()->setMousePositionScreen(x, y);
-
- //on a forced move, all deltas get zeroed out to prevent jumping
- mCurrentMousePoint.set(x,y);
- mLastMousePoint.set(x,y);
- mCurrentMouseDelta.set(0,0);
- }
+ if (! gSavedSettings.getBOOL("DisableMouseWarp"))
+ {
+ S32 x = getWorldViewWidthScaled() / 2;
+ S32 y = getWorldViewHeightScaled() / 2;
+
+ LLUI::getInstance()->setMousePositionScreen(x, y);
+
+ //on a forced move, all deltas get zeroed out to prevent jumping
+ mCurrentMousePoint.set(x,y);
+ mLastMousePoint.set(x,y);
+ mCurrentMouseDelta.set(0,0);
+ }
}
@@ -3280,32 +3282,32 @@ void LLViewerWindow::moveCursorToCenter()
void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
{
- if (viewp)
- {
- if (!params.styled_message.empty())
- {
- params.styled_message.add().text("\n---------\n");
- }
- LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView();
- // NOTE: we skip "root" since it is assumed
- for (LLView::root_to_view_iterator_t tooltip_it = ++viewp->beginRootToView();
- tooltip_it != end_tooltip_it;
- ++tooltip_it)
- {
- LLView* viewp = *tooltip_it;
-
- params.styled_message.add().text(viewp->getName());
-
- LLPanel* panelp = dynamic_cast<LLPanel*>(viewp);
- if (panelp && !panelp->getXMLFilename().empty())
- {
- params.styled_message.add()
- .text("(" + panelp->getXMLFilename() + ")")
- .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f));
- }
- params.styled_message.add().text("/");
- }
- }
+ if (viewp)
+ {
+ if (!params.styled_message.empty())
+ {
+ params.styled_message.add().text("\n---------\n");
+ }
+ LLView::root_to_view_iterator_t end_tooltip_it = viewp->endRootToView();
+ // NOTE: we skip "root" since it is assumed
+ for (LLView::root_to_view_iterator_t tooltip_it = ++viewp->beginRootToView();
+ tooltip_it != end_tooltip_it;
+ ++tooltip_it)
+ {
+ LLView* viewp = *tooltip_it;
+
+ params.styled_message.add().text(viewp->getName());
+
+ LLPanel* panelp = dynamic_cast<LLPanel*>(viewp);
+ if (panelp && !panelp->getXMLFilename().empty())
+ {
+ params.styled_message.add()
+ .text("(" + panelp->getXMLFilename() + ")")
+ .style.color(LLColor4(0.7f, 0.7f, 1.f, 1.f));
+ }
+ params.styled_message.add().text("/");
+ }
+ }
}
static LLTrace::BlockTimerStatHandle ftm("Update UI");
@@ -3314,920 +3316,922 @@ static LLTrace::BlockTimerStatHandle ftm("Update UI");
// event processing.
void LLViewerWindow::updateUI()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm);
-
- static std::string last_handle_msg;
-
- if (gLoggedInTime.getStarted())
- {
- if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout"))
- {
- LLFirstUse::notUsingDestinationGuide();
- }
- if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
- {
- LLFirstUse::notUsingSidePanel();
- }
- }
-
- LLConsole::updateClass();
-
- // animate layout stacks so we have up to date rect for world view
- LLLayoutStack::updateClass();
-
- // use full window for world view when not rendering UI
- bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- updateWorldViewRect(world_view_uses_full_window);
-
- LLView::sMouseHandlerMessage.clear();
-
- S32 x = mCurrentMousePoint.mX;
- S32 y = mCurrentMousePoint.mY;
-
- MASK mask = gKeyboard->currentMask(TRUE);
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
- {
- gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, FALSE,
- &gDebugRaycastFaceHit,
- &gDebugRaycastIntersection,
- &gDebugRaycastTexCoord,
- &gDebugRaycastNormal,
- &gDebugRaycastTangent,
- &gDebugRaycastStart,
- &gDebugRaycastEnd);
-
- gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL);
- }
-
- updateMouseDelta();
- updateKeyboardFocus();
-
- BOOL handled = FALSE;
-
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- LLView* captor_view = dynamic_cast<LLView*>(mouse_captor);
-
- //FIXME: only include captor and captor's ancestors if mouse is truly over them --RN
-
- //build set of views containing mouse cursor by traversing UI hierarchy and testing
- //screen rect against mouse cursor
- view_handle_set_t mouse_hover_set;
-
- // constraint mouse enter events to children of mouse captor
- LLView* root_view = captor_view;
-
- // if mouse captor doesn't exist or isn't a LLView
- // then allow mouse enter events on entire UI hierarchy
- if (!root_view)
- {
- root_view = mRootView;
- }
-
- static LLCachedControl<bool> dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false);
- if (dump_menu_holder)
- {
- static bool init = false;
- static LLFrameTimer child_count_timer;
- static std::vector <std::string> child_vec;
- if (!init)
- {
- child_count_timer.resetWithExpiry(5.f);
- init = true;
- }
- if (child_count_timer.hasExpired())
- {
- LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL;
- std::vector<std::string> local_child_vec;
- LLView::child_list_t child_list = *gMenuHolder->getChildList();
- for (auto child : child_list)
- {
- local_child_vec.emplace_back(child->getName());
- }
- if (!local_child_vec.empty() && local_child_vec != child_vec)
- {
- std::vector<std::string> out_vec;
- std::sort(local_child_vec.begin(), local_child_vec.end());
- std::sort(child_vec.begin(), child_vec.end());
- std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin()));
- if (!out_vec.empty())
- {
- LL_INFOS() << "gMenuHolder removal diff size: '"<<out_vec.size() <<"' begin_child_diff";
- for (auto str : out_vec)
- {
- LL_CONT << " : " << str;
- }
- LL_CONT << " : end_child_diff" << LL_ENDL;
- }
-
- out_vec.clear();
- std::set_difference(local_child_vec.begin(), local_child_vec.end(), child_vec.begin(), child_vec.end(), std::inserter(out_vec, out_vec.begin()));
- if (!out_vec.empty())
- {
- LL_INFOS() << "gMenuHolder addition diff size: '" << out_vec.size() << "' begin_child_diff";
- for (auto str : out_vec)
- {
- LL_CONT << " : " << str;
- }
- LL_CONT << " : end_child_diff" << LL_ENDL;
- }
- child_vec.swap(local_child_vec);
- }
- child_count_timer.resetWithExpiry(5.f);
- }
- }
-
- // only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // include all ancestors of captor_view as automatically having mouse
- if (captor_view)
- {
- LLView* captor_parent_view = captor_view->getParent();
- while(captor_parent_view)
- {
- mouse_hover_set.insert(captor_parent_view->getHandle());
- captor_parent_view = captor_parent_view->getParent();
- }
- }
-
- // aggregate visible views that contain mouse cursor in display order
- LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups();
-
- for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it)
- {
- LLView* popup = popup_it->get();
- if (popup && popup->calcScreenBoundingRect().pointInRect(x, y))
- {
- // iterator over contents of top_ctrl, and throw into mouse_hover_set
- for (LLView::tree_iterator_t it = popup->beginTreeDFS();
- it != popup->endTreeDFS();
- ++it)
- {
- LLView* viewp = *it;
- if (viewp->getVisible()
- && viewp->calcScreenBoundingRect().pointInRect(x, y))
- {
- // we have a view that contains the mouse, add it to the set
- mouse_hover_set.insert(viewp->getHandle());
- }
- else
- {
- // skip this view and all of its children
- it.skipDescendants();
- }
- }
- }
- }
-
- // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events
- if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y))
- {
- // iterator over contents of top_ctrl, and throw into mouse_hover_set
- for (LLView::tree_iterator_t it = top_ctrl->beginTreeDFS();
- it != top_ctrl->endTreeDFS();
- ++it)
- {
- LLView* viewp = *it;
- if (viewp->getVisible()
- && viewp->calcScreenBoundingRect().pointInRect(x, y))
- {
- // we have a view that contains the mouse, add it to the set
- mouse_hover_set.insert(viewp->getHandle());
- }
- else
- {
- // skip this view and all of its children
- it.skipDescendants();
- }
- }
- }
- else
- {
- // walk UI tree in depth-first order
- for (LLView::tree_iterator_t it = root_view->beginTreeDFS();
- it != root_view->endTreeDFS();
- ++it)
- {
- LLView* viewp = *it;
- // calculating the screen rect involves traversing the parent, so this is less than optimal
- if (viewp->getVisible()
- && viewp->calcScreenBoundingRect().pointInRect(x, y))
- {
-
- // if this view is mouse opaque, nothing behind it should be in mouse_hover_set
- if (viewp->getMouseOpaque())
- {
- // constrain further iteration to children of this widget
- it = viewp->beginTreeDFS();
- }
-
- // we have a view that contains the mouse, add it to the set
- mouse_hover_set.insert(viewp->getHandle());
- }
- else
- {
- // skip this view and all of its children
- it.skipDescendants();
- }
- }
- }
- }
-
- typedef std::vector<LLHandle<LLView> > view_handle_list_t;
-
- // call onMouseEnter() on all views which contain the mouse cursor but did not before
- view_handle_list_t mouse_enter_views;
- std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(),
- mMouseHoverViews.begin(), mMouseHoverViews.end(),
- std::back_inserter(mouse_enter_views));
- for (view_handle_list_t::iterator it = mouse_enter_views.begin();
- it != mouse_enter_views.end();
- ++it)
- {
- LLView* viewp = it->get();
- if (viewp)
- {
- LLRect view_screen_rect = viewp->calcScreenRect();
- viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
- }
- }
-
- // call onMouseLeave() on all views which no longer contain the mouse cursor
- view_handle_list_t mouse_leave_views;
- std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(),
- mouse_hover_set.begin(), mouse_hover_set.end(),
- std::back_inserter(mouse_leave_views));
- for (view_handle_list_t::iterator it = mouse_leave_views.begin();
- it != mouse_leave_views.end();
- ++it)
- {
- LLView* viewp = it->get();
- if (viewp)
- {
- LLRect view_screen_rect = viewp->calcScreenRect();
- viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
- }
- }
-
- // store resulting hover set for next frame
- swap(mMouseHoverViews, mouse_hover_set);
-
- // only handle hover events when UI is enabled
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
-
- if( mouse_captor )
- {
- // Pass hover events to object capturing mouse events.
- S32 local_x;
- S32 local_y;
- mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
- handled = mouse_captor->handleHover(local_x, local_y, mask);
- if (LLView::sDebugMouseHandling)
- {
- LL_INFOS() << "Hover handled by captor " << mouse_captor->getName() << LL_ENDL;
- }
-
- if( !handled )
- {
- LL_DEBUGS("UserInput") << "hover not handled by mouse captor" << LL_ENDL;
- }
- }
- else
- {
- if (top_ctrl)
- {
- S32 local_x, local_y;
- top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
- handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
- }
-
- if ( !handled )
- {
- // x and y are from last time mouse was in window
- // mMouseInWindow tracks *actual* mouse location
- if (mMouseInWindow && mRootView->handleHover(x, y, mask) )
- {
- if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg)
- {
- last_handle_msg = LLView::sMouseHandlerMessage;
- LL_INFOS() << "Hover" << LLView::sMouseHandlerMessage << LL_ENDL;
- }
- handled = TRUE;
- }
- else if (LLView::sDebugMouseHandling)
- {
- if (last_handle_msg != LLStringUtil::null)
- {
- last_handle_msg.clear();
- LL_INFOS() << "Hover not handled by view" << LL_ENDL;
- }
- }
- }
-
- if (!handled)
- {
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
-
- if(mMouseInWindow && tool)
- {
- handled = tool->handleHover(x, y, mask);
- }
- }
- }
-
- // Show a new tool tip (or update one that is already shown)
- BOOL tool_tip_handled = FALSE;
- std::string tool_tip_msg;
- if( handled
- && !mWindow->isCursorHidden())
- {
- LLRect screen_sticky_rect = mRootView->getLocalRect();
- S32 local_x, local_y;
-
- static LLCachedControl<bool> debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0);
- if (debug_show_xui_names)
- {
- LLToolTip::Params params;
-
- LLView* tooltip_view = mRootView;
- LLView::tree_iterator_t end_it = mRootView->endTreeDFS();
- for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it)
- {
- LLView* viewp = *it;
- LLRect screen_rect;
- viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect);
- if (!(viewp->getVisible()
- && screen_rect.pointInRect(x, y)))
- {
- it.skipDescendants();
- }
- // only report xui names for LLUICtrls,
- // and blacklist the various containers we don't care about
- else if (dynamic_cast<LLUICtrl*>(viewp)
- && viewp != gMenuHolder
- && viewp != gFloaterView
- && viewp != gConsole)
- {
- if (dynamic_cast<LLFloater*>(viewp))
- {
- // constrain search to descendants of this (frontmost) floater
- // by resetting iterator
- it = viewp->beginTreeDFS();
- }
-
- // if we are in a new part of the tree (not a descendent of current tooltip_view)
- // then push the results for tooltip_view and start with a new potential view
- // NOTE: this emulates visiting only the leaf nodes that meet our criteria
- if (!viewp->hasAncestor(tooltip_view))
- {
- append_xui_tooltip(tooltip_view, params);
- screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
- }
- tooltip_view = viewp;
- }
- }
-
- append_xui_tooltip(tooltip_view, params);
- params.styled_message.add().text("\n");
-
- screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
-
- params.sticky_rect = screen_sticky_rect;
- params.max_width = 400;
-
- LLToolTipMgr::instance().show(params);
- }
- // if there is a mouse captor, nothing else gets a tooltip
- else if (mouse_captor)
- {
- mouse_captor->screenPointToLocal(x, y, &local_x, &local_y);
- tool_tip_handled = mouse_captor->handleToolTip(local_x, local_y, mask);
- }
- else
- {
- // next is top_ctrl
- if (!tool_tip_handled && top_ctrl)
- {
- top_ctrl->screenPointToLocal(x, y, &local_x, &local_y);
- tool_tip_handled = top_ctrl->handleToolTip(local_x, local_y, mask );
- }
-
- if (!tool_tip_handled)
- {
- local_x = x; local_y = y;
- tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask );
- }
-
- LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool();
- if (!tool_tip_handled && current_tool)
- {
- current_tool->screenPointToLocal(x, y, &local_x, &local_y);
- tool_tip_handled = current_tool->handleToolTip(local_x, local_y, mask );
- }
- }
- }
- }
- else
- { // just have tools handle hover when UI is turned off
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
-
- if(mMouseInWindow && tool)
- {
- handled = tool->handleHover(x, y, mask);
- }
- }
-
- updateLayout();
-
- mLastMousePoint = mCurrentMousePoint;
-
- // cleanup unused selections when no modal dialogs are open
- if (LLModalDialog::activeCount() == 0)
- {
- LLViewerParcelMgr::getInstance()->deselectUnused();
- }
-
- if (LLModalDialog::activeCount() == 0)
- {
- LLSelectMgr::getInstance()->deselectUnused();
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm);
+
+ static std::string last_handle_msg;
+
+ if (gLoggedInTime.getStarted())
+ {
+ if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout"))
+ {
+ LLFirstUse::notUsingDestinationGuide();
+ }
+ if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
+ {
+ LLFirstUse::notUsingSidePanel();
+ }
+ }
+
+ LLConsole::updateClass();
+
+ // animate layout stacks so we have up to date rect for world view
+ LLLayoutStack::updateClass();
+
+ // use full window for world view when not rendering UI
+ bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ updateWorldViewRect(world_view_uses_full_window);
+
+ LLView::sMouseHandlerMessage.clear();
+
+ S32 x = mCurrentMousePoint.mX;
+ S32 y = mCurrentMousePoint.mY;
+
+ MASK mask = gKeyboard->currentMask(TRUE);
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
+ {
+ gDebugRaycastFaceHit = gDebugRaycastGLTFNodeHit = gDebugRaycastGLTFPrimitiveHit = -1;
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, FALSE,
+ &gDebugRaycastFaceHit,
+ &gDebugRaycastGLTFNodeHit,
+ &gDebugRaycastGLTFPrimitiveHit,
+ &gDebugRaycastIntersection,
+ &gDebugRaycastTexCoord,
+ &gDebugRaycastNormal,
+ &gDebugRaycastTangent,
+ &gDebugRaycastStart,
+ &gDebugRaycastEnd);
+
+ gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL);
+ }
+
+ updateMouseDelta();
+ updateKeyboardFocus();
+
+ BOOL handled = FALSE;
+
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ LLView* captor_view = dynamic_cast<LLView*>(mouse_captor);
+
+ //FIXME: only include captor and captor's ancestors if mouse is truly over them --RN
+
+ //build set of views containing mouse cursor by traversing UI hierarchy and testing
+ //screen rect against mouse cursor
+ view_handle_set_t mouse_hover_set;
+
+ // constraint mouse enter events to children of mouse captor
+ LLView* root_view = captor_view;
+
+ // if mouse captor doesn't exist or isn't a LLView
+ // then allow mouse enter events on entire UI hierarchy
+ if (!root_view)
+ {
+ root_view = mRootView;
+ }
+
+ static LLCachedControl<bool> dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false);
+ if (dump_menu_holder)
+ {
+ static bool init = false;
+ static LLFrameTimer child_count_timer;
+ static std::vector <std::string> child_vec;
+ if (!init)
+ {
+ child_count_timer.resetWithExpiry(5.f);
+ init = true;
+ }
+ if (child_count_timer.hasExpired())
+ {
+ LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL;
+ std::vector<std::string> local_child_vec;
+ LLView::child_list_t child_list = *gMenuHolder->getChildList();
+ for (auto child : child_list)
+ {
+ local_child_vec.emplace_back(child->getName());
+ }
+ if (!local_child_vec.empty() && local_child_vec != child_vec)
+ {
+ std::vector<std::string> out_vec;
+ std::sort(local_child_vec.begin(), local_child_vec.end());
+ std::sort(child_vec.begin(), child_vec.end());
+ std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin()));
+ if (!out_vec.empty())
+ {
+ LL_INFOS() << "gMenuHolder removal diff size: '"<<out_vec.size() <<"' begin_child_diff";
+ for (auto str : out_vec)
+ {
+ LL_CONT << " : " << str;
+ }
+ LL_CONT << " : end_child_diff" << LL_ENDL;
+ }
+
+ out_vec.clear();
+ std::set_difference(local_child_vec.begin(), local_child_vec.end(), child_vec.begin(), child_vec.end(), std::inserter(out_vec, out_vec.begin()));
+ if (!out_vec.empty())
+ {
+ LL_INFOS() << "gMenuHolder addition diff size: '" << out_vec.size() << "' begin_child_diff";
+ for (auto str : out_vec)
+ {
+ LL_CONT << " : " << str;
+ }
+ LL_CONT << " : end_child_diff" << LL_ENDL;
+ }
+ child_vec.swap(local_child_vec);
+ }
+ child_count_timer.resetWithExpiry(5.f);
+ }
+ }
+
+ // only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // include all ancestors of captor_view as automatically having mouse
+ if (captor_view)
+ {
+ LLView* captor_parent_view = captor_view->getParent();
+ while(captor_parent_view)
+ {
+ mouse_hover_set.insert(captor_parent_view->getHandle());
+ captor_parent_view = captor_parent_view->getParent();
+ }
+ }
+
+ // aggregate visible views that contain mouse cursor in display order
+ LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups();
+
+ for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it)
+ {
+ LLView* popup = popup_it->get();
+ if (popup && popup->calcScreenBoundingRect().pointInRect(x, y))
+ {
+ // iterator over contents of top_ctrl, and throw into mouse_hover_set
+ for (LLView::tree_iterator_t it = popup->beginTreeDFS();
+ it != popup->endTreeDFS();
+ ++it)
+ {
+ LLView* viewp = *it;
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
+ {
+ // we have a view that contains the mouse, add it to the set
+ mouse_hover_set.insert(viewp->getHandle());
+ }
+ else
+ {
+ // skip this view and all of its children
+ it.skipDescendants();
+ }
+ }
+ }
+ }
+
+ // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events
+ if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y))
+ {
+ // iterator over contents of top_ctrl, and throw into mouse_hover_set
+ for (LLView::tree_iterator_t it = top_ctrl->beginTreeDFS();
+ it != top_ctrl->endTreeDFS();
+ ++it)
+ {
+ LLView* viewp = *it;
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
+ {
+ // we have a view that contains the mouse, add it to the set
+ mouse_hover_set.insert(viewp->getHandle());
+ }
+ else
+ {
+ // skip this view and all of its children
+ it.skipDescendants();
+ }
+ }
+ }
+ else
+ {
+ // walk UI tree in depth-first order
+ for (LLView::tree_iterator_t it = root_view->beginTreeDFS();
+ it != root_view->endTreeDFS();
+ ++it)
+ {
+ LLView* viewp = *it;
+ // calculating the screen rect involves traversing the parent, so this is less than optimal
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
+ {
+
+ // if this view is mouse opaque, nothing behind it should be in mouse_hover_set
+ if (viewp->getMouseOpaque())
+ {
+ // constrain further iteration to children of this widget
+ it = viewp->beginTreeDFS();
+ }
+
+ // we have a view that contains the mouse, add it to the set
+ mouse_hover_set.insert(viewp->getHandle());
+ }
+ else
+ {
+ // skip this view and all of its children
+ it.skipDescendants();
+ }
+ }
+ }
+ }
+
+ typedef std::vector<LLHandle<LLView> > view_handle_list_t;
+
+ // call onMouseEnter() on all views which contain the mouse cursor but did not before
+ view_handle_list_t mouse_enter_views;
+ std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(),
+ mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ std::back_inserter(mouse_enter_views));
+ for (view_handle_list_t::iterator it = mouse_enter_views.begin();
+ it != mouse_enter_views.end();
+ ++it)
+ {
+ LLView* viewp = it->get();
+ if (viewp)
+ {
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
+ }
+ }
+
+ // call onMouseLeave() on all views which no longer contain the mouse cursor
+ view_handle_list_t mouse_leave_views;
+ std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ mouse_hover_set.begin(), mouse_hover_set.end(),
+ std::back_inserter(mouse_leave_views));
+ for (view_handle_list_t::iterator it = mouse_leave_views.begin();
+ it != mouse_leave_views.end();
+ ++it)
+ {
+ LLView* viewp = it->get();
+ if (viewp)
+ {
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
+ }
+ }
+
+ // store resulting hover set for next frame
+ swap(mMouseHoverViews, mouse_hover_set);
+
+ // only handle hover events when UI is enabled
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+
+ if( mouse_captor )
+ {
+ // Pass hover events to object capturing mouse events.
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
+ handled = mouse_captor->handleHover(local_x, local_y, mask);
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Hover handled by captor " << mouse_captor->getName() << LL_ENDL;
+ }
+
+ if( !handled )
+ {
+ LL_DEBUGS("UserInput") << "hover not handled by mouse captor" << LL_ENDL;
+ }
+ }
+ else
+ {
+ if (top_ctrl)
+ {
+ S32 local_x, local_y;
+ top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
+ handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
+ }
+
+ if ( !handled )
+ {
+ // x and y are from last time mouse was in window
+ // mMouseInWindow tracks *actual* mouse location
+ if (mMouseInWindow && mRootView->handleHover(x, y, mask) )
+ {
+ if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg)
+ {
+ last_handle_msg = LLView::sMouseHandlerMessage;
+ LL_INFOS() << "Hover" << LLView::sMouseHandlerMessage << LL_ENDL;
+ }
+ handled = TRUE;
+ }
+ else if (LLView::sDebugMouseHandling)
+ {
+ if (last_handle_msg != LLStringUtil::null)
+ {
+ last_handle_msg.clear();
+ LL_INFOS() << "Hover not handled by view" << LL_ENDL;
+ }
+ }
+ }
+
+ if (!handled)
+ {
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ if(mMouseInWindow && tool)
+ {
+ handled = tool->handleHover(x, y, mask);
+ }
+ }
+ }
+
+ // Show a new tool tip (or update one that is already shown)
+ BOOL tool_tip_handled = FALSE;
+ std::string tool_tip_msg;
+ if( handled
+ && !mWindow->isCursorHidden())
+ {
+ LLRect screen_sticky_rect = mRootView->getLocalRect();
+ S32 local_x, local_y;
+
+ static LLCachedControl<bool> debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0);
+ if (debug_show_xui_names)
+ {
+ LLToolTip::Params params;
+
+ LLView* tooltip_view = mRootView;
+ LLView::tree_iterator_t end_it = mRootView->endTreeDFS();
+ for (LLView::tree_iterator_t it = mRootView->beginTreeDFS(); it != end_it; ++it)
+ {
+ LLView* viewp = *it;
+ LLRect screen_rect;
+ viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect);
+ if (!(viewp->getVisible()
+ && screen_rect.pointInRect(x, y)))
+ {
+ it.skipDescendants();
+ }
+ // only report xui names for LLUICtrls,
+ // and blacklist the various containers we don't care about
+ else if (dynamic_cast<LLUICtrl*>(viewp)
+ && viewp != gMenuHolder
+ && viewp != gFloaterView
+ && viewp != gConsole)
+ {
+ if (dynamic_cast<LLFloater*>(viewp))
+ {
+ // constrain search to descendants of this (frontmost) floater
+ // by resetting iterator
+ it = viewp->beginTreeDFS();
+ }
+
+ // if we are in a new part of the tree (not a descendent of current tooltip_view)
+ // then push the results for tooltip_view and start with a new potential view
+ // NOTE: this emulates visiting only the leaf nodes that meet our criteria
+ if (!viewp->hasAncestor(tooltip_view))
+ {
+ append_xui_tooltip(tooltip_view, params);
+ screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
+ }
+ tooltip_view = viewp;
+ }
+ }
+
+ append_xui_tooltip(tooltip_view, params);
+ params.styled_message.add().text("\n");
+
+ screen_sticky_rect.intersectWith(tooltip_view->calcScreenRect());
+
+ params.sticky_rect = screen_sticky_rect;
+ params.max_width = 400;
+
+ LLToolTipMgr::instance().show(params);
+ }
+ // if there is a mouse captor, nothing else gets a tooltip
+ else if (mouse_captor)
+ {
+ mouse_captor->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = mouse_captor->handleToolTip(local_x, local_y, mask);
+ }
+ else
+ {
+ // next is top_ctrl
+ if (!tool_tip_handled && top_ctrl)
+ {
+ top_ctrl->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = top_ctrl->handleToolTip(local_x, local_y, mask );
+ }
+
+ if (!tool_tip_handled)
+ {
+ local_x = x; local_y = y;
+ tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask );
+ }
+
+ LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (!tool_tip_handled && current_tool)
+ {
+ current_tool->screenPointToLocal(x, y, &local_x, &local_y);
+ tool_tip_handled = current_tool->handleToolTip(local_x, local_y, mask );
+ }
+ }
+ }
+ }
+ else
+ { // just have tools handle hover when UI is turned off
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ if(mMouseInWindow && tool)
+ {
+ handled = tool->handleHover(x, y, mask);
+ }
+ }
+
+ updateLayout();
+
+ mLastMousePoint = mCurrentMousePoint;
+
+ // cleanup unused selections when no modal dialogs are open
+ if (LLModalDialog::activeCount() == 0)
+ {
+ LLViewerParcelMgr::getInstance()->deselectUnused();
+ }
+
+ if (LLModalDialog::activeCount() == 0)
+ {
+ LLSelectMgr::getInstance()->deselectUnused();
+ }
}
void LLViewerWindow::updateLayout()
{
- LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
- if (gFloaterTools != NULL
- && tool != NULL
- && tool != gToolNull
- && tool != LLToolCompInspect::getInstance()
- && tool != LLToolDragAndDrop::getInstance()
- && !gSavedSettings.getBOOL("FreezeTime"))
- {
- // Suppress the toolbox view if our source tool was the pie tool,
- // and we've overridden to something else.
- bool suppress_toolbox =
- (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) &&
- (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance());
-
- LLMouseHandler *captor = gFocusMgr.getMouseCapture();
- // With the null, inspect, or drag and drop tool, don't muck
- // with visibility.
-
- if (gFloaterTools->isMinimized()
- || (tool != LLToolPie::getInstance() // not default tool
- && tool != LLToolCompGun::getInstance() // not coming out of mouselook
- && !suppress_toolbox // not override in third person
- && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools()
- && (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging
- {
- // Force floater tools to be visible (unless minimized)
- if (!gFloaterTools->getVisible())
- {
- gFloaterTools->openFloater();
- }
- // Update the location of the blue box tool popup
- LLCoordGL select_center_screen;
- MASK mask = gKeyboard->currentMask(TRUE);
- gFloaterTools->updatePopup( select_center_screen, mask );
- }
- else
- {
- gFloaterTools->setVisible(FALSE);
- }
- //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
- }
-
- // Always update console
- if(gConsole)
- {
- LLRect console_rect = getChatConsoleRect();
- gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
- gConsole->setRect(console_rect);
- }
+ LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (gFloaterTools != NULL
+ && tool != NULL
+ && tool != gToolNull
+ && tool != LLToolCompInspect::getInstance()
+ && tool != LLToolDragAndDrop::getInstance()
+ && !gSavedSettings.getBOOL("FreezeTime"))
+ {
+ // Suppress the toolbox view if our source tool was the pie tool,
+ // and we've overridden to something else.
+ bool suppress_toolbox =
+ (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) &&
+ (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance());
+
+ LLMouseHandler *captor = gFocusMgr.getMouseCapture();
+ // With the null, inspect, or drag and drop tool, don't muck
+ // with visibility.
+
+ if (gFloaterTools->isMinimized()
+ || (tool != LLToolPie::getInstance() // not default tool
+ && tool != LLToolCompGun::getInstance() // not coming out of mouselook
+ && !suppress_toolbox // not override in third person
+ && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools()
+ && (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging
+ {
+ // Force floater tools to be visible (unless minimized)
+ if (!gFloaterTools->getVisible())
+ {
+ gFloaterTools->openFloater();
+ }
+ // Update the location of the blue box tool popup
+ LLCoordGL select_center_screen;
+ MASK mask = gKeyboard->currentMask(TRUE);
+ gFloaterTools->updatePopup( select_center_screen, mask );
+ }
+ else
+ {
+ gFloaterTools->setVisible(FALSE);
+ }
+ //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
+ }
+
+ // Always update console
+ if(gConsole)
+ {
+ LLRect console_rect = getChatConsoleRect();
+ gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
+ gConsole->setRect(console_rect);
+ }
}
void LLViewerWindow::updateMouseDelta()
{
#if LL_WINDOWS
- LLCoordCommon delta;
+ LLCoordCommon delta;
mWindow->getCursorDelta(&delta);
S32 dx = delta.mX;
S32 dy = delta.mY;
#else
- S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
- S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
+ S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
+ S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
#endif
- //RN: fix for asynchronous notification of mouse leaving window not working
- LLCoordWindow mouse_pos;
- mWindow->getCursorPosition(&mouse_pos);
- if (mouse_pos.mX < 0 ||
- mouse_pos.mY < 0 ||
- mouse_pos.mX > mWindowRectRaw.getWidth() ||
- mouse_pos.mY > mWindowRectRaw.getHeight())
- {
- mMouseInWindow = FALSE;
- }
- else
- {
- mMouseInWindow = TRUE;
- }
-
- LLVector2 mouse_vel;
-
- if (gSavedSettings.getBOOL("MouseSmooth"))
- {
- static F32 fdx = 0.f;
- static F32 fdy = 0.f;
-
- F32 amount = 16.f;
- fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
- fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
-
- mCurrentMouseDelta.set(ll_round(fdx), ll_round(fdy));
- mouse_vel.setVec(fdx,fdy);
- }
- else
- {
- mCurrentMouseDelta.set(dx, dy);
- mouse_vel.setVec((F32) dx, (F32) dy);
- }
-
- sample(sMouseVelocityStat, mouse_vel.magVec());
+ //RN: fix for asynchronous notification of mouse leaving window not working
+ LLCoordWindow mouse_pos;
+ mWindow->getCursorPosition(&mouse_pos);
+ if (mouse_pos.mX < 0 ||
+ mouse_pos.mY < 0 ||
+ mouse_pos.mX > mWindowRectRaw.getWidth() ||
+ mouse_pos.mY > mWindowRectRaw.getHeight())
+ {
+ mMouseInWindow = FALSE;
+ }
+ else
+ {
+ mMouseInWindow = TRUE;
+ }
+
+ LLVector2 mouse_vel;
+
+ if (gSavedSettings.getBOOL("MouseSmooth"))
+ {
+ static F32 fdx = 0.f;
+ static F32 fdy = 0.f;
+
+ F32 amount = 16.f;
+ fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
+ fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
+
+ mCurrentMouseDelta.set(ll_round(fdx), ll_round(fdy));
+ mouse_vel.setVec(fdx,fdy);
+ }
+ else
+ {
+ mCurrentMouseDelta.set(dx, dy);
+ mouse_vel.setVec((F32) dx, (F32) dy);
+ }
+
+ sample(sMouseVelocityStat, mouse_vel.magVec());
}
void LLViewerWindow::updateKeyboardFocus()
{
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- gFocusMgr.setKeyboardFocus(NULL);
- }
-
- // clean up current focus
- LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (cur_focus)
- {
- if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
- {
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ gFocusMgr.setKeyboardFocus(NULL);
+ }
+
+ // clean up current focus
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus)
+ {
+ if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
+ {
// don't release focus, just reassign so that if being given
// to a sibling won't call onFocusLost on all the ancestors
- // gFocusMgr.releaseFocusIfNeeded(cur_focus);
-
- LLUICtrl* parent = cur_focus->getParentUICtrl();
- const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
- bool new_focus_found = false;
- while(parent)
- {
- if (parent->isCtrl()
- && (parent->hasTabStop() || parent == focus_root)
- && !parent->getIsChrome()
- && parent->isInVisibleChain()
- && parent->isInEnabledChain())
- {
- if (!parent->focusFirstItem())
- {
- parent->setFocus(TRUE);
- }
- new_focus_found = true;
- break;
- }
- parent = parent->getParentUICtrl();
- }
-
- // if we didn't find a better place to put focus, just release it
- // hasFocus() will return true if and only if we didn't touch focus since we
- // are only moving focus higher in the hierarchy
- if (!new_focus_found)
- {
- cur_focus->setFocus(FALSE);
- }
- }
- else if (cur_focus->isFocusRoot())
- {
- // focus roots keep trying to delegate focus to their first valid descendant
- // this assumes that focus roots are not valid focus holders on their own
- cur_focus->focusFirstItem();
- }
- }
-
- // last ditch force of edit menu to selection manager
- if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
- {
- LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance();
- }
-
- if (gFloaterView->getCycleMode())
- {
- // sync all floaters with their focus state
- gFloaterView->highlightFocusedFloater();
- gSnapshotFloaterView->highlightFocusedFloater();
- MASK mask = gKeyboard->currentMask(TRUE);
- if ((mask & MASK_CONTROL) == 0)
- {
- // control key no longer held down, finish cycle mode
- gFloaterView->setCycleMode(FALSE);
-
- gFloaterView->syncFloaterTabOrder();
- }
- else
- {
- // user holding down CTRL, don't update tab order of floaters
- }
- }
- else
- {
- // update focused floater
- gFloaterView->highlightFocusedFloater();
- gSnapshotFloaterView->highlightFocusedFloater();
- // make sure floater visible order is in sync with tab order
- gFloaterView->syncFloaterTabOrder();
- }
+ // gFocusMgr.releaseFocusIfNeeded(cur_focus);
+
+ LLUICtrl* parent = cur_focus->getParentUICtrl();
+ const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
+ bool new_focus_found = false;
+ while(parent)
+ {
+ if (parent->isCtrl()
+ && (parent->hasTabStop() || parent == focus_root)
+ && !parent->getIsChrome()
+ && parent->isInVisibleChain()
+ && parent->isInEnabledChain())
+ {
+ if (!parent->focusFirstItem())
+ {
+ parent->setFocus(TRUE);
+ }
+ new_focus_found = true;
+ break;
+ }
+ parent = parent->getParentUICtrl();
+ }
+
+ // if we didn't find a better place to put focus, just release it
+ // hasFocus() will return true if and only if we didn't touch focus since we
+ // are only moving focus higher in the hierarchy
+ if (!new_focus_found)
+ {
+ cur_focus->setFocus(FALSE);
+ }
+ }
+ else if (cur_focus->isFocusRoot())
+ {
+ // focus roots keep trying to delegate focus to their first valid descendant
+ // this assumes that focus roots are not valid focus holders on their own
+ cur_focus->focusFirstItem();
+ }
+ }
+
+ // last ditch force of edit menu to selection manager
+ if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
+ {
+ LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance();
+ }
+
+ if (gFloaterView->getCycleMode())
+ {
+ // sync all floaters with their focus state
+ gFloaterView->highlightFocusedFloater();
+ gSnapshotFloaterView->highlightFocusedFloater();
+ MASK mask = gKeyboard->currentMask(TRUE);
+ if ((mask & MASK_CONTROL) == 0)
+ {
+ // control key no longer held down, finish cycle mode
+ gFloaterView->setCycleMode(FALSE);
+
+ gFloaterView->syncFloaterTabOrder();
+ }
+ else
+ {
+ // user holding down CTRL, don't update tab order of floaters
+ }
+ }
+ else
+ {
+ // update focused floater
+ gFloaterView->highlightFocusedFloater();
+ gSnapshotFloaterView->highlightFocusedFloater();
+ // make sure floater visible order is in sync with tab order
+ gFloaterView->syncFloaterTabOrder();
+ }
}
static LLTrace::BlockTimerStatHandle FTM_UPDATE_WORLD_VIEW("Update World View");
void LLViewerWindow::updateWorldViewRect(bool use_full_window)
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_WORLD_VIEW);
+ LL_RECORD_BLOCK_TIME(FTM_UPDATE_WORLD_VIEW);
- // start off using whole window to render world
- LLRect new_world_rect = mWindowRectRaw;
+ // start off using whole window to render world
+ LLRect new_world_rect = mWindowRectRaw;
- if (use_full_window == false && mWorldViewPlaceholder.get())
- {
- new_world_rect = mWorldViewPlaceholder.get()->calcScreenRect();
- // clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers
- new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1);
- new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1);
-
- new_world_rect.mLeft = ll_round((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]);
- new_world_rect.mRight = ll_round((F32)new_world_rect.mRight * mDisplayScale.mV[VX]);
- new_world_rect.mBottom = ll_round((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]);
- new_world_rect.mTop = ll_round((F32)new_world_rect.mTop * mDisplayScale.mV[VY]);
- }
+ if (use_full_window == false && mWorldViewPlaceholder.get())
+ {
+ new_world_rect = mWorldViewPlaceholder.get()->calcScreenRect();
+ // clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers
+ new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1);
+ new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1);
- if (mWorldViewRectRaw != new_world_rect)
- {
- mWorldViewRectRaw = new_world_rect;
- gResizeScreenTexture = TRUE;
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ new_world_rect.mLeft = ll_round((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]);
+ new_world_rect.mRight = ll_round((F32)new_world_rect.mRight * mDisplayScale.mV[VX]);
+ new_world_rect.mBottom = ll_round((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]);
+ new_world_rect.mTop = ll_round((F32)new_world_rect.mTop * mDisplayScale.mV[VY]);
+ }
- LLRect old_world_rect_scaled = mWorldViewRectScaled;
- mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
+ if (mWorldViewRectRaw != new_world_rect)
+ {
+ mWorldViewRectRaw = new_world_rect;
+ gResizeScreenTexture = TRUE;
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
- // sending a signal with a new WorldView rect
- mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled);
- }
+ LLRect old_world_rect_scaled = mWorldViewRectScaled;
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
+
+ // sending a signal with a new WorldView rect
+ mOnWorldViewRectUpdated(old_world_rect_scaled, mWorldViewRectScaled);
+ }
}
void LLViewerWindow::saveLastMouse(const LLCoordGL &point)
{
- // Store last mouse location.
- // If mouse leaves window, pretend last point was on edge of window
-
- if (point.mX < 0)
- {
- mCurrentMousePoint.mX = 0;
- }
- else if (point.mX > getWindowWidthScaled())
- {
- mCurrentMousePoint.mX = getWindowWidthScaled();
- }
- else
- {
- mCurrentMousePoint.mX = point.mX;
- }
-
- if (point.mY < 0)
- {
- mCurrentMousePoint.mY = 0;
- }
- else if (point.mY > getWindowHeightScaled() )
- {
- mCurrentMousePoint.mY = getWindowHeightScaled();
- }
- else
- {
- mCurrentMousePoint.mY = point.mY;
- }
+ // Store last mouse location.
+ // If mouse leaves window, pretend last point was on edge of window
+
+ if (point.mX < 0)
+ {
+ mCurrentMousePoint.mX = 0;
+ }
+ else if (point.mX > getWindowWidthScaled())
+ {
+ mCurrentMousePoint.mX = getWindowWidthScaled();
+ }
+ else
+ {
+ mCurrentMousePoint.mX = point.mX;
+ }
+
+ if (point.mY < 0)
+ {
+ mCurrentMousePoint.mY = 0;
+ }
+ else if (point.mY > getWindowHeightScaled() )
+ {
+ mCurrentMousePoint.mY = getWindowHeightScaled();
+ }
+ else
+ {
+ mCurrentMousePoint.mY = point.mY;
+ }
}
// Draws the selection outlines for the currently selected objects
// Must be called after displayObjects is called, which sets the mGLName parameter
// NOTE: This function gets called 3 times:
-// render_ui_3d: FALSE, FALSE, TRUE
-// render_hud_elements: FALSE, FALSE, FALSE
+// render_ui_3d: FALSE, FALSE, TRUE
+// render_hud_elements: FALSE, FALSE, FALSE
void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud )
{
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- if (!for_hud && !for_gl_pick)
- {
- // Call this once and only once
- LLSelectMgr::getInstance()->updateSilhouettes();
- }
-
- // Draw fence around land selections
- if (for_gl_pick)
- {
- if (pick_parcel_walls)
- {
- LLViewerParcelMgr::getInstance()->renderParcelCollision();
- }
- }
- else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) ||
- (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD))
- {
- LLSelectMgr::getInstance()->renderSilhouettes(for_hud);
-
- stop_glerror();
-
- // setup HUD render
- if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
- {
- LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
-
- // set up transform to encompass bounding box of HUD
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
- gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
- gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
- }
-
- // Render light for editing
- if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit())
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable gls_blend(GL_BLEND);
- LLGLEnable gls_cull(GL_CULL_FACE);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- if (selection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 zoom = gAgentCamera.mHUDCurZoom;
- gGL.scalef(zoom, zoom, zoom);
- }
-
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLDrawable* drawable = object->mDrawable;
- if (drawable && drawable->isLight())
- {
- LLVOVolume* vovolume = drawable->getVOVolume();
- gGL.pushMatrix();
-
- LLVector3 center = drawable->getPositionAgent();
- gGL.translatef(center[0], center[1], center[2]);
- F32 scale = vovolume->getLightRadius();
- gGL.scalef(scale, scale, scale);
-
- LLColor4 color(vovolume->getLightSRGBColor(), .5f);
- gGL.color4fv(color.mV);
-
- //F32 pixel_area = 100000.f;
- // Render Outside
- gSphere.render();
-
- // Render Inside
- glCullFace(GL_FRONT);
- gSphere.render();
- glCullFace(GL_BACK);
-
- gGL.popMatrix();
- }
- return true;
- }
- } func;
- LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
-
- gGL.popMatrix();
- }
-
- // NOTE: The average position for the axis arrows of the selected objects should
- // not be recalculated at this time. If they are, then group rotations will break.
-
- // Draw arrows at average center of all selected objects
- LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
- if (tool)
- {
- if(tool->isAlwaysRendered())
- {
- tool->render();
- }
- else
- {
- if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() )
- {
- bool all_selected_objects_move;
- bool all_selected_objects_modify;
- // Note: This might be costly to do on each frame and when a lot of objects are selected
- // we might be better off with some kind of memory for selection and/or states, consider
- // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to
- // make whole viewer benefit.
- LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify);
-
- BOOL draw_handles = TRUE;
-
- if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
- {
- draw_handles = FALSE;
- }
-
- if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
- {
- draw_handles = FALSE;
- }
-
- if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() )
- {
- draw_handles = FALSE;
- }
-
- if( draw_handles )
- {
- tool->render();
- }
- }
- }
- if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount())
- {
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- stop_glerror();
- }
- }
- }
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (!for_hud && !for_gl_pick)
+ {
+ // Call this once and only once
+ LLSelectMgr::getInstance()->updateSilhouettes();
+ }
+
+ // Draw fence around land selections
+ if (for_gl_pick)
+ {
+ if (pick_parcel_walls)
+ {
+ LLViewerParcelMgr::getInstance()->renderParcelCollision();
+ }
+ }
+ else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) ||
+ (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD))
+ {
+ LLSelectMgr::getInstance()->renderSilhouettes(for_hud);
+
+ stop_glerror();
+
+ // setup HUD render
+ if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
+ {
+ LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
+
+ // set up transform to encompass bounding box of HUD
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
+ gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.loadMatrix(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
+ gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
+ }
+
+ // Render light for editing
+ if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit())
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLEnable gls_blend(GL_BLEND);
+ LLGLEnable gls_cull(GL_CULL_FACE);
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ if (selection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ F32 zoom = gAgentCamera.mHUDCurZoom;
+ gGL.scalef(zoom, zoom, zoom);
+ }
+
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ LLDrawable* drawable = object->mDrawable;
+ if (drawable && drawable->isLight())
+ {
+ LLVOVolume* vovolume = drawable->getVOVolume();
+ gGL.pushMatrix();
+
+ LLVector3 center = drawable->getPositionAgent();
+ gGL.translatef(center[0], center[1], center[2]);
+ F32 scale = vovolume->getLightRadius();
+ gGL.scalef(scale, scale, scale);
+
+ LLColor4 color(vovolume->getLightSRGBColor(), .5f);
+ gGL.color4fv(color.mV);
+
+ //F32 pixel_area = 100000.f;
+ // Render Outside
+ gSphere.render();
+
+ // Render Inside
+ glCullFace(GL_FRONT);
+ gSphere.render();
+ glCullFace(GL_BACK);
+
+ gGL.popMatrix();
+ }
+ return true;
+ }
+ } func;
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
+
+ gGL.popMatrix();
+ }
+
+ // NOTE: The average position for the axis arrows of the selected objects should
+ // not be recalculated at this time. If they are, then group rotations will break.
+
+ // Draw arrows at average center of all selected objects
+ LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (tool)
+ {
+ if(tool->isAlwaysRendered())
+ {
+ tool->render();
+ }
+ else
+ {
+ if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() )
+ {
+ bool all_selected_objects_move;
+ bool all_selected_objects_modify;
+ // Note: This might be costly to do on each frame and when a lot of objects are selected
+ // we might be better off with some kind of memory for selection and/or states, consider
+ // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to
+ // make whole viewer benefit.
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify);
+
+ BOOL draw_handles = TRUE;
+
+ if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
+ {
+ draw_handles = FALSE;
+ }
+
+ if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
+ {
+ draw_handles = FALSE;
+ }
+
+ if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() )
+ {
+ draw_handles = FALSE;
+ }
+
+ if( draw_handles )
+ {
+ tool->render();
+ }
+ }
+ }
+ if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount())
+ {
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ stop_glerror();
+ }
+ }
+ }
}
// Return a point near the clicked object representative of the place the object was clicked.
LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLViewerObject* clicked_object) const
{
- // create a normalized vector pointing from the camera center into the
- // world at the location of the mouse click
- LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot );
+ // create a normalized vector pointing from the camera center into the
+ // world at the location of the mouse click
+ LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot );
- LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal();
+ LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal();
- // make mouse vector as long as object vector, so it touchs a point near
- // where the user clicked on the object
- mouse_direction_global *= (F32) relative_object.magVec();
+ // make mouse vector as long as object vector, so it touchs a point near
+ // where the user clicked on the object
+ mouse_direction_global *= (F32) relative_object.magVec();
- LLVector3d new_pos;
- new_pos.setVec(mouse_direction_global);
- // transform mouse vector back to world coords
- new_pos += gAgentCamera.getCameraPositionGlobal();
+ LLVector3d new_pos;
+ new_pos.setVec(mouse_direction_global);
+ // transform mouse vector back to world coords
+ new_pos += gAgentCamera.getCameraPositionGlobal();
- return new_pos;
+ return new_pos;
}
BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const
{
- BOOL intersect = FALSE;
+ BOOL intersect = FALSE;
-// U8 shape = objectp->mPrimitiveCode & LL_PCODE_BASE_MASK;
- if (!intersect)
- {
- point_global = clickPointInWorldGlobal(x, y, objectp);
- LL_INFOS() << "approx intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "good intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL;
- }
+// U8 shape = objectp->mPrimitiveCode & LL_PCODE_BASE_MASK;
+ if (!intersect)
+ {
+ point_global = clickPointInWorldGlobal(x, y, objectp);
+ LL_INFOS() << "approx intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "good intersection at " << (objectp->getPositionGlobal() - point_global) << LL_ENDL;
+ }
- return intersect;
+ return intersect;
}
void LLViewerWindow::pickAsync( S32 x,
- S32 y_from_bot,
- MASK mask,
- void (*callback)(const LLPickInfo& info),
- BOOL pick_transparent,
- BOOL pick_rigged,
- BOOL pick_unselectable,
+ S32 y_from_bot,
+ MASK mask,
+ void (*callback)(const LLPickInfo& info),
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
BOOL pick_reflection_probes)
{
- // "Show Debug Alpha" means no object actually transparent
+ // "Show Debug Alpha" means no object actually transparent
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (LLDrawPoolAlpha::sShowDebugAlpha
|| (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
@@ -4235,585 +4239,587 @@ void LLViewerWindow::pickAsync( S32 x,
pick_transparent = TRUE;
}
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, pick_reflection_probes, pick_unselectable, TRUE, callback);
- schedulePick(pick_info);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, pick_reflection_probes, pick_unselectable, TRUE, callback);
+ schedulePick(pick_info);
}
void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
{
- if (mPicks.size() >= 1024 || mWindow->getMinimized())
- { //something went wrong, picks are being scheduled but not processed
-
- if (pick_info.mPickCallback)
- {
- pick_info.mPickCallback(pick_info);
- }
-
- return;
- }
- mPicks.push_back(pick_info);
-
- // delay further event processing until we receive results of pick
- // only do this for async picks so that handleMouseUp won't be called
- // until the pick triggered in handleMouseDown has been processed, for example
- mWindow->delayInputProcessing();
+ if (mPicks.size() >= 1024 || mWindow->getMinimized())
+ { //something went wrong, picks are being scheduled but not processed
+
+ if (pick_info.mPickCallback)
+ {
+ pick_info.mPickCallback(pick_info);
+ }
+
+ return;
+ }
+ mPicks.push_back(pick_info);
+
+ // delay further event processing until we receive results of pick
+ // only do this for async picks so that handleMouseUp won't be called
+ // until the pick triggered in handleMouseDown has been processed, for example
+ mWindow->delayInputProcessing();
}
void LLViewerWindow::performPick()
{
- if (!mPicks.empty())
- {
- std::vector<LLPickInfo>::iterator pick_it;
- for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
- {
- pick_it->fetchResults();
- }
+ if (!mPicks.empty())
+ {
+ std::vector<LLPickInfo>::iterator pick_it;
+ for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
+ {
+ pick_it->fetchResults();
+ }
- mLastPick = mPicks.back();
- mPicks.clear();
- }
+ mLastPick = mPicks.back();
+ mPicks.clear();
+ }
}
void LLViewerWindow::returnEmptyPicks()
{
- std::vector<LLPickInfo>::iterator pick_it;
- for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
- {
- mLastPick = *pick_it;
- // just trigger callback with empty results
- if (pick_it->mPickCallback)
- {
- pick_it->mPickCallback(*pick_it);
- }
- }
- mPicks.clear();
+ std::vector<LLPickInfo>::iterator pick_it;
+ for (pick_it = mPicks.begin(); pick_it != mPicks.end(); ++pick_it)
+ {
+ mLastPick = *pick_it;
+ // just trigger callback with empty results
+ if (pick_it->mPickCallback)
+ {
+ pick_it->mPickCallback(*pick_it);
+ }
+ }
+ mPicks.clear();
}
// Performs the GL object/land pick.
LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable, BOOL pick_reflection_probe)
{
- BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
- {
- // build mode allows interaction with all transparent objects
- // "Show Debug Alpha" means no object actually transparent
- pick_transparent = TRUE;
- }
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
+ if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
+ {
+ // build mode allows interaction with all transparent objects
+ // "Show Debug Alpha" means no object actually transparent
+ pick_transparent = TRUE;
+ }
+
+ // shortcut queueing in mPicks and just update mLastPick in place
+ MASK key_mask = gKeyboard->currentMask(TRUE);
+ mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, TRUE, FALSE, NULL);
+ mLastPick.fetchResults();
- // shortcut queueing in mPicks and just update mLastPick in place
- MASK key_mask = gKeyboard->currentMask(TRUE);
- mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, TRUE, FALSE, NULL);
- mLastPick.fetchResults();
-
- return mLastPick;
+ return mLastPick;
}
LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector4a* intersection)
+ LLVector4a* intersection)
{
- S32 x = mouse_x;
- S32 y = mouse_y;
-
- if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
- {
- x = getCurrentMouseX();
- y = getCurrentMouseY();
- }
+ S32 x = mouse_x;
+ S32 y = mouse_y;
- // world coordinates of mouse
- // VECTORIZE THIS
- LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
- LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
- LLVector3 mouse_world_start = mouse_point_global;
- LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
+ if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
+ {
+ x = getCurrentMouseX();
+ y = getCurrentMouseY();
+ }
- LLVector4a start, end;
- start.load3(mouse_world_start.mV);
- end.load3(mouse_world_end.mV);
+ // world coordinates of mouse
+ // VECTORIZE THIS
+ LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
+ LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
+ LLVector3 mouse_world_start = mouse_point_global;
+ LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
- return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);
+ LLVector4a start, end;
+ start.load3(mouse_world_start.mV);
+ end.load3(mouse_world_end.mV);
+
+ return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);
}
LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
- LLViewerObject *this_object,
- S32 this_face,
- BOOL pick_transparent,
- BOOL pick_rigged,
+ LLViewerObject *this_object,
+ S32 this_face,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable,
BOOL pick_reflection_probe,
- S32* face_hit,
- LLVector4a *intersection,
- LLVector2 *uv,
- LLVector4a *normal,
- LLVector4a *tangent,
- LLVector4a* start,
- LLVector4a* end)
-{
- S32 x = mouse_x;
- S32 y = mouse_y;
-
- if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
- {
- x = getCurrentMouseX();
- y = getCurrentMouseY();
- }
-
- // HUD coordinates of mouse
- LLVector3 mouse_point_hud = mousePointHUD(x, y);
- LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0);
- LLVector3 mouse_hud_end = mouse_point_hud + LLVector3(depth, 0, 0);
-
- // world coordinates of mouse
- LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
- LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
-
- //get near clip plane
- LLVector3 n = LLViewerCamera::getInstance()->getAtAxis();
- LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear();
-
- //project mouse point onto plane
- LLVector3 pos;
- line_plane(mouse_point_global, mouse_direction_global, p, n, pos);
- mouse_point_global = pos;
-
- LLVector3 mouse_world_start = mouse_point_global;
- LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
-
- if (!LLViewerJoystick::getInstance()->getOverrideCamera())
- { //always set raycast intersection to mouse_world_end unless
- //flycam is on (for DoF effect)
- gDebugRaycastIntersection.load3(mouse_world_end.mV);
- }
-
- LLVector4a mw_start;
- mw_start.load3(mouse_world_start.mV);
- LLVector4a mw_end;
- mw_end.load3(mouse_world_end.mV);
-
- LLVector4a mh_start;
- mh_start.load3(mouse_hud_start.mV);
- LLVector4a mh_end;
- mh_end.load3(mouse_hud_end.mV);
-
- if (start)
- {
- *start = mw_start;
- }
-
- if (end)
- {
- *end = mw_end;
- }
-
- LLViewerObject* found = NULL;
-
- if (this_object) // check only this object
- {
- if (this_object->isHUDAttachment()) // is a HUD object?
- {
- if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
- face_hit, intersection, uv, normal, tangent))
- {
- found = this_object;
- }
- }
- else // is a world object
- {
+ S32* face_hit,
+ S32* gltf_node_hit,
+ S32* gltf_primitive_hit,
+ LLVector4a *intersection,
+ LLVector2 *uv,
+ LLVector4a *normal,
+ LLVector4a *tangent,
+ LLVector4a* start,
+ LLVector4a* end)
+{
+ S32 x = mouse_x;
+ S32 y = mouse_y;
+
+ if ((mouse_x == -1) && (mouse_y == -1)) // use current mouse position
+ {
+ x = getCurrentMouseX();
+ y = getCurrentMouseY();
+ }
+
+ // HUD coordinates of mouse
+ LLVector3 mouse_point_hud = mousePointHUD(x, y);
+ LLVector3 mouse_hud_start = mouse_point_hud - LLVector3(depth, 0, 0);
+ LLVector3 mouse_hud_end = mouse_point_hud + LLVector3(depth, 0, 0);
+
+ // world coordinates of mouse
+ LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
+ LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
+
+ //get near clip plane
+ LLVector3 n = LLViewerCamera::getInstance()->getAtAxis();
+ LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear();
+
+ //project mouse point onto plane
+ LLVector3 pos;
+ line_plane(mouse_point_global, mouse_direction_global, p, n, pos);
+ mouse_point_global = pos;
+
+ LLVector3 mouse_world_start = mouse_point_global;
+ LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
+
+ if (!LLViewerJoystick::getInstance()->getOverrideCamera())
+ { //always set raycast intersection to mouse_world_end unless
+ //flycam is on (for DoF effect)
+ gDebugRaycastIntersection.load3(mouse_world_end.mV);
+ }
+
+ LLVector4a mw_start;
+ mw_start.load3(mouse_world_start.mV);
+ LLVector4a mw_end;
+ mw_end.load3(mouse_world_end.mV);
+
+ LLVector4a mh_start;
+ mh_start.load3(mouse_hud_start.mV);
+ LLVector4a mh_end;
+ mh_end.load3(mouse_hud_end.mV);
+
+ if (start)
+ {
+ *start = mw_start;
+ }
+
+ if (end)
+ {
+ *end = mw_end;
+ }
+
+ LLViewerObject* found = NULL;
+
+ if (this_object) // check only this object
+ {
+ if (this_object->isHUDAttachment()) // is a HUD object?
+ {
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
+ face_hit, intersection, uv, normal, tangent))
+ {
+ found = this_object;
+ }
+ }
+ else // is a world object
+ {
if ((pick_reflection_probe || !this_object->isReflectionProbe())
&& this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
- face_hit, intersection, uv, normal, tangent))
- {
- found = this_object;
- }
- }
- }
- else // check ALL objects
- {
- found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent,
- face_hit, intersection, uv, normal, tangent);
-
- if (!found) // if not found in HUD, look in world:
- {
- found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe,
- face_hit, intersection, uv, normal, tangent);
- if (found && !pick_transparent)
- {
- gDebugRaycastIntersection = *intersection;
- }
- }
- }
-
- return found;
+ face_hit, intersection, uv, normal, tangent))
+ {
+ found = this_object;
+ }
+ }
+ }
+ else // check ALL objects
+ {
+ found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent,
+ face_hit, intersection, uv, normal, tangent);
+
+ if (!found) // if not found in HUD, look in world:
+ {
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe,
+ face_hit, gltf_node_hit, gltf_primitive_hit, intersection, uv, normal, tangent);
+ if (found && !pick_transparent)
+ {
+ gDebugRaycastIntersection = *intersection;
+ }
+ }
+ }
+
+ return found;
}
// Returns unit vector relative to camera
// indicating direction of point on screen x,y
LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
{
- // find vertical field of view
- F32 fov = LLViewerCamera::getInstance()->getView();
+ // find vertical field of view
+ F32 fov = LLViewerCamera::getInstance()->getView();
- // find world view center in scaled ui coordinates
- F32 center_x = getWorldViewRectScaled().getCenterX();
- F32 center_y = getWorldViewRectScaled().getCenterY();
+ // find world view center in scaled ui coordinates
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
- // calculate pixel distance to screen
- F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f));
+ // calculate pixel distance to screen
+ F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f));
- // calculate click point relative to middle of screen
- F32 click_x = x - center_x;
- F32 click_y = y - center_y;
+ // calculate click point relative to middle of screen
+ F32 click_x = x - center_x;
+ F32 click_y = y - center_y;
- // compute mouse vector
- LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis()
- - click_x * LLViewerCamera::getInstance()->getLeftAxis()
- + click_y * LLViewerCamera::getInstance()->getUpAxis();
+ // compute mouse vector
+ LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis()
+ - click_x * LLViewerCamera::getInstance()->getLeftAxis()
+ + click_y * LLViewerCamera::getInstance()->getUpAxis();
- mouse_vector.normVec();
+ mouse_vector.normVec();
- return mouse_vector;
+ return mouse_vector;
}
LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
{
- // find screen resolution
- S32 height = getWorldViewHeightScaled();
+ // find screen resolution
+ S32 height = getWorldViewHeightScaled();
- // find world view center
- F32 center_x = getWorldViewRectScaled().getCenterX();
- F32 center_y = getWorldViewRectScaled().getCenterY();
+ // find world view center
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
- // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5
- F32 hud_x = -((F32)x - center_x) / height;
- F32 hud_y = ((F32)y - center_y) / height;
+ // remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5
+ F32 hud_x = -((F32)x - center_x) / height;
+ F32 hud_y = ((F32)y - center_y) / height;
- return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom);
+ return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom);
}
// Returns unit vector relative to camera in camera space
// indicating direction of point on screen x,y
LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
{
- // find vertical field of view
- F32 fov_height = LLViewerCamera::getInstance()->getView();
- F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
+ // find vertical field of view
+ F32 fov_height = LLViewerCamera::getInstance()->getView();
+ F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
- // find screen resolution
- S32 height = getWorldViewHeightScaled();
- S32 width = getWorldViewWidthScaled();
+ // find screen resolution
+ S32 height = getWorldViewHeightScaled();
+ S32 width = getWorldViewWidthScaled();
- // find world view center
- F32 center_x = getWorldViewRectScaled().getCenterX();
- F32 center_y = getWorldViewRectScaled().getCenterY();
+ // find world view center
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
- // calculate click point relative to middle of screen
- F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f;
- F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height;
+ // calculate click point relative to middle of screen
+ F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f;
+ F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height;
- // compute mouse vector
- LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f);
- LLQuaternion mouse_rotate;
- mouse_rotate.setQuat(click_y, click_x, 0.f);
+ // compute mouse vector
+ LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f);
+ LLQuaternion mouse_rotate;
+ mouse_rotate.setQuat(click_y, click_x, 0.f);
- mouse_vector = mouse_vector * mouse_rotate;
- // project to z = -1 plane;
- mouse_vector = mouse_vector * (-1.f / mouse_vector.mV[VZ]);
+ mouse_vector = mouse_vector * mouse_rotate;
+ // project to z = -1 plane;
+ mouse_vector = mouse_vector * (-1.f / mouse_vector.mV[VZ]);
- return mouse_vector;
+ return mouse_vector;
}
-BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y,
- const LLVector3d &plane_point_global,
- const LLVector3 &plane_normal_global)
+BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y,
+ const LLVector3d &plane_point_global,
+ const LLVector3 &plane_normal_global)
{
- LLVector3d mouse_direction_global_d;
-
- mouse_direction_global_d.setVec(mouseDirectionGlobal(x,y));
- LLVector3d plane_normal_global_d;
- plane_normal_global_d.setVec(plane_normal_global);
- F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d);
- LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal();
- F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel)
- / plane_mouse_dot;
- if (llabs(plane_mouse_dot) < 0.00001)
- {
- // if mouse is parallel to plane, return closest point on line through plane origin
- // that is parallel to camera plane by scaling mouse direction vector
- // by distance to plane origin, modulated by deviation of mouse direction from plane origin
- LLVector3d plane_origin_dir = plane_origin_camera_rel;
- plane_origin_dir.normVec();
+ LLVector3d mouse_direction_global_d;
- mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d);
- }
+ mouse_direction_global_d.setVec(mouseDirectionGlobal(x,y));
+ LLVector3d plane_normal_global_d;
+ plane_normal_global_d.setVec(plane_normal_global);
+ F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d);
+ LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal();
+ F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel)
+ / plane_mouse_dot;
+ if (llabs(plane_mouse_dot) < 0.00001)
+ {
+ // if mouse is parallel to plane, return closest point on line through plane origin
+ // that is parallel to camera plane by scaling mouse direction vector
+ // by distance to plane origin, modulated by deviation of mouse direction from plane origin
+ LLVector3d plane_origin_dir = plane_origin_camera_rel;
+ plane_origin_dir.normVec();
+
+ mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d);
+ }
- point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d;
+ point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d;
- return mouse_look_at_scale > 0.0;
+ return mouse_look_at_scale > 0.0;
}
// Returns global position
BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_position_global, BOOL ignore_distance)
{
- LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
- F32 mouse_dir_scale;
- BOOL hit_land = FALSE;
- LLViewerRegion *regionp;
- F32 land_z;
- const F32 FIRST_PASS_STEP = 1.0f; // meters
- const F32 SECOND_PASS_STEP = 0.1f; // meters
- const F32 draw_distance = ignore_distance ? MAX_FAR_CLIP : gAgentCamera.mDrawDistance;
- LLVector3d camera_pos_global;
-
- camera_pos_global = gAgentCamera.getCameraPositionGlobal();
- LLVector3d probe_point_global;
- LLVector3 probe_point_region;
-
- // walk forwards to find the point
- for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < draw_distance; mouse_dir_scale += FIRST_PASS_STEP)
- {
- LLVector3d mouse_direction_global_d;
- mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
- probe_point_global = camera_pos_global + mouse_direction_global_d;
-
- regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
-
- if (!regionp)
- {
- // ...we're outside the world somehow
- continue;
- }
-
- S32 i = (S32) (probe_point_region.mV[VX]/regionp->getLand().getMetersPerGrid());
- S32 j = (S32) (probe_point_region.mV[VY]/regionp->getLand().getMetersPerGrid());
- S32 grids_per_edge = (S32) regionp->getLand().mGridsPerEdge;
- if ((i >= grids_per_edge) || (j >= grids_per_edge))
- {
- //LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL;
- continue;
- }
-
- land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
-
- //LL_INFOS() << "mousePointOnLand initial z " << land_z << LL_ENDL;
-
- if (probe_point_region.mV[VZ] < land_z)
- {
- // ...just went under land
-
- // cout << "under land at " << probe_point << " scale " << mouse_vec_scale << endl;
-
- hit_land = TRUE;
- break;
- }
- }
-
-
- if (hit_land)
- {
- // Don't go more than one step beyond where we stopped above.
- // This can't just be "mouse_vec_scale" because floating point error
- // will stop the loop before the last increment.... X - 1.0 + 0.1 + 0.1 + ... + 0.1 != X
- F32 stop_mouse_dir_scale = mouse_dir_scale + FIRST_PASS_STEP;
-
- // take a step backwards, then walk forwards again to refine position
- for ( mouse_dir_scale -= FIRST_PASS_STEP; mouse_dir_scale <= stop_mouse_dir_scale; mouse_dir_scale += SECOND_PASS_STEP)
- {
- LLVector3d mouse_direction_global_d;
- mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
- probe_point_global = camera_pos_global + mouse_direction_global_d;
-
- regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
-
- if (!regionp)
- {
- // ...we're outside the world somehow
- continue;
- }
-
- /*
- i = (S32) (local_probe_point.mV[VX]/regionp->getLand().getMetersPerGrid());
- j = (S32) (local_probe_point.mV[VY]/regionp->getLand().getMetersPerGrid());
- if ((i >= regionp->getLand().mGridsPerEdge) || (j >= regionp->getLand().mGridsPerEdge))
- {
- // LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL;
- continue;
- }
- land_z = regionp->getLand().mSurfaceZ[ i + j * (regionp->getLand().mGridsPerEdge) ];
- */
-
- land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
-
- //LL_INFOS() << "mousePointOnLand refine z " << land_z << LL_ENDL;
-
- if (probe_point_region.mV[VZ] < land_z)
- {
- // ...just went under land again
-
- *land_position_global = probe_point_global;
- return TRUE;
- }
- }
- }
-
- return FALSE;
+ LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
+ F32 mouse_dir_scale;
+ BOOL hit_land = FALSE;
+ LLViewerRegion *regionp;
+ F32 land_z;
+ const F32 FIRST_PASS_STEP = 1.0f; // meters
+ const F32 SECOND_PASS_STEP = 0.1f; // meters
+ const F32 draw_distance = ignore_distance ? MAX_FAR_CLIP : gAgentCamera.mDrawDistance;
+ LLVector3d camera_pos_global;
+
+ camera_pos_global = gAgentCamera.getCameraPositionGlobal();
+ LLVector3d probe_point_global;
+ LLVector3 probe_point_region;
+
+ // walk forwards to find the point
+ for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < draw_distance; mouse_dir_scale += FIRST_PASS_STEP)
+ {
+ LLVector3d mouse_direction_global_d;
+ mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
+ probe_point_global = camera_pos_global + mouse_direction_global_d;
+
+ regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
+
+ if (!regionp)
+ {
+ // ...we're outside the world somehow
+ continue;
+ }
+
+ S32 i = (S32) (probe_point_region.mV[VX]/regionp->getLand().getMetersPerGrid());
+ S32 j = (S32) (probe_point_region.mV[VY]/regionp->getLand().getMetersPerGrid());
+ S32 grids_per_edge = (S32) regionp->getLand().mGridsPerEdge;
+ if ((i >= grids_per_edge) || (j >= grids_per_edge))
+ {
+ //LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL;
+ continue;
+ }
+
+ land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
+
+ //LL_INFOS() << "mousePointOnLand initial z " << land_z << LL_ENDL;
+
+ if (probe_point_region.mV[VZ] < land_z)
+ {
+ // ...just went under land
+
+ // cout << "under land at " << probe_point << " scale " << mouse_vec_scale << endl;
+
+ hit_land = TRUE;
+ break;
+ }
+ }
+
+
+ if (hit_land)
+ {
+ // Don't go more than one step beyond where we stopped above.
+ // This can't just be "mouse_vec_scale" because floating point error
+ // will stop the loop before the last increment.... X - 1.0 + 0.1 + 0.1 + ... + 0.1 != X
+ F32 stop_mouse_dir_scale = mouse_dir_scale + FIRST_PASS_STEP;
+
+ // take a step backwards, then walk forwards again to refine position
+ for ( mouse_dir_scale -= FIRST_PASS_STEP; mouse_dir_scale <= stop_mouse_dir_scale; mouse_dir_scale += SECOND_PASS_STEP)
+ {
+ LLVector3d mouse_direction_global_d;
+ mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
+ probe_point_global = camera_pos_global + mouse_direction_global_d;
+
+ regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
+
+ if (!regionp)
+ {
+ // ...we're outside the world somehow
+ continue;
+ }
+
+ /*
+ i = (S32) (local_probe_point.mV[VX]/regionp->getLand().getMetersPerGrid());
+ j = (S32) (local_probe_point.mV[VY]/regionp->getLand().getMetersPerGrid());
+ if ((i >= regionp->getLand().mGridsPerEdge) || (j >= regionp->getLand().mGridsPerEdge))
+ {
+ // LL_INFOS() << "LLViewerWindow::mousePointOnLand probe_point is out of region" << LL_ENDL;
+ continue;
+ }
+ land_z = regionp->getLand().mSurfaceZ[ i + j * (regionp->getLand().mGridsPerEdge) ];
+ */
+
+ land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
+
+ //LL_INFOS() << "mousePointOnLand refine z " << land_z << LL_ENDL;
+
+ if (probe_point_region.mV[VZ] < land_z)
+ {
+ // ...just went under land again
+
+ *land_position_global = probe_point_global;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
}
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
- if (!image)
- {
- LL_WARNS() << "No image to save" << LL_ENDL;
- return;
- }
- std::string extension("." + image->getExtension());
- LLImageFormatted* formatted_image = image;
- // Get a base file location if needed.
- if (force_picker || !isSnapshotLocSet())
- {
- std::string proposed_name(sSnapshotBaseName);
-
- // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
- LLFilePicker::ESaveFilter pick_type;
-
- if (extension == ".j2c")
- pick_type = LLFilePicker::FFSAVE_J2C;
- else if (extension == ".bmp")
- pick_type = LLFilePicker::FFSAVE_BMP;
- else if (extension == ".jpg")
- pick_type = LLFilePicker::FFSAVE_JPEG;
- else if (extension == ".png")
- pick_type = LLFilePicker::FFSAVE_PNG;
- else if (extension == ".tga")
- pick_type = LLFilePicker::FFSAVE_TGA;
- else
- pick_type = LLFilePicker::FFSAVE_ALL;
-
- LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
- boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb));
- }
- else
- {
- saveImageLocal(formatted_image, success_cb, failure_cb);
- }
+ if (!image)
+ {
+ LL_WARNS() << "No image to save" << LL_ENDL;
+ return;
+ }
+ std::string extension("." + image->getExtension());
+ LLImageFormatted* formatted_image = image;
+ // Get a base file location if needed.
+ if (force_picker || !isSnapshotLocSet())
+ {
+ std::string proposed_name(sSnapshotBaseName);
+
+ // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
+ LLFilePicker::ESaveFilter pick_type;
+
+ if (extension == ".j2c")
+ pick_type = LLFilePicker::FFSAVE_J2C;
+ else if (extension == ".bmp")
+ pick_type = LLFilePicker::FFSAVE_BMP;
+ else if (extension == ".jpg")
+ pick_type = LLFilePicker::FFSAVE_JPEG;
+ else if (extension == ".png")
+ pick_type = LLFilePicker::FFSAVE_PNG;
+ else if (extension == ".tga")
+ pick_type = LLFilePicker::FFSAVE_TGA;
+ else
+ pick_type = LLFilePicker::FFSAVE_ALL;
+
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
+ boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb));
+ }
+ else
+ {
+ saveImageLocal(formatted_image, success_cb, failure_cb);
+ }
}
void LLViewerWindow::onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
- // Copy the directory + file name
- std::string filepath = filenames[0];
+ // Copy the directory + file name
+ std::string filepath = filenames[0];
- gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
- gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
- saveImageLocal(image, success_cb, failure_cb);
+ gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
+ saveImageLocal(image, success_cb, failure_cb);
}
void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb)
{
- failure_cb();
+ failure_cb();
}
void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
- std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
- if (lastSnapshotDir.empty())
- {
- failure_cb();
- return;
- }
+ std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
+ if (lastSnapshotDir.empty())
+ {
+ failure_cb();
+ return;
+ }
// Check if there is enough free space to save snapshot
#ifdef LL_WINDOWS
- boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
+ boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
#else
- boost::filesystem::path b_path(lastSnapshotDir);
+ boost::filesystem::path b_path(lastSnapshotDir);
#endif
- if (!boost::filesystem::is_directory(b_path))
- {
- LLSD args;
- args["PATH"] = lastSnapshotDir;
- LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args);
- resetSnapshotLoc();
- failure_cb();
- return;
- }
- boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
- if (b_space.free < image->getDataSize())
- {
- LLSD args;
- args["PATH"] = lastSnapshotDir;
-
- std::string needM_bytes_string;
- LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10);
- args["NEED_MEMORY"] = needM_bytes_string;
-
- std::string freeM_bytes_string;
- LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
- args["FREE_MEMORY"] = freeM_bytes_string;
-
- LLNotificationsUtil::add("SnapshotToComputerFailed", args);
-
- failure_cb();
- }
-
- // Look for an unused file name
- BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
- std::string filepath;
- S32 i = 1;
- S32 err = 0;
- std::string extension("." + image->getExtension());
- do
- {
- filepath = sSnapshotDir;
- filepath += gDirUtilp->getDirDelimiter();
- filepath += sSnapshotBaseName;
-
- if (is_snapshot_name_loc_set)
- {
- filepath += llformat("_%.3d",i);
- }
-
- filepath += extension;
-
- llstat stat_info;
- err = LLFile::stat( filepath, &stat_info );
- i++;
- }
- while( -1 != err // Search until the file is not found (i.e., stat() gives an error).
- && is_snapshot_name_loc_set); // Or stop if we are rewriting.
-
- LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
- if (image->save(filepath))
- {
- playSnapshotAnimAndSound();
- success_cb();
- }
- else
- {
- failure_cb();
- }
+ if (!boost::filesystem::is_directory(b_path))
+ {
+ LLSD args;
+ args["PATH"] = lastSnapshotDir;
+ LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args);
+ resetSnapshotLoc();
+ failure_cb();
+ return;
+ }
+ boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
+ if (b_space.free < image->getDataSize())
+ {
+ LLSD args;
+ args["PATH"] = lastSnapshotDir;
+
+ std::string needM_bytes_string;
+ LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10);
+ args["NEED_MEMORY"] = needM_bytes_string;
+
+ std::string freeM_bytes_string;
+ LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
+ args["FREE_MEMORY"] = freeM_bytes_string;
+
+ LLNotificationsUtil::add("SnapshotToComputerFailed", args);
+
+ failure_cb();
+ }
+
+ // Look for an unused file name
+ BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
+ std::string filepath;
+ S32 i = 1;
+ S32 err = 0;
+ std::string extension("." + image->getExtension());
+ do
+ {
+ filepath = sSnapshotDir;
+ filepath += gDirUtilp->getDirDelimiter();
+ filepath += sSnapshotBaseName;
+
+ if (is_snapshot_name_loc_set)
+ {
+ filepath += llformat("_%.3d",i);
+ }
+
+ filepath += extension;
+
+ llstat stat_info;
+ err = LLFile::stat( filepath, &stat_info );
+ i++;
+ }
+ while( -1 != err // Search until the file is not found (i.e., stat() gives an error).
+ && is_snapshot_name_loc_set); // Or stop if we are rewriting.
+
+ LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
+ if (image->save(filepath))
+ {
+ playSnapshotAnimAndSound();
+ success_cb();
+ }
+ else
+ {
+ failure_cb();
+ }
}
void LLViewerWindow::resetSnapshotLoc()
{
- gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
}
// static
void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
{
- LLCoordWindow size;
- LLCoordWindow new_size(new_width, new_height);
- gViewerWindow->getWindow()->getSize(&size);
- if ( size != new_size )
- {
- gViewerWindow->getWindow()->setSize(new_size);
- }
+ LLCoordWindow size;
+ LLCoordWindow new_size(new_width, new_height);
+ gViewerWindow->getWindow()->getSize(&size);
+ if ( size != new_size )
+ {
+ gViewerWindow->getWindow()->setSize(new_size);
+ }
}
BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format)
@@ -4861,347 +4867,347 @@ BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width,
void LLViewerWindow::playSnapshotAnimAndSound()
{
- if (gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
- {
- return;
- }
- gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START);
- send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
+ if (gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
+ {
+ return;
+ }
+ gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START);
+ send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
}
BOOL LLViewerWindow::isSnapshotLocSet() const
{
- std::string snapshot_dir = sSnapshotDir;
- return !snapshot_dir.empty();
+ std::string snapshot_dir = sSnapshotDir;
+ return !snapshot_dir.empty();
}
void LLViewerWindow::resetSnapshotLoc() const
{
- gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
}
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type)
{
- return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type);
+ return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, no_post, type);
}
// Saves the image from the screen to a raw image
// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
// the results over to the final raw image.
-BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
+BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
{
- if (!raw)
- {
- return FALSE;
- }
- //check if there is enough memory for the snapshot image
- if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
- {
- if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3))
- {
- LL_WARNS() << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << LL_ENDL ;
- return FALSE ; //there is no enough memory for taking this snapshot.
- }
- }
-
- // PRE SNAPSHOT
- gSnapshotNoPost = no_post;
- gDisplaySwapBuffers = FALSE;
-
+ if (!raw)
+ {
+ return FALSE;
+ }
+ //check if there is enough memory for the snapshot image
+ if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
+ {
+ if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3))
+ {
+ LL_WARNS() << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << LL_ENDL ;
+ return FALSE ; //there is no enough memory for taking this snapshot.
+ }
+ }
+
+ // PRE SNAPSHOT
+ gSnapshotNoPost = no_post;
+ gDisplaySwapBuffers = FALSE;
+
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
- setCursor(UI_CURSOR_WAIT);
+ setCursor(UI_CURSOR_WAIT);
- // Hide all the UI widgets first and draw a frame
- BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
+ // Hide all the UI widgets first and draw a frame
+ BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
- if ( prev_draw_ui != show_ui)
- {
- LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
+ if ( prev_draw_ui != show_ui)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
BOOL hide_hud = !show_hud && LLPipeline::sShowHUDAttachments;
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = FALSE;
- }
-
- // if not showing ui, use full window to render world view
- updateWorldViewRect(!show_ui);
-
- // Copy screen to a buffer
- // crop sides or top and bottom, if taking a snapshot of different aspect ratio
- // from window
- LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();
-
- S32 snapshot_width = window_rect.getWidth();
- S32 snapshot_height = window_rect.getHeight();
- // SNAPSHOT
- S32 window_width = snapshot_width;
- S32 window_height = snapshot_height;
-
- // Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested
- if (show_ui)
- {
- // If the user wants the UI, limit the output size to the available screen size
- image_width = llmin(image_width, window_width);
- image_height = llmin(image_height, window_height);
- }
-
- S32 original_width = 0;
- S32 original_height = 0;
- bool reset_deferred = false;
-
- LLRenderTarget scratch_space;
-
- F32 scale_factor = 1.0f ;
- if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
- {
- if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) &&
- (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
- {
- U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
- if (scratch_space.allocate(image_width, image_height, color_fmt, true))
- {
- original_width = gPipeline.mRT->deferredScreen.getWidth();
- original_height = gPipeline.mRT->deferredScreen.getHeight();
-
- if (gPipeline.allocateScreenBuffer(image_width, image_height))
- {
- window_width = image_width;
- window_height = image_height;
- snapshot_width = image_width;
- snapshot_height = image_height;
- reset_deferred = true;
- mWorldViewRectRaw.set(0, image_height, image_width, 0);
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
- scratch_space.bindTarget();
- }
- else
- {
- scratch_space.release();
- gPipeline.allocateScreenBuffer(original_width, original_height);
- }
- }
- }
-
- if (!reset_deferred)
- {
- // if image cropping or need to enlarge the scene, compute a scale_factor
- F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
- snapshot_width = (S32)(ratio * image_width) ;
- snapshot_height = (S32)(ratio * image_height) ;
- scale_factor = llmax(1.0f, 1.0f / ratio) ;
- }
- }
-
- if (show_ui && scale_factor > 1.f)
- {
- // Note: we should never get there...
- LL_WARNS() << "over scaling UI not supported." << LL_ENDL;
- }
-
- S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
- S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
-
- S32 image_buffer_x = llfloor(snapshot_width * scale_factor) ;
- S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ;
-
- if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow
- {
- scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ;
- image_buffer_x = llfloor(snapshot_width * scale_factor) ;
- image_buffer_y = llfloor(snapshot_height * scale_factor) ;
- }
- if ((image_buffer_x > 0) && (image_buffer_y > 0))
- {
- raw->resize(image_buffer_x, image_buffer_y, 3);
- }
- else
- {
- return FALSE ;
- }
- if (raw->isBufferInvalid())
- {
- return FALSE ;
- }
-
- BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher
- if (high_res && show_ui)
- {
- // Note: we should never get there...
- LL_WARNS() << "High res UI snapshot not supported. " << LL_ENDL;
- /*send_agent_pause();
- //rescale fonts
- initFonts(scale_factor);
- LLHUDObject::reshapeAll();*/
- }
-
- S32 output_buffer_offset_y = 0;
-
- F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
- F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
-
- // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
- // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
- for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
- {
- S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);;
- // handle fractional columns
- U32 read_height = llmax(0, (window_height - subimage_y_offset) -
- llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight())));
-
- S32 output_buffer_offset_x = 0;
- for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x)
- {
- gDisplaySwapBuffers = FALSE;
- gDepthDirty = TRUE;
-
- S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
- // handle fractional rows
- U32 read_width = llmax(0, (window_width - subimage_x_offset) -
- llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
-
- // Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases)
- if (read_width && read_height)
- {
- const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
- display(do_rebuild, scale_factor, subfield, TRUE);
-
- if (!LLPipeline::sRenderDeferred)
- {
- // Required for showing the GUI in snapshots and performing bloom composite overlay
- // Call even if show_ui is FALSE
- render_ui(scale_factor, subfield);
- swap();
- }
-
- for (U32 out_y = 0; out_y < read_height ; out_y++)
- {
- S32 output_buffer_offset = (
- (out_y * (raw->getWidth())) // ...plus iterated y...
- + (window_width * subimage_x) // ...plus subimage start in x...
- + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
- - output_buffer_offset_x // ...minus buffer padding x...
- - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
- ) * raw->getComponents();
-
- // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change)
- if (out_y % 100 == 0)
- {
- LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
- }
- // disable use of glReadPixels when doing nVidia nSight graphics debugging
- if (!LLRender::sNsightDebugSupport)
- {
- if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
- {
- glReadPixels(
- subimage_x_offset, out_y + subimage_y_offset,
- read_width, 1,
- GL_RGB, GL_UNSIGNED_BYTE,
- raw->getData() + output_buffer_offset
- );
- }
- else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
- {
- LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
- glReadPixels(
- subimage_x_offset, out_y + subimage_y_offset,
- read_width, 1,
- GL_DEPTH_COMPONENT, GL_FLOAT,
- depth_line_buffer->getData()// current output pixel is beginning of buffer...
- );
-
- for (S32 i = 0; i < (S32)read_width; i++)
- {
- F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
-
- F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
- // write converted scanline out to result image
- for (S32 j = 0; j < raw->getComponents(); j++)
- {
- *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
- }
- }
- }
- }
- }
- }
- output_buffer_offset_x += subimage_x_offset;
- stop_glerror();
- }
- output_buffer_offset_y += subimage_y_offset;
- }
-
- gDisplaySwapBuffers = FALSE;
- gSnapshotNoPost = FALSE;
- gDepthDirty = TRUE;
-
- // POST SNAPSHOT
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = TRUE;
- }
-
- /*if (high_res)
- {
- initFonts(1.f);
- LLHUDObject::reshapeAll();
- }*/
-
- // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding)
- // Note: this formula depends on the number of components being 3. Not obvious, but it's correct.
- image_width += (image_width * 3) % 4;
-
- BOOL ret = TRUE ;
- // Resize image
- if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4)
- {
- ret = raw->scale( image_width, image_height );
- }
- else if(image_width != image_buffer_x || image_height != image_buffer_y)
- {
- ret = raw->scale( image_width, image_height, FALSE );
- }
-
-
- setCursor(UI_CURSOR_ARROW);
-
- if (do_rebuild)
- {
- // If we had to do a rebuild, that means that the lists of drawables to be rendered
- // was empty before we started.
- // Need to reset these, otherwise we call state sort on it again when render gets called the next time
- // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of
- // objects on them.
- gPipeline.resetDrawOrders();
- }
-
- if (reset_deferred)
- {
- mWorldViewRectRaw = window_rect;
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
- scratch_space.flush();
- scratch_space.release();
- gPipeline.allocateScreenBuffer(original_width, original_height);
-
- }
-
- if (high_res)
- {
- send_agent_resume();
- }
-
- return ret;
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = FALSE;
+ }
+
+ // if not showing ui, use full window to render world view
+ updateWorldViewRect(!show_ui);
+
+ // Copy screen to a buffer
+ // crop sides or top and bottom, if taking a snapshot of different aspect ratio
+ // from window
+ LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();
+
+ S32 snapshot_width = window_rect.getWidth();
+ S32 snapshot_height = window_rect.getHeight();
+ // SNAPSHOT
+ S32 window_width = snapshot_width;
+ S32 window_height = snapshot_height;
+
+ // Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested
+ if (show_ui)
+ {
+ // If the user wants the UI, limit the output size to the available screen size
+ image_width = llmin(image_width, window_width);
+ image_height = llmin(image_height, window_height);
+ }
+
+ S32 original_width = 0;
+ S32 original_height = 0;
+ bool reset_deferred = false;
+
+ LLRenderTarget scratch_space;
+
+ F32 scale_factor = 1.0f ;
+ if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
+ {
+ if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) &&
+ (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
+ {
+ U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
+ if (scratch_space.allocate(image_width, image_height, color_fmt, true))
+ {
+ original_width = gPipeline.mRT->deferredScreen.getWidth();
+ original_height = gPipeline.mRT->deferredScreen.getHeight();
+
+ if (gPipeline.allocateScreenBuffer(image_width, image_height))
+ {
+ window_width = image_width;
+ window_height = image_height;
+ snapshot_width = image_width;
+ snapshot_height = image_height;
+ reset_deferred = true;
+ mWorldViewRectRaw.set(0, image_height, image_width, 0);
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ scratch_space.bindTarget();
+ }
+ else
+ {
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+ }
+ }
+ }
+
+ if (!reset_deferred)
+ {
+ // if image cropping or need to enlarge the scene, compute a scale_factor
+ F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
+ snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_height = (S32)(ratio * image_height) ;
+ scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ }
+ }
+
+ if (show_ui && scale_factor > 1.f)
+ {
+ // Note: we should never get there...
+ LL_WARNS() << "over scaling UI not supported." << LL_ENDL;
+ }
+
+ S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
+ S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
+
+ S32 image_buffer_x = llfloor(snapshot_width * scale_factor) ;
+ S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ;
+
+ if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow
+ {
+ scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ;
+ image_buffer_x = llfloor(snapshot_width * scale_factor) ;
+ image_buffer_y = llfloor(snapshot_height * scale_factor) ;
+ }
+ if ((image_buffer_x > 0) && (image_buffer_y > 0))
+ {
+ raw->resize(image_buffer_x, image_buffer_y, 3);
+ }
+ else
+ {
+ return FALSE ;
+ }
+ if (raw->isBufferInvalid())
+ {
+ return FALSE ;
+ }
+
+ BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher
+ if (high_res && show_ui)
+ {
+ // Note: we should never get there...
+ LL_WARNS() << "High res UI snapshot not supported. " << LL_ENDL;
+ /*send_agent_pause();
+ //rescale fonts
+ initFonts(scale_factor);
+ LLHUDObject::reshapeAll();*/
+ }
+
+ S32 output_buffer_offset_y = 0;
+
+ F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
+ F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
+
+ // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
+ // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
+ for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
+ {
+ S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);;
+ // handle fractional columns
+ U32 read_height = llmax(0, (window_height - subimage_y_offset) -
+ llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight())));
+
+ S32 output_buffer_offset_x = 0;
+ for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x)
+ {
+ gDisplaySwapBuffers = FALSE;
+ gDepthDirty = TRUE;
+
+ S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
+ // handle fractional rows
+ U32 read_width = llmax(0, (window_width - subimage_x_offset) -
+ llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
+
+ // Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases)
+ if (read_width && read_height)
+ {
+ const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
+ display(do_rebuild, scale_factor, subfield, TRUE);
+
+ if (!LLPipeline::sRenderDeferred)
+ {
+ // Required for showing the GUI in snapshots and performing bloom composite overlay
+ // Call even if show_ui is FALSE
+ render_ui(scale_factor, subfield);
+ swap();
+ }
+
+ for (U32 out_y = 0; out_y < read_height ; out_y++)
+ {
+ S32 output_buffer_offset = (
+ (out_y * (raw->getWidth())) // ...plus iterated y...
+ + (window_width * subimage_x) // ...plus subimage start in x...
+ + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
+ - output_buffer_offset_x // ...minus buffer padding x...
+ - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
+ ) * raw->getComponents();
+
+ // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change)
+ if (out_y % 100 == 0)
+ {
+ LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
+ }
+ // disable use of glReadPixels when doing nVidia nSight graphics debugging
+ if (!LLRender::sNsightDebugSupport)
+ {
+ if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
+ {
+ glReadPixels(
+ subimage_x_offset, out_y + subimage_y_offset,
+ read_width, 1,
+ GL_RGB, GL_UNSIGNED_BYTE,
+ raw->getData() + output_buffer_offset
+ );
+ }
+ else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
+ {
+ LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
+ glReadPixels(
+ subimage_x_offset, out_y + subimage_y_offset,
+ read_width, 1,
+ GL_DEPTH_COMPONENT, GL_FLOAT,
+ depth_line_buffer->getData()// current output pixel is beginning of buffer...
+ );
+
+ for (S32 i = 0; i < (S32)read_width; i++)
+ {
+ F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
+
+ F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
+ U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
+ // write converted scanline out to result image
+ for (S32 j = 0; j < raw->getComponents(); j++)
+ {
+ *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ }
+ }
+ }
+ }
+ }
+ }
+ output_buffer_offset_x += subimage_x_offset;
+ stop_glerror();
+ }
+ output_buffer_offset_y += subimage_y_offset;
+ }
+
+ gDisplaySwapBuffers = FALSE;
+ gSnapshotNoPost = FALSE;
+ gDepthDirty = TRUE;
+
+ // POST SNAPSHOT
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = TRUE;
+ }
+
+ /*if (high_res)
+ {
+ initFonts(1.f);
+ LLHUDObject::reshapeAll();
+ }*/
+
+ // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding)
+ // Note: this formula depends on the number of components being 3. Not obvious, but it's correct.
+ image_width += (image_width * 3) % 4;
+
+ BOOL ret = TRUE ;
+ // Resize image
+ if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4)
+ {
+ ret = raw->scale( image_width, image_height );
+ }
+ else if(image_width != image_buffer_x || image_height != image_buffer_y)
+ {
+ ret = raw->scale( image_width, image_height, FALSE );
+ }
+
+
+ setCursor(UI_CURSOR_ARROW);
+
+ if (do_rebuild)
+ {
+ // If we had to do a rebuild, that means that the lists of drawables to be rendered
+ // was empty before we started.
+ // Need to reset these, otherwise we call state sort on it again when render gets called the next time
+ // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of
+ // objects on them.
+ gPipeline.resetDrawOrders();
+ }
+
+ if (reset_deferred)
+ {
+ mWorldViewRectRaw = window_rect;
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ scratch_space.flush();
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+
+ }
+
+ if (high_res)
+ {
+ send_agent_resume();
+ }
+
+ return ret;
}
BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)
@@ -5219,10 +5225,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
}
BOOL hide_hud = LLPipeline::sShowHUDAttachments;
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = FALSE;
- }
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = FALSE;
+ }
LLRect window_rect = getWorldViewRectRaw();
@@ -5247,8 +5253,8 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
}
// we render the scene more than once since this helps
- // greatly with the objects not being drawn in the
- // snapshot when they are drawn in the scene. This is
+ // greatly with the objects not being drawn in the
+ // snapshot when they are drawn in the scene. This is
// evident when you set this value via the debug setting
// called 360CaptureNumRenderPasses to 1. The theory is
// that the missing objects are caused by the sUseOcclusion
@@ -5293,10 +5299,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
}
}
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = TRUE;
- }
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = TRUE;
+ }
setCursor(UI_CURSOR_ARROW);
@@ -5311,14 +5317,14 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
void display_cube_face();
-BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render)
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render, bool useCustomClipPlane, LLPlane clipPlane)
{
// NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
LL_PROFILE_GPU_ZONE("cubeSnapshot");
llassert(LLPipeline::sRenderDeferred);
llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress
-
+
U32 res = gPipeline.mRT->deferredScreen.getWidth();
//llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
@@ -5330,7 +5336,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
// set new parameters specific to the 360 requirements
LLPipeline::sUseOcclusion = 0;
LLViewerCamera* camera = LLViewerCamera::getInstance();
-
+
LLViewerCamera saved_camera = LLViewerCamera::instance();
glh::matrix4f saved_proj = get_current_projection();
glh::matrix4f saved_mod = get_current_modelview();
@@ -5342,8 +5348,16 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
camera->setOrigin(origin);
camera->setNear(near_clip);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
+ LLPlane previousClipPlane;
+
+ if (useCustomClipPlane)
+ {
+ previousClipPlane = camera->getUserClipPlane();
+ camera->setUserClipPlane(clipPlane);
+ }
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
+
U32 dynamic_render_types[] = {
LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
@@ -5352,7 +5366,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32);
bool prev_dynamic_render_type[dynamic_render_type_count];
-
+
if (!dynamic_render)
{
for (int i = 0; i < dynamic_render_type_count; ++i)
@@ -5370,12 +5384,12 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
{
LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
-
+
BOOL hide_hud = LLPipeline::sShowHUDAttachments;
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = FALSE;
- }
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = FALSE;
+ }
LLRect window_rect = getWorldViewRectRaw();
mWorldViewRectRaw.set(0, res, res, 0);
@@ -5441,14 +5455,19 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
}
}
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = TRUE;
- }
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = TRUE;
+ }
gPipeline.resetDrawOrders();
mWorldViewRectRaw = window_rect;
+ if (useCustomClipPlane)
+ {
+ camera->setUserClipPlane(previousClipPlane);
+ }
+
// restore original view/camera/avatar settings settings
*camera = saved_camera;
set_current_modelview(saved_mod);
@@ -5462,138 +5481,138 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
void LLViewerWindow::destroyWindow()
{
- if (mWindow)
- {
- LLWindowManager::destroyWindow(mWindow);
- }
- mWindow = NULL;
+ if (mWindow)
+ {
+ LLWindowManager::destroyWindow(mWindow);
+ }
+ mWindow = NULL;
}
void LLViewerWindow::drawMouselookInstructions()
{
- // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.)
- const std::string instructions = LLTrans::getString("LeaveMouselook");
- const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD));
-
- //to be on top of Bottom bar when it is opened
- const S32 INSTRUCTIONS_PAD = 50;
+ // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.)
+ const std::string instructions = LLTrans::getString("LeaveMouselook");
+ const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Large", LLFontGL::BOLD));
+
+ //to be on top of Bottom bar when it is opened
+ const S32 INSTRUCTIONS_PAD = 50;
- font->renderUTF8(
- instructions, 0,
- getWorldViewRectScaled().getCenterX(),
- getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD,
- LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ),
- LLFontGL::HCENTER, LLFontGL::TOP,
- LLFontGL::NORMAL,LLFontGL::DROP_SHADOW);
+ font->renderUTF8(
+ instructions, 0,
+ getWorldViewRectScaled().getCenterX(),
+ getWorldViewRectScaled().mBottom + INSTRUCTIONS_PAD,
+ LLColor4( 1.0f, 1.0f, 1.0f, 0.5f ),
+ LLFontGL::HCENTER, LLFontGL::TOP,
+ LLFontGL::NORMAL,LLFontGL::DROP_SHADOW);
}
void* LLViewerWindow::getPlatformWindow() const
{
- return mWindow->getPlatformWindow();
+ return mWindow->getPlatformWindow();
}
-void* LLViewerWindow::getMediaWindow() const
+void* LLViewerWindow::getMediaWindow() const
{
- return mWindow->getMediaWindow();
+ return mWindow->getMediaWindow();
}
-void LLViewerWindow::focusClient() const
+void LLViewerWindow::focusClient() const
{
- return mWindow->focusClient();
+ return mWindow->focusClient();
}
-LLRootView* LLViewerWindow::getRootView() const
+LLRootView* LLViewerWindow::getRootView() const
{
- return mRootView;
+ return mRootView;
}
LLRect LLViewerWindow::getWorldViewRectScaled() const
{
- return mWorldViewRectScaled;
+ return mWorldViewRectScaled;
}
S32 LLViewerWindow::getWorldViewHeightScaled() const
{
- return mWorldViewRectScaled.getHeight();
+ return mWorldViewRectScaled.getHeight();
}
S32 LLViewerWindow::getWorldViewWidthScaled() const
{
- return mWorldViewRectScaled.getWidth();
+ return mWorldViewRectScaled.getWidth();
}
S32 LLViewerWindow::getWorldViewHeightRaw() const
{
- return mWorldViewRectRaw.getHeight();
+ return mWorldViewRectRaw.getHeight();
}
S32 LLViewerWindow::getWorldViewWidthRaw() const
{
- return mWorldViewRectRaw.getWidth();
+ return mWorldViewRectRaw.getWidth();
}
-S32 LLViewerWindow::getWindowHeightScaled() const
-{
- return mWindowRectScaled.getHeight();
+S32 LLViewerWindow::getWindowHeightScaled() const
+{
+ return mWindowRectScaled.getHeight();
}
-S32 LLViewerWindow::getWindowWidthScaled() const
-{
- return mWindowRectScaled.getWidth();
+S32 LLViewerWindow::getWindowWidthScaled() const
+{
+ return mWindowRectScaled.getWidth();
}
-S32 LLViewerWindow::getWindowHeightRaw() const
-{
- return mWindowRectRaw.getHeight();
+S32 LLViewerWindow::getWindowHeightRaw() const
+{
+ return mWindowRectRaw.getHeight();
}
-S32 LLViewerWindow::getWindowWidthRaw() const
-{
- return mWindowRectRaw.getWidth();
+S32 LLViewerWindow::getWindowWidthRaw() const
+{
+ return mWindowRectRaw.getWidth();
}
void LLViewerWindow::setup2DRender()
{
- // setup ortho camera
- gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight());
- setup2DViewport();
+ // setup ortho camera
+ gl_state_for_2d(mWindowRectRaw.getWidth(), mWindowRectRaw.getHeight());
+ setup2DViewport();
}
void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset)
{
- gGLViewport[0] = mWindowRectRaw.mLeft + x_offset;
- gGLViewport[1] = mWindowRectRaw.mBottom + y_offset;
- gGLViewport[2] = mWindowRectRaw.getWidth();
- gGLViewport[3] = mWindowRectRaw.getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ gGLViewport[0] = mWindowRectRaw.mLeft + x_offset;
+ gGLViewport[1] = mWindowRectRaw.mBottom + y_offset;
+ gGLViewport[2] = mWindowRectRaw.getWidth();
+ gGLViewport[3] = mWindowRectRaw.getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
void LLViewerWindow::setup3DRender()
{
- // setup perspective camera
- LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
- setup3DViewport();
+ // setup perspective camera
+ LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
+ setup3DViewport();
}
void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
- gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset;
- gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
- gGLViewport[2] = mWorldViewRectRaw.getWidth();
- gGLViewport[3] = mWorldViewRectRaw.getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset;
+ gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
+ gGLViewport[2] = mWorldViewRectRaw.getWidth();
+ gGLViewport[3] = mWorldViewRectRaw.getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
void LLViewerWindow::revealIntroPanel()
{
- if (mProgressView)
- {
- mProgressView->revealIntroPanel();
- }
+ if (mProgressView)
+ {
+ mProgressView->revealIntroPanel();
+ }
}
void LLViewerWindow::initTextures(S32 location_id)
@@ -5606,417 +5625,417 @@ void LLViewerWindow::initTextures(S32 location_id)
void LLViewerWindow::setShowProgress(const BOOL show)
{
- if (mProgressView)
- {
- mProgressView->setVisible(show);
- }
+ if (mProgressView)
+ {
+ mProgressView->setVisible(show);
+ }
}
void LLViewerWindow::setStartupComplete()
{
- if (mProgressView)
- {
- mProgressView->setStartupComplete();
- }
+ if (mProgressView)
+ {
+ mProgressView->setStartupComplete();
+ }
}
BOOL LLViewerWindow::getShowProgress() const
{
- return (mProgressView && mProgressView->getVisible());
+ return (mProgressView && mProgressView->getVisible());
}
void LLViewerWindow::setProgressString(const std::string& string)
{
- if (mProgressView)
- {
- mProgressView->setText(string);
- }
+ if (mProgressView)
+ {
+ mProgressView->setText(string);
+ }
}
void LLViewerWindow::setProgressMessage(const std::string& msg)
{
- if(mProgressView)
- {
- mProgressView->setMessage(msg);
- }
+ if(mProgressView)
+ {
+ mProgressView->setMessage(msg);
+ }
}
void LLViewerWindow::setProgressPercent(const F32 percent)
{
- if (mProgressView)
- {
- mProgressView->setPercent(percent);
- }
+ if (mProgressView)
+ {
+ mProgressView->setPercent(percent);
+ }
}
void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string& label )
{
- if (mProgressView)
- {
- mProgressView->setCancelButtonVisible( b, label );
- }
+ if (mProgressView)
+ {
+ mProgressView->setCancelButtonVisible( b, label );
+ }
}
LLProgressView *LLViewerWindow::getProgressView() const
{
- return mProgressView;
+ return mProgressView;
}
void LLViewerWindow::dumpState()
{
- LL_INFOS() << "LLViewerWindow Active " << S32(mActive) << LL_ENDL;
- LL_INFOS() << "mWindow visible " << S32(mWindow->getVisible())
- << " minimized " << S32(mWindow->getMinimized())
- << LL_ENDL;
+ LL_INFOS() << "LLViewerWindow Active " << S32(mActive) << LL_ENDL;
+ LL_INFOS() << "mWindow visible " << S32(mWindow->getVisible())
+ << " minimized " << S32(mWindow->getMinimized())
+ << LL_ENDL;
}
void LLViewerWindow::stopGL(BOOL save_state)
{
- //Note: --bao
- //if not necessary, do not change the order of the function calls in this function.
- //if change something, make sure it will not break anything.
- //especially be careful to put anything behind gTextureList.destroyGL(save_state);
- if (!gGLManager.mIsDisabled)
- {
- LL_INFOS() << "Shutting down GL..." << LL_ENDL;
-
- // Pause texture decode threads (will get unpaused during main loop)
- LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getTextureFetch()->pause();
-
- gSky.destroyGL();
- stop_glerror();
-
- LLManipTranslate::destroyGL() ;
- stop_glerror();
-
- gBumpImageList.destroyGL();
- stop_glerror();
-
- LLFontGL::destroyAllGL();
- stop_glerror();
-
- LLVOAvatar::destroyGL();
- stop_glerror();
-
- LLVOPartGroup::destroyGL();
-
- LLViewerDynamicTexture::destroyGL();
- stop_glerror();
-
- if (gPipeline.isInit())
- {
- gPipeline.destroyGL();
- }
-
- gBox.cleanupGL();
-
- if(gPostProcess)
- {
- gPostProcess->invalidate();
- }
-
- gTextureList.destroyGL(save_state);
- stop_glerror();
-
- gGLManager.mIsDisabled = TRUE;
- stop_glerror();
-
- //unload shader's
- while (LLGLSLShader::sInstances.size())
- {
- LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
- shader->unload();
- }
- }
+ //Note: --bao
+ //if not necessary, do not change the order of the function calls in this function.
+ //if change something, make sure it will not break anything.
+ //especially be careful to put anything behind gTextureList.destroyGL(save_state);
+ if (!gGLManager.mIsDisabled)
+ {
+ LL_INFOS() << "Shutting down GL..." << LL_ENDL;
+
+ // Pause texture decode threads (will get unpaused during main loop)
+ LLAppViewer::getTextureCache()->pause();
+ LLAppViewer::getTextureFetch()->pause();
+
+ gSky.destroyGL();
+ stop_glerror();
+
+ LLManipTranslate::destroyGL() ;
+ stop_glerror();
+
+ gBumpImageList.destroyGL();
+ stop_glerror();
+
+ LLFontGL::destroyAllGL();
+ stop_glerror();
+
+ LLVOAvatar::destroyGL();
+ stop_glerror();
+
+ LLVOPartGroup::destroyGL();
+
+ LLViewerDynamicTexture::destroyGL();
+ stop_glerror();
+
+ if (gPipeline.isInit())
+ {
+ gPipeline.destroyGL();
+ }
+
+ gBox.cleanupGL();
+
+ if(gPostProcess)
+ {
+ gPostProcess->invalidate();
+ }
+
+ gTextureList.destroyGL(save_state);
+ stop_glerror();
+
+ gGLManager.mIsDisabled = TRUE;
+ stop_glerror();
+
+ //unload shader's
+ while (LLGLSLShader::sInstances.size())
+ {
+ LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
+ shader->unload();
+ }
+ }
}
void LLViewerWindow::restoreGL(const std::string& progress_message)
{
- //Note: --bao
- //if not necessary, do not change the order of the function calls in this function.
- //if change something, make sure it will not break anything.
- //especially, be careful to put something before gTextureList.restoreGL();
- if (gGLManager.mIsDisabled)
- {
- LL_INFOS() << "Restoring GL..." << LL_ENDL;
- gGLManager.mIsDisabled = FALSE;
-
- initGLDefaults();
- LLGLState::restoreGL();
-
- gTextureList.restoreGL();
-
- // for future support of non-square pixels, and fonts that are properly stretched
- //LLFontGL::destroyDefaultFonts();
- initFonts();
-
- gSky.restoreGL();
- gPipeline.restoreGL();
- LLManipTranslate::restoreGL();
-
- gBumpImageList.restoreGL();
- LLViewerDynamicTexture::restoreGL();
- LLVOAvatar::restoreGL();
- LLVOPartGroup::restoreGL();
-
- gResizeScreenTexture = TRUE;
- gWindowResized = TRUE;
-
- if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
- {
- LLVisualParamHint::requestHintUpdates();
- }
-
- if (!progress_message.empty())
- {
- gRestoreGLTimer.reset();
- gRestoreGL = TRUE;
- setShowProgress(TRUE);
- setProgressString(progress_message);
- }
- LL_INFOS() << "...Restoring GL done" << LL_ENDL;
- if(!LLAppViewer::instance()->restoreErrorTrap())
- {
- LL_WARNS() << " Someone took over my signal/exception handler (post restoreGL)!" << LL_ENDL;
- }
-
- }
+ //Note: --bao
+ //if not necessary, do not change the order of the function calls in this function.
+ //if change something, make sure it will not break anything.
+ //especially, be careful to put something before gTextureList.restoreGL();
+ if (gGLManager.mIsDisabled)
+ {
+ LL_INFOS() << "Restoring GL..." << LL_ENDL;
+ gGLManager.mIsDisabled = FALSE;
+
+ initGLDefaults();
+ LLGLState::restoreGL();
+
+ gTextureList.restoreGL();
+
+ // for future support of non-square pixels, and fonts that are properly stretched
+ //LLFontGL::destroyDefaultFonts();
+ initFonts();
+
+ gSky.restoreGL();
+ gPipeline.restoreGL();
+ LLManipTranslate::restoreGL();
+
+ gBumpImageList.restoreGL();
+ LLViewerDynamicTexture::restoreGL();
+ LLVOAvatar::restoreGL();
+ LLVOPartGroup::restoreGL();
+
+ gResizeScreenTexture = TRUE;
+ gWindowResized = TRUE;
+
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+
+ if (!progress_message.empty())
+ {
+ gRestoreGLTimer.reset();
+ gRestoreGL = TRUE;
+ setShowProgress(TRUE);
+ setProgressString(progress_message);
+ }
+ LL_INFOS() << "...Restoring GL done" << LL_ENDL;
+ if(!LLAppViewer::instance()->restoreErrorTrap())
+ {
+ LL_WARNS() << " Someone took over my signal/exception handler (post restoreGL)!" << LL_ENDL;
+ }
+
+ }
}
void LLViewerWindow::initFonts(F32 zoom_factor)
{
- LLFontGL::destroyAllGL();
- // Initialize with possibly different zoom factor
+ LLFontGL::destroyAllGL();
+ // Initialize with possibly different zoom factor
- LLFontManager::initClass();
+ LLFontManager::initClass();
- LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
- mDisplayScale.mV[VX] * zoom_factor,
- mDisplayScale.mV[VY] * zoom_factor,
- gDirUtilp->getAppRODataDir());
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
+ mDisplayScale.mV[VX] * zoom_factor,
+ mDisplayScale.mV[VY] * zoom_factor,
+ gDirUtilp->getAppRODataDir());
}
void LLViewerWindow::requestResolutionUpdate()
{
- mResDirty = true;
+ mResDirty = true;
}
static LLTrace::BlockTimerStatHandle FTM_WINDOW_CHECK_SETTINGS("Window Settings");
void LLViewerWindow::checkSettings()
{
- LL_RECORD_BLOCK_TIME(FTM_WINDOW_CHECK_SETTINGS);
- if (mStatesDirty)
- {
- gGL.refreshState();
- LLViewerShaderMgr::instance()->setShaders();
- mStatesDirty = false;
- }
-
- // We want to update the resolution AFTER the states getting refreshed not before.
- if (mResDirty)
- {
- reshape(getWindowWidthRaw(), getWindowHeightRaw());
- mResDirty = false;
- }
+ LL_RECORD_BLOCK_TIME(FTM_WINDOW_CHECK_SETTINGS);
+ if (mStatesDirty)
+ {
+ gGL.refreshState();
+ LLViewerShaderMgr::instance()->setShaders();
+ mStatesDirty = false;
+ }
+
+ // We want to update the resolution AFTER the states getting refreshed not before.
+ if (mResDirty)
+ {
+ reshape(getWindowWidthRaw(), getWindowHeightRaw());
+ mResDirty = false;
+ }
}
void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
{
- LL_INFOS() << "Restaring GL" << LL_ENDL;
- stopGL();
- if (show_progress_bar)
- {
- restoreGL(LLTrans::getString("ProgressChangingResolution"));
- }
- else
- {
- restoreGL();
- }
+ LL_INFOS() << "Restaring GL" << LL_ENDL;
+ stopGL();
+ if (show_progress_bar)
+ {
+ restoreGL(LLTrans::getString("ProgressChangingResolution"));
+ }
+ else
+ {
+ restoreGL();
+ }
}
BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar)
{
- //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
+ //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
- //gResizeScreenTexture = TRUE;
+ //gResizeScreenTexture = TRUE;
- //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
- //U32 old_fsaa = mWindow->getFSAASamples();
+ //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
+ //U32 old_fsaa = mWindow->getFSAASamples();
- // if not maximized, use the request size
- if (!mWindow->getMaximized())
- {
- mWindow->setSize(size);
- }
+ // if not maximized, use the request size
+ if (!mWindow->getMaximized())
+ {
+ mWindow->setSize(size);
+ }
- //if (fsaa == old_fsaa)
- {
- return TRUE;
- }
+ //if (fsaa == old_fsaa)
+ {
+ return TRUE;
+ }
/*
- // Close floaters that don't handle settings change
- LLFloaterReg::hideInstance("snapshot");
-
- BOOL result_first_try = FALSE;
- BOOL result_second_try = FALSE;
-
- LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
- send_agent_pause();
- LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL;
- stopGL();
- mIgnoreActivate = TRUE;
- LLCoordScreen old_size;
- LLCoordScreen old_pos;
- mWindow->getSize(&old_size);
-
- //mWindow->setFSAASamples(fsaa);
-
- result_first_try = mWindow->switchContext(false, size, disable_vsync);
- if (!result_first_try)
- {
- // try to switch back
- //mWindow->setFSAASamples(old_fsaa);
- result_second_try = mWindow->switchContext(false, old_size, disable_vsync);
-
- if (!result_second_try)
- {
- // we are stuck...try once again with a minimal resolution?
- send_agent_resume();
- mIgnoreActivate = FALSE;
- return FALSE;
- }
- }
- send_agent_resume();
-
- LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL;
- if (show_progress_bar)
- {
- restoreGL(LLTrans::getString("ProgressChangingResolution"));
- }
- else
- {
- restoreGL();
- }
-
- if (!result_first_try)
- {
- LLSD args;
- args["RESX"] = llformat("%d",size.mX);
- args["RESY"] = llformat("%d",size.mY);
- LLNotificationsUtil::add("ResolutionSwitchFail", args);
- size = old_size; // for reshape below
- }
-
- BOOL success = result_first_try || result_second_try;
-
- if (success)
- {
- // maximize window if was maximized, else reposition
- if (was_maximized)
- {
- mWindow->maximize();
- }
- else
- {
- S32 windowX = gSavedSettings.getS32("WindowX");
- S32 windowY = gSavedSettings.getS32("WindowY");
-
- mWindow->setPosition(LLCoordScreen ( windowX, windowY ) );
- }
- }
-
- mIgnoreActivate = FALSE;
- gFocusMgr.setKeyboardFocus(keyboard_focus);
-
- return success;
-
- */
-}
-
-F32 LLViewerWindow::getWorldViewAspectRatio() const
-{
- F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight();
- return world_aspect;
+ // Close floaters that don't handle settings change
+ LLFloaterReg::hideInstance("snapshot");
+
+ BOOL result_first_try = FALSE;
+ BOOL result_second_try = FALSE;
+
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ send_agent_pause();
+ LL_INFOS() << "Stopping GL during changeDisplaySettings" << LL_ENDL;
+ stopGL();
+ mIgnoreActivate = TRUE;
+ LLCoordScreen old_size;
+ LLCoordScreen old_pos;
+ mWindow->getSize(&old_size);
+
+ //mWindow->setFSAASamples(fsaa);
+
+ result_first_try = mWindow->switchContext(false, size, disable_vsync);
+ if (!result_first_try)
+ {
+ // try to switch back
+ //mWindow->setFSAASamples(old_fsaa);
+ result_second_try = mWindow->switchContext(false, old_size, disable_vsync);
+
+ if (!result_second_try)
+ {
+ // we are stuck...try once again with a minimal resolution?
+ send_agent_resume();
+ mIgnoreActivate = FALSE;
+ return FALSE;
+ }
+ }
+ send_agent_resume();
+
+ LL_INFOS() << "Restoring GL during resolution change" << LL_ENDL;
+ if (show_progress_bar)
+ {
+ restoreGL(LLTrans::getString("ProgressChangingResolution"));
+ }
+ else
+ {
+ restoreGL();
+ }
+
+ if (!result_first_try)
+ {
+ LLSD args;
+ args["RESX"] = llformat("%d",size.mX);
+ args["RESY"] = llformat("%d",size.mY);
+ LLNotificationsUtil::add("ResolutionSwitchFail", args);
+ size = old_size; // for reshape below
+ }
+
+ BOOL success = result_first_try || result_second_try;
+
+ if (success)
+ {
+ // maximize window if was maximized, else reposition
+ if (was_maximized)
+ {
+ mWindow->maximize();
+ }
+ else
+ {
+ S32 windowX = gSavedSettings.getS32("WindowX");
+ S32 windowY = gSavedSettings.getS32("WindowY");
+
+ mWindow->setPosition(LLCoordScreen ( windowX, windowY ) );
+ }
+ }
+
+ mIgnoreActivate = FALSE;
+ gFocusMgr.setKeyboardFocus(keyboard_focus);
+
+ return success;
+
+ */
+}
+
+F32 LLViewerWindow::getWorldViewAspectRatio() const
+{
+ F32 world_aspect = (F32)mWorldViewRectRaw.getWidth() / (F32)mWorldViewRectRaw.getHeight();
+ return world_aspect;
}
void LLViewerWindow::calcDisplayScale()
{
- F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE);
- LLVector2 display_scale;
- display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
- display_scale *= ui_scale_factor;
+ F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE);
+ LLVector2 display_scale;
+ display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
+ display_scale *= ui_scale_factor;
- // limit minimum display scale
- if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE)
- {
- display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]);
- }
-
- if (display_scale != mDisplayScale)
- {
- LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL;
+ // limit minimum display scale
+ if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE)
+ {
+ display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]);
+ }
+
+ if (display_scale != mDisplayScale)
+ {
+ LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL;
- mDisplayScale = display_scale;
- // Init default fonts
- initFonts();
- }
+ mDisplayScale = display_scale;
+ // Init default fonts
+ initFonts();
+ }
}
//static
-LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale)
+LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale)
{
- LLRect res = rect;
- res.mLeft = ll_round((F32)res.mLeft / display_scale.mV[VX]);
- res.mRight = ll_round((F32)res.mRight / display_scale.mV[VX]);
- res.mBottom = ll_round((F32)res.mBottom / display_scale.mV[VY]);
- res.mTop = ll_round((F32)res.mTop / display_scale.mV[VY]);
+ LLRect res = rect;
+ res.mLeft = ll_round((F32)res.mLeft / display_scale.mV[VX]);
+ res.mRight = ll_round((F32)res.mRight / display_scale.mV[VX]);
+ res.mBottom = ll_round((F32)res.mBottom / display_scale.mV[VY]);
+ res.mTop = ll_round((F32)res.mTop / display_scale.mV[VY]);
- return res;
+ return res;
}
S32 LLViewerWindow::getChatConsoleBottomPad()
{
- S32 offset = 0;
+ S32 offset = 0;
- if(gToolBarView)
- offset += gToolBarView->getBottomToolbar()->getRect().getHeight();
+ if(gToolBarView)
+ offset += gToolBarView->getBottomToolbar()->getRect().getHeight();
- return offset;
+ return offset;
}
LLRect LLViewerWindow::getChatConsoleRect()
{
- LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0);
- LLRect console_rect = full_window;
+ LLRect full_window(0, getWindowHeightScaled(), getWindowWidthScaled(), 0);
+ LLRect console_rect = full_window;
- const S32 CONSOLE_PADDING_TOP = 24;
- const S32 CONSOLE_PADDING_LEFT = 24;
- const S32 CONSOLE_PADDING_RIGHT = 10;
+ const S32 CONSOLE_PADDING_TOP = 24;
+ const S32 CONSOLE_PADDING_LEFT = 24;
+ const S32 CONSOLE_PADDING_RIGHT = 10;
- console_rect.mTop -= CONSOLE_PADDING_TOP;
- console_rect.mBottom += getChatConsoleBottomPad();
+ console_rect.mTop -= CONSOLE_PADDING_TOP;
+ console_rect.mBottom += getChatConsoleBottomPad();
- console_rect.mLeft += CONSOLE_PADDING_LEFT;
+ console_rect.mLeft += CONSOLE_PADDING_LEFT;
- static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth");
+ static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth");
- if (CHAT_FULL_WIDTH)
- {
- console_rect.mRight -= CONSOLE_PADDING_RIGHT;
- }
- else
- {
- // Make console rect somewhat narrow so having inventory open is
- // less of a problem.
- console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3;
- }
+ if (CHAT_FULL_WIDTH)
+ {
+ console_rect.mRight -= CONSOLE_PADDING_RIGHT;
+ }
+ else
+ {
+ // Make console rect somewhat narrow so having inventory open is
+ // less of a problem.
+ console_rect.mRight = console_rect.mLeft + 2 * getWindowWidthScaled() / 3;
+ }
- return console_rect;
+ return console_rect;
}
void LLViewerWindow::reshapeStatusBarContainer()
@@ -6044,31 +6063,31 @@ void LLViewerWindow::reshapeStatusBarContainer()
void LLViewerWindow::setUIVisibility(bool visible)
{
- mUIVisible = visible;
+ mUIVisible = visible;
- if (!visible)
- {
- gAgentCamera.changeCameraToThirdPerson(FALSE);
- gFloaterView->hideAllFloaters();
- }
- else
- {
- gFloaterView->showHiddenFloaters();
- }
+ if (!visible)
+ {
+ gAgentCamera.changeCameraToThirdPerson(FALSE);
+ gFloaterView->hideAllFloaters();
+ }
+ else
+ {
+ gFloaterView->showHiddenFloaters();
+ }
- if (gToolBarView)
- {
- gToolBarView->setToolBarsVisible(visible);
- }
+ if (gToolBarView)
+ {
+ gToolBarView->setToolBarsVisible(visible);
+ }
- LLNavigationBar::getInstance()->setVisible(visible ? gSavedSettings.getBOOL("ShowNavbarNavigationPanel") : FALSE);
- LLPanelTopInfoBar::getInstance()->setVisible(visible? gSavedSettings.getBOOL("ShowMiniLocationPanel") : FALSE);
- mRootView->getChildView("status_bar_container")->setVisible(visible);
+ LLNavigationBar::getInstance()->setVisible(visible ? gSavedSettings.getBOOL("ShowNavbarNavigationPanel") : FALSE);
+ LLPanelTopInfoBar::getInstance()->setVisible(visible? gSavedSettings.getBOOL("ShowMiniLocationPanel") : FALSE);
+ mRootView->getChildView("status_bar_container")->setVisible(visible);
}
bool LLViewerWindow::getUIVisibility()
{
- return mUIVisible;
+ return mUIVisible;
}
////////////////////////////////////////////////////////////////////////////
@@ -6076,22 +6095,22 @@ bool LLViewerWindow::getUIVisibility()
// LLPickInfo
//
LLPickInfo::LLPickInfo()
- : mKeyMask(MASK_NONE),
- mPickCallback(NULL),
- mPickType(PICK_INVALID),
- mWantSurfaceInfo(FALSE),
- mObjectFace(-1),
- mUVCoords(-1.f, -1.f),
- mSTCoords(-1.f, -1.f),
- mXYCoords(-1, -1),
- mIntersection(),
- mNormal(),
- mTangent(),
- mBinormal(),
- mHUDIcon(NULL),
- mPickTransparent(FALSE),
- mPickRigged(FALSE),
- mPickParticle(FALSE)
+ : mKeyMask(MASK_NONE),
+ mPickCallback(NULL),
+ mPickType(PICK_INVALID),
+ mWantSurfaceInfo(FALSE),
+ mObjectFace(-1),
+ mUVCoords(-1.f, -1.f),
+ mSTCoords(-1.f, -1.f),
+ mXYCoords(-1, -1),
+ mIntersection(),
+ mNormal(),
+ mTangent(),
+ mBinormal(),
+ mHUDIcon(NULL),
+ mPickTransparent(FALSE),
+ mPickRigged(FALSE),
+ mPickParticle(FALSE)
{
}
@@ -6121,234 +6140,236 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
mPickRigged(pick_rigged),
mPickParticle(pick_particle),
mPickReflectionProbe(pick_reflection_probe),
- mPickUnselectable(pick_unselectable)
+ mPickUnselectable(pick_unselectable)
{
}
void LLPickInfo::fetchResults()
{
-
- S32 face_hit = -1;
- LLVector4a intersection, normal;
- LLVector4a tangent;
-
- LLVector2 uv;
-
- LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
-
- LLVector4a origin;
- origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
- F32 icon_dist = 0.f;
- LLVector4a start;
- LLVector4a end;
- LLVector4a particle_end;
-
- if (hit_icon)
- {
- LLVector4a delta;
- delta.setSub(intersection, origin);
- icon_dist = delta.getLength3().getF32();
- }
-
- LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
- NULL, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, &face_hit,
- &intersection, &uv, &normal, &tangent, &start, &end);
-
- mPickPt = mMousePt;
-
- U32 te_offset = face_hit > -1 ? face_hit : 0;
-
- if (mPickParticle)
- { //get the end point of line segement to use for particle raycast
- if (hit_object)
- {
- particle_end = intersection;
- }
- else
- {
- particle_end = end;
- }
- }
-
- LLViewerObject* objectp = hit_object;
-
-
- LLVector4a delta;
- delta.setSub(origin, intersection);
-
- if (hit_icon &&
- (!objectp ||
- icon_dist < delta.getLength3().getF32()))
- {
- // was this name referring to a hud icon?
- mHUDIcon = hit_icon;
- mPickType = PICK_ICON;
- mPosGlobal = mHUDIcon->getPositionGlobal();
-
- }
- else if (objectp)
- {
- if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
- {
- // Hit land
- mPickType = PICK_LAND;
- mObjectID.setNull(); // land has no id
-
- // put global position into land_pos
- LLVector3d land_pos;
- if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos, mPickUnselectable))
- {
- // The selected point is beyond the draw distance or is otherwise
- // not selectable. Return before calling mPickCallback().
- return;
- }
-
- // Fudge the land focus a little bit above ground.
- mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f;
- }
- else
- {
- if(isFlora(objectp))
- {
- mPickType = PICK_FLORA;
- }
- else
- {
- mPickType = PICK_OBJECT;
- }
-
- LLVector3 v_intersection(intersection.getF32ptr());
-
- mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);
- mObjectID = objectp->mID;
- mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
-
-
-
- mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);
-
- if (mWantSurfaceInfo)
- {
- getSurfaceInfo();
- }
- }
- }
-
- if (mPickParticle)
- { //search for closest particle to click origin out to intersection point
- S32 part_face = -1;
-
- LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face);
- if (group)
- {
- mParticleOwnerID = group->getPartOwner(part_face);
- mParticleSourceID = group->getPartSource(part_face);
- }
- }
-
- if (mPickCallback)
- {
- mPickCallback(*this);
- }
+ S32 face_hit = -1;
+
+ LLVector4a intersection, normal;
+ LLVector4a tangent;
+
+ LLVector2 uv;
+
+ LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
+
+ LLVector4a origin;
+ origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
+ F32 icon_dist = 0.f;
+ LLVector4a start;
+ LLVector4a end;
+ LLVector4a particle_end;
+
+ if (hit_icon)
+ {
+ LLVector4a delta;
+ delta.setSub(intersection, origin);
+ icon_dist = delta.getLength3().getF32();
+ }
+
+ LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
+ nullptr, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, &face_hit, &mGLTFNodeIndex, &mGLTFPrimitiveIndex,
+ &intersection, &uv, &normal, &tangent, &start, &end);
+
+ mPickPt = mMousePt;
+
+ U32 te_offset = face_hit > -1 ? face_hit : 0;
+
+ if (mPickParticle)
+ { //get the end point of line segement to use for particle raycast
+ if (hit_object)
+ {
+ particle_end = intersection;
+ }
+ else
+ {
+ particle_end = end;
+ }
+ }
+
+ LLViewerObject* objectp = hit_object;
+
+
+ LLVector4a delta;
+ delta.setSub(origin, intersection);
+
+ if (hit_icon &&
+ (!objectp ||
+ icon_dist < delta.getLength3().getF32()))
+ {
+ // was this name referring to a hud icon?
+ mHUDIcon = hit_icon;
+ mPickType = PICK_ICON;
+ mPosGlobal = mHUDIcon->getPositionGlobal();
+
+ }
+ else if (objectp)
+ {
+ if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
+ {
+ // Hit land
+ mPickType = PICK_LAND;
+ mObjectID.setNull(); // land has no id
+
+ // put global position into land_pos
+ LLVector3d land_pos;
+ if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos, mPickUnselectable))
+ {
+ // The selected point is beyond the draw distance or is otherwise
+ // not selectable. Return before calling mPickCallback().
+ return;
+ }
+
+ // Fudge the land focus a little bit above ground.
+ mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f;
+ }
+ else
+ {
+ if(isFlora(objectp))
+ {
+ mPickType = PICK_FLORA;
+ }
+ else
+ {
+ mPickType = PICK_OBJECT;
+ }
+
+ LLVector3 v_intersection(intersection.getF32ptr());
+
+ mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);
+ mObjectID = objectp->mID;
+ mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
+
+
+
+ mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);
+
+ if (mWantSurfaceInfo)
+ {
+ getSurfaceInfo();
+ }
+ }
+ }
+
+ if (mPickParticle)
+ { //search for closest particle to click origin out to intersection point
+ S32 part_face = -1;
+
+ LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face);
+ if (group)
+ {
+ mParticleOwnerID = group->getPartOwner(part_face);
+ mParticleSourceID = group->getPartSource(part_face);
+ }
+ }
+
+ if (mPickCallback)
+ {
+ mPickCallback(*this);
+ }
}
LLPointer<LLViewerObject> LLPickInfo::getObject() const
{
- return gObjectList.findObject( mObjectID );
+ return gObjectList.findObject( mObjectID );
}
void LLPickInfo::updateXYCoords()
{
- if (mObjectFace > -1)
- {
- const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
- LLPointer<LLViewerTexture> imagep = LLViewerTextureManager::getFetchedTexture(tep->getID());
- if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
- {
- mXYCoords.mX = ll_round(mUVCoords.mV[VX] * (F32)imagep->getWidth());
- mXYCoords.mY = ll_round((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight());
- }
- }
+ if (mObjectFace > -1)
+ {
+ const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
+ LLPointer<LLViewerTexture> imagep = LLViewerTextureManager::getFetchedTexture(tep->getID());
+ if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
+ {
+ mXYCoords.mX = ll_round(mUVCoords.mV[VX] * (F32)imagep->getWidth());
+ mXYCoords.mY = ll_round((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight());
+ }
+ }
}
void LLPickInfo::getSurfaceInfo()
{
- // set values to uninitialized - this is what we return if no intersection is found
- mObjectFace = -1;
- mUVCoords = LLVector2(-1, -1);
- mSTCoords = LLVector2(-1, -1);
- mXYCoords = LLCoordScreen(-1, -1);
- mIntersection = LLVector3(0,0,0);
- mNormal = LLVector3(0,0,0);
- mBinormal = LLVector3(0,0,0);
- mTangent = LLVector4(0,0,0,0);
-
- LLVector4a tangent;
- LLVector4a intersection;
- LLVector4a normal;
-
- tangent.clear();
- normal.clear();
- intersection.clear();
-
- LLViewerObject* objectp = getObject();
-
- if (objectp)
- {
- if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
- objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe,
- &mObjectFace,
- &intersection,
- &mSTCoords,
- &normal,
- &tangent))
- {
- // if we succeeded with the intersect above, compute the texture coordinates:
-
- if (objectp->mDrawable.notNull() && mObjectFace > -1)
- {
- LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
- if (facep)
- {
- mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
- }
- }
-
- mIntersection.set(intersection.getF32ptr());
- mNormal.set(normal.getF32ptr());
- mTangent.set(tangent.getF32ptr());
-
- //extrapoloate binormal from normal and tangent
-
- LLVector4a binormal;
- binormal.setCross3(normal, tangent);
- binormal.mul(tangent.getF32ptr()[3]);
-
- mBinormal.set(binormal.getF32ptr());
-
- mBinormal.normalize();
- mNormal.normalize();
- mTangent.normalize();
-
- // and XY coords:
- updateXYCoords();
-
- }
- }
-}
-
-//static
+ // set values to uninitialized - this is what we return if no intersection is found
+ mObjectFace = -1;
+ mUVCoords = LLVector2(-1, -1);
+ mSTCoords = LLVector2(-1, -1);
+ mXYCoords = LLCoordScreen(-1, -1);
+ mIntersection = LLVector3(0,0,0);
+ mNormal = LLVector3(0,0,0);
+ mBinormal = LLVector3(0,0,0);
+ mTangent = LLVector4(0,0,0,0);
+
+ LLVector4a tangent;
+ LLVector4a intersection;
+ LLVector4a normal;
+
+ tangent.clear();
+ normal.clear();
+ intersection.clear();
+
+ LLViewerObject* objectp = getObject();
+
+ if (objectp)
+ {
+ if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
+ objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe,
+ &mObjectFace,
+ &mGLTFNodeIndex,
+ &mGLTFPrimitiveIndex,
+ &intersection,
+ &mSTCoords,
+ &normal,
+ &tangent))
+ {
+ // if we succeeded with the intersect above, compute the texture coordinates:
+
+ if (objectp->mDrawable.notNull() && mObjectFace > -1)
+ {
+ LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
+ if (facep)
+ {
+ mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
+ }
+ }
+
+ mIntersection.set(intersection.getF32ptr());
+ mNormal.set(normal.getF32ptr());
+ mTangent.set(tangent.getF32ptr());
+
+ //extrapoloate binormal from normal and tangent
+
+ LLVector4a binormal;
+ binormal.setCross3(normal, tangent);
+ binormal.mul(tangent.getF32ptr()[3]);
+
+ mBinormal.set(binormal.getF32ptr());
+
+ mBinormal.normalize();
+ mNormal.normalize();
+ mTangent.normalize();
+
+ // and XY coords:
+ updateXYCoords();
+
+ }
+ }
+}
+
+//static
bool LLPickInfo::isFlora(LLViewerObject* object)
{
- if (!object) return false;
+ if (!object) return false;
- LLPCode pcode = object->getPCode();
+ LLPCode pcode = object->getPCode();
- if( (LL_PCODE_LEGACY_GRASS == pcode)
- || (LL_PCODE_LEGACY_TREE == pcode)
- || (LL_PCODE_TREE_NEW == pcode))
- {
- return true;
- }
- return false;
+ if( (LL_PCODE_LEGACY_GRASS == pcode)
+ || (LL_PCODE_LEGACY_TREE == pcode)
+ || (LL_PCODE_TREE_NEW == pcode))
+ {
+ return true;
+ }
+ return false;
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index d2a337649e..121b5b6fad 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerwindow.h
* @brief Description of the LLViewerWindow class.
*
* $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$
*/
@@ -77,67 +77,69 @@ class LLCubeMapArray;
class LLPickInfo
{
public:
- typedef enum
- {
- PICK_OBJECT,
- PICK_FLORA,
- PICK_LAND,
- PICK_ICON,
- PICK_PARCEL_WALL,
- PICK_INVALID
- } EPickType;
+ typedef enum
+ {
+ PICK_OBJECT,
+ PICK_FLORA,
+ PICK_LAND,
+ PICK_ICON,
+ PICK_PARCEL_WALL,
+ PICK_INVALID
+ } EPickType;
public:
- LLPickInfo();
- LLPickInfo(const LLCoordGL& mouse_pos,
- MASK keyboard_mask,
- BOOL pick_transparent,
- BOOL pick_rigged,
- BOOL pick_particle,
+ LLPickInfo();
+ LLPickInfo(const LLCoordGL& mouse_pos,
+ MASK keyboard_mask,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_particle,
BOOL pick_reflection_probe,
- BOOL pick_surface_info,
- BOOL pick_unselectable,
- void (*pick_callback)(const LLPickInfo& pick_info));
+ BOOL pick_surface_info,
+ BOOL pick_unselectable,
+ void (*pick_callback)(const LLPickInfo& pick_info));
- void fetchResults();
- LLPointer<LLViewerObject> getObject() const;
- LLUUID getObjectID() const { return mObjectID; }
- bool isValid() const { return mPickType != PICK_INVALID; }
+ void fetchResults();
+ LLPointer<LLViewerObject> getObject() const;
+ LLUUID getObjectID() const { return mObjectID; }
+ bool isValid() const { return mPickType != PICK_INVALID; }
- static bool isFlora(LLViewerObject* object);
+ static bool isFlora(LLViewerObject* object);
public:
- LLCoordGL mMousePt;
- MASK mKeyMask;
- void (*mPickCallback)(const LLPickInfo& pick_info);
-
- EPickType mPickType;
- LLCoordGL mPickPt;
- LLVector3d mPosGlobal;
- LLVector3 mObjectOffset;
- LLUUID mObjectID;
- LLUUID mParticleOwnerID;
- LLUUID mParticleSourceID;
- S32 mObjectFace;
- LLHUDIcon* mHUDIcon;
- LLVector3 mIntersection;
- LLVector2 mUVCoords;
- LLVector2 mSTCoords;
- LLCoordScreen mXYCoords;
- LLVector3 mNormal;
- LLVector4 mTangent;
- LLVector3 mBinormal;
- BOOL mPickTransparent;
- BOOL mPickRigged;
- BOOL mPickParticle;
- BOOL mPickUnselectable;
+ LLCoordGL mMousePt;
+ MASK mKeyMask;
+ void (*mPickCallback)(const LLPickInfo& pick_info);
+
+ EPickType mPickType;
+ LLCoordGL mPickPt;
+ LLVector3d mPosGlobal;
+ LLVector3 mObjectOffset;
+ LLUUID mObjectID;
+ LLUUID mParticleOwnerID;
+ LLUUID mParticleSourceID;
+ S32 mObjectFace;
+ S32 mGLTFNodeIndex = -1;
+ S32 mGLTFPrimitiveIndex = -1;
+ LLHUDIcon* mHUDIcon;
+ LLVector3 mIntersection;
+ LLVector2 mUVCoords;
+ LLVector2 mSTCoords;
+ LLCoordScreen mXYCoords;
+ LLVector3 mNormal;
+ LLVector4 mTangent;
+ LLVector3 mBinormal;
+ BOOL mPickTransparent;
+ BOOL mPickRigged;
+ BOOL mPickParticle;
+ BOOL mPickUnselectable;
BOOL mPickReflectionProbe = FALSE;
- void getSurfaceInfo();
+ void getSurfaceInfo();
private:
- void updateXYCoords();
+ void updateXYCoords();
- BOOL mWantSurfaceInfo; // do we populate mUVCoord, mNormal, mBinormal?
+ BOOL mWantSurfaceInfo; // do we populate mUVCoord, mNormal, mBinormal?
};
@@ -146,430 +148,433 @@ static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680
class LLViewerWindow : public LLWindowCallbacks
{
public:
- //
- // CREATORS
- //
- struct Params : public LLInitParam::Block<Params>
- {
- Mandatory<std::string> title,
- name;
- Mandatory<S32> x,
- y,
- width,
- height,
- min_width,
- min_height;
- Optional<bool> fullscreen,
- ignore_pixel_depth,
- first_run;
-
- Params();
- };
-
- LLViewerWindow(const Params& p);
- virtual ~LLViewerWindow();
-
- void shutdownViews();
- void shutdownGL();
-
- void initGLDefaults();
- void initBase();
- void adjustRectanglesForFirstUse(const LLRect& window);
- void adjustControlRectanglesForFirstUse(const LLRect& window);
- void initWorldUI();
- void setUIVisibility(bool);
- bool getUIVisibility();
- void handlePieMenu(S32 x, S32 y, MASK mask);
+ //
+ // CREATORS
+ //
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<std::string> title,
+ name;
+ Mandatory<S32> x,
+ y,
+ width,
+ height,
+ min_width,
+ min_height;
+ Optional<bool> fullscreen,
+ ignore_pixel_depth,
+ first_run;
+
+ Params();
+ };
+
+ LLViewerWindow(const Params& p);
+ virtual ~LLViewerWindow();
+
+ void shutdownViews();
+ void shutdownGL();
+
+ void initGLDefaults();
+ void initBase();
+ void adjustRectanglesForFirstUse(const LLRect& window);
+ void adjustControlRectanglesForFirstUse(const LLRect& window);
+ void initWorldUI();
+ void setUIVisibility(bool);
+ bool getUIVisibility();
+ void handlePieMenu(S32 x, S32 y, MASK mask);
void reshapeStatusBarContainer();
- BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action);
-
- //
- // LLWindowCallback interface implementation
- //
- /*virtual*/ BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated);
- /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask);
- /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
- /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended
- /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleCloseRequest(LLWindow *window);
- /*virtual*/ void handleQuit(LLWindow *window);
- /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
- /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
- BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down);
- /*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data);
- void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
+ BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action);
+
+ //
+ // LLWindowCallback interface implementation
+ //
+ /*virtual*/ BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated);
+ /*virtual*/ BOOL handleTranslatedKeyUp(KEY key, MASK mask);
+ /*virtual*/ void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
+ /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended
+ /*virtual*/ BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleCloseRequest(LLWindow *window);
+ /*virtual*/ void handleQuit(LLWindow *window);
+ /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down);
+ /*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data);
+ void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ void handleMouseLeave(LLWindow *window);
- /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y);
- /*virtual*/ void handleFocus(LLWindow *window);
- /*virtual*/ void handleFocusLost(LLWindow *window);
- /*virtual*/ BOOL handleActivate(LLWindow *window, BOOL activated);
- /*virtual*/ BOOL handleActivateApp(LLWindow *window, BOOL activating);
- /*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item);
- /*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
- /*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks);
- /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks);
- /*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ void handleWindowBlock(LLWindow *window);
- /*virtual*/ void handleWindowUnblock(LLWindow *window);
- /*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
- /*virtual*/ BOOL handleTimerEvent(LLWindow *window);
- /*virtual*/ BOOL handleDeviceChange(LLWindow *window);
- /*virtual*/ BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
- /*virtual*/ BOOL handleWindowDidChangeScreen(LLWindow *window);
-
- /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
- /*virtual*/ void handlePauseWatchdog(LLWindow *window);
- /*virtual*/ void handleResumeWatchdog(LLWindow *window);
- /*virtual*/ std::string translateString(const char* tag);
- /*virtual*/ std::string translateString(const char* tag,
- const std::map<std::string, std::string>& args);
-
- // signal on update of WorldView rect
- typedef boost::function<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_callback_t;
- typedef boost::signals2::signal<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_signal_t;
- world_rect_signal_t mOnWorldViewRectUpdated;
- boost::signals2::connection setOnWorldViewRectUpdated(world_rect_callback_t cb) { return mOnWorldViewRectUpdated.connect(cb); }
-
- //
- // ACCESSORS
- //
- LLRootView* getRootView() const;
-
- // 3D world area in scaled pixels (via UI scale), use for most UI computations
- LLRect getWorldViewRectScaled() const;
- S32 getWorldViewHeightScaled() const;
- S32 getWorldViewWidthScaled() const;
-
- // 3D world area, in raw unscaled pixels
- LLRect getWorldViewRectRaw() const { return mWorldViewRectRaw; }
- S32 getWorldViewHeightRaw() const;
- S32 getWorldViewWidthRaw() const;
-
- // Window in scaled pixels (via UI scale), use for most UI computations
- LLRect getWindowRectScaled() const { return mWindowRectScaled; }
- S32 getWindowHeightScaled() const;
- S32 getWindowWidthScaled() const;
-
- // Window in raw pixels as seen on screen.
- LLRect getWindowRectRaw() const { return mWindowRectRaw; }
- S32 getWindowHeightRaw() const;
- S32 getWindowWidthRaw() const;
-
- LLWindow* getWindow() const { return mWindow; }
- void* getPlatformWindow() const;
- void* getMediaWindow() const;
- void focusClient() const;
-
- LLCoordGL getLastMouse() const { return mLastMousePoint; }
- S32 getLastMouseX() const { return mLastMousePoint.mX; }
- S32 getLastMouseY() const { return mLastMousePoint.mY; }
- LLCoordGL getCurrentMouse() const { return mCurrentMousePoint; }
- S32 getCurrentMouseX() const { return mCurrentMousePoint.mX; }
- S32 getCurrentMouseY() const { return mCurrentMousePoint.mY; }
- S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; }
- S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; }
- LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; }
- static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; }
- BOOL getLeftMouseDown() const { return mLeftMouseDown; }
- BOOL getMiddleMouseDown() const { return mMiddleMouseDown; }
- BOOL getRightMouseDown() const { return mRightMouseDown; }
-
- const LLPickInfo& getLastPick() const { return mLastPick; }
-
- void setup2DViewport(S32 x_offset = 0, S32 y_offset = 0);
- void setup3DViewport(S32 x_offset = 0, S32 y_offset = 0);
- void setup3DRender();
- void setup2DRender();
-
- LLVector3 mouseDirectionGlobal(const S32 x, const S32 y) const;
- LLVector3 mouseDirectionCamera(const S32 x, const S32 y) const;
- LLVector3 mousePointHUD(const S32 x, const S32 y) const;
-
-
- // Is window of our application frontmost?
- BOOL getActive() const { return mActive; }
-
- const std::string& getInitAlert() { return mInitAlert; }
-
- //
- // MANIPULATORS
- //
- void saveLastMouse(const LLCoordGL &point);
-
- void setCursor( ECursorType c );
- void showCursor();
- void hideCursor();
- BOOL getCursorHidden() { return mCursorHidden; }
- void moveCursorToCenter(); // move to center of window
-
- void initTextures(S32 location_id);
- void setShowProgress(const BOOL show);
- BOOL getShowProgress() const;
- void setProgressString(const std::string& string);
- void setProgressPercent(const F32 percent);
- void setProgressMessage(const std::string& msg);
- void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null );
- LLProgressView *getProgressView() const;
- void revealIntroPanel();
- void setStartupComplete();
-
- void updateObjectUnderCursor();
-
- void updateUI(); // Once per frame, update UI based on mouse position, calls following update* functions
- void updateLayout();
- void updateMouseDelta();
- void updateKeyboardFocus();
-
- void updateWorldViewRect(bool use_full_window=false);
- LLView* getToolBarHolder() { return mToolBarHolder.get(); }
- LLView* getHintHolder() { return mHintHolder.get(); }
- LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); }
- BOOL handleKey(KEY key, MASK mask);
- BOOL handleKeyUp(KEY key, MASK mask);
- void handleScrollWheel (S32 clicks);
- void handleScrollHWheel (S32 clicks);
-
- // add and remove views from "popup" layer
- void addPopup(LLView* popup);
- void removePopup(LLView* popup);
- void clearPopups();
-
- // Hide normal UI when a logon fails, re-show everything when logon is attempted again
- void setNormalControlsVisible( BOOL visible );
- void setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
-
- void reshape(S32 width, S32 height);
- void sendShapeToSim();
-
- void draw();
- void updateDebugText();
- void drawDebugText();
-
- static void loadUserImage(void **cb_data, const LLUUID &uuid);
-
- static void movieSize(S32 new_width, S32 new_height);
-
- // snapshot functionality.
- // perhaps some of this should move to llfloatershapshot? -MG
-
- BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
- BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
- BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
-
- BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
-
-
-
+ /*virtual*/ void handleMouseLeave(LLWindow *window);
+ /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y);
+ /*virtual*/ void handleFocus(LLWindow *window);
+ /*virtual*/ void handleFocusLost(LLWindow *window);
+ /*virtual*/ BOOL handleActivate(LLWindow *window, BOOL activated);
+ /*virtual*/ BOOL handleActivateApp(LLWindow *window, BOOL activating);
+ /*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item);
+ /*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
+ /*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks);
+ /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks);
+ /*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ void handleWindowBlock(LLWindow *window);
+ /*virtual*/ void handleWindowUnblock(LLWindow *window);
+ /*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
+ /*virtual*/ BOOL handleTimerEvent(LLWindow *window);
+ /*virtual*/ BOOL handleDeviceChange(LLWindow *window);
+ /*virtual*/ BOOL handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+ /*virtual*/ BOOL handleWindowDidChangeScreen(LLWindow *window);
+
+ /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
+ /*virtual*/ void handlePauseWatchdog(LLWindow *window);
+ /*virtual*/ void handleResumeWatchdog(LLWindow *window);
+ /*virtual*/ std::string translateString(const char* tag);
+ /*virtual*/ std::string translateString(const char* tag,
+ const std::map<std::string, std::string>& args);
+
+ // signal on update of WorldView rect
+ typedef boost::function<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_callback_t;
+ typedef boost::signals2::signal<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_signal_t;
+ world_rect_signal_t mOnWorldViewRectUpdated;
+ boost::signals2::connection setOnWorldViewRectUpdated(world_rect_callback_t cb) { return mOnWorldViewRectUpdated.connect(cb); }
+
+ //
+ // ACCESSORS
+ //
+ LLRootView* getRootView() const;
+
+ // 3D world area in scaled pixels (via UI scale), use for most UI computations
+ LLRect getWorldViewRectScaled() const;
+ S32 getWorldViewHeightScaled() const;
+ S32 getWorldViewWidthScaled() const;
+
+ // 3D world area, in raw unscaled pixels
+ LLRect getWorldViewRectRaw() const { return mWorldViewRectRaw; }
+ S32 getWorldViewHeightRaw() const;
+ S32 getWorldViewWidthRaw() const;
+
+ // Window in scaled pixels (via UI scale), use for most UI computations
+ LLRect getWindowRectScaled() const { return mWindowRectScaled; }
+ S32 getWindowHeightScaled() const;
+ S32 getWindowWidthScaled() const;
+
+ // Window in raw pixels as seen on screen.
+ LLRect getWindowRectRaw() const { return mWindowRectRaw; }
+ S32 getWindowHeightRaw() const;
+ S32 getWindowWidthRaw() const;
+
+ LLWindow* getWindow() const { return mWindow; }
+ void* getPlatformWindow() const;
+ void* getMediaWindow() const;
+ void focusClient() const;
+
+ LLCoordGL getLastMouse() const { return mLastMousePoint; }
+ S32 getLastMouseX() const { return mLastMousePoint.mX; }
+ S32 getLastMouseY() const { return mLastMousePoint.mY; }
+ LLCoordGL getCurrentMouse() const { return mCurrentMousePoint; }
+ S32 getCurrentMouseX() const { return mCurrentMousePoint.mX; }
+ S32 getCurrentMouseY() const { return mCurrentMousePoint.mY; }
+ S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; }
+ S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; }
+ LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; }
+ static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; }
+ BOOL getLeftMouseDown() const { return mLeftMouseDown; }
+ BOOL getMiddleMouseDown() const { return mMiddleMouseDown; }
+ BOOL getRightMouseDown() const { return mRightMouseDown; }
+
+ const LLPickInfo& getLastPick() const { return mLastPick; }
+
+ void setup2DViewport(S32 x_offset = 0, S32 y_offset = 0);
+ void setup3DViewport(S32 x_offset = 0, S32 y_offset = 0);
+ void setup3DRender();
+ void setup2DRender();
+
+ LLVector3 mouseDirectionGlobal(const S32 x, const S32 y) const;
+ LLVector3 mouseDirectionCamera(const S32 x, const S32 y) const;
+ LLVector3 mousePointHUD(const S32 x, const S32 y) const;
+
+
+ // Is window of our application frontmost?
+ BOOL getActive() const { return mActive; }
+
+ const std::string& getInitAlert() { return mInitAlert; }
+
+ //
+ // MANIPULATORS
+ //
+ void saveLastMouse(const LLCoordGL &point);
+
+ void setCursor( ECursorType c );
+ void showCursor();
+ void hideCursor();
+ BOOL getCursorHidden() { return mCursorHidden; }
+ void moveCursorToCenter(); // move to center of window
+
+ void initTextures(S32 location_id);
+ void setShowProgress(const BOOL show);
+ BOOL getShowProgress() const;
+ void setProgressString(const std::string& string);
+ void setProgressPercent(const F32 percent);
+ void setProgressMessage(const std::string& msg);
+ void setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null );
+ LLProgressView *getProgressView() const;
+ void revealIntroPanel();
+ void setStartupComplete();
+
+ void updateObjectUnderCursor();
+
+ void updateUI(); // Once per frame, update UI based on mouse position, calls following update* functions
+ void updateLayout();
+ void updateMouseDelta();
+ void updateKeyboardFocus();
+
+ void updateWorldViewRect(bool use_full_window=false);
+ LLView* getToolBarHolder() { return mToolBarHolder.get(); }
+ LLView* getHintHolder() { return mHintHolder.get(); }
+ LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); }
+ BOOL handleKey(KEY key, MASK mask);
+ BOOL handleKeyUp(KEY key, MASK mask);
+ void handleScrollWheel (S32 clicks);
+ void handleScrollHWheel (S32 clicks);
+
+ // add and remove views from "popup" layer
+ void addPopup(LLView* popup);
+ void removePopup(LLView* popup);
+ void clearPopups();
+
+ // Hide normal UI when a logon fails, re-show everything when logon is attempted again
+ void setNormalControlsVisible( BOOL visible );
+ void setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
+
+ void reshape(S32 width, S32 height);
+ void sendShapeToSim();
+
+ void draw();
+ void updateDebugText();
+ void drawDebugText();
+
+ static void loadUserImage(void **cb_data, const LLUUID &uuid);
+
+ static void movieSize(S32 new_width, S32 new_height);
+
+ // snapshot functionality.
+ // perhaps some of this should move to llfloatershapshot? -MG
+
+ BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
+ BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
+ BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, BOOL no_post = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
+
+ BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+
+
// take a cubemap snapshot
// origin - vantage point to take the snapshot from
// cubearray - cubemap array for storing the results
// index - cube index in the array to use (cube index, not face-layer)
// face - which cube face to update
// near_clip - near clip setting to use
- BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars);
-
+ BOOL cubeSnapshot(const LLVector3 &origin, LLCubeMapArray *cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars,
+ bool customCullingPlane = false, LLPlane cullingPlane = LLPlane(LLVector3(0, 0, 0), LLVector3(0, 0, 1)));
+
// special implementation of simpleSnapshot for reflection maps
- BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
-
- BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type);
- BOOL isSnapshotLocSet() const;
- void resetSnapshotLoc() const;
-
- typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
-
- void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
- void onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
- void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
- void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb);
-
- // Reset the directory where snapshots are saved.
- // Client will open directory picker on next snapshot save.
- void resetSnapshotLoc();
-
- void playSnapshotAnimAndSound();
-
- // draws selection boxes around selected objects, must call displayObjects first
- void renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud );
- void performPick();
- void returnEmptyPicks();
-
- void pickAsync( S32 x,
- S32 y_from_bot,
- MASK mask,
- void (*callback)(const LLPickInfo& pick_info),
- BOOL pick_transparent = FALSE,
- BOOL pick_rigged = FALSE,
- BOOL pick_unselectable = FALSE,
+ BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+ BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, BOOL no_post, LLSnapshotModel::ESnapshotLayerType type);
+ BOOL isSnapshotLocSet() const;
+ void resetSnapshotLoc() const;
+
+ typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
+
+ void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb);
+
+ // Reset the directory where snapshots are saved.
+ // Client will open directory picker on next snapshot save.
+ void resetSnapshotLoc();
+
+ void playSnapshotAnimAndSound();
+
+ // draws selection boxes around selected objects, must call displayObjects first
+ void renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud );
+ void performPick();
+ void returnEmptyPicks();
+
+ void pickAsync( S32 x,
+ S32 y_from_bot,
+ MASK mask,
+ void (*callback)(const LLPickInfo& pick_info),
+ BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = FALSE,
BOOL pick_reflection_probes = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = FALSE);
- LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector4a* intersection);
-
- LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
- LLViewerObject *this_object = NULL,
- S32 this_face = -1,
- BOOL pick_transparent = FALSE,
- BOOL pick_rigged = FALSE,
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = FALSE);
+ LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
+ LLVector4a* intersection);
+
+ LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
+ LLViewerObject *this_object = NULL,
+ S32 this_face = -1,
+ BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
BOOL pick_unselectable = TRUE,
BOOL pick_reflection_probe = TRUE,
- S32* face_hit = NULL,
- LLVector4a *intersection = NULL,
- LLVector2 *uv = NULL,
- LLVector4a *normal = NULL,
- LLVector4a *tangent = NULL,
- LLVector4a* start = NULL,
- LLVector4a* end = NULL);
-
-
- // Returns a pointer to the last object hit
- //LLViewerObject *getObject();
- //LLViewerObject *lastNonFloraObjectHit();
-
- //const LLVector3d& getObjectOffset();
- //const LLVector3d& lastNonFloraObjectHitOffset();
-
- // mousePointOnLand() returns true if found point
- BOOL mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_pos_global, BOOL ignore_distance = FALSE);
- BOOL mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, const LLVector3d &plane_point, const LLVector3 &plane_normal);
- LLVector3d clickPointInWorldGlobal(const S32 x, const S32 y_from_bot, LLViewerObject* clicked_object) const;
- BOOL clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const;
-
- // Prints window implementation details
- void dumpState();
-
- // handle shutting down GL and bringing it back up
- void requestResolutionUpdate();
- void checkSettings();
- void restartDisplay(BOOL show_progress_bar);
- BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar);
- BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; }
- F32 getWorldViewAspectRatio() const;
- const LLVector2& getDisplayScale() const { return mDisplayScale; }
- void calcDisplayScale();
- static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
-
- static std::string getLastSnapshotDir();
+ S32* face_hit = NULL,
+ S32* gltf_node_hit = nullptr,
+ S32* gltf_primitive_hit = nullptr,
+ LLVector4a *intersection = NULL,
+ LLVector2 *uv = NULL,
+ LLVector4a *normal = NULL,
+ LLVector4a *tangent = NULL,
+ LLVector4a* start = NULL,
+ LLVector4a* end = NULL);
+
+
+ // Returns a pointer to the last object hit
+ //LLViewerObject *getObject();
+ //LLViewerObject *lastNonFloraObjectHit();
+
+ //const LLVector3d& getObjectOffset();
+ //const LLVector3d& lastNonFloraObjectHitOffset();
+
+ // mousePointOnLand() returns true if found point
+ BOOL mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_pos_global, BOOL ignore_distance = FALSE);
+ BOOL mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y, const LLVector3d &plane_point, const LLVector3 &plane_normal);
+ LLVector3d clickPointInWorldGlobal(const S32 x, const S32 y_from_bot, LLViewerObject* clicked_object) const;
+ BOOL clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const;
+
+ // Prints window implementation details
+ void dumpState();
+
+ // handle shutting down GL and bringing it back up
+ void requestResolutionUpdate();
+ void checkSettings();
+ void restartDisplay(BOOL show_progress_bar);
+ BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar);
+ BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; }
+ F32 getWorldViewAspectRatio() const;
+ const LLVector2& getDisplayScale() const { return mDisplayScale; }
+ void calcDisplayScale();
+ static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
+
+ static std::string getLastSnapshotDir();
private:
- bool shouldShowToolTipFor(LLMouseHandler *mh);
-
- void switchToolByMask(MASK mask);
- void destroyWindow();
- void drawMouselookInstructions();
- void stopGL(BOOL save_state = TRUE);
- void restoreGL(const std::string& progress_message = LLStringUtil::null);
- void initFonts(F32 zoom_factor = 1.f);
- void schedulePick(LLPickInfo& pick_info);
- S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter
- LLRect getChatConsoleRect(); // Get optimal cosole rect.
+ bool shouldShowToolTipFor(LLMouseHandler *mh);
+
+ void switchToolByMask(MASK mask);
+ void destroyWindow();
+ void drawMouselookInstructions();
+ void stopGL(BOOL save_state = TRUE);
+ void restoreGL(const std::string& progress_message = LLStringUtil::null);
+ void initFonts(F32 zoom_factor = 1.f);
+ void schedulePick(LLPickInfo& pick_info);
+ S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter
+ LLRect getChatConsoleRect(); // Get optimal cosole rect.
private:
- LLWindow* mWindow; // graphical window object
- bool mActive;
- bool mUIVisible;
-
- LLNotificationChannelPtr mSystemChannel;
- LLNotificationChannelPtr mCommunicationChannel;
- LLNotificationChannelPtr mAlertsChannel;
- LLNotificationChannelPtr mModalAlertsChannel;
-
- LLRect mWindowRectRaw; // whole window, including UI
- LLRect mWindowRectScaled; // whole window, scaled by UI size
- LLRect mWorldViewRectRaw; // area of screen for 3D world
- LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size
- LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views
- LLVector2 mDisplayScale;
-
- LLCoordGL mCurrentMousePoint; // last mouse position in GL coords
- LLCoordGL mLastMousePoint; // Mouse point at last frame.
- LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame
- BOOL mLeftMouseDown;
- BOOL mMiddleMouseDown;
- BOOL mRightMouseDown;
-
- LLProgressView *mProgressView;
-
- LLFrameTimer mToolTipFadeTimer;
- LLPanel* mToolTip;
- std::string mLastToolTipMessage;
- LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect.
-
- BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse.
- BOOL mFocusCycleMode;
+ LLWindow* mWindow; // graphical window object
+ bool mActive;
+ bool mUIVisible;
+
+ LLNotificationChannelPtr mSystemChannel;
+ LLNotificationChannelPtr mCommunicationChannel;
+ LLNotificationChannelPtr mAlertsChannel;
+ LLNotificationChannelPtr mModalAlertsChannel;
+
+ LLRect mWindowRectRaw; // whole window, including UI
+ LLRect mWindowRectScaled; // whole window, scaled by UI size
+ LLRect mWorldViewRectRaw; // area of screen for 3D world
+ LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size
+ LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views
+ LLVector2 mDisplayScale;
+
+ LLCoordGL mCurrentMousePoint; // last mouse position in GL coords
+ LLCoordGL mLastMousePoint; // Mouse point at last frame.
+ LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame
+ BOOL mLeftMouseDown;
+ BOOL mMiddleMouseDown;
+ BOOL mRightMouseDown;
+
+ LLProgressView *mProgressView;
+
+ LLFrameTimer mToolTipFadeTimer;
+ LLPanel* mToolTip;
+ std::string mLastToolTipMessage;
+ LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect.
+
+ BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse.
+ BOOL mFocusCycleMode;
BOOL mAllowMouseDragging;
LLFrameTimer mMouseDownTimer;
- typedef std::set<LLHandle<LLView> > view_handle_set_t;
- view_handle_set_t mMouseHoverViews;
-
- // Variables used for tool override switching based on modifier keys. JC
- MASK mLastMask; // used to detect changes in modifier mask
- LLTool* mToolStored; // the tool we're overriding
- BOOL mHideCursorPermanent; // true during drags, mouselook
- BOOL mCursorHidden;
- LLPickInfo mLastPick;
- std::vector<LLPickInfo> mPicks;
- LLRect mPickScreenRegion; // area of frame buffer for rendering pick frames (generally follows mouse to avoid going offscreen)
- LLTimer mPickTimer; // timer for scheduling n picks per second
-
- std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta"
-
- BOOL mIgnoreActivate;
-
- std::string mInitAlert; // Window / GL initialization requires an alert
-
- LLHandle<LLView> mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world
- LLHandle<LLView> mToolBarHolder; // container for toolbars
- LLHandle<LLView> mHintHolder; // container for hints
- LLHandle<LLView> mLoginPanelHolder; // container for login panel
- LLPopupView* mPopupView; // container for transient popups
-
- class LLDebugText* mDebugText; // Internal class for debug text
-
- bool mResDirty;
- bool mStatesDirty;
- U32 mCurrResolutionIndex;
-
- std::unique_ptr<LLWindowListener> mWindowListener;
- std::unique_ptr<LLViewerWindowListener> mViewerWindowListener;
-
- // Object temporarily hovered over while dragging
- LLPointer<LLViewerObject> mDragHoveredObject;
-
- static LLTrace::SampleStatHandle<> sMouseVelocityStat;
+ typedef std::set<LLHandle<LLView> > view_handle_set_t;
+ view_handle_set_t mMouseHoverViews;
+
+ // Variables used for tool override switching based on modifier keys. JC
+ MASK mLastMask; // used to detect changes in modifier mask
+ LLTool* mToolStored; // the tool we're overriding
+ BOOL mHideCursorPermanent; // true during drags, mouselook
+ BOOL mCursorHidden;
+ LLPickInfo mLastPick;
+ std::vector<LLPickInfo> mPicks;
+ LLRect mPickScreenRegion; // area of frame buffer for rendering pick frames (generally follows mouse to avoid going offscreen)
+ LLTimer mPickTimer; // timer for scheduling n picks per second
+
+ std::string mOverlayTitle; // Used for special titles such as "Second Life - Special E3 2003 Beta"
+
+ BOOL mIgnoreActivate;
+
+ std::string mInitAlert; // Window / GL initialization requires an alert
+
+ LLHandle<LLView> mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world
+ LLHandle<LLView> mToolBarHolder; // container for toolbars
+ LLHandle<LLView> mHintHolder; // container for hints
+ LLHandle<LLView> mLoginPanelHolder; // container for login panel
+ LLPopupView* mPopupView; // container for transient popups
+
+ class LLDebugText* mDebugText; // Internal class for debug text
+
+ bool mResDirty;
+ bool mStatesDirty;
+ U32 mCurrResolutionIndex;
+
+ std::unique_ptr<LLWindowListener> mWindowListener;
+ std::unique_ptr<LLViewerWindowListener> mViewerWindowListener;
+
+ // Object temporarily hovered over while dragging
+ LLPointer<LLViewerObject> mDragHoveredObject;
+
+ static LLTrace::SampleStatHandle<> sMouseVelocityStat;
};
//
// Globals
//
-extern LLViewerWindow* gViewerWindow;
+extern LLViewerWindow* gViewerWindow;
-extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true
-extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away
+extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true
+extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away
extern LLViewerObject* gDebugRaycastObject;
extern LLVector4a gDebugRaycastIntersection;
-extern LLVOPartGroup* gDebugRaycastParticle;
-extern LLVector4a gDebugRaycastParticleIntersection;
+extern LLVOPartGroup* gDebugRaycastParticle;
+extern LLVector4a gDebugRaycastParticleIntersection;
extern LLVector2 gDebugRaycastTexCoord;
extern LLVector4a gDebugRaycastNormal;
extern LLVector4a gDebugRaycastTangent;
-extern S32 gDebugRaycastFaceHit;
-extern LLVector4a gDebugRaycastStart;
-extern LLVector4a gDebugRaycastEnd;
-
-extern BOOL gDisplayCameraPos;
-extern BOOL gDisplayWindInfo;
-extern BOOL gDisplayFOV;
-extern BOOL gDisplayBadge;
+extern S32 gDebugRaycastFaceHit;
+extern LLVector4a gDebugRaycastStart;
+extern LLVector4a gDebugRaycastEnd;
+
+extern BOOL gDisplayCameraPos;
+extern BOOL gDisplayWindInfo;
+extern BOOL gDisplayFOV;
+extern BOOL gDisplayBadge;
#endif
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c3334866a5..8d3b5cc8a5 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvlcomposition.cpp
* @brief Viewer-side representation of a composition layer...
*
* $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$
*/
@@ -28,473 +28,930 @@
#include "llvlcomposition.h"
+#include <functional>
+
#include "llerror.h"
#include "v3math.h"
#include "llsurface.h"
#include "lltextureview.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
+#include "llfetchedgltfmaterial.h"
+#include "llgltfmateriallist.h"
#include "llviewerregion.h"
#include "noise.h"
#include "llregionhandle.h" // for from_region_handle
#include "llviewercontrol.h"
+extern LLColor4U MAX_WATER_COLOR;
+
+static const U32 BASE_SIZE = 128;
+static const F32 TERRAIN_DECODE_PRIORITY = 2048.f * 2048.f;
-F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac)
+namespace
{
- // Not sure if this is the right math...
- // Take weighted average of all four points (bilinear interpolation)
- F32 result;
-
- const F32 inv_x_frac = 1.f - x_frac;
- const F32 inv_y_frac = 1.f - y_frac;
- result = inv_x_frac*inv_y_frac*v00
- + x_frac*inv_y_frac*v10
- + inv_x_frac*y_frac*v01
- + x_frac*y_frac*v11;
-
- return result;
-}
+ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac)
+ {
+ // Not sure if this is the right math...
+ // Take weighted average of all four points (bilinear interpolation)
+ F32 result;
+
+ const F32 inv_x_frac = 1.f - x_frac;
+ const F32 inv_y_frac = 1.f - y_frac;
+ result = inv_x_frac*inv_y_frac*v00
+ + x_frac*inv_y_frac*v10
+ + inv_x_frac*y_frac*v01
+ + x_frac*y_frac*v11;
+
+ return result;
+ }
+ void boost_minimap_texture(LLViewerFetchedTexture* tex, F32 virtual_size)
+ {
+ llassert(tex);
+ if (!tex) { return; }
-LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
- LLViewerLayer(width, scale),
- mParamsReady(FALSE)
-{
- mSurfacep = surfacep;
+ tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case the raw image is at low detail
+ tex->addTextureStats(virtual_size); // priority
+ }
- // Load Terrain Textures - Original ones
- setDetailTextureID(0, TERRAIN_DIRT_DETAIL);
- setDetailTextureID(1, TERRAIN_GRASS_DETAIL);
- setDetailTextureID(2, TERRAIN_MOUNTAIN_DETAIL);
- setDetailTextureID(3, TERRAIN_ROCK_DETAIL);
+ void boost_minimap_material(LLFetchedGLTFMaterial* mat, F32 virtual_size)
+ {
+ if (!mat) { return; }
+ if (mat->mBaseColorTexture) { boost_minimap_texture(mat->mBaseColorTexture, virtual_size); }
+ if (mat->mNormalTexture) { boost_minimap_texture(mat->mNormalTexture, virtual_size); }
+ if (mat->mMetallicRoughnessTexture) { boost_minimap_texture(mat->mMetallicRoughnessTexture, virtual_size); }
+ if (mat->mEmissiveTexture) { boost_minimap_texture(mat->mEmissiveTexture, virtual_size); }
+ }
- // Initialize the texture matrix to defaults.
- for (S32 i = 0; i < CORNER_COUNT; ++i)
+ void unboost_minimap_texture(LLViewerFetchedTexture* tex)
{
- mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
- mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
+ if (!tex) { return; }
+ tex->setBoostLevel(LLGLTexture::BOOST_NONE);
+ tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
}
- mTexScaleX = 16.f;
- mTexScaleY = 16.f;
- mTexturesLoaded = FALSE;
-}
+ void unboost_minimap_material(LLFetchedGLTFMaterial* mat)
+ {
+ if (!mat) { return; }
+ if (mat->mBaseColorTexture) { unboost_minimap_texture(mat->mBaseColorTexture); }
+ if (mat->mNormalTexture) { unboost_minimap_texture(mat->mNormalTexture); }
+ if (mat->mMetallicRoughnessTexture) { unboost_minimap_texture(mat->mMetallicRoughnessTexture); }
+ if (mat->mEmissiveTexture) { unboost_minimap_texture(mat->mEmissiveTexture); }
+ }
+};
-LLVLComposition::~LLVLComposition()
+LLTerrainMaterials::LLTerrainMaterials()
{
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
+ {
+ mMaterialTexturesSet[i] = false;
+ }
}
-
-void LLVLComposition::setSurface(LLSurface *surfacep)
+LLTerrainMaterials::~LLTerrainMaterials()
{
- mSurfacep = surfacep;
+ unboost();
}
-
-void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id)
+BOOL LLTerrainMaterials::generateMaterials()
{
- if(id.isNull())
+ if (texturesReady(true, true))
{
- return;
+ return TRUE;
}
- // This is terrain texture, but we are not setting it as BOOST_TERRAIN
- // since we will be manipulating it later as needed.
- mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
- mDetailTextures[corner]->setNoDelete() ;
- mRawImages[corner] = NULL;
-}
-BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
- const F32 width, const F32 height)
-{
- if (!mParamsReady)
+ if (materialsReady(true, true))
{
- // All the parameters haven't been set yet (we haven't gotten the message from the sim)
- return FALSE;
+ return TRUE;
}
- llassert(mSurfacep);
+ return FALSE;
+}
- if (!mSurfacep || !mSurfacep->getRegion())
+void LLTerrainMaterials::boost()
+{
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
{
- // We don't always have the region yet here....
- return FALSE;
- }
-
- S32 x_begin, y_begin, x_end, y_end;
+ LLPointer<LLViewerFetchedTexture>& tex = mDetailTextures[i];
+ llassert(tex.notNull());
+ boost_minimap_texture(tex, TERRAIN_DECODE_PRIORITY);
- x_begin = ll_round( x * mScaleInv );
- y_begin = ll_round( y * mScaleInv );
- x_end = ll_round( (x + width) * mScaleInv );
- y_end = ll_round( (y + width) * mScaleInv );
+ LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[i];
+ boost_minimap_material(mat, TERRAIN_DECODE_PRIORITY);
+ }
+}
- if (x_end > mWidth)
+void LLTerrainMaterials::unboost()
+{
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
{
- x_end = mWidth;
+ LLPointer<LLViewerFetchedTexture>& tex = mDetailTextures[i];
+ unboost_minimap_texture(tex);
+
+ LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[i];
+ unboost_minimap_material(mat);
}
- if (y_end > mWidth)
+}
+
+LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset)
+{
+ llassert(mDetailTextures[asset] && mDetailMaterials[asset]);
+ // Assume both the the material and texture were fetched in the same way
+ // using the same UUID. However, we may not know at this point which one
+ // will load.
+ return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null;
+}
+
+LLPointer<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
+{
+ if (id.isNull())
{
- y_end = mWidth;
+ return nullptr;
}
- LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
+ LLPointer<LLViewerFetchedTexture> tex = LLViewerTextureManager::getFetchedTexture(id);
+ return tex;
+}
- // For perlin noise generation...
- const F32 slope_squared = 1.5f*1.5f;
- const F32 xyScale = 4.9215f; //0.93284f;
- const F32 zScale = 4; //0.92165f;
- const F32 z_offset = 0.f;
- const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
- // simple height)
+void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id)
+{
+ // *NOTE: If there were multiple terrain swatches using the same asset
+ // ID, the asset still in use will be temporarily unboosted.
+ // It will be boosted again during terrain rendering.
+ unboost_minimap_texture(mDetailTextures[asset]);
+ unboost_minimap_material(mDetailMaterials[asset]);
+
+ // This is terrain texture, but we are not setting it as BOOST_TERRAIN
+ // since we will be manipulating it later as needed.
+ mDetailTextures[asset] = fetch_terrain_texture(id);
+ LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[asset];
+ mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id);
+ mMaterialTexturesSet[asset] = false;
+}
- // Heights map into textures as 0-1 = first, 1-2 = second, etc.
- // So we need to compress heights into this range.
- const S32 NUM_TEXTURES = 4;
+LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType()
+{
+ LL_PROFILE_ZONE_SCOPED;
- const F32 xyScaleInv = (1.f / xyScale);
- const F32 zScaleInv = (1.f / zScale);
+ const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false);
+ return use_textures ? Type::TEXTURE : Type::PBR;
+}
- const F32 inv_width = 1.f/mWidth;
+bool LLTerrainMaterials::texturesReady(bool boost, bool strict)
+{
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ ready[i] = mDetailTextures[i].notNull() && textureReady(mDetailTextures[i], boost);
+ }
- // OK, for now, just have the composition value equal the height at the point.
- for (S32 j = y_begin; j < y_end; j++)
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- for (S32 i = x_begin; i < x_end; i++)
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
{
-
- F32 vec[3];
- F32 vec1[3];
- F32 twiddle;
-
- // Bilinearly interpolate the start height and height range of the textures
- F32 start_height = bilinear(mStartHeight[SOUTHWEST],
- mStartHeight[SOUTHEAST],
- mStartHeight[NORTHWEST],
- mStartHeight[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
- F32 height_range = bilinear(mHeightRange[SOUTHWEST],
- mHeightRange[SOUTHEAST],
- mHeightRange[NORTHWEST],
- mHeightRange[NORTHEAST],
- i*inv_width, j*inv_width); // These will be bilinearly interpolated
-
- LLVector3 location(i*mScale, j*mScale, 0.f);
-
- F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
-
- // Step 0: Measure the exact height at this texel
- vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
- vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv;
- vec[2] = height*zScaleInv;
- //
- // Choose material value by adding to the exact height a random value
- //
- vec1[0] = vec[0]*(0.2222222222f);
- vec1[1] = vec[1]*(0.2222222222f);
- vec1[2] = vec[2]*(0.2222222222f);
- twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
-
- twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
- twiddle *= noise_magnitude;
-
- F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range;
-
- scaled_noisy_height = llmax(0.f, scaled_noisy_height);
- scaled_noisy_height = llmin(3.f, scaled_noisy_height);
- *(mDatap + i + j*mWidth) = scaled_noisy_height;
+ return false;
}
}
- return TRUE;
+ return one_ready;
}
-static const U32 BASE_SIZE = 128;
-
-BOOL LLVLComposition::generateComposition()
+bool LLTerrainMaterials::materialsReady(bool boost, bool strict)
{
-
- if (!mParamsReady)
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to materialReady may boost materials/textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- // All the parameters haven't been set yet (we haven't gotten the message from the sim)
- return FALSE;
+ ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict);
}
- for (S32 i = 0; i < 4; i++)
+#if 1
+ static LLCachedControl<bool> sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+ static LLCachedControl<bool> sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false);
+ if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce)
{
- if (mDetailTextures[i]->getDiscardLevel() < 0)
+ bool defined = true;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
{
- mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
- mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE);
- return FALSE;
- }
- if ((mDetailTextures[i]->getDiscardLevel() != 0 &&
- (mDetailTextures[i]->getWidth() < BASE_SIZE ||
- mDetailTextures[i]->getHeight() < BASE_SIZE)))
- {
- S32 width = mDetailTextures[i]->getFullWidth();
- S32 height = mDetailTextures[i]->getFullHeight();
- S32 min_dim = llmin(width, height);
- S32 ddiscard = 0;
- while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
+ if (!mDetailMaterials[i])
{
- ddiscard++;
- min_dim /= 2;
+ defined = false;
+ break;
}
- mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
- mDetailTextures[i]->setMinDiscardLevel(ddiscard);
- mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
- return FALSE;
+ }
+ if (defined)
+ {
+ return true;
}
}
+#endif
- return TRUE;
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
+ {
+ return false;
+ }
+ }
+ return one_ready;
}
-BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
- const F32 width, const F32 height)
+// Boost the texture loading priority
+// Return true when ready to use (i.e. texture is sufficiently loaded)
+// static
+bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost)
{
- LL_PROFILE_ZONE_SCOPED
- llassert(mSurfacep);
- llassert(x >= 0.f);
- llassert(y >= 0.f);
-
- LLTimer gen_timer;
-
- ///////////////////////////
- //
- // Generate raw data arrays for surface textures
- //
- //
+ llassert(tex);
+ if (!tex) { return false; }
- // These have already been validated by generateComposition.
- U8* st_data[4];
- S32 st_data_size[4]; // for debugging
-
- for (S32 i = 0; i < 4; i++)
+ if (tex->getDiscardLevel() < 0)
+ {
+ if (boost)
+ {
+ boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE);
+ }
+ return false;
+ }
+ if ((tex->getDiscardLevel() != 0 &&
+ (tex->getWidth() < BASE_SIZE ||
+ tex->getHeight() < BASE_SIZE)))
{
- if (mRawImages[i].isNull())
+ if (boost)
{
- // Read back a raw image for this discard level, if it exists
- S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight());
+ boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE);
+
+ S32 width = tex->getFullWidth();
+ S32 height = tex->getFullHeight();
+ S32 min_dim = llmin(width, height);
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
{
ddiscard++;
min_dim /= 2;
}
+ tex->setMinDiscardLevel(ddiscard);
+ }
+ return false;
+ }
+ if (tex->getComponents() == 0)
+ {
+ return false;
+ }
+ return true;
+}
- BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ;
- if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
- {
- if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
- {
- mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP);
- mDetailTextures[i]->forceToRefetchTexture(ddiscard);
- }
+// Boost the loading priority of every known texture in the material
+// Return true when ready to use
+// static
+bool LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial> &mat, bool &textures_set, bool boost, bool strict)
+{
+ if (!mat || !mat->isLoaded())
+ {
+ return false;
+ }
- if(delete_raw)
- {
- mDetailTextures[i]->destroyRawImage() ;
- }
- LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL;
- return FALSE;
- }
+ // Material is loaded, but textures may not be
+ if (!textures_set)
+ {
+ textures_set = true;
+ // *NOTE: These can sometimes be set to to nullptr due to
+ // updateTEMaterialTextures. For the sake of robustness, we emulate
+ // that fetching behavior by setting textures of null IDs to nullptr.
+ mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+ mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+ mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+ }
- mRawImages[i] = mDetailTextures[i]->getRawImage() ;
- if(delete_raw)
- {
- mDetailTextures[i]->destroyRawImage() ;
- }
- if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE ||
- mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE ||
- mDetailTextures[i]->getComponents() != 3)
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() ||
+ textureReady(mat->mMetallicRoughnessTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost);
+
+ if (strict)
+ {
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (!ready[i])
{
- LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
- newraw->composite(mRawImages[i]);
- mRawImages[i] = newraw; // deletes old
+ return false;
}
}
- st_data[i] = mRawImages[i]->getData();
- st_data_size[i] = mRawImages[i]->getDataSize();
}
- ///////////////////////////////////////
- //
- // Generate and clamp x/y bounding box.
- //
- //
-
- S32 x_begin, y_begin, x_end, y_end;
- x_begin = (S32)(x * mScaleInv);
- y_begin = (S32)(y * mScaleInv);
- x_end = ll_round( (x + width) * mScaleInv );
- y_end = ll_round( (y + width) * mScaleInv );
+ return true;
+}
- if (x_end > mWidth)
+// static
+const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT]
+{
+ const static LLUUID default_textures[LLVLComposition::ASSET_COUNT] =
{
- LL_WARNS("Terrain") << "x end > width" << LL_ENDL;
- x_end = mWidth;
- }
- if (y_end > mWidth)
+ TERRAIN_DIRT_DETAIL,
+ TERRAIN_GRASS_DETAIL,
+ TERRAIN_MOUNTAIN_DETAIL,
+ TERRAIN_ROCK_DETAIL
+ };
+ return default_textures;
+}
+
+LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) :
+ LLTerrainMaterials(),
+ LLViewerLayer(width, scale)
+{
+ // Load Terrain Textures - Original ones
+ const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures();
+ for (S32 i = 0; i < ASSET_COUNT; ++i)
{
- LL_WARNS("Terrain") << "y end > width" << LL_ENDL;
- y_end = mWidth;
+ setDetailAssetID(i, default_textures[i]);
}
+ mSurfacep = surfacep;
- ///////////////////////////////////////////
- //
- // Generate target texture information, stride ratios.
- //
- //
+ // Initialize the texture matrix to defaults.
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight");
+ mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange");
+ }
+}
+
+
+LLVLComposition::~LLVLComposition()
+{
+ LLTerrainMaterials::~LLTerrainMaterials();
+}
- LLViewerTexture *texturep;
- U32 tex_width, tex_height, tex_comps;
- U32 tex_stride;
- F32 tex_x_scalef, tex_y_scalef;
- S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
- F32 tex_x_ratiof, tex_y_ratiof;
- texturep = mSurfacep->getSTexture();
- tex_width = texturep->getWidth();
- tex_height = texturep->getHeight();
- tex_comps = texturep->getComponents();
- tex_stride = tex_width * tex_comps;
+void LLVLComposition::setSurface(LLSurface *surfacep)
+{
+ mSurfacep = surfacep;
+}
- U32 st_comps = 3;
- U32 st_width = BASE_SIZE;
- U32 st_height = BASE_SIZE;
+BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
+ const F32 width, const F32 height)
+{
+ if (!mParamsReady)
+ {
+ // All the parameters haven't been set yet (we haven't gotten the message from the sim)
+ return FALSE;
+ }
+
+ llassert(mSurfacep);
+
+ if (!mSurfacep || !mSurfacep->getRegion())
+ {
+ // We don't always have the region yet here....
+ return FALSE;
+ }
+
+ S32 x_begin, y_begin, x_end, y_end;
+
+ x_begin = ll_round( x * mScaleInv );
+ y_begin = ll_round( y * mScaleInv );
+ x_end = ll_round( (x + width) * mScaleInv );
+ y_end = ll_round( (y + width) * mScaleInv );
+
+ if (x_end > mWidth)
+ {
+ x_end = mWidth;
+ }
+ if (y_end > mWidth)
+ {
+ y_end = mWidth;
+ }
+
+ LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle());
+
+ // For perlin noise generation...
+ const F32 slope_squared = 1.5f*1.5f;
+ const F32 xyScale = 4.9215f; //0.93284f;
+ const F32 zScale = 4; //0.92165f;
+ const F32 z_offset = 0.f;
+ const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
+ // simple height)
+
+ const F32 xyScaleInv = (1.f / xyScale);
+ const F32 zScaleInv = (1.f / zScale);
+
+ const F32 inv_width = 1.f/mWidth;
+
+ // OK, for now, just have the composition value equal the height at the point.
+ for (S32 j = y_begin; j < y_end; j++)
+ {
+ for (S32 i = x_begin; i < x_end; i++)
+ {
+
+ F32 vec[3];
+ F32 vec1[3];
+ F32 twiddle;
+
+ // Bilinearly interpolate the start height and height range of the textures
+ F32 start_height = bilinear(mStartHeight[SOUTHWEST],
+ mStartHeight[SOUTHEAST],
+ mStartHeight[NORTHWEST],
+ mStartHeight[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+ F32 height_range = bilinear(mHeightRange[SOUTHWEST],
+ mHeightRange[SOUTHEAST],
+ mHeightRange[NORTHWEST],
+ mHeightRange[NORTHEAST],
+ i*inv_width, j*inv_width); // These will be bilinearly interpolated
+
+ LLVector3 location(i*mScale, j*mScale, 0.f);
+
+ F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
+
+ // Step 0: Measure the exact height at this texel
+ vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
+ vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv;
+ vec[2] = height*zScaleInv;
+ //
+ // Choose material value by adding to the exact height a random value
+ //
+ vec1[0] = vec[0]*(0.2222222222f);
+ vec1[1] = vec[1]*(0.2222222222f);
+ vec1[2] = vec[2]*(0.2222222222f);
+ twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
+
+ twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component
+ twiddle *= noise_magnitude;
+
+ F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range;
+
+ scaled_noisy_height = llmax(0.f, scaled_noisy_height);
+ scaled_noisy_height = llmin(3.f, scaled_noisy_height);
+ *(mDatap + i + j*mWidth) = scaled_noisy_height;
+ }
+ }
+ return TRUE;
+}
- if (tex_comps != st_comps)
+LLTerrainMaterials gLocalTerrainMaterials;
+
+BOOL LLVLComposition::generateComposition()
+{
+ if (!mParamsReady)
+ {
+ // All the parameters haven't been set yet (we haven't gotten the message from the sim)
+ return FALSE;
+ }
+
+ return LLTerrainMaterials::generateMaterials();
+}
+
+namespace
+{
+ void prepare_fallback_image(LLImageRaw* raw_image)
{
- LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL;
- return FALSE;
+ raw_image->resize(BASE_SIZE, BASE_SIZE, 4);
+ raw_image->fill(LLColor4U::white);
}
- tex_x_scalef = (F32)tex_width / (F32)mWidth;
- tex_y_scalef = (F32)tex_height / (F32)mWidth;
- tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
- tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
- tex_x_end = (S32)((F32)x_end * tex_x_scalef);
- tex_y_end = (S32)((F32)y_end * tex_y_scalef);
-
- tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
- tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;
-
- LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
- U8 *rawp = raw->getData();
-
- F32 st_x_stride, st_y_stride;
- st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
- st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
-
- llassert(st_x_stride > 0.f);
- llassert(st_y_stride > 0.f);
- ////////////////////////////////
- //
- // Iterate through the target texture, striding through the
- // subtextures and interpolating appropriately.
- //
- //
-
- F32 sti, stj;
- S32 st_offset;
- sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
- stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));
-
- st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
- for (S32 j = tex_y_begin; j < tex_y_end; j++)
+ // Check if the raw image is loaded for this texture at a discard
+ // level the minimap can use, and if not then try to get it loaded.
+ bool prepare_raw_image(LLPointer<LLImageRaw>& raw_image, bool emissive, LLViewerFetchedTexture* tex, bool& delete_raw_post)
{
- U32 offset = j * tex_stride + tex_x_begin * tex_comps;
- sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
- for (S32 i = tex_x_begin; i < tex_x_end; i++)
+ if (!tex)
{
- S32 tex0, tex1;
- F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);
+ if (!emissive)
+ {
+ prepare_fallback_image(raw_image);
+ }
+ else
+ {
+ llassert(!raw_image);
+ raw_image = nullptr;
+ }
+ return true;
+ }
+ if (raw_image)
+ {
+ // Callback already initiated
+ if (raw_image->getDataSize() > 0)
+ {
+ // Callback finished
+ delete_raw_post = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
- tex0 = llfloor( composition );
- tex0 = llclamp(tex0, 0, 3);
- composition -= tex0;
- tex1 = tex0 + 1;
- tex1 = llclamp(tex1, 0, 3);
+ raw_image = new LLImageRaw();
+
+ S32 ddiscard = 0;
+ {
+ S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight());
+ while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
+ {
+ ddiscard++;
+ min_dim /= 2;
+ }
+ }
- st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
- for (U32 k = 0; k < tex_comps; k++)
+ struct PendingImage
+ {
+ LLImageRaw* mRawImage;
+ S32 mDesiredDiscard;
+ LLUUID mTextureId;
+ PendingImage(LLImageRaw* raw_image, S32 ddiscard, const LLUUID& texture_id)
+ : mRawImage(raw_image)
+ , mDesiredDiscard(ddiscard)
+ , mTextureId(texture_id)
+ {
+ mRawImage->ref();
+ }
+ ~PendingImage()
{
- // Linearly interpolate based on composition.
- if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
+ mRawImage->unref();
+ }
+ };
+ PendingImage* pending_image = new PendingImage(raw_image, ddiscard, tex->getID());
+
+ loaded_callback_func cb = [](BOOL success, LLViewerFetchedTexture * src_vi, LLImageRaw * src, LLImageRaw * src_aux, S32 discard_level, BOOL is_final, void* userdata) {
+ PendingImage* pending = (PendingImage*)userdata;
+ // Owning LLVLComposition still exists
+
+ // Assume mRawImage only used by single LLVLComposition for now
+ const bool in_use_by_composition = pending->mRawImage->getNumRefs() > 1;
+ llassert(pending->mRawImage->getNumRefs());
+ llassert(pending->mRawImage->getNumRefs() <= 2);
+ const bool needs_data = !pending->mRawImage->getDataSize();
+ if (in_use_by_composition && needs_data)
+ {
+ if (success && pending->mDesiredDiscard == discard_level)
{
- // SJB: This shouldn't be happening, but does... Rounding error?
- //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL;
- //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL;
+ pending->mRawImage->resize(BASE_SIZE, BASE_SIZE, src->getComponents());
+ pending->mRawImage->copyScaled(src);
}
- else
+ else if (is_final)
{
- F32 a = *(st_data[tex0] + st_offset);
- F32 b = *(st_data[tex1] + st_offset);
- rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
+ prepare_fallback_image(pending->mRawImage);
}
- offset++;
- st_offset++;
}
- sti += st_x_stride;
- if (sti >= st_width)
- {
- sti -= st_width;
- }
- }
+ if (is_final) { delete pending; }
+ };
+ tex->setLoadedCallback(cb, ddiscard, true, false, pending_image, nullptr);
+ tex->forceToSaveRawImage(ddiscard);
- stj += st_y_stride;
- if (stj >= st_height)
- {
- stj -= st_height;
- }
+ return false;
}
+};
- if (!texturep->hasGLTexture())
+BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
+ const F32 width, const F32 height)
+{
+ LL_PROFILE_ZONE_SCOPED
+ llassert(mSurfacep);
+ llassert(x >= 0.f);
+ llassert(y >= 0.f);
+
+ ///////////////////////////
+ //
+ // Generate raw data arrays for surface textures
+ //
+ //
+
+ // These have already been validated by generateComposition.
+ U8* st_data[ASSET_COUNT];
+ S32 st_data_size[ASSET_COUNT]; // for debugging
+
+ const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
+ if (use_textures)
{
- texturep->createGLTexture(0, raw);
+ if (!texturesReady(true, true)) { return FALSE; }
}
- texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
-
- for (S32 i = 0; i < 4; i++)
+ else
{
- // Un-boost detatil textures (will get re-boosted if rendering in high detail)
- mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE);
- mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
+ if (!materialsReady(true, true)) { return FALSE; }
}
- return TRUE;
-}
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ if (mRawImages[i].isNull())
+ {
+ // Read back a raw image for this discard level, if it exists
+ LLViewerFetchedTexture* tex;
+ LLViewerFetchedTexture* tex_emissive; // Can be null
+ bool has_base_color_factor;
+ bool has_emissive_factor;
+ bool has_alpha;
+ LLColor3 base_color_factor;
+ LLColor3 emissive_factor;
+ if (use_textures)
+ {
+ tex = mDetailTextures[i];
+ tex_emissive = nullptr;
+ has_base_color_factor = false;
+ has_emissive_factor = false;
+ has_alpha = false;
+ llassert(tex);
+ }
+ else
+ {
+ tex = mDetailMaterials[i]->mBaseColorTexture;
+ tex_emissive = mDetailMaterials[i]->mEmissiveTexture;
+ base_color_factor = LLColor3(mDetailMaterials[i]->mBaseColor);
+ // *HACK: Treat alpha as black
+ base_color_factor *= (mDetailMaterials[i]->mBaseColor.mV[VW]);
+ emissive_factor = mDetailMaterials[i]->mEmissiveColor;
+ has_base_color_factor = (base_color_factor.mV[VX] != 1.f ||
+ base_color_factor.mV[VY] != 1.f ||
+ base_color_factor.mV[VZ] != 1.f);
+ has_emissive_factor = (emissive_factor.mV[VX] != 1.f ||
+ emissive_factor.mV[VY] != 1.f ||
+ emissive_factor.mV[VZ] != 1.f);
+ has_alpha = mDetailMaterials[i]->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE;
+ }
-LLUUID LLVLComposition::getDetailTextureID(S32 corner)
-{
- return mDetailTextures[corner]->getID();
+ if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; }
+
+ bool delete_raw_post = false;
+ bool delete_raw_post_emissive = false;
+ if (!prepare_raw_image(mRawImagesBaseColor[i], false, tex, delete_raw_post)) { return FALSE; }
+ if (tex_emissive && !prepare_raw_image(mRawImagesEmissive[i], true, tex_emissive, delete_raw_post_emissive)) { return FALSE; }
+ // tex_emissive can be null, and then will be ignored
+
+ // In the simplest case, the minimap image is just the base color.
+ // This will be replaced if we need to do any tinting/compositing.
+ mRawImages[i] = mRawImagesBaseColor[i];
+
+ // *TODO: This isn't quite right for PBR:
+ // 1) It does not convert the color images from SRGB to linear
+ // before mixing (which will always require copying the image).
+ // 2) It mixes emissive and base color before mixing terrain
+ // materials, but it should be the other way around
+ // Long-term, we should consider a method that is more
+ // maintainable. Shaders, perhaps? Bake shaders to textures?
+ LLPointer<LLImageRaw> raw_emissive;
+ if (tex_emissive)
+ {
+ raw_emissive = mRawImagesEmissive[i];
+ if (has_emissive_factor ||
+ tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
+ tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE ||
+ tex_emissive->getComponents() != 4)
+ {
+ LLPointer<LLImageRaw> newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4);
+ // Copy RGB, leave alpha alone (set to opaque by default)
+ newraw_emissive->copy(mRawImagesEmissive[i]);
+ if (has_emissive_factor)
+ {
+ newraw_emissive->tint(emissive_factor);
+ }
+ raw_emissive = newraw_emissive;
+ }
+ }
+ if (has_base_color_factor ||
+ raw_emissive ||
+ has_alpha ||
+ tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE ||
+ tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE ||
+ tex->getComponents() != 3)
+ {
+ LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
+ if (has_alpha)
+ {
+ // Approximate the water underneath terrain alpha with solid water color
+ newraw->clear(
+ MAX_WATER_COLOR.mV[VX],
+ MAX_WATER_COLOR.mV[VY],
+ MAX_WATER_COLOR.mV[VZ],
+ 255);
+ }
+ newraw->composite(mRawImagesBaseColor[i]);
+ if (has_base_color_factor)
+ {
+ newraw->tint(base_color_factor);
+ }
+ // Apply emissive texture
+ if (raw_emissive)
+ {
+ newraw->addEmissive(raw_emissive);
+ }
+
+ mRawImages[i] = newraw; // deletes old
+ }
+
+ if (delete_raw_post)
+ {
+ tex->destroyRawImage();
+ }
+ if (delete_raw_post_emissive)
+ {
+ tex_emissive->destroyRawImage();
+ }
+
+ // Remove intermediary image references
+ mRawImagesBaseColor[i] = nullptr;
+ mRawImagesEmissive[i] = nullptr;
+ }
+ st_data[i] = mRawImages[i]->getData();
+ st_data_size[i] = mRawImages[i]->getDataSize();
+ }
+
+ ///////////////////////////////////////
+ //
+ // Generate and clamp x/y bounding box.
+ //
+ //
+
+ S32 x_begin, y_begin, x_end, y_end;
+ x_begin = (S32)(x * mScaleInv);
+ y_begin = (S32)(y * mScaleInv);
+ x_end = ll_round( (x + width) * mScaleInv );
+ y_end = ll_round( (y + width) * mScaleInv );
+
+ if (x_end > mWidth)
+ {
+ llassert(false);
+ x_end = mWidth;
+ }
+ if (y_end > mWidth)
+ {
+ llassert(false);
+ y_end = mWidth;
+ }
+
+
+ ///////////////////////////////////////////
+ //
+ // Generate target texture information, stride ratios.
+ //
+ //
+
+ LLViewerTexture *texturep;
+ U32 tex_width, tex_height, tex_comps;
+ U32 tex_stride;
+ F32 tex_x_scalef, tex_y_scalef;
+ S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
+ F32 tex_x_ratiof, tex_y_ratiof;
+
+ texturep = mSurfacep->getSTexture();
+ tex_width = texturep->getWidth();
+ tex_height = texturep->getHeight();
+ tex_comps = texturep->getComponents();
+ tex_stride = tex_width * tex_comps;
+
+ U32 st_comps = 3;
+ U32 st_width = BASE_SIZE;
+ U32 st_height = BASE_SIZE;
+
+ if (tex_comps != st_comps)
+ {
+ llassert(false);
+ return FALSE;
+ }
+
+ tex_x_scalef = (F32)tex_width / (F32)mWidth;
+ tex_y_scalef = (F32)tex_height / (F32)mWidth;
+ tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
+ tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
+ tex_x_end = (S32)((F32)x_end * tex_x_scalef);
+ tex_y_end = (S32)((F32)y_end * tex_y_scalef);
+
+ tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
+ tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
+ U8 *rawp = raw->getData();
+
+ F32 st_x_stride, st_y_stride;
+ st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
+ st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
+
+ llassert(st_x_stride > 0.f);
+ llassert(st_y_stride > 0.f);
+ ////////////////////////////////
+ //
+ // Iterate through the target texture, striding through the
+ // subtextures and interpolating appropriately.
+ //
+ //
+
+ F32 sti, stj;
+ S32 st_offset;
+ sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
+ stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));
+
+ st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
+ for (S32 j = tex_y_begin; j < tex_y_end; j++)
+ {
+ U32 offset = j * tex_stride + tex_x_begin * tex_comps;
+ sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
+ for (S32 i = tex_x_begin; i < tex_x_end; i++)
+ {
+ S32 tex0, tex1;
+ F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);
+
+ tex0 = llfloor( composition );
+ tex0 = llclamp(tex0, 0, 3);
+ composition -= tex0;
+ tex1 = tex0 + 1;
+ tex1 = llclamp(tex1, 0, 3);
+
+ st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
+ for (U32 k = 0; k < tex_comps; k++)
+ {
+ // Linearly interpolate based on composition.
+ if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
+ {
+ // SJB: This shouldn't be happening, but does... Rounding error?
+ //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL;
+ //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL;
+ }
+ else
+ {
+ F32 a = *(st_data[tex0] + st_offset);
+ F32 b = *(st_data[tex1] + st_offset);
+ rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
+ }
+ offset++;
+ st_offset++;
+ }
+
+ sti += st_x_stride;
+ if (sti >= st_width)
+ {
+ sti -= st_width;
+ }
+ }
+
+ stj += st_y_stride;
+ if (stj >= st_height)
+ {
+ stj -= st_height;
+ }
+ }
+
+ if (!texturep->hasGLTexture())
+ {
+ texturep->createGLTexture(0, raw);
+ }
+ texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
+
+ // Un-boost detail textures (will get re-boosted if rendering in high detail)
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ unboost_minimap_texture(mDetailTextures[i]);
+ }
+
+ // Un-boost textures for each detail material (will get re-boosted if rendering in high detail)
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ unboost_minimap_material(mDetailMaterials[i]);
+ }
+
+ return TRUE;
}
-LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner)
+F32 LLVLComposition::getStartHeight(S32 corner)
{
- return mDetailTextures[corner];
+ return mStartHeight[corner];
}
-F32 LLVLComposition::getStartHeight(S32 corner)
+void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id)
{
- return mStartHeight[corner];
+ if (id.isNull())
+ {
+ return;
+ }
+ LLTerrainMaterials::setDetailAssetID(asset, id);
+ mRawImages[asset] = NULL;
+ mRawImagesBaseColor[asset] = NULL;
+ mRawImagesEmissive[asset] = NULL;
}
void LLVLComposition::setStartHeight(S32 corner, const F32 start_height)
{
- mStartHeight[corner] = start_height;
+ mStartHeight[corner] = start_height;
}
F32 LLVLComposition::getHeightRange(S32 corner)
{
- return mHeightRange[corner];
+ return mHeightRange[corner];
}
void LLVLComposition::setHeightRange(S32 corner, const F32 range)
{
- mHeightRange[corner] = range;
+ mHeightRange[corner] = range;
}
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index cbea18b062..5db832e034 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvlcomposition.h
* @brief Viewer-side representation of a composition layer...
*
* $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$
*/
@@ -28,59 +28,120 @@
#define LL_LLVLCOMPOSITION_H
#include "llviewerlayer.h"
-#include "llviewertexture.h"
+#include "llpointer.h"
+
+#include "llimage.h"
class LLSurface;
-class LLVLComposition : public LLViewerLayer
+class LLViewerFetchedTexture;
+class LLFetchedGLTFMaterial;
+
+class LLTerrainMaterials
{
public:
- LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale);
- /*virtual*/ ~LLVLComposition();
+ friend class LLDrawPoolTerrain;
- void setSurface(LLSurface *surfacep);
+ LLTerrainMaterials();
+ virtual ~LLTerrainMaterials();
- // Viewer side hack to generate composition values
- BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height);
- BOOL generateComposition();
- // Generate texture from composition values.
- BOOL generateTexture(const F32 x, const F32 y, const F32 width, const F32 height);
+ // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc.
+ // So we need to compress heights into this range.
+ static const S32 ASSET_COUNT = 4;
- // Use these as indeces ito the get/setters below that use 'corner'
- enum ECorner
+ enum class Type
{
- SOUTHWEST = 0,
- SOUTHEAST = 1,
- NORTHWEST = 2,
- NORTHEAST = 3,
- CORNER_COUNT = 4
+ TEXTURE,
+ PBR,
+ COUNT
};
- LLUUID getDetailTextureID(S32 corner);
- LLViewerFetchedTexture* getDetailTexture(S32 corner);
- F32 getStartHeight(S32 corner);
- F32 getHeightRange(S32 corner);
-
- void setDetailTextureID(S32 corner, const LLUUID& id);
- void setStartHeight(S32 corner, F32 start_height);
- void setHeightRange(S32 corner, F32 range);
-
- friend class LLVOSurfacePatch;
- friend class LLDrawPoolTerrain;
- void setParamsReady() { mParamsReady = TRUE; }
- BOOL getParamsReady() const { return mParamsReady; }
+
+ BOOL generateMaterials();
+
+ void boost();
+
+ virtual LLUUID getDetailAssetID(S32 asset);
+ virtual void setDetailAssetID(S32 asset, const LLUUID& id);
+ Type getMaterialType();
+ bool texturesReady(bool boost, bool strict);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ bool materialsReady(bool boost, bool strict);
+
+protected:
+ void unboost();
+ static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict);
+ LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
+ LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
+ bool mMaterialTexturesSet[ASSET_COUNT];
+};
+
+// Local materials to override all regions
+extern LLTerrainMaterials gLocalTerrainMaterials;
+
+class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer
+{
+public:
+ // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc.
+ // So we need to compress heights into this range.
+ static const S32 ASSET_COUNT = 4;
+ static const LLUUID (&getDefaultTextures())[ASSET_COUNT];
+
+ LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale);
+ /*virtual*/ ~LLVLComposition();
+
+ void setSurface(LLSurface *surfacep);
+
+ // Viewer side hack to generate composition values
+ BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height);
+ BOOL generateComposition();
+ // Generate texture from composition values.
+ BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height);
+
+ // Use these as indeces ito the get/setters below that use 'corner'
+ enum ECorner
+ {
+ SOUTHWEST = 0,
+ SOUTHEAST = 1,
+ NORTHWEST = 2,
+ NORTHEAST = 3,
+ CORNER_COUNT = 4
+ };
+
+ void setDetailAssetID(S32 asset, const LLUUID& id) override;
+ F32 getStartHeight(S32 corner);
+ F32 getHeightRange(S32 corner);
+
+ void setStartHeight(S32 corner, F32 start_height);
+ void setHeightRange(S32 corner, F32 range);
+
+ friend class LLVOSurfacePatch;
+ friend class LLDrawPoolTerrain;
+ void setParamsReady() { mParamsReady = TRUE; }
+ BOOL getParamsReady() const { return mParamsReady; }
+
protected:
- BOOL mParamsReady;
- LLSurface *mSurfacep;
- BOOL mTexturesLoaded;
+ static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost = false);
+ static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost = false);
+
+ BOOL mParamsReady = FALSE;
+ LLSurface *mSurfacep;
+
+ // Final minimap raw images
+ LLPointer<LLImageRaw> mRawImages[LLTerrainMaterials::ASSET_COUNT];
- LLPointer<LLViewerFetchedTexture> mDetailTextures[CORNER_COUNT];
- LLPointer<LLImageRaw> mRawImages[CORNER_COUNT];
+ // Only non-null during minimap tile generation
+ LLPointer<LLImageRaw> mRawImagesBaseColor[LLTerrainMaterials::ASSET_COUNT];
+ LLPointer<LLImageRaw> mRawImagesEmissive[LLTerrainMaterials::ASSET_COUNT];
- F32 mStartHeight[CORNER_COUNT];
- F32 mHeightRange[CORNER_COUNT];
+ F32 mStartHeight[CORNER_COUNT];
+ F32 mHeightRange[CORNER_COUNT];
- F32 mTexScaleX;
- F32 mTexScaleY;
+ F32 mTexScaleX = 16.f;
+ F32 mTexScaleY = 16.f;
};
#endif //LL_LLVLCOMPOSITION_H
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 71dcd03d04..d8ac3613bc 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5,21 +5,21 @@
* $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$
*/
@@ -49,7 +49,7 @@
#include "llexperiencecache.h"
#include "llphysicsmotion.h"
#include "llviewercontrol.h"
-#include "llcallingcard.h" // IDEVO for LLAvatarTracker
+#include "llcallingcard.h" // IDEVO for LLAvatarTracker
#include "lldrawpoolavatar.h"
#include "lldriverparam.h"
#include "llpolyskeletaldistortion.h"
@@ -60,7 +60,7 @@
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llhudnametag.h"
-#include "llhudtext.h" // for mText/mDebugText
+#include "llhudtext.h" // for mText/mDebugText
#include "llimview.h"
#include "llinitparam.h"
#include "llkeyframefallmotion.h"
@@ -141,30 +141,30 @@ using namespace LLAvatarAppearanceDefines;
// Global constants
//-----------------------------------------------------------------------------
const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise"
-const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot"
-const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing"
-const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye"
+const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot"
+const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing"
+const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye"
const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust"
-const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion"
+const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion"
const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot"
const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix"
const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target"
-const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust"
+const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust"
const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion"
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
-const F32 DELTA_TIME_MIN = 0.01f; // we clamp measured delta_time to this
-const F32 DELTA_TIME_MAX = 0.2f; // range to insure stability of computations.
+const F32 DELTA_TIME_MIN = 0.01f; // we clamp measured delta_time to this
+const F32 DELTA_TIME_MAX = 0.2f; // range to insure stability of computations.
-const F32 PELVIS_LAG_FLYING = 0.22f;// pelvis follow half life while flying
-const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking
+const F32 PELVIS_LAG_FLYING = 0.22f;// pelvis follow half life while flying
+const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking
const F32 PELVIS_LAG_MOUSELOOK = 0.15f;
const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f;
-const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees
-const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise.
+const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees
+const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise.
const F32 BREATHE_ROT_MOTION_STRENGTH = 0.05f;
@@ -211,9 +211,9 @@ const S32 MIN_NONTUNED_AVS = 5;
enum ERenderName
{
- RENDER_NAME_NEVER,
- RENDER_NAME_ALWAYS,
- RENDER_NAME_FADE
+ RENDER_NAME_NEVER,
+ RENDER_NAME_ALWAYS,
+ RENDER_NAME_FADE
};
#define JELLYDOLLS_SHOULD_IMPOSTOR
@@ -224,12 +224,12 @@ enum ERenderName
struct LLTextureMaskData
{
- LLTextureMaskData( const LLUUID& id ) :
- mAvatarID(id),
- mLastDiscardLevel(S32_MAX)
- {}
- LLUUID mAvatarID;
- S32 mLastDiscardLevel;
+ LLTextureMaskData( const LLUUID& id ) :
+ mAvatarID(id),
+ mLastDiscardLevel(S32_MAX)
+ {}
+ LLUUID mAvatarID;
+ S32 mLastDiscardLevel;
};
/*********************************************************************************
@@ -241,22 +241,22 @@ struct LLTextureMaskData
struct LLAppearanceMessageContents: public LLRefCount
{
- LLAppearanceMessageContents():
- mAppearanceVersion(-1),
- mParamAppearanceVersion(-1),
- mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
- {
- }
- LLTEContents mTEContents;
- S32 mAppearanceVersion;
- S32 mParamAppearanceVersion;
- S32 mCOFVersion;
- // For future use:
- //U32 appearance_flags = 0;
- std::vector<F32> mParamWeights;
- std::vector<LLVisualParam*> mParams;
- LLVector3 mHoverOffset;
- bool mHoverOffsetWasSet;
+ LLAppearanceMessageContents():
+ mAppearanceVersion(-1),
+ mParamAppearanceVersion(-1),
+ mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
+ {
+ }
+ LLTEContents mTEContents;
+ S32 mAppearanceVersion;
+ S32 mParamAppearanceVersion;
+ S32 mCOFVersion;
+ // For future use:
+ //U32 appearance_flags = 0;
+ std::vector<F32> mParamWeights;
+ std::vector<LLVisualParam*> mParams;
+ LLVector3 mHoverOffset;
+ bool mHoverOffsetWasSet;
};
@@ -264,317 +264,317 @@ struct LLAppearanceMessageContents: public LLRefCount
// class LLBodyNoiseMotion
//-----------------------------------------------------------------------------
class LLBodyNoiseMotion :
- public LLMotion
+ public LLMotion
{
public:
- // Constructor
- LLBodyNoiseMotion(const LLUUID &id)
- : LLMotion(id)
- {
- mName = "body_noise";
- mTorsoState = new LLJointState;
- }
+ // Constructor
+ LLBodyNoiseMotion(const LLUUID &id)
+ : LLMotion(id)
+ {
+ mName = "body_noise";
+ mTorsoState = new LLJointState;
+ }
- // Destructor
- virtual ~LLBodyNoiseMotion() { }
+ // Destructor
+ virtual ~LLBodyNoiseMotion() { }
public:
- //-------------------------------------------------------------------------
- // functions to support MotionController and MotionRegistry
- //-------------------------------------------------------------------------
- // static constructor
- // all subclasses must implement such a function and register it
- static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); }
+ //-------------------------------------------------------------------------
+ // functions to support MotionController and MotionRegistry
+ //-------------------------------------------------------------------------
+ // static constructor
+ // all subclasses must implement such a function and register it
+ static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); }
public:
- //-------------------------------------------------------------------------
- // animation callbacks to be implemented by subclasses
- //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ // animation callbacks to be implemented by subclasses
+ //-------------------------------------------------------------------------
- // motions must specify whether or not they loop
- virtual BOOL getLoop() { return TRUE; }
+ // motions must specify whether or not they loop
+ virtual BOOL getLoop() { return TRUE; }
- // motions must report their total duration
- virtual F32 getDuration() { return 0.0; }
+ // motions must report their total duration
+ virtual F32 getDuration() { return 0.0; }
- // motions must report their "ease in" duration
- virtual F32 getEaseInDuration() { return 0.0; }
+ // motions must report their "ease in" duration
+ virtual F32 getEaseInDuration() { return 0.0; }
- // motions must report their "ease out" duration.
- virtual F32 getEaseOutDuration() { return 0.0; }
+ // motions must report their "ease out" duration.
+ virtual F32 getEaseOutDuration() { return 0.0; }
- // motions must report their priority
- virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; }
+ // motions must report their priority
+ virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; }
- virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; }
+ virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; }
- // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
- virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; }
+ // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
+ virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; }
- // run-time (post constructor) initialization,
- // called after parameters have been set
- // must return true to indicate success and be available for activation
- virtual LLMotionInitStatus onInitialize(LLCharacter *character)
- {
- if( !mTorsoState->setJoint( character->getJoint("mTorso") ))
- {
- return STATUS_FAILURE;
- }
+ // run-time (post constructor) initialization,
+ // called after parameters have been set
+ // must return true to indicate success and be available for activation
+ virtual LLMotionInitStatus onInitialize(LLCharacter *character)
+ {
+ if( !mTorsoState->setJoint( character->getJoint("mTorso") ))
+ {
+ return STATUS_FAILURE;
+ }
- mTorsoState->setUsage(LLJointState::ROT);
+ mTorsoState->setUsage(LLJointState::ROT);
- addJointState( mTorsoState );
- return STATUS_SUCCESS;
- }
+ addJointState( mTorsoState );
+ return STATUS_SUCCESS;
+ }
- // called when a motion is activated
- // must return TRUE to indicate success, or else
- // it will be deactivated
- virtual BOOL onActivate() { return TRUE; }
+ // called when a motion is activated
+ // must return TRUE to indicate success, or else
+ // it will be deactivated
+ virtual BOOL onActivate() { return TRUE; }
- // called per time step
- // must return TRUE while it is active, and
- // must return FALSE when the motion is completed.
- virtual BOOL onUpdate(F32 time, U8* joint_mask)
- {
+ // called per time step
+ // must return TRUE while it is active, and
+ // must return FALSE when the motion is completed.
+ virtual BOOL onUpdate(F32 time, U8* joint_mask)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- F32 nx[2];
- nx[0]=time*TORSO_NOISE_SPEED;
- nx[1]=0.0f;
- F32 ny[2];
- ny[0]=0.0f;
- ny[1]=time*TORSO_NOISE_SPEED;
- F32 noiseX = noise2(nx);
- F32 noiseY = noise2(ny);
-
- F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f;
- F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f;
- LLQuaternion tQn;
- tQn.setQuat( rx, ry, 0.0f );
- mTorsoState->setRotation( tQn );
-
- return TRUE;
- }
-
- // called when a motion is deactivated
- virtual void onDeactivate() {}
+ F32 nx[2];
+ nx[0]=time*TORSO_NOISE_SPEED;
+ nx[1]=0.0f;
+ F32 ny[2];
+ ny[0]=0.0f;
+ ny[1]=time*TORSO_NOISE_SPEED;
+ F32 noiseX = noise2(nx);
+ F32 noiseY = noise2(ny);
+
+ F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f;
+ F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f;
+ LLQuaternion tQn;
+ tQn.setQuat( rx, ry, 0.0f );
+ mTorsoState->setRotation( tQn );
+
+ return TRUE;
+ }
+
+ // called when a motion is deactivated
+ virtual void onDeactivate() {}
private:
- //-------------------------------------------------------------------------
- // joint states to be animated
- //-------------------------------------------------------------------------
- LLPointer<LLJointState> mTorsoState;
+ //-------------------------------------------------------------------------
+ // joint states to be animated
+ //-------------------------------------------------------------------------
+ LLPointer<LLJointState> mTorsoState;
};
//-----------------------------------------------------------------------------
// class LLBreatheMotionRot
//-----------------------------------------------------------------------------
class LLBreatheMotionRot :
- public LLMotion
+ public LLMotion
{
public:
- // Constructor
- LLBreatheMotionRot(const LLUUID &id) :
- LLMotion(id),
- mBreatheRate(1.f),
- mCharacter(NULL)
- {
- mName = "breathe_rot";
- mChestState = new LLJointState;
- }
-
- // Destructor
- virtual ~LLBreatheMotionRot() {}
+ // Constructor
+ LLBreatheMotionRot(const LLUUID &id) :
+ LLMotion(id),
+ mBreatheRate(1.f),
+ mCharacter(NULL)
+ {
+ mName = "breathe_rot";
+ mChestState = new LLJointState;
+ }
+
+ // Destructor
+ virtual ~LLBreatheMotionRot() {}
public:
- //-------------------------------------------------------------------------
- // functions to support MotionController and MotionRegistry
- //-------------------------------------------------------------------------
- // static constructor
- // all subclasses must implement such a function and register it
- static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); }
+ //-------------------------------------------------------------------------
+ // functions to support MotionController and MotionRegistry
+ //-------------------------------------------------------------------------
+ // static constructor
+ // all subclasses must implement such a function and register it
+ static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); }
public:
- //-------------------------------------------------------------------------
- // animation callbacks to be implemented by subclasses
- //-------------------------------------------------------------------------
-
- // motions must specify whether or not they loop
- virtual BOOL getLoop() { return TRUE; }
-
- // motions must report their total duration
- virtual F32 getDuration() { return 0.0; }
-
- // motions must report their "ease in" duration
- virtual F32 getEaseInDuration() { return 0.0; }
-
- // motions must report their "ease out" duration.
- virtual F32 getEaseOutDuration() { return 0.0; }
-
- // motions must report their priority
- virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; }
-
- virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
-
- // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
- virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; }
-
- // run-time (post constructor) initialization,
- // called after parameters have been set
- // must return true to indicate success and be available for activation
- virtual LLMotionInitStatus onInitialize(LLCharacter *character)
- {
- mCharacter = character;
- BOOL success = true;
-
- if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) )
- {
- success = false;
- }
-
- if ( success )
- {
- mChestState->setUsage(LLJointState::ROT);
- addJointState( mChestState );
- }
-
- if ( success )
- {
- return STATUS_SUCCESS;
- }
- else
- {
- return STATUS_FAILURE;
- }
- }
-
- // called when a motion is activated
- // must return TRUE to indicate success, or else
- // it will be deactivated
- virtual BOOL onActivate() { return TRUE; }
-
- // called per time step
- // must return TRUE while it is active, and
- // must return FALSE when the motion is completed.
- virtual BOOL onUpdate(F32 time, U8* joint_mask)
- {
+ //-------------------------------------------------------------------------
+ // animation callbacks to be implemented by subclasses
+ //-------------------------------------------------------------------------
+
+ // motions must specify whether or not they loop
+ virtual BOOL getLoop() { return TRUE; }
+
+ // motions must report their total duration
+ virtual F32 getDuration() { return 0.0; }
+
+ // motions must report their "ease in" duration
+ virtual F32 getEaseInDuration() { return 0.0; }
+
+ // motions must report their "ease out" duration.
+ virtual F32 getEaseOutDuration() { return 0.0; }
+
+ // motions must report their priority
+ virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; }
+
+ virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
+
+ // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
+ virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; }
+
+ // run-time (post constructor) initialization,
+ // called after parameters have been set
+ // must return true to indicate success and be available for activation
+ virtual LLMotionInitStatus onInitialize(LLCharacter *character)
+ {
+ mCharacter = character;
+ BOOL success = true;
+
+ if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) )
+ {
+ success = false;
+ }
+
+ if ( success )
+ {
+ mChestState->setUsage(LLJointState::ROT);
+ addJointState( mChestState );
+ }
+
+ if ( success )
+ {
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ return STATUS_FAILURE;
+ }
+ }
+
+ // called when a motion is activated
+ // must return TRUE to indicate success, or else
+ // it will be deactivated
+ virtual BOOL onActivate() { return TRUE; }
+
+ // called per time step
+ // must return TRUE while it is active, and
+ // must return FALSE when the motion is completed.
+ virtual BOOL onUpdate(F32 time, U8* joint_mask)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- mBreatheRate = 1.f;
+ mBreatheRate = 1.f;
- F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH);
+ F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH);
- mChestState->setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f)));
+ mChestState->setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f)));
- return TRUE;
- }
+ return TRUE;
+ }
- // called when a motion is deactivated
- virtual void onDeactivate() {}
+ // called when a motion is deactivated
+ virtual void onDeactivate() {}
private:
- //-------------------------------------------------------------------------
- // joint states to be animated
- //-------------------------------------------------------------------------
- LLPointer<LLJointState> mChestState;
- F32 mBreatheRate;
- LLCharacter* mCharacter;
+ //-------------------------------------------------------------------------
+ // joint states to be animated
+ //-------------------------------------------------------------------------
+ LLPointer<LLJointState> mChestState;
+ F32 mBreatheRate;
+ LLCharacter* mCharacter;
};
//-----------------------------------------------------------------------------
// class LLPelvisFixMotion
//-----------------------------------------------------------------------------
class LLPelvisFixMotion :
- public LLMotion
+ public LLMotion
{
public:
- // Constructor
- LLPelvisFixMotion(const LLUUID &id)
- : LLMotion(id), mCharacter(NULL)
- {
- mName = "pelvis_fix";
+ // Constructor
+ LLPelvisFixMotion(const LLUUID &id)
+ : LLMotion(id), mCharacter(NULL)
+ {
+ mName = "pelvis_fix";
- mPelvisState = new LLJointState;
- }
+ mPelvisState = new LLJointState;
+ }
- // Destructor
- virtual ~LLPelvisFixMotion() { }
+ // Destructor
+ virtual ~LLPelvisFixMotion() { }
public:
- //-------------------------------------------------------------------------
- // functions to support MotionController and MotionRegistry
- //-------------------------------------------------------------------------
- // static constructor
- // all subclasses must implement such a function and register it
- static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); }
+ //-------------------------------------------------------------------------
+ // functions to support MotionController and MotionRegistry
+ //-------------------------------------------------------------------------
+ // static constructor
+ // all subclasses must implement such a function and register it
+ static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); }
public:
- //-------------------------------------------------------------------------
- // animation callbacks to be implemented by subclasses
- //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ // animation callbacks to be implemented by subclasses
+ //-------------------------------------------------------------------------
- // motions must specify whether or not they loop
- virtual BOOL getLoop() { return TRUE; }
+ // motions must specify whether or not they loop
+ virtual BOOL getLoop() { return TRUE; }
- // motions must report their total duration
- virtual F32 getDuration() { return 0.0; }
+ // motions must report their total duration
+ virtual F32 getDuration() { return 0.0; }
- // motions must report their "ease in" duration
- virtual F32 getEaseInDuration() { return 0.5f; }
+ // motions must report their "ease in" duration
+ virtual F32 getEaseInDuration() { return 0.5f; }
- // motions must report their "ease out" duration.
- virtual F32 getEaseOutDuration() { return 0.5f; }
+ // motions must report their "ease out" duration.
+ virtual F32 getEaseOutDuration() { return 0.5f; }
- // motions must report their priority
- virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; }
+ // motions must report their priority
+ virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; }
- virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
+ virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
- // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
- virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; }
+ // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
+ virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; }
- // run-time (post constructor) initialization,
- // called after parameters have been set
- // must return true to indicate success and be available for activation
- virtual LLMotionInitStatus onInitialize(LLCharacter *character)
- {
- mCharacter = character;
+ // run-time (post constructor) initialization,
+ // called after parameters have been set
+ // must return true to indicate success and be available for activation
+ virtual LLMotionInitStatus onInitialize(LLCharacter *character)
+ {
+ mCharacter = character;
- if (!mPelvisState->setJoint( character->getJoint("mPelvis")))
- {
- return STATUS_FAILURE;
- }
+ if (!mPelvisState->setJoint( character->getJoint("mPelvis")))
+ {
+ return STATUS_FAILURE;
+ }
- mPelvisState->setUsage(LLJointState::POS);
+ mPelvisState->setUsage(LLJointState::POS);
- addJointState( mPelvisState );
- return STATUS_SUCCESS;
- }
+ addJointState( mPelvisState );
+ return STATUS_SUCCESS;
+ }
- // called when a motion is activated
- // must return TRUE to indicate success, or else
- // it will be deactivated
- virtual BOOL onActivate() { return TRUE; }
+ // called when a motion is activated
+ // must return TRUE to indicate success, or else
+ // it will be deactivated
+ virtual BOOL onActivate() { return TRUE; }
- // called per time step
- // must return TRUE while it is active, and
- // must return FALSE when the motion is completed.
- virtual BOOL onUpdate(F32 time, U8* joint_mask)
- {
+ // called per time step
+ // must return TRUE while it is active, and
+ // must return FALSE when the motion is completed.
+ virtual BOOL onUpdate(F32 time, U8* joint_mask)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- mPelvisState->setPosition(LLVector3::zero);
+ mPelvisState->setPosition(LLVector3::zero);
- return TRUE;
- }
+ return TRUE;
+ }
- // called when a motion is deactivated
- virtual void onDeactivate() {}
+ // called when a motion is deactivated
+ virtual void onDeactivate() {}
private:
- //-------------------------------------------------------------------------
- // joint states to be animated
- //-------------------------------------------------------------------------
- LLPointer<LLJointState> mPelvisState;
- LLCharacter* mCharacter;
+ //-------------------------------------------------------------------------
+ // joint states to be animated
+ //-------------------------------------------------------------------------
+ LLPointer<LLJointState> mPelvisState;
+ LLCharacter* mCharacter;
};
/**
@@ -590,19 +590,19 @@ private:
U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
-S32 LLVOAvatar::sNumVisibleAvatars = 0;
-S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
+S32 LLVOAvatar::sNumVisibleAvatars = 0;
+S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
const LLUUID LLVOAvatar::sStepSoundOnLand("e8af4a28-aa83-4310-a7c4-c047e15ea0df");
const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] =
{
- SND_STONE_RUBBER,
- SND_METAL_RUBBER,
- SND_GLASS_RUBBER,
- SND_WOOD_RUBBER,
- SND_FLESH_RUBBER,
- SND_RUBBER_PLASTIC,
- SND_RUBBER_RUBBER
+ SND_STONE_RUBBER,
+ SND_METAL_RUBBER,
+ SND_GLASS_RUBBER,
+ SND_WOOD_RUBBER,
+ SND_FLESH_RUBBER,
+ SND_RUBBER_PLASTIC,
+ SND_RUBBER_RUBBER
};
S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS;
@@ -632,138 +632,138 @@ static F32 calc_bouncy_animation(F32 x);
// LLVOAvatar()
//-----------------------------------------------------------------------------
LLVOAvatar::LLVOAvatar(const LLUUID& id,
- const LLPCode pcode,
- LLViewerRegion* regionp) :
- LLAvatarAppearance(&gAgentWearables),
- LLViewerObject(id, pcode, regionp),
- mSpecialRenderMode(0),
- mAttachmentSurfaceArea(0.f),
- mAttachmentVisibleTriangleCount(0),
- mAttachmentEstTriangleCount(0.f),
- mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
- mTurning(FALSE),
- mLastSkeletonSerialNum( 0 ),
- mIsSitting(FALSE),
- mTimeVisible(),
- mTyping(FALSE),
- mMeshValid(FALSE),
- mVisible(FALSE),
- mLastImpostorUpdateFrameTime(0.f),
- mLastImpostorUpdateReason(0),
- mWindFreq(0.f),
- mRipplePhase( 0.f ),
- mBelowWater(FALSE),
- mLastAppearanceBlendTime(0.f),
- mAppearanceAnimating(FALSE),
+ const LLPCode pcode,
+ LLViewerRegion* regionp) :
+ LLAvatarAppearance(&gAgentWearables),
+ LLViewerObject(id, pcode, regionp),
+ mSpecialRenderMode(0),
+ mAttachmentSurfaceArea(0.f),
+ mAttachmentVisibleTriangleCount(0),
+ mAttachmentEstTriangleCount(0.f),
+ mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
+ mTurning(FALSE),
+ mLastSkeletonSerialNum( 0 ),
+ mIsSitting(FALSE),
+ mTimeVisible(),
+ mTyping(FALSE),
+ mMeshValid(FALSE),
+ mVisible(FALSE),
+ mLastImpostorUpdateFrameTime(0.f),
+ mLastImpostorUpdateReason(0),
+ mWindFreq(0.f),
+ mRipplePhase( 0.f ),
+ mBelowWater(FALSE),
+ mLastAppearanceBlendTime(0.f),
+ mAppearanceAnimating(FALSE),
mNameIsSet(false),
- mTitle(),
- mNameAway(false),
- mNameDoNotDisturb(false),
- mNameMute(false),
- mNameAppearance(false),
- mNameFriend(false),
- mNameAlpha(0.f),
- mRenderGroupTitles(sRenderGroupTitles),
- mNameCloud(false),
- mFirstTEMessageReceived( FALSE ),
- mFirstAppearanceMessageReceived( FALSE ),
- mCulled( FALSE ),
- mVisibilityRank(0),
- mNeedsSkin(FALSE),
- mLastSkinTime(0.f),
- mUpdatePeriod(1),
- mOverallAppearance(AOA_INVISIBLE),
- mVisualComplexityStale(true),
- mVisuallyMuteSetting(AV_RENDER_NORMALLY),
- mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
- mFirstFullyVisible(TRUE),
- mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY),
- mFullyLoaded(FALSE),
- mPreviousFullyLoaded(FALSE),
- mFullyLoadedInitialized(FALSE),
- mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
- mLoadedCallbacksPaused(FALSE),
- mLoadedCallbackTextures(0),
- mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
- mLastRezzedStatus(-1),
- mIsEditingAppearance(FALSE),
- mUseLocalAppearance(FALSE),
- mLastUpdateRequestCOFVersion(-1),
- mLastUpdateReceivedCOFVersion(-1),
- mCachedMuteListUpdateTime(0),
- mCachedInMuteList(false),
+ mTitle(),
+ mNameAway(false),
+ mNameDoNotDisturb(false),
+ mNameMute(false),
+ mNameAppearance(false),
+ mNameFriend(false),
+ mNameAlpha(0.f),
+ mRenderGroupTitles(sRenderGroupTitles),
+ mNameCloud(false),
+ mFirstTEMessageReceived( FALSE ),
+ mFirstAppearanceMessageReceived( FALSE ),
+ mCulled( FALSE ),
+ mVisibilityRank(0),
+ mNeedsSkin(FALSE),
+ mLastSkinTime(0.f),
+ mUpdatePeriod(1),
+ mOverallAppearance(AOA_INVISIBLE),
+ mVisualComplexityStale(true),
+ mVisuallyMuteSetting(AV_RENDER_NORMALLY),
+ mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
+ mFirstFullyVisible(TRUE),
+ mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY),
+ mFullyLoaded(FALSE),
+ mPreviousFullyLoaded(FALSE),
+ mFullyLoadedInitialized(FALSE),
+ mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
+ mLoadedCallbacksPaused(FALSE),
+ mLoadedCallbackTextures(0),
+ mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
+ mLastRezzedStatus(-1),
+ mIsEditingAppearance(FALSE),
+ mUseLocalAppearance(FALSE),
+ mLastUpdateRequestCOFVersion(-1),
+ mLastUpdateReceivedCOFVersion(-1),
+ mCachedMuteListUpdateTime(0),
+ mCachedInMuteList(false),
mIsControlAvatar(false),
mIsUIAvatar(false),
mEnableDefaultMotions(true)
{
- LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL;
+ LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL;
- //VTResume(); // VTune
- setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+ //VTResume(); // VTune
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
- // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
- const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
- mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
+ // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
+ const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
+ mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
- LL_DEBUGS("Avatar","Message") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL;
- mPelvisp = NULL;
+ LL_DEBUGS("Avatar","Message") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL;
+ mPelvisp = NULL;
- mDirtyMesh = 2; // Dirty geometry, need to regenerate.
- mMeshTexturesDirty = FALSE;
- mHeadp = NULL;
+ mDirtyMesh = 2; // Dirty geometry, need to regenerate.
+ mMeshTexturesDirty = FALSE;
+ mHeadp = NULL;
- // set up animation variables
- mSpeed = 0.f;
- setAnimationData("Speed", &mSpeed);
+ // set up animation variables
+ mSpeed = 0.f;
+ setAnimationData("Speed", &mSpeed);
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 0;
- mNeedsAnimUpdate = TRUE;
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 0;
+ mNeedsAnimUpdate = TRUE;
- mNeedsExtentUpdate = true;
+ mNeedsExtentUpdate = true;
- mImpostorDistance = 0;
- mImpostorPixelArea = 0;
+ mImpostorDistance = 0;
+ mImpostorPixelArea = 0;
- setNumTEs(TEX_NUM_INDICES);
+ setNumTEs(TEX_NUM_INDICES);
- mbCanSelect = TRUE;
+ mbCanSelect = TRUE;
- mSignaledAnimations.clear();
- mPlayingAnimations.clear();
+ mSignaledAnimations.clear();
+ mPlayingAnimations.clear();
- mWasOnGroundLeft = FALSE;
- mWasOnGroundRight = FALSE;
+ mWasOnGroundLeft = FALSE;
+ mWasOnGroundRight = FALSE;
- mTimeLast = 0.0f;
- mSpeedAccum = 0.0f;
+ mTimeLast = 0.0f;
+ mSpeedAccum = 0.0f;
- mRippleTimeLast = 0.f;
+ mRippleTimeLast = 0.f;
- mInAir = FALSE;
+ mInAir = FALSE;
- mStepOnLand = TRUE;
- mStepMaterial = 0;
+ mStepOnLand = TRUE;
+ mStepMaterial = 0;
- mLipSyncActive = false;
- mOohMorph = NULL;
- mAahMorph = NULL;
+ mLipSyncActive = false;
+ mOohMorph = NULL;
+ mAahMorph = NULL;
- mCurrentGesticulationLevel = 0;
+ mCurrentGesticulationLevel = 0;
mFirstAppearanceMessageTimer.reset();
- mRuthTimer.reset();
- mRuthDebugTimer.reset();
- mDebugExistenceTimer.reset();
- mLastAppearanceMessageTimer.reset();
+ mRuthTimer.reset();
+ mRuthDebugTimer.reset();
+ mDebugExistenceTimer.reset();
+ mLastAppearanceMessageTimer.reset();
- if(LLSceneMonitor::getInstance()->isEnabled())
- {
- LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
- }
+ if(LLSceneMonitor::getInstance()->isEnabled())
+ {
+ LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
+ }
- mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID()));
+ mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID()));
}
std::string LLVOAvatar::avString() const
@@ -774,8 +774,8 @@ std::string LLVOAvatar::avString() const
}
else
{
- std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
- return " Avatar '" + getFullname() + "' " + viz_string + " ";
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ return " Avatar '" + getFullname() + "' " + viz_string + " ";
}
}
@@ -788,22 +788,22 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
return;
}
- LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
- << "sec ]"
- << avString()
- << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
- << " Notification " << notification_name
- << " : " << comment
- << LL_ENDL;
+ LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
+ << "sec ]"
+ << avString()
+ << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
+ << " Notification " << notification_name
+ << " : " << comment
+ << LL_ENDL;
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add(notification_name,args);
- }
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+ args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
+ args["NAME"] = getFullname();
+ LLNotificationsUtil::add(notification_name,args);
+ }
}
//------------------------------------------------------------------------
@@ -811,14 +811,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
//------------------------------------------------------------------------
LLVOAvatar::~LLVOAvatar()
{
- if (!mFullyLoaded)
- {
- debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
- }
- else
- {
- debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
- }
+ if (!mFullyLoaded)
+ {
+ debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
+ }
+ else
+ {
+ debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
+ }
if(mTuned)
{
@@ -828,306 +828,306 @@ LLVOAvatar::~LLVOAvatar()
sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end());
- logPendingPhases();
-
- LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL;
-
- std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
- mAttachmentPoints.clear();
+ logPendingPhases();
+
+ LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL;
- mDead = TRUE;
+ std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
+ mAttachmentPoints.clear();
- mAnimationSources.clear();
- LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
+ mDead = TRUE;
+
+ mAnimationSources.clear();
+ LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
- getPhases().clearPhases();
-
- LL_DEBUGS() << "LLVOAvatar Destructor end" << LL_ENDL;
+ getPhases().clearPhases();
+
+ LL_DEBUGS() << "LLVOAvatar Destructor end" << LL_ENDL;
}
void LLVOAvatar::markDead()
{
- if (mNameText)
- {
- mNameText->markDead();
- mNameText = NULL;
- sNumVisibleChatBubbles--;
- }
- mVoiceVisualizer->markDead();
- LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
- LLViewerObject::markDead();
+ if (mNameText)
+ {
+ mNameText->markDead();
+ mNameText = NULL;
+ sNumVisibleChatBubbles--;
+ }
+ mVoiceVisualizer->markDead();
+ LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
+ LLViewerObject::markDead();
}
BOOL LLVOAvatar::isFullyBaked()
{
- if (mIsDummy) return TRUE;
- if (getNumTEs() == 0) return FALSE;
+ if (mIsDummy) return TRUE;
+ if (getNumTEs() == 0) return FALSE;
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex)
- && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))
- && (i != BAKED_LEFT_ARM) && (i != BAKED_LEFT_LEG) && (i != BAKED_AUX1) && (i != BAKED_AUX2) && (i != BAKED_AUX3))
- {
- return FALSE;
- }
- }
- return TRUE;
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex)
+ && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))
+ && (i != BAKED_LEFT_ARM) && (i != BAKED_LEFT_LEG) && (i != BAKED_AUX1) && (i != BAKED_AUX2) && (i != BAKED_AUX3))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
BOOL LLVOAvatar::isFullyTextured() const
{
- for (S32 i = 0; i < mMeshLOD.size(); i++)
- {
- LLAvatarJoint* joint = mMeshLOD[i];
- if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
- {
- continue; // don't care about skirt textures if we're not wearing one.
- }
- if (!joint)
- {
- continue; // nonexistent LOD OK.
- }
- avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
- if (meshIter != joint->mMeshParts.end())
- {
- LLAvatarJointMesh *mesh = (*meshIter);
- if (!mesh)
- {
- continue; // nonexistent mesh OK
- }
- if (mesh->hasGLTexture())
- {
- continue; // Mesh exists and has a baked texture.
- }
- if (mesh->hasComposite())
- {
- continue; // Mesh exists and has a composite texture.
- }
- // Fail
- return FALSE;
- }
- }
- return TRUE;
+ for (S32 i = 0; i < mMeshLOD.size(); i++)
+ {
+ LLAvatarJoint* joint = mMeshLOD[i];
+ if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
+ {
+ continue; // don't care about skirt textures if we're not wearing one.
+ }
+ if (!joint)
+ {
+ continue; // nonexistent LOD OK.
+ }
+ avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+ if (meshIter != joint->mMeshParts.end())
+ {
+ LLAvatarJointMesh *mesh = (*meshIter);
+ if (!mesh)
+ {
+ continue; // nonexistent mesh OK
+ }
+ if (mesh->hasGLTexture())
+ {
+ continue; // Mesh exists and has a baked texture.
+ }
+ if (mesh->hasComposite())
+ {
+ continue; // Mesh exists and has a composite texture.
+ }
+ // Fail
+ return FALSE;
+ }
+ }
+ return TRUE;
}
BOOL LLVOAvatar::hasGray() const
{
- return !getIsCloud() && !isFullyTextured();
+ return !getIsCloud() && !isFullyTextured();
}
S32 LLVOAvatar::getRezzedStatus() const
{
- if (getIsCloud()) return 0;
- bool textured = isFullyTextured();
- if (textured && allBakedTexturesCompletelyDownloaded()) return 3;
- if (textured) return 2;
- llassert(hasGray());
- return 1; // gray
+ if (getIsCloud()) return 0;
+ bool textured = isFullyTextured();
+ if (textured && allBakedTexturesCompletelyDownloaded()) return 3;
+ if (textured) return 2;
+ llassert(hasGray());
+ return 1; // gray
}
void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- if (mBakedTextureDatas[i].mTexLayerSet)
- {
- // ! BACKWARDS COMPATIBILITY !
- // Can be removed after hair baking is mandatory on the grid
- if ((i != BAKED_HAIR || isSelf()) && !clearAll)
- {
- mBakedTextureDatas[i].mTexLayerSet->deleteCaches();
- }
- }
- if (mBakedTextureDatas[i].mMaskTexName)
- {
- LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
- mBakedTextureDatas[i].mMaskTexName = 0 ;
- }
- }
-}
-
-// static
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (mBakedTextureDatas[i].mTexLayerSet)
+ {
+ // ! BACKWARDS COMPATIBILITY !
+ // Can be removed after hair baking is mandatory on the grid
+ if ((i != BAKED_HAIR || isSelf()) && !clearAll)
+ {
+ mBakedTextureDatas[i].mTexLayerSet->deleteCaches();
+ }
+ }
+ if (mBakedTextureDatas[i].mMaskTexName)
+ {
+ LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+ mBakedTextureDatas[i].mMaskTexName = 0 ;
+ }
+ }
+}
+
+// static
BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
{
- BOOL res = TRUE;
- grey_avatars = 0;
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- if( inst->isDead() )
- {
- continue;
- }
- else if( !inst->isFullyBaked() )
- {
- res = FALSE;
- if (inst->mHasGrey)
- {
- ++grey_avatars;
- }
- }
- }
- return res;
+ BOOL res = TRUE;
+ grey_avatars = 0;
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if( inst->isDead() )
+ {
+ continue;
+ }
+ else if( !inst->isFullyBaked() )
+ {
+ res = FALSE;
+ if (inst->mHasGrey)
+ {
+ ++grey_avatars;
+ }
+ }
+ }
+ return res;
}
// static
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
{
- counts.clear();
- counts.resize(4);
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- if (inst)
- {
- S32 rez_status = inst->getRezzedStatus();
- counts[rez_status]++;
- }
- }
+ counts.clear();
+ counts.resize(4);
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if (inst)
+ {
+ S32 rez_status = inst->getRezzedStatus();
+ counts[rez_status]++;
+ }
+ }
}
// static
std::string LLVOAvatar::rezStatusToString(S32 rez_status)
{
- if (rez_status==0) return "cloud";
- if (rez_status==1) return "gray";
- if (rez_status==2) return "downloading";
- if (rez_status==3) return "full";
- return "unknown";
+ if (rez_status==0) return "cloud";
+ if (rez_status==1) return "gray";
+ if (rez_status==2) return "downloading";
+ if (rez_status==3) return "full";
+ return "unknown";
}
// static
void LLVOAvatar::dumpBakedStatus()
{
- LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal();
-
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- LL_INFOS() << "Avatar ";
-
- LLNameValue* firstname = inst->getNVPair("FirstName");
- LLNameValue* lastname = inst->getNVPair("LastName");
-
- if( firstname )
- {
- LL_CONT << firstname->getString();
- }
- if( lastname )
- {
- LL_CONT << " " << lastname->getString();
- }
-
- LL_CONT << " " << inst->mID;
-
- if( inst->isDead() )
- {
- LL_CONT << " DEAD ("<< inst->getNumRefs() << " refs)";
- }
-
- if( inst->isSelf() )
- {
- LL_CONT << " (self)";
- }
-
-
- F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).length();
- LL_CONT << " " << dist_to_camera << "m ";
-
- LL_CONT << " " << inst->mPixelArea << " pixels";
-
- if( inst->isVisible() )
- {
- LL_CONT << " (visible)";
- }
- else
- {
- LL_CONT << " (not visible)";
- }
-
- if( inst->isFullyBaked() )
- {
- LL_CONT << " Baked";
- }
- else
- {
- LL_CONT << " Unbaked (";
-
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
- ++iter)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
- const ETextureIndex index = baked_dict->mTextureIndex;
- if (!inst->isTextureDefined(index))
- {
- LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : "");
- }
- }
- LL_CONT << " ) " << inst->getUnbakedPixelAreaRank();
- if( inst->isCulled() )
- {
- LL_CONT << " culled";
- }
- }
- LL_CONT << LL_ENDL;
- }
+ LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal();
+
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ LL_INFOS() << "Avatar ";
+
+ LLNameValue* firstname = inst->getNVPair("FirstName");
+ LLNameValue* lastname = inst->getNVPair("LastName");
+
+ if( firstname )
+ {
+ LL_CONT << firstname->getString();
+ }
+ if( lastname )
+ {
+ LL_CONT << " " << lastname->getString();
+ }
+
+ LL_CONT << " " << inst->mID;
+
+ if( inst->isDead() )
+ {
+ LL_CONT << " DEAD ("<< inst->getNumRefs() << " refs)";
+ }
+
+ if( inst->isSelf() )
+ {
+ LL_CONT << " (self)";
+ }
+
+
+ F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).length();
+ LL_CONT << " " << dist_to_camera << "m ";
+
+ LL_CONT << " " << inst->mPixelArea << " pixels";
+
+ if( inst->isVisible() )
+ {
+ LL_CONT << " (visible)";
+ }
+ else
+ {
+ LL_CONT << " (not visible)";
+ }
+
+ if( inst->isFullyBaked() )
+ {
+ LL_CONT << " Baked";
+ }
+ else
+ {
+ LL_CONT << " Unbaked (";
+
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
+ ++iter)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
+ const ETextureIndex index = baked_dict->mTextureIndex;
+ if (!inst->isTextureDefined(index))
+ {
+ LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : "");
+ }
+ }
+ LL_CONT << " ) " << inst->getUnbakedPixelAreaRank();
+ if( inst->isCulled() )
+ {
+ LL_CONT << " culled";
+ }
+ }
+ LL_CONT << LL_ENDL;
+ }
}
//static
void LLVOAvatar::restoreGL()
{
- if (!isAgentAvatarValid()) return;
+ if (!isAgentAvatarValid()) return;
- gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
- for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++)
- {
- gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i));
- }
- gAgentAvatarp->updateMeshTextures();
+ gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
+ for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++)
+ {
+ gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i));
+ }
+ gAgentAvatarp->updateMeshTextures();
}
//static
void LLVOAvatar::destroyGL()
{
- deleteCachedImages();
+ deleteCachedImages();
- resetImpostors();
+ resetImpostors();
}
//static
void LLVOAvatar::resetImpostors()
{
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* avatar = (LLVOAvatar*) *iter;
- avatar->mImpostor.release();
- avatar->mNeedsImpostorUpdate = TRUE;
- avatar->mLastImpostorUpdateReason = 1;
- }
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*) *iter;
+ avatar->mImpostor.release();
+ avatar->mNeedsImpostorUpdate = TRUE;
+ avatar->mLastImpostorUpdateReason = 1;
+ }
}
// static
void LLVOAvatar::deleteCachedImages(bool clearAll)
-{
- if (LLViewerTexLayerSet::sHasCaches)
- {
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- inst->deleteLayerSetCaches(clearAll);
- }
- LLViewerTexLayerSet::sHasCaches = FALSE;
- }
- LLVOAvatarSelf::deleteScratchTextures();
- LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
+{
+ if (LLViewerTexLayerSet::sHasCaches)
+ {
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ inst->deleteLayerSetCaches(clearAll);
+ }
+ LLViewerTexLayerSet::sHasCaches = FALSE;
+ }
+ LLVOAvatarSelf::deleteScratchTextures();
+ LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
}
@@ -1136,23 +1136,23 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
// LLVOAvatar::initClass()
//------------------------------------------------------------------------
void LLVOAvatar::initClass()
-{
- gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
- gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
- gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion");
- gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing");
- gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye");
- gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust");
- gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion");
- gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot");
- gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix");
- gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target");
- gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust");
+{
+ gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_EDITING,"editing");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_EYE,"eye");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_FLY_ADJUST,"fly_adjust");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_HAND_MOTION,"hand_motion");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_HEAD_ROT,"head_rot");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target");
+ gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust");
// Where should this be set initially?
LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints"));
- LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged);
+ LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged);
sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c");
}
@@ -1165,74 +1165,74 @@ void LLVOAvatar::cleanupClass()
// virtual
void LLVOAvatar::initInstance()
{
- //-------------------------------------------------------------------------
- // register motions
- //-------------------------------------------------------------------------
- if (LLCharacter::sInstances.size() == 1)
- {
- registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create );
- registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create );
- registerMotion( ANIM_AGENT_FEMALE_RUN_NEW, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_FEMALE_WALK_NEW, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_RUN_NEW, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create );
- registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create );
-
- // motions without a start/stop bit
- registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create );
- registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create );
- registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create );
- registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create );
- registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create );
- registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create );
- registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create );
- registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create );
- registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create );
- registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create );
- registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
- registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
- }
-
- LLAvatarAppearance::initInstance();
-
- // preload specific motions here
- createMotion( ANIM_AGENT_CUSTOMIZE);
- createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
-
- //VTPause(); // VTune
-
- mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+ //-------------------------------------------------------------------------
+ // register motions
+ //-------------------------------------------------------------------------
+ if (LLCharacter::sInstances.size() == 1)
+ {
+ registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create );
+ registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create );
+ registerMotion( ANIM_AGENT_FEMALE_RUN_NEW, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_FEMALE_WALK_NEW, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_RUN_NEW, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create );
+ registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_WALK_NEW, LLKeyframeWalkMotion::create );
+
+ // motions without a start/stop bit
+ registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create );
+ registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create );
+ registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create );
+ registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create );
+ registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create );
+ registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create );
+ registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create );
+ registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create );
+ registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create );
+ registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create );
+ registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
+ registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
+ }
+
+ LLAvatarAppearance::initInstance();
+
+ // preload specific motions here
+ createMotion( ANIM_AGENT_CUSTOMIZE);
+ createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
+
+ //VTPause(); // VTune
+
+ mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
mInitFlags |= 1<<1;
}
@@ -1240,65 +1240,65 @@ void LLVOAvatar::initInstance()
// virtual
LLAvatarJoint* LLVOAvatar::createAvatarJoint()
{
- return new LLViewerJoint();
+ return new LLViewerJoint();
}
// virtual
LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num)
{
- return new LLViewerJoint(joint_num);
+ return new LLViewerJoint(joint_num);
}
// virtual
LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh()
{
- return new LLViewerJointMesh();
+ return new LLViewerJointMesh();
}
// virtual
LLTexLayerSet* LLVOAvatar::createTexLayerSet()
{
- return new LLViewerTexLayerSet(this);
+ return new LLViewerTexLayerSet(this);
}
const LLVector3 LLVOAvatar::getRenderPosition() const
{
- if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
- {
- return getPositionAgent();
- }
- else if (isRoot())
- {
- F32 fixup;
- if ( hasPelvisFixup( fixup) )
- {
- //Apply a pelvis fixup (as defined by the avs skin)
- LLVector3 pos = mDrawable->getPositionAgent();
- pos[VZ] += fixup;
- return pos;
- }
- else
- {
- return mDrawable->getPositionAgent();
- }
- }
- else
- {
- return getPosition() * mDrawable->getParent()->getRenderMatrix();
- }
+ if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
+ {
+ return getPositionAgent();
+ }
+ else if (isRoot())
+ {
+ F32 fixup;
+ if ( hasPelvisFixup( fixup) )
+ {
+ //Apply a pelvis fixup (as defined by the avs skin)
+ LLVector3 pos = mDrawable->getPositionAgent();
+ pos[VZ] += fixup;
+ return pos;
+ }
+ else
+ {
+ return mDrawable->getPositionAgent();
+ }
+ }
+ else
+ {
+ return getPosition() * mDrawable->getParent()->getRenderMatrix();
+ }
}
void LLVOAvatar::updateDrawable(BOOL force_damped)
{
- clearChanged(SHIFTED);
+ clearChanged(SHIFTED);
}
void LLVOAvatar::onShift(const LLVector4a& shift_vector)
{
- const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
- mLastAnimExtents[0] += shift;
- mLastAnimExtents[1] += shift;
+ const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
+ mLastAnimExtents[0] += shift;
+ mLastAnimExtents[1] += shift;
}
void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
@@ -1313,37 +1313,37 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
calculateSpatialExtents(newMin,newMax);
mLastAnimExtents[0].set(newMin.getF32ptr());
mLastAnimExtents[1].set(newMax.getF32ptr());
- mLastAnimBasePos = mPelvisp->getWorldPosition();
+ mLastAnimBasePos = mPelvisp->getWorldPosition();
mNeedsExtentUpdate = false;
}
- else
- {
- LLVector3 new_base_pos = mPelvisp->getWorldPosition();
- LLVector3 shift = new_base_pos-mLastAnimBasePos;
- mLastAnimExtents[0] += shift;
- mLastAnimExtents[1] += shift;
- mLastAnimBasePos = new_base_pos;
-
- }
-
- if (isImpostor() && !needsImpostorUpdate())
- {
- LLVector3 delta = getRenderPosition() -
- ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset));
-
- newMin.load3( (mLastAnimExtents[0] + delta).mV);
- newMax.load3( (mLastAnimExtents[1] + delta).mV);
- }
- else
- {
+ else
+ {
+ LLVector3 new_base_pos = mPelvisp->getWorldPosition();
+ LLVector3 shift = new_base_pos-mLastAnimBasePos;
+ mLastAnimExtents[0] += shift;
+ mLastAnimExtents[1] += shift;
+ mLastAnimBasePos = new_base_pos;
+
+ }
+
+ if (isImpostor() && !needsImpostorUpdate())
+ {
+ LLVector3 delta = getRenderPosition() -
+ ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset));
+
+ newMin.load3( (mLastAnimExtents[0] + delta).mV);
+ newMax.load3( (mLastAnimExtents[1] + delta).mV);
+ }
+ else
+ {
newMin.load3(mLastAnimExtents[0].mV);
newMax.load3(mLastAnimExtents[1].mV);
- LLVector4a pos_group;
- pos_group.setAdd(newMin,newMax);
- pos_group.mul(0.5f);
- mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition();
- mDrawable->setPositionGroup(pos_group);
- }
+ LLVector4a pos_group;
+ pos_group.setAdd(newMin,newMax);
+ pos_group.mul(0.5f);
+ mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition();
+ mDrawable->setPositionGroup(pos_group);
+ }
}
@@ -1414,8 +1414,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
if (box_detail >= 2)
{
float max_attachment_span = get_default_max_prim_scale() * 5.0f;
-
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
{
@@ -1434,7 +1434,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);
if (vol && vol->isAnimatedObject())
{
- // Animated objects already have a bounding box in their control av, use that.
+ // Animated objects already have a bounding box in their control av, use that.
// Could lag by a frame if there's no guarantee on order of processing for avatars.
LLControlAvatar *cav = vol->getControlAvatar();
if (cav)
@@ -1464,10 +1464,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
LLVector4a max_span(max_attachment_span);
S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
-
+
// Only add the prim to spatial extents calculations if it isn't a megaprim.
- // max_attachment_span calculated at the start of the function
- // (currently 5 times our max prim size)
+ // max_attachment_span calculated at the start of the function
+ // (currently 5 times our max prim size)
if (lt == 0x7)
{
update_min_max(newMin,newMax,ext[0]);
@@ -1521,10 +1521,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
LLVector4a center, size;
center.setAdd(newMin, newMax);
center.mul(0.5f);
-
+
size.setSub(newMax,newMin);
size.mul(0.5f);
-
+
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
}
@@ -1537,24 +1537,24 @@ void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos
gGL.diffuseColor3f(visible_color[0], visible_color[1], visible_color[2]);
gGL.begin(LLRender::LINES);
- gGL.vertex3fv(begin_pos.mV);
+ gGL.vertex3fv(begin_pos.mV);
gGL.vertex3fv(end_pos.mV);
gGL.end();
-
+
// Draw sphere representing joint pos
gGL.pushMatrix();
gGL.scalef(sphere_scale, sphere_scale, sphere_scale);
gSphere.renderGGL();
gGL.popMatrix();
-
+
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
// Occluded bone portions
gGL.diffuseColor3f(occ_color[0], occ_color[1], occ_color[2]);
gGL.begin(LLRender::LINES);
- gGL.vertex3fv(begin_pos.mV);
+ gGL.vertex3fv(begin_pos.mV);
gGL.vertex3fv(end_pos.mV);
gGL.end();
@@ -1570,18 +1570,18 @@ void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos
//-----------------------------------------------------------------------------
void LLVOAvatar::renderCollisionVolumes()
{
- std::ostringstream ostr;
+ std::ostringstream ostr;
- for (S32 i = 0; i < mNumCollisionVolumes; i++)
- {
- ostr << mCollisionVolumes[i].getName() << ", ";
+ for (S32 i = 0; i < mNumCollisionVolumes; i++)
+ {
+ ostr << mCollisionVolumes[i].getName() << ", ";
LLAvatarJointCollisionVolume& collision_volume = mCollisionVolumes[i];
- collision_volume.updateWorldMatrix();
+ collision_volume.updateWorldMatrix();
- gGL.pushMatrix();
- gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] );
+ gGL.pushMatrix();
+ gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] );
LLVector3 begin_pos(0,0,0);
LLVector3 end_pos(collision_volume.getEnd());
@@ -1593,7 +1593,7 @@ void LLVOAvatar::renderCollisionVolumes()
static LLVector3 RED(1.0f, 0.0f, 0.0f);
static LLVector3 PASTEL_RED(1.0f, 0.5f, 0.5f);
static LLVector3 WHITE(1.0f, 1.0f, 1.0f);
-
+
LLVector3 cv_color_occluded;
LLVector3 cv_color_visible;
@@ -1615,20 +1615,20 @@ void LLVOAvatar::renderCollisionVolumes()
gGL.popMatrix();
}
-
- if (mNameText.notNull())
- {
- LLVector4a unused;
-
- mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
- }
+
+ if (mNameText.notNull())
+ {
+ LLVector4a unused;
+
+ mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
+ }
}
void LLVOAvatar::renderBones(const std::string &selected_joint)
{
LLGLEnable blend(GL_BLEND);
- avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
avatar_joint_list_t::iterator end = mSkeleton.end();
// For selected joints
@@ -1643,18 +1643,18 @@ void LLVOAvatar::renderBones(const std::string &selected_joint)
// For bones not otherwise colored
static LLVector3 OTHER_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f);
static LLVector3 OTHER_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
-
+
static F32 SPHERE_SCALEF = 0.001f;
- for (; iter != end; ++iter)
- {
- LLJoint* jointp = *iter;
- if (!jointp)
- {
- continue;
- }
+ for (; iter != end; ++iter)
+ {
+ LLJoint* jointp = *iter;
+ if (!jointp)
+ {
+ continue;
+ }
- jointp->updateWorldMatrix();
+ jointp->updateWorldMatrix();
LLVector3 occ_color, visible_color;
@@ -1692,267 +1692,267 @@ void LLVOAvatar::renderBones(const std::string &selected_joint)
LLVector3 begin_pos(0,0,0);
LLVector3 end_pos(jointp->getEnd());
-
- gGL.pushMatrix();
- gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
render_sphere_and_line(begin_pos, end_pos, sphere_scale, occ_color, visible_color);
-
- gGL.popMatrix();
- }
+
+ gGL.popMatrix();
+ }
}
void LLVOAvatar::renderJoints()
{
- std::ostringstream ostr;
- std::ostringstream nullstr;
-
- for (joint_map_t::iterator iter = mJointMap.begin(); iter != mJointMap.end(); ++iter)
- {
- LLJoint* jointp = iter->second;
- if (!jointp)
- {
- nullstr << iter->first << " is NULL" << std::endl;
- continue;
- }
+ std::ostringstream ostr;
+ std::ostringstream nullstr;
- ostr << jointp->getName() << ", ";
+ for (joint_map_t::iterator iter = mJointMap.begin(); iter != mJointMap.end(); ++iter)
+ {
+ LLJoint* jointp = iter->second;
+ if (!jointp)
+ {
+ nullstr << iter->first << " is NULL" << std::endl;
+ continue;
+ }
- jointp->updateWorldMatrix();
+ ostr << jointp->getName() << ", ";
- gGL.pushMatrix();
- gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
+ jointp->updateWorldMatrix();
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
- gGL.diffuseColor3f( 1.f, 0.f, 1.f );
+ gGL.diffuseColor3f( 1.f, 0.f, 1.f );
+
+ gGL.begin(LLRender::LINES);
+
+ LLVector3 v[] =
+ {
+ LLVector3(1,0,0),
+ LLVector3(-1,0,0),
+ LLVector3(0,1,0),
+ LLVector3(0,-1,0),
- gGL.begin(LLRender::LINES);
+ LLVector3(0,0,-1),
+ LLVector3(0,0,1),
+ };
- LLVector3 v[] =
- {
- LLVector3(1,0,0),
- LLVector3(-1,0,0),
- LLVector3(0,1,0),
- LLVector3(0,-1,0),
-
- LLVector3(0,0,-1),
- LLVector3(0,0,1),
- };
+ //sides
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[2].mV);
- //sides
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[3].mV);
+ //top
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[4].mV);
- //top
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[4].mV);
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[4].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[4].mV);
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[4].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[4].mV);
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[4].mV);
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[4].mV);
+ //bottom
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[5].mV);
- //bottom
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[5].mV);
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[5].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[5].mV);
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[5].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[5].mV);
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[5].mV);
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[5].mV);
+ gGL.end();
- gGL.end();
+ gGL.popMatrix();
+ }
- gGL.popMatrix();
- }
-
- mDebugText.clear();
- addDebugText(ostr.str());
- addDebugText(nullstr.str());
+ mDebugText.clear();
+ addDebugText(ostr.str());
+ addDebugText(nullstr.str());
}
BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face,
- BOOL pick_transparent,
- BOOL pick_rigged,
+ S32 face,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable,
- S32* face_hit,
- LLVector4a* intersection,
- LLVector2* tex_coord,
- LLVector4a* normal,
- LLVector4a* tangent)
+ S32* face_hit,
+ LLVector4a* intersection,
+ LLVector2* tex_coord,
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
- if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)
- {
- return FALSE;
- }
+ if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)
+ {
+ return FALSE;
+ }
if (isControlAvatar())
{
return FALSE;
}
-
- if (lineSegmentBoundingBox(start, end))
- {
- for (S32 i = 0; i < mNumCollisionVolumes; ++i)
- {
- mCollisionVolumes[i].updateWorldMatrix();
-
- glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix);
- glh::matrix4f inverse = mat.inverse();
- glh::matrix4f norm_mat = inverse.transpose();
-
- glh::vec3f p1(start.getF32ptr());
- glh::vec3f p2(end.getF32ptr());
-
- inverse.mult_matrix_vec(p1);
- inverse.mult_matrix_vec(p2);
-
- LLVector3 position;
- LLVector3 norm;
-
- if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm))
- {
- glh::vec3f res_pos(position.mV);
- mat.mult_matrix_vec(res_pos);
-
- norm.normalize();
- glh::vec3f res_norm(norm.mV);
- norm_mat.mult_matrix_dir(res_norm);
-
- if (intersection)
- {
- intersection->load3(res_pos.v);
- }
-
- if (normal)
- {
- normal->load3(res_norm.v);
- }
-
- return TRUE;
- }
- }
-
- if (isSelf())
- {
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject* attached_object = attachment_iter->get();
-
- if (attached_object && !attached_object->isDead() && attachment->getValid())
- {
- LLDrawable* drawable = attached_object->mDrawable;
- if (drawable->isState(LLDrawable::RIGGED))
- { //regenerate octree for rigged attachment
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED);
- }
- }
- }
- }
- }
- }
-
-
-
- LLVector4a position;
- if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
- {
- if (intersection)
- {
- *intersection = position;
- }
-
- return TRUE;
- }
-
- return FALSE;
+
+ if (lineSegmentBoundingBox(start, end))
+ {
+ for (S32 i = 0; i < mNumCollisionVolumes; ++i)
+ {
+ mCollisionVolumes[i].updateWorldMatrix();
+
+ glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix);
+ glh::matrix4f inverse = mat.inverse();
+ glh::matrix4f norm_mat = inverse.transpose();
+
+ glh::vec3f p1(start.getF32ptr());
+ glh::vec3f p2(end.getF32ptr());
+
+ inverse.mult_matrix_vec(p1);
+ inverse.mult_matrix_vec(p2);
+
+ LLVector3 position;
+ LLVector3 norm;
+
+ if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm))
+ {
+ glh::vec3f res_pos(position.mV);
+ mat.mult_matrix_vec(res_pos);
+
+ norm.normalize();
+ glh::vec3f res_norm(norm.mV);
+ norm_mat.mult_matrix_dir(res_norm);
+
+ if (intersection)
+ {
+ intersection->load3(res_pos.v);
+ }
+
+ if (normal)
+ {
+ normal->load3(res_norm.v);
+ }
+
+ return TRUE;
+ }
+ }
+
+ if (isSelf())
+ {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+
+ if (attached_object && !attached_object->isDead() && attachment->getValid())
+ {
+ LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable->isState(LLDrawable::RIGGED))
+ { //regenerate octree for rigged attachment
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ LLVector4a position;
+ if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
+ {
+ if (intersection)
+ {
+ *intersection = position;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
}
// virtual
LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
- S32 face,
- BOOL pick_transparent,
- BOOL pick_rigged,
+ S32 face,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable,
- S32* face_hit,
- LLVector4a* intersection,
- LLVector2* tex_coord,
- LLVector4a* normal,
- LLVector4a* tangent)
-{
- if (isSelf() && !gAgent.needsRenderAvatar())
- {
- return NULL;
- }
-
- LLViewerObject* hit = NULL;
-
- if (lineSegmentBoundingBox(start, end))
- {
- LLVector4a local_end = end;
- LLVector4a local_intersection;
-
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject* attached_object = attachment_iter->get();
-
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
- {
- local_end = local_intersection;
- if (intersection)
- {
- *intersection = local_intersection;
- }
-
- hit = attached_object;
- }
- }
- }
- }
-
- return hit;
+ S32* face_hit,
+ LLVector4a* intersection,
+ LLVector2* tex_coord,
+ LLVector4a* normal,
+ LLVector4a* tangent)
+{
+ if (isSelf() && !gAgent.needsRenderAvatar())
+ {
+ return NULL;
+ }
+
+ LLViewerObject* hit = NULL;
+
+ if (lineSegmentBoundingBox(start, end))
+ {
+ LLVector4a local_end = end;
+ LLVector4a local_intersection;
+
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
+ {
+ local_end = local_intersection;
+ if (intersection)
+ {
+ *intersection = local_intersection;
+ }
+
+ hit = attached_object;
+ }
+ }
+ }
+ }
+
+ return hit;
}
LLVOAvatar* LLVOAvatar::asAvatar()
{
- return this;
+ return this;
}
//-----------------------------------------------------------------------------
@@ -1960,21 +1960,21 @@ LLVOAvatar* LLVOAvatar::asAvatar()
//-----------------------------------------------------------------------------
void LLVOAvatar::startDefaultMotions()
{
- //-------------------------------------------------------------------------
- // start default motions
- //-------------------------------------------------------------------------
- startMotion( ANIM_AGENT_HEAD_ROT );
- startMotion( ANIM_AGENT_EYE );
- startMotion( ANIM_AGENT_BODY_NOISE );
- startMotion( ANIM_AGENT_BREATHE_ROT );
- startMotion( ANIM_AGENT_PHYSICS_MOTION );
- startMotion( ANIM_AGENT_HAND_MOTION );
- startMotion( ANIM_AGENT_PELVIS_FIX );
+ //-------------------------------------------------------------------------
+ // start default motions
+ //-------------------------------------------------------------------------
+ startMotion( ANIM_AGENT_HEAD_ROT );
+ startMotion( ANIM_AGENT_EYE );
+ startMotion( ANIM_AGENT_BODY_NOISE );
+ startMotion( ANIM_AGENT_BREATHE_ROT );
+ startMotion( ANIM_AGENT_PHYSICS_MOTION );
+ startMotion( ANIM_AGENT_HAND_MOTION );
+ startMotion( ANIM_AGENT_PELVIS_FIX );
- //-------------------------------------------------------------------------
- // restart any currently active motions
- //-------------------------------------------------------------------------
- processAnimationStateChanges();
+ //-------------------------------------------------------------------------
+ // restart any currently active motions
+ //-------------------------------------------------------------------------
+ processAnimationStateChanges();
}
//-----------------------------------------------------------------------------
@@ -1984,51 +1984,51 @@ void LLVOAvatar::startDefaultMotions()
// virtual
void LLVOAvatar::buildCharacter()
{
- LLAvatarAppearance::buildCharacter();
+ LLAvatarAppearance::buildCharacter();
- // Not done building yet; more to do.
- mIsBuilt = FALSE;
+ // Not done building yet; more to do.
+ mIsBuilt = FALSE;
- //-------------------------------------------------------------------------
- // set head offset from pelvis
- //-------------------------------------------------------------------------
- updateHeadOffset();
+ //-------------------------------------------------------------------------
+ // set head offset from pelvis
+ //-------------------------------------------------------------------------
+ updateHeadOffset();
- //-------------------------------------------------------------------------
- // initialize lip sync morph pointers
- //-------------------------------------------------------------------------
- mOohMorph = getVisualParam( "Lipsync_Ooh" );
- mAahMorph = getVisualParam( "Lipsync_Aah" );
+ //-------------------------------------------------------------------------
+ // initialize lip sync morph pointers
+ //-------------------------------------------------------------------------
+ mOohMorph = getVisualParam( "Lipsync_Ooh" );
+ mAahMorph = getVisualParam( "Lipsync_Aah" );
- // If we don't have the Ooh morph, use the Kiss morph
- if (!mOohMorph)
- {
- LL_WARNS() << "Missing 'Ooh' morph for lipsync, using fallback." << LL_ENDL;
- mOohMorph = getVisualParam( "Express_Kiss" );
- }
+ // If we don't have the Ooh morph, use the Kiss morph
+ if (!mOohMorph)
+ {
+ LL_WARNS() << "Missing 'Ooh' morph for lipsync, using fallback." << LL_ENDL;
+ mOohMorph = getVisualParam( "Express_Kiss" );
+ }
- // If we don't have the Aah morph, use the Open Mouth morph
- if (!mAahMorph)
- {
- LL_WARNS() << "Missing 'Aah' morph for lipsync, using fallback." << LL_ENDL;
- mAahMorph = getVisualParam( "Express_Open_Mouth" );
- }
+ // If we don't have the Aah morph, use the Open Mouth morph
+ if (!mAahMorph)
+ {
+ LL_WARNS() << "Missing 'Aah' morph for lipsync, using fallback." << LL_ENDL;
+ mAahMorph = getVisualParam( "Express_Open_Mouth" );
+ }
// Currently disabled for control avatars (animated objects), enabled for all others.
if (mEnableDefaultMotions)
{
- startDefaultMotions();
+ startDefaultMotions();
}
- //-------------------------------------------------------------------------
- // restart any currently active motions
- //-------------------------------------------------------------------------
- processAnimationStateChanges();
+ //-------------------------------------------------------------------------
+ // restart any currently active motions
+ //-------------------------------------------------------------------------
+ processAnimationStateChanges();
- mIsBuilt = TRUE;
- stop_glerror();
+ mIsBuilt = TRUE;
+ stop_glerror();
- mMeshValid = TRUE;
+ mMeshValid = TRUE;
}
//-----------------------------------------------------------------------------
@@ -2036,30 +2036,30 @@ void LLVOAvatar::buildCharacter()
//-----------------------------------------------------------------------------
void LLVOAvatar::resetVisualParams()
{
- // Skeletal params
- {
- LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
- for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
- iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
- ++iter)
- {
- LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
- LLPolySkeletalDistortion *param = dynamic_cast<LLPolySkeletalDistortion*>(getVisualParam(info->getID()));
+ // Skeletal params
+ {
+ LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+ for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+ iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
+ ++iter)
+ {
+ LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+ LLPolySkeletalDistortion *param = dynamic_cast<LLPolySkeletalDistortion*>(getVisualParam(info->getID()));
*param = LLPolySkeletalDistortion(this);
llassert(param);
- if (!param->setInfo(info))
- {
- llassert(false);
- }
- }
- }
-
- // Driver parameters
- for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
- iter != sAvatarXmlInfo->mDriverInfoList.end();
- ++iter)
- {
- LLDriverParamInfo *info = *iter;
+ if (!param->setInfo(info))
+ {
+ llassert(false);
+ }
+ }
+ }
+
+ // Driver parameters
+ for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+ iter != sAvatarXmlInfo->mDriverInfoList.end();
+ ++iter)
+ {
+ LLDriverParamInfo *info = *iter;
LLDriverParam *param = dynamic_cast<LLDriverParam*>(getVisualParam(info->getID()));
LLDriverParam::entry_list_t driven_list = param->getDrivenList();
*param = LLDriverParam(this);
@@ -2067,41 +2067,41 @@ void LLVOAvatar::resetVisualParams()
if (!param->setInfo(info))
{
llassert(false);
- }
+ }
param->setDrivenList(driven_list);
- }
+ }
}
void LLVOAvatar::applyDefaultParams()
{
- // These are params from avs with newly created copies of shape,
- // skin, hair, eyes, plus gender set as noted. Run arche_tool.py
- // to get params from some other xml appearance dump.
- std::map<S32, U8> male_params = {
- {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
- };
- std::map<S32, U8> female_params = {
- {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
- };
- std::map<S32, U8> *params = NULL;
- if (getSex() == SEX_MALE)
- params = &male_params;
- else
- params = &female_params;
-
- for( auto it = params->begin(); it != params->end(); ++it)
- {
- LLVisualParam* param = getVisualParam(it->first);
- if( !param )
- {
- // invalid id
- break;
- }
-
- U8 value = it->second;
- F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
- param->setWeight(newWeight);
- }
+ // These are params from avs with newly created copies of shape,
+ // skin, hair, eyes, plus gender set as noted. Run arche_tool.py
+ // to get params from some other xml appearance dump.
+ std::map<S32, U8> male_params = {
+ {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+ };
+ std::map<S32, U8> female_params = {
+ {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+ };
+ std::map<S32, U8> *params = NULL;
+ if (getSex() == SEX_MALE)
+ params = &male_params;
+ else
+ params = &female_params;
+
+ for( auto it = params->begin(); it != params->end(); ++it)
+ {
+ LLVisualParam* param = getVisualParam(it->first);
+ if( !param )
+ {
+ // invalid id
+ break;
+ }
+
+ U8 value = it->second;
+ F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+ param->setWeight(newWeight);
+ }
}
//-----------------------------------------------------------------------------
@@ -2127,10 +2127,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
// just to get the right scale for the collision volumes, because
// this will be used in setting the mJointScales for the
// LLPolySkeletalDistortions of which the CVs are children.
- if( !buildSkeleton(sAvatarSkeletonInfo) )
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
{
LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
- }
+ }
// Reset some params to default state, without propagating changes downstream.
resetVisualParams();
@@ -2138,10 +2138,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
// Now we have to reset the skeleton again, because its state
// got clobbered by the resetVisualParams() calls
// above.
- if( !buildSkeleton(sAvatarSkeletonInfo) )
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
{
LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
- }
+ }
// Reset attachment points
// BuildSkeleton only does bones and CVs but we still need to reinit huds
@@ -2150,7 +2150,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
initAttachmentPoints(ignore_hud_joints);
// Fix up collision volumes
- for (LLVisualParam *param = getFirstVisualParam();
+ for (LLVisualParam *param = getFirstVisualParam();
param;
param = getNextVisualParam())
{
@@ -2166,30 +2166,30 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
}
// Reset tweakable params to preserved state
- if (getOverallAppearance() == AOA_NORMAL)
- {
- if (mLastProcessedAppearance)
- {
- bool slam_params = true;
- applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
- }
- }
- else
- {
- // Stripped down approximation of
- // applyParsedAppearanceMessage, but with alternative default
- // (jellydoll) params
- setCompositeUpdatesEnabled( FALSE );
- gPipeline.markGLRebuild(this);
- applyDefaultParams();
- setCompositeUpdatesEnabled( TRUE );
- updateMeshTextures();
- updateMeshVisibility();
- }
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ if (mLastProcessedAppearance)
+ {
+ bool slam_params = true;
+ applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+ }
+ }
+ else
+ {
+ // Stripped down approximation of
+ // applyParsedAppearanceMessage, but with alternative default
+ // (jellydoll) params
+ setCompositeUpdatesEnabled( FALSE );
+ gPipeline.markGLRebuild(this);
+ applyDefaultParams();
+ setCompositeUpdatesEnabled( TRUE );
+ updateMeshTextures();
+ updateMeshVisibility();
+ }
updateVisualParams();
// Restore attachment pos overrides
- updateAttachmentOverrides();
+ updateAttachmentOverrides();
// Animations
if (reset_animations)
@@ -2207,7 +2207,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
resetAnimations();
}
}
-
+
LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL;
}
@@ -2216,49 +2216,49 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
//-----------------------------------------------------------------------------
void LLVOAvatar::releaseMeshData()
{
- if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || isUIAvatar())
- {
- return;
- }
-
- // cleanup mesh data
- for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end();
- ++iter)
- {
- LLAvatarJoint* joint = (*iter);
- joint->setValid(FALSE, TRUE);
- }
-
- //cleanup data
- if (mDrawable.notNull())
- {
- LLFace* facep = mDrawable->getFace(0);
- if (facep)
- {
- facep->setSize(0, 0);
- for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
- {
- facep = mDrawable->getFace(i);
- if (facep)
- {
- facep->setSize(0, 0);
- }
- }
- }
- }
-
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (!attachment->getIsHUDAttachment())
- {
- attachment->setAttachmentVisibility(FALSE);
- }
- }
- mMeshValid = FALSE;
+ if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || isUIAvatar())
+ {
+ return;
+ }
+
+ // cleanup mesh data
+ for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+ iter != mMeshLOD.end();
+ ++iter)
+ {
+ LLAvatarJoint* joint = (*iter);
+ joint->setValid(FALSE, TRUE);
+ }
+
+ //cleanup data
+ if (mDrawable.notNull())
+ {
+ LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep->setSize(0, 0);
+ for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+ {
+ facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ facep->setSize(0, 0);
+ }
+ }
+ }
+ }
+
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment->getIsHUDAttachment())
+ {
+ attachment->setAttachmentVisibility(FALSE);
+ }
+ }
+ mMeshValid = FALSE;
}
//-----------------------------------------------------------------------------
@@ -2267,29 +2267,29 @@ void LLVOAvatar::releaseMeshData()
// virtual
void LLVOAvatar::restoreMeshData()
{
- llassert(!isSelf());
+ llassert(!isSelf());
if (mDrawable.isNull())
{
return;
}
+
+ //LL_INFOS() << "Restoring" << LL_ENDL;
+ mMeshValid = TRUE;
+ updateJointLODs();
- //LL_INFOS() << "Restoring" << LL_ENDL;
- mMeshValid = TRUE;
- updateJointLODs();
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment->getIsHUDAttachment())
+ {
+ attachment->setAttachmentVisibility(TRUE);
+ }
+ }
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (!attachment->getIsHUDAttachment())
- {
- attachment->setAttachmentVisibility(TRUE);
- }
- }
-
- // force mesh update as LOD might not have changed to trigger this
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ // force mesh update as LOD might not have changed to trigger this
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
//-----------------------------------------------------------------------------
@@ -2297,149 +2297,149 @@ void LLVOAvatar::restoreMeshData()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateMeshData()
{
- if (mDrawable.notNull())
- {
- stop_glerror();
-
- S32 f_num = 0 ;
- const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer.
- const S32 num_parts = mMeshLOD.size();
-
- // this order is determined by number of LODS
- // if a mesh earlier in this list changed LODs while a later mesh doesn't,
- // the later mesh's index offset will be inaccurate
- for(S32 part_index = 0 ; part_index < num_parts ;)
- {
- S32 j = part_index ;
- U32 last_v_num = 0, num_vertices = 0 ;
- U32 last_i_num = 0, num_indices = 0 ;
-
- while(part_index < num_parts && num_vertices < VERTEX_NUMBER_THRESHOLD)
- {
- last_v_num = num_vertices ;
- last_i_num = num_indices ;
-
- LLViewerJoint* part_mesh = getViewerJoint(part_index++);
- if (part_mesh)
- {
- part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
- }
- }
- if(num_vertices < 1)//skip empty meshes
- {
- continue ;
- }
- if(last_v_num > 0)//put the last inserted part into next vertex buffer.
- {
- num_vertices = last_v_num ;
- num_indices = last_i_num ;
- part_index-- ;
- }
-
- LLFace* facep = NULL;
- if(f_num < mDrawable->getNumFaces())
- {
- facep = mDrawable->getFace(f_num);
- }
- else
- {
- facep = mDrawable->getFace(0);
- if (facep)
- {
- facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ;
- }
- }
- if (!facep) continue;
-
- // resize immediately
- facep->setSize(num_vertices, num_indices);
-
- bool terse_update = false;
-
- facep->setGeomIndex(0);
- facep->setIndicesIndex(0);
-
- LLVertexBuffer* buff = facep->getVertexBuffer();
- if(!facep->getVertexBuffer())
- {
+ if (mDrawable.notNull())
+ {
+ stop_glerror();
+
+ S32 f_num = 0 ;
+ const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer.
+ const S32 num_parts = mMeshLOD.size();
+
+ // this order is determined by number of LODS
+ // if a mesh earlier in this list changed LODs while a later mesh doesn't,
+ // the later mesh's index offset will be inaccurate
+ for(S32 part_index = 0 ; part_index < num_parts ;)
+ {
+ S32 j = part_index ;
+ U32 last_v_num = 0, num_vertices = 0 ;
+ U32 last_i_num = 0, num_indices = 0 ;
+
+ while(part_index < num_parts && num_vertices < VERTEX_NUMBER_THRESHOLD)
+ {
+ last_v_num = num_vertices ;
+ last_i_num = num_indices ;
+
+ LLViewerJoint* part_mesh = getViewerJoint(part_index++);
+ if (part_mesh)
+ {
+ part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+ }
+ }
+ if(num_vertices < 1)//skip empty meshes
+ {
+ continue ;
+ }
+ if(last_v_num > 0)//put the last inserted part into next vertex buffer.
+ {
+ num_vertices = last_v_num ;
+ num_indices = last_i_num ;
+ part_index-- ;
+ }
+
+ LLFace* facep = NULL;
+ if(f_num < mDrawable->getNumFaces())
+ {
+ facep = mDrawable->getFace(f_num);
+ }
+ else
+ {
+ facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ;
+ }
+ }
+ if (!facep) continue;
+
+ // resize immediately
+ facep->setSize(num_vertices, num_indices);
+
+ bool terse_update = false;
+
+ facep->setGeomIndex(0);
+ facep->setIndicesIndex(0);
+
+ LLVertexBuffer* buff = facep->getVertexBuffer();
+ if(!facep->getVertexBuffer())
+ {
buff = new LLVertexBuffer(LLDrawPoolAvatar::VERTEX_DATA_MASK);
- if (!buff->allocateBuffer(num_vertices, num_indices))
- {
- LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to "
- << num_vertices << " vertices and "
- << num_indices << " indices" << LL_ENDL;
- // Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
- facep->setSize(1, 3);
- buff->allocateBuffer(1, 3);
- memset((U8*) buff->getMappedData(), 0, buff->getSize());
- memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
- }
- facep->setVertexBuffer(buff);
- }
- else
- {
- if (buff->getNumIndices() == num_indices &&
- buff->getNumVerts() == num_vertices)
- {
- terse_update = true;
- }
- else
- {
+ if (!buff->allocateBuffer(num_vertices, num_indices))
+ {
+ LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to "
+ << num_vertices << " vertices and "
+ << num_indices << " indices" << LL_ENDL;
+ // Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
+ facep->setSize(1, 3);
+ buff->allocateBuffer(1, 3);
+ memset((U8*) buff->getMappedData(), 0, buff->getSize());
+ memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
+ }
+ facep->setVertexBuffer(buff);
+ }
+ else
+ {
+ if (buff->getNumIndices() == num_indices &&
+ buff->getNumVerts() == num_vertices)
+ {
+ terse_update = true;
+ }
+ else
+ {
buff = new LLVertexBuffer(buff->getTypeMask());
if (!buff->allocateBuffer(num_vertices, num_indices))
{
- LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL;
- // Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
- facep->setSize(1, 3);
- buff->allocateBuffer(1, 3);
- memset((U8*) buff->getMappedData(), 0, buff->getSize());
- memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
- }
- }
- }
-
-
- // This is a hack! Avatars have their own pool, so we are detecting
- // the case of more than one avatar in the pool (thus > 0 instead of >= 0)
- if (facep->getGeomIndex() > 0)
- {
- LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL;
- }
-
- if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices())
- {
- for(S32 k = j ; k < part_index ; k++)
- {
- bool rigid = false;
- if (k == MESH_ID_EYEBALL_LEFT ||
- k == MESH_ID_EYEBALL_RIGHT)
- {
- //eyeballs can't have terse updates since they're never rendered with
- //the hardware skinning shader
- rigid = true;
- }
-
- LLViewerJoint* mesh = getViewerJoint(k);
- if (mesh)
- {
- mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
- }
- }
- }
-
- stop_glerror();
- buff->unmapBuffer();
-
- if(!f_num)
- {
- f_num += mNumInitFaces ;
- }
- else
- {
- f_num++ ;
- }
- }
- }
+ LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL;
+ // Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
+ facep->setSize(1, 3);
+ buff->allocateBuffer(1, 3);
+ memset((U8*) buff->getMappedData(), 0, buff->getSize());
+ memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
+ }
+ }
+ }
+
+
+ // This is a hack! Avatars have their own pool, so we are detecting
+ // the case of more than one avatar in the pool (thus > 0 instead of >= 0)
+ if (facep->getGeomIndex() > 0)
+ {
+ LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL;
+ }
+
+ if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices())
+ {
+ for(S32 k = j ; k < part_index ; k++)
+ {
+ bool rigid = false;
+ if (k == MESH_ID_EYEBALL_LEFT ||
+ k == MESH_ID_EYEBALL_RIGHT)
+ {
+ //eyeballs can't have terse updates since they're never rendered with
+ //the hardware skinning shader
+ rigid = true;
+ }
+
+ LLViewerJoint* mesh = getViewerJoint(k);
+ if (mesh)
+ {
+ mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+ }
+ }
+ }
+
+ stop_glerror();
+ buff->unmapBuffer();
+
+ if(!f_num)
+ {
+ f_num += mNumInitFaces ;
+ }
+ else
+ {
+ f_num++ ;
+ }
+ }
+ }
}
//------------------------------------------------------------------------
@@ -2448,78 +2448,78 @@ void LLVOAvatar::updateMeshData()
// LLVOAvatar::processUpdateMessage()
//------------------------------------------------------------------------
U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp)
+ void **user_data,
+ U32 block_num, const EObjectUpdateType update_type,
+ LLDataPacker *dp)
{
- const BOOL has_name = !getNVPair("FirstName");
+ const BOOL has_name = !getNVPair("FirstName");
- // Do base class updates...
- U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
+ // Do base class updates...
+ U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
- // Print out arrival information once we have name of avatar.
+ // Print out arrival information once we have name of avatar.
if (has_name && getNVPair("FirstName"))
{
mDebugExistenceTimer.reset();
debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");
}
- if(retval & LLViewerObject::INVALID_UPDATE)
- {
- if (isSelf())
- {
- //tell sim to cancel this update
- gAgent.teleportViaLocation(gAgent.getPositionGlobal());
- }
- }
+ if(retval & LLViewerObject::INVALID_UPDATE)
+ {
+ if (isSelf())
+ {
+ //tell sim to cancel this update
+ gAgent.teleportViaLocation(gAgent.getPositionGlobal());
+ }
+ }
- return retval;
+ return retval;
}
LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid)
{
- LLViewerFetchedTexture *result = NULL;
-
- if (uuid == IMG_DEFAULT_AVATAR ||
- uuid == IMG_DEFAULT ||
- uuid == IMG_INVISIBLE)
- {
- // Should already exist, don't need to find it on sim or baked-texture host.
- result = gTextureList.findImage(uuid, TEX_LIST_STANDARD);
- }
- if (!result)
- {
- const std::string url = getImageURL(te,uuid);
-
- if (url.empty())
- {
- LL_WARNS() << "unable to determine URL for te " << te << " uuid " << uuid << LL_ENDL;
- return NULL;
- }
- LL_DEBUGS("Avatar") << avString() << "get server-bake image from URL " << url << LL_ENDL;
- result = LLViewerTextureManager::getFetchedTextureFromUrl(
- url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
- if (result->isMissingAsset())
- {
- result->setIsMissingAsset(false);
- }
-
- }
- return result;
+ LLViewerFetchedTexture *result = NULL;
+
+ if (uuid == IMG_DEFAULT_AVATAR ||
+ uuid == IMG_DEFAULT ||
+ uuid == IMG_INVISIBLE)
+ {
+ // Should already exist, don't need to find it on sim or baked-texture host.
+ result = gTextureList.findImage(uuid, TEX_LIST_STANDARD);
+ }
+ if (!result)
+ {
+ const std::string url = getImageURL(te,uuid);
+
+ if (url.empty())
+ {
+ LL_WARNS() << "unable to determine URL for te " << te << " uuid " << uuid << LL_ENDL;
+ return NULL;
+ }
+ LL_DEBUGS("Avatar") << avString() << "get server-bake image from URL " << url << LL_ENDL;
+ result = LLViewerTextureManager::getFetchedTextureFromUrl(
+ url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
+ if (result->isMissingAsset())
+ {
+ result->setIsMissingAsset(false);
+ }
+
+ }
+ return result;
}
// virtual
S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
{
- if (!isIndexBakedTexture((ETextureIndex)te))
- {
- // Sim still sends some uuids for non-baked slots sometimes - ignore.
- return LLViewerObject::setTETexture(te, LLUUID::null);
- }
+ if (!isIndexBakedTexture((ETextureIndex)te))
+ {
+ // Sim still sends some uuids for non-baked slots sometimes - ignore.
+ return LLViewerObject::setTETexture(te, LLUUID::null);
+ }
- LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid);
- llassert(image);
- return setTETextureCore(te, image);
+ LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid);
+ llassert(image);
+ return setTETextureCore(te, image);
}
//------------------------------------------------------------------------
@@ -2527,26 +2527,26 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
//------------------------------------------------------------------------
void LLVOAvatar::dumpAnimationState()
{
- LL_INFOS() << "==============================================" << LL_ENDL;
- for (LLVOAvatar::AnimIterator it = mSignaledAnimations.begin(); it != mSignaledAnimations.end(); ++it)
- {
- LLUUID id = it->first;
- std::string playtag = "";
- if (mPlayingAnimations.find(id) != mPlayingAnimations.end())
- {
- playtag = "*";
- }
- LL_INFOS() << gAnimLibrary.animationName(id) << playtag << LL_ENDL;
- }
- for (LLVOAvatar::AnimIterator it = mPlayingAnimations.begin(); it != mPlayingAnimations.end(); ++it)
- {
- LLUUID id = it->first;
- bool is_signaled = mSignaledAnimations.find(id) != mSignaledAnimations.end();
- if (!is_signaled)
- {
- LL_INFOS() << gAnimLibrary.animationName(id) << "!S" << LL_ENDL;
- }
- }
+ LL_INFOS() << "==============================================" << LL_ENDL;
+ for (LLVOAvatar::AnimIterator it = mSignaledAnimations.begin(); it != mSignaledAnimations.end(); ++it)
+ {
+ LLUUID id = it->first;
+ std::string playtag = "";
+ if (mPlayingAnimations.find(id) != mPlayingAnimations.end())
+ {
+ playtag = "*";
+ }
+ LL_INFOS() << gAnimLibrary.animationName(id) << playtag << LL_ENDL;
+ }
+ for (LLVOAvatar::AnimIterator it = mPlayingAnimations.begin(); it != mPlayingAnimations.end(); ++it)
+ {
+ LLUUID id = it->first;
+ bool is_signaled = mSignaledAnimations.find(id) != mSignaledAnimations.end();
+ if (!is_signaled)
+ {
+ LL_INFOS() << gAnimLibrary.animationName(id) << "!S" << LL_ENDL;
+ }
+ }
}
//------------------------------------------------------------------------
@@ -2556,118 +2556,118 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (isDead())
- {
- LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
- return;
- }
+ if (isDead())
+ {
+ LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
+ return;
+ }
// record time and refresh "tooSlow" status
updateTooSlow();
- static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
- if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
- && !disable_all_render_types && !isSelf())
- {
+ static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
+ if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
+ && !disable_all_render_types && !isSelf())
+ {
if (!mIsControlAvatar)
{
idleUpdateNameTag(idleCalcNameTagPosition(mLastRootPos));
}
- return;
- }
+ return;
+ }
// Update should be happening max once per frame.
- if ((mLastAnimExtents[0]==LLVector3())||
- (mLastAnimExtents[1])==LLVector3())
- {
- mNeedsExtentUpdate = true;
- }
- else
- {
- const S32 upd_freq = 4; // force update every upd_freq frames.
- mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
- }
-
+ if ((mLastAnimExtents[0]==LLVector3())||
+ (mLastAnimExtents[1])==LLVector3())
+ {
+ mNeedsExtentUpdate = true;
+ }
+ else
+ {
+ const S32 upd_freq = 4; // force update every upd_freq frames.
+ mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
+ }
+
LLScopedContextString str("avatar_idle_update " + getFullname());
-
- checkTextureLoading() ;
-
- // force immediate pixel area update on avatars using last frames data (before drawable or camera updates)
- setPixelAreaAndAngle(gAgent);
-
- // force asynchronous drawable update
- if(mDrawable.notNull())
- {
- if (isSitting() && getParent())
- {
- LLViewerObject *root_object = (LLViewerObject*)getRoot();
- LLDrawable* drawablep = root_object->mDrawable;
- // if this object hasn't already been updated by another avatar...
- if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE))
- {
- if (root_object->isSelected())
- {
- gPipeline.updateMoveNormalAsync(drawablep);
- }
- else
- {
- gPipeline.updateMoveDampedAsync(drawablep);
- }
- }
- }
- else
- {
- gPipeline.updateMoveDampedAsync(mDrawable);
- }
- }
-
- //--------------------------------------------------------------------
- // set alpha flag depending on state
- //--------------------------------------------------------------------
-
- if (isSelf())
- {
- LLViewerObject::idleUpdate(agent, time);
-
- // trigger fidget anims
- if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS))
- {
- agent.fidget();
- }
- }
- else
- {
- // Should override the idleUpdate stuff and leave out the angular update part.
- LLQuaternion rotation = getRotation();
- LLViewerObject::idleUpdate(agent, time);
- setRotation(rotation);
- }
-
- // attach objects that were waiting for a drawable
- lazyAttach();
-
- // animate the character
- // store off last frame's root position to be consistent with camera position
- mLastRootPos = mRoot->getWorldPosition();
- BOOL detailed_update = updateCharacter(agent);
-
- static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
- bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) &&
- LLVoiceClient::getInstance()->getVoiceEnabled(mID);
+
+ checkTextureLoading() ;
+
+ // force immediate pixel area update on avatars using last frames data (before drawable or camera updates)
+ setPixelAreaAndAngle(gAgent);
+
+ // force asynchronous drawable update
+ if(mDrawable.notNull())
+ {
+ if (isSitting() && getParent())
+ {
+ LLViewerObject *root_object = (LLViewerObject*)getRoot();
+ LLDrawable* drawablep = root_object->mDrawable;
+ // if this object hasn't already been updated by another avatar...
+ if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE))
+ {
+ if (root_object->isSelected())
+ {
+ gPipeline.updateMoveNormalAsync(drawablep);
+ }
+ else
+ {
+ gPipeline.updateMoveDampedAsync(drawablep);
+ }
+ }
+ }
+ else
+ {
+ gPipeline.updateMoveDampedAsync(mDrawable);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // set alpha flag depending on state
+ //--------------------------------------------------------------------
+
+ if (isSelf())
+ {
+ LLViewerObject::idleUpdate(agent, time);
+
+ // trigger fidget anims
+ if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS))
+ {
+ agent.fidget();
+ }
+ }
+ else
+ {
+ // Should override the idleUpdate stuff and leave out the angular update part.
+ LLQuaternion rotation = getRotation();
+ LLViewerObject::idleUpdate(agent, time);
+ setRotation(rotation);
+ }
+
+ // attach objects that were waiting for a drawable
+ lazyAttach();
+
+ // animate the character
+ // store off last frame's root position to be consistent with camera position
+ mLastRootPos = mRoot->getWorldPosition();
+ BOOL detailed_update = updateCharacter(agent);
+
+ static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
+ bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) &&
+ LLVoiceClient::getInstance()->getVoiceEnabled(mID);
LLVector3 hud_name_pos = idleCalcNameTagPosition(mLastRootPos);
- idleUpdateVoiceVisualizer(voice_enabled, hud_name_pos);
- idleUpdateMisc( detailed_update );
- idleUpdateAppearanceAnimation();
- if (detailed_update)
- {
- idleUpdateLipSync( voice_enabled );
- idleUpdateLoadingEffect();
- idleUpdateBelowWater(); // wind effect uses this
- idleUpdateWindEffect();
- }
-
- idleUpdateNameTag(hud_name_pos);
+ idleUpdateVoiceVisualizer(voice_enabled, hud_name_pos);
+ idleUpdateMisc( detailed_update );
+ idleUpdateAppearanceAnimation();
+ if (detailed_update)
+ {
+ idleUpdateLipSync( voice_enabled );
+ idleUpdateLoadingEffect();
+ idleUpdateBelowWater(); // wind effect uses this
+ idleUpdateWindEffect();
+ }
+
+ idleUpdateNameTag(hud_name_pos);
// Complexity has stale mechanics, but updates still can be very rapid
// so spread avatar complexity calculations over frames to lesen load from
@@ -2698,7 +2698,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
{
- // DEPRECATED
+ // DEPRECATED
// replace with LLPipeline::profileAvatar?
// Avatar profile takes ~ 0.5ms while idleUpdateRenderComplexity takes ~5ms
// (both are unacceptably costly)
@@ -2709,96 +2709,96 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled, const LLVector3 &position)
{
- bool render_visualizer = voice_enabled;
-
- // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
- if(isSelf())
- {
+ bool render_visualizer = voice_enabled;
+
+ // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
+ if(isSelf())
+ {
static LLCachedControl<bool> voice_disable_mic(gSavedSettings, "VoiceDisableMic");
- if(gAgentCamera.cameraMouselook() || voice_disable_mic)
- {
- render_visualizer = false;
- }
- }
-
- mVoiceVisualizer->setVoiceEnabled(render_visualizer);
-
- if ( voice_enabled )
- {
- //----------------------------------------------------------------
- // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
- //----------------------------------------------------------------
- if( isSelf() )
- {
- //----------------------------------------------------------------------------------------
- // The following takes the voice signal and uses that to trigger gesticulations.
- //----------------------------------------------------------------------------------------
- int lastGesticulationLevel = mCurrentGesticulationLevel;
- mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
-
- //---------------------------------------------------------------------------------------------------
- // If "current gesticulation level" changes, we catch this, and trigger the new gesture
- //---------------------------------------------------------------------------------------------------
- if ( lastGesticulationLevel != mCurrentGesticulationLevel )
- {
- if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
- {
- std::string gestureString = "unInitialized";
- if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
- else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
- else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
- else { LL_INFOS() << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << LL_ENDL; }
-
- // this is the call that Karl S. created for triggering gestures from within the code.
- LLGestureMgr::instance().triggerAndReviseString( gestureString );
- }
- }
-
- } //if( isSelf() )
-
- //-----------------------------------------------------------------------------------------------------------------
- // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
- // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
- //
- // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
- // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
- //-----------------------------------------------------------------------------------------------------------------
- if (LLVoiceClient::getInstance()->getIsSpeaking( mID ))
- {
- if (!mVoiceVisualizer->getCurrentlySpeaking())
- {
- mVoiceVisualizer->setStartSpeaking();
-
- //printf( "gAwayTimer.reset();\n" );
- }
-
- mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) );
-
- if( isSelf() )
- {
- gAgent.clearAFK();
- }
- }
- else
- {
- if ( mVoiceVisualizer->getCurrentlySpeaking() )
- {
- mVoiceVisualizer->setStopSpeaking();
-
- if ( mLipSyncActive )
- {
- if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight());
- if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight());
-
- mLipSyncActive = false;
- LLCharacter::updateVisualParams();
- dirtyMesh();
- }
- }
- }
+ if(gAgentCamera.cameraMouselook() || voice_disable_mic)
+ {
+ render_visualizer = false;
+ }
+ }
+
+ mVoiceVisualizer->setVoiceEnabled(render_visualizer);
+
+ if ( voice_enabled )
+ {
+ //----------------------------------------------------------------
+ // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
+ //----------------------------------------------------------------
+ if( isSelf() )
+ {
+ //----------------------------------------------------------------------------------------
+ // The following takes the voice signal and uses that to trigger gesticulations.
+ //----------------------------------------------------------------------------------------
+ int lastGesticulationLevel = mCurrentGesticulationLevel;
+ mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
+
+ //---------------------------------------------------------------------------------------------------
+ // If "current gesticulation level" changes, we catch this, and trigger the new gesture
+ //---------------------------------------------------------------------------------------------------
+ if ( lastGesticulationLevel != mCurrentGesticulationLevel )
+ {
+ if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
+ {
+ std::string gestureString = "unInitialized";
+ if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
+ else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
+ else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
+ else { LL_INFOS() << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << LL_ENDL; }
+
+ // this is the call that Karl S. created for triggering gestures from within the code.
+ LLGestureMgr::instance().triggerAndReviseString( gestureString );
+ }
+ }
+
+ } //if( isSelf() )
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
+ // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
+ //
+ // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
+ // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
+ //-----------------------------------------------------------------------------------------------------------------
+ if (LLVoiceClient::getInstance()->getIsSpeaking( mID ))
+ {
+ if (!mVoiceVisualizer->getCurrentlySpeaking())
+ {
+ mVoiceVisualizer->setStartSpeaking();
+
+ //printf( "gAwayTimer.reset();\n" );
+ }
+
+ mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) );
+
+ if( isSelf() )
+ {
+ gAgent.clearAFK();
+ }
+ }
+ else
+ {
+ if ( mVoiceVisualizer->getCurrentlySpeaking() )
+ {
+ mVoiceVisualizer->setStopSpeaking();
+
+ if ( mLipSyncActive )
+ {
+ if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight());
+ if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight());
+
+ mLipSyncActive = false;
+ LLCharacter::updateVisualParams();
+ dirtyMesh();
+ }
+ }
+ }
mVoiceVisualizer->setPositionAgent(position);
- }//if ( voiceEnabled )
-}
+ }//if ( voiceEnabled )
+}
static void override_bbox(LLDrawable* drawable, LLVector4a* extents)
{
@@ -2811,31 +2811,31 @@ static void override_bbox(LLDrawable* drawable, LLVector4a* extents)
void LLVOAvatar::idleUpdateMisc(bool detailed_update)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (LLVOAvatar::sJointDebug)
- {
- LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL;
- }
+ if (LLVOAvatar::sJointDebug)
+ {
+ LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL;
+ }
- LLJoint::sNumUpdates = 0;
- LLJoint::sNumTouches = 0;
+ LLJoint::sNumUpdates = 0;
+ LLJoint::sNumTouches = 0;
- BOOL visible = isVisible() || mNeedsAnimUpdate;
+ BOOL visible = isVisible() || mNeedsAnimUpdate;
- // update attachments positions
- if (detailed_update)
- {
+ // update attachments positions
+ if (detailed_update)
+ {
U32 draw_order = 0;
S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
LLViewerObject* attached_object = attachment_iter->get();
if (!attached_object
|| attached_object->isDead()
@@ -2846,9 +2846,9 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
-
- if (visible || !(bridge && bridge->getRadius() < 2.0))
- {
+
+ if (visible || !(bridge && bridge->getRadius() < 2.0))
+ {
//override rigged attachments' octree spatial extents with this avatar's bounding box
bool rigged = false;
if (bridge)
@@ -2902,839 +2902,839 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
}
- attached_object->updateText();
- }
- }
- }
- }
-
- mNeedsAnimUpdate = FALSE;
-
- if (isImpostor() && !mNeedsImpostorUpdate)
- {
- LL_ALIGN_16(LLVector4a ext[2]);
- F32 distance;
- LLVector3 angle;
-
- getImpostorValues(ext, angle, distance);
-
- for (U32 i = 0; i < 3 && !mNeedsImpostorUpdate; i++)
- {
- F32 cur_angle = angle.mV[i];
- F32 old_angle = mImpostorAngle.mV[i];
- F32 angle_diff = fabsf(cur_angle-old_angle);
-
- if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 2;
- }
- }
-
- if (detailed_update && !mNeedsImpostorUpdate)
- { //update impostor if view angle, distance, or bounding box change
- //significantly
-
- F32 dist_diff = fabsf(distance-mImpostorDistance);
- if (dist_diff/mImpostorDistance > 0.1f)
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 3;
- }
- else
- {
- ext[0].load3(mLastAnimExtents[0].mV);
+ attached_object->updateText();
+ }
+ }
+ }
+ }
+
+ mNeedsAnimUpdate = FALSE;
+
+ if (isImpostor() && !mNeedsImpostorUpdate)
+ {
+ LL_ALIGN_16(LLVector4a ext[2]);
+ F32 distance;
+ LLVector3 angle;
+
+ getImpostorValues(ext, angle, distance);
+
+ for (U32 i = 0; i < 3 && !mNeedsImpostorUpdate; i++)
+ {
+ F32 cur_angle = angle.mV[i];
+ F32 old_angle = mImpostorAngle.mV[i];
+ F32 angle_diff = fabsf(cur_angle-old_angle);
+
+ if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 2;
+ }
+ }
+
+ if (detailed_update && !mNeedsImpostorUpdate)
+ { //update impostor if view angle, distance, or bounding box change
+ //significantly
+
+ F32 dist_diff = fabsf(distance-mImpostorDistance);
+ if (dist_diff/mImpostorDistance > 0.1f)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 3;
+ }
+ else
+ {
+ ext[0].load3(mLastAnimExtents[0].mV);
ext[1].load3(mLastAnimExtents[1].mV);
// Expensive. Just call this once per frame, in updateSpatialExtents();
//calculateSpatialExtents(ext[0], ext[1]);
- LLVector4a diff;
- diff.setSub(ext[1], mImpostorExtents[1]);
- if (diff.getLength3().getF32() > 0.05f)
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 4;
- }
- else
- {
- diff.setSub(ext[0], mImpostorExtents[0]);
- if (diff.getLength3().getF32() > 0.05f)
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 5;
- }
- }
- }
- }
- }
+ LLVector4a diff;
+ diff.setSub(ext[1], mImpostorExtents[1]);
+ if (diff.getLength3().getF32() > 0.05f)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 4;
+ }
+ else
+ {
+ diff.setSub(ext[0], mImpostorExtents[0]);
+ if (diff.getLength3().getF32() > 0.05f)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 5;
+ }
+ }
+ }
+ }
+ }
if (mDrawable.notNull())
{
- mDrawable->movePartition();
-
- //force a move if sitting on an active object
- if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
- {
- gPipeline.markMoved(mDrawable, TRUE);
- }
+ mDrawable->movePartition();
+
+ //force a move if sitting on an active object
+ if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
+ {
+ gPipeline.markMoved(mDrawable, TRUE);
+ }
}
}
void LLVOAvatar::idleUpdateAppearanceAnimation()
{
- // update morphing params
- if (mAppearanceAnimating)
- {
- ESex avatar_sex = getSex();
- F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32();
- if (appearance_anim_time >= APPEARANCE_MORPH_TIME)
- {
- mAppearanceAnimating = FALSE;
- for (LLVisualParam *param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
- {
- if (param->isTweakable())
- {
- param->stopAnimating();
- }
- }
- updateVisualParams();
- }
- else
- {
- F32 morph_amt = calcMorphAmount();
- LLVisualParam *param;
-
- if (!isSelf())
- {
- // animate only top level params for non-self avatars
- for (param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
- {
- if (param->isTweakable())
- {
- param->animate(morph_amt);
- }
- }
- }
-
- // apply all params
- for (param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
- {
- param->apply(avatar_sex);
- }
-
- mLastAppearanceBlendTime = appearance_anim_time;
- }
- dirtyMesh();
- }
+ // update morphing params
+ if (mAppearanceAnimating)
+ {
+ ESex avatar_sex = getSex();
+ F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32();
+ if (appearance_anim_time >= APPEARANCE_MORPH_TIME)
+ {
+ mAppearanceAnimating = FALSE;
+ for (LLVisualParam *param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ if (param->isTweakable())
+ {
+ param->stopAnimating();
+ }
+ }
+ updateVisualParams();
+ }
+ else
+ {
+ F32 morph_amt = calcMorphAmount();
+ LLVisualParam *param;
+
+ if (!isSelf())
+ {
+ // animate only top level params for non-self avatars
+ for (param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ if (param->isTweakable())
+ {
+ param->animate(morph_amt);
+ }
+ }
+ }
+
+ // apply all params
+ for (param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ param->apply(avatar_sex);
+ }
+
+ mLastAppearanceBlendTime = appearance_anim_time;
+ }
+ dirtyMesh();
+ }
}
F32 LLVOAvatar::calcMorphAmount()
{
- F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32();
- F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME);
- F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME);
+ F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32();
+ F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME);
+ F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME);
- F32 morph_amt;
- if (last_blend_frac == 1.f)
- {
- morph_amt = 1.f;
- }
- else
- {
- morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac);
- }
+ F32 morph_amt;
+ if (last_blend_frac == 1.f)
+ {
+ morph_amt = 1.f;
+ }
+ else
+ {
+ morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac);
+ }
- return morph_amt;
+ return morph_amt;
}
void LLVOAvatar::idleUpdateLipSync(bool voice_enabled)
{
- // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
+ // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
if ( voice_enabled
&& mLastRezzedStatus > 0 // no point updating lip-sync for clouds
&& (LLVoiceClient::getInstance()->lipSyncEnabled())
&& LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
- {
- F32 ooh_morph_amount = 0.0f;
- F32 aah_morph_amount = 0.0f;
+ {
+ F32 ooh_morph_amount = 0.0f;
+ F32 aah_morph_amount = 0.0f;
- mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount );
+ mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount );
- if( mOohMorph )
- {
- F32 ooh_weight = mOohMorph->getMinWeight()
- + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight());
+ if( mOohMorph )
+ {
+ F32 ooh_weight = mOohMorph->getMinWeight()
+ + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight());
- mOohMorph->setWeight( ooh_weight);
- }
+ mOohMorph->setWeight( ooh_weight);
+ }
- if( mAahMorph )
- {
- F32 aah_weight = mAahMorph->getMinWeight()
- + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight());
+ if( mAahMorph )
+ {
+ F32 aah_weight = mAahMorph->getMinWeight()
+ + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight());
- mAahMorph->setWeight( aah_weight);
- }
+ mAahMorph->setWeight( aah_weight);
+ }
- mLipSyncActive = true;
- LLCharacter::updateVisualParams();
- dirtyMesh();
- }
+ mLipSyncActive = true;
+ LLCharacter::updateVisualParams();
+ dirtyMesh();
+ }
}
void LLVOAvatar::idleUpdateLoadingEffect()
{
- // update visibility when avatar is partially loaded
- if (updateIsFullyLoaded()) // changed?
- {
- if (isFullyLoaded())
- {
- if (mFirstFullyVisible)
- {
- mFirstFullyVisible = FALSE;
- if (isSelf())
- {
- LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
- LLAppearanceMgr::instance().onFirstFullyVisible();
- }
- else
- {
- LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
- }
- }
-
- deleteParticleSource();
- updateLOD();
- }
- else
- {
- LLPartSysData particle_parameters;
-
- // fancy particle cloud designed by Brent
- particle_parameters.mPartData.mMaxAge = 4.f;
- particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
- particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
- particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f;
- particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f;
- particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f;
- particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
- particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
- particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
- particle_parameters.mPartImageID = sCloudTexture->getID();
- particle_parameters.mMaxAge = 0.f;
- particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
- particle_parameters.mInnerAngle = F_PI;
- particle_parameters.mOuterAngle = 0.f;
- particle_parameters.mBurstRate = 0.02f;
- particle_parameters.mBurstRadius = 0.0f;
- particle_parameters.mBurstPartCount = 1;
- particle_parameters.mBurstSpeedMin = 0.1f;
- particle_parameters.mBurstSpeedMax = 1.f;
- particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
- LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK |
- LLPartData::LL_PART_TARGET_POS_MASK );
-
- // do not generate particles for dummy or overly-complex avatars
- if (!mIsDummy && !isTooComplex() && !isTooSlow())
- {
- setParticleSource(particle_parameters, getID());
- }
- }
- }
-}
+ // update visibility when avatar is partially loaded
+ if (updateIsFullyLoaded()) // changed?
+ {
+ if (isFullyLoaded())
+ {
+ if (mFirstFullyVisible)
+ {
+ mFirstFullyVisible = FALSE;
+ if (isSelf())
+ {
+ LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
+ LLAppearanceMgr::instance().onFirstFullyVisible();
+ }
+ else
+ {
+ LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
+ }
+ }
+
+ deleteParticleSource();
+ updateLOD();
+ }
+ else
+ {
+ LLPartSysData particle_parameters;
+
+ // fancy particle cloud designed by Brent
+ particle_parameters.mPartData.mMaxAge = 4.f;
+ particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
+ particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
+ particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f;
+ particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f;
+ particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f;
+ particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
+ particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
+ particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
+ particle_parameters.mPartImageID = sCloudTexture->getID();
+ particle_parameters.mMaxAge = 0.f;
+ particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
+ particle_parameters.mInnerAngle = F_PI;
+ particle_parameters.mOuterAngle = 0.f;
+ particle_parameters.mBurstRate = 0.02f;
+ particle_parameters.mBurstRadius = 0.0f;
+ particle_parameters.mBurstPartCount = 1;
+ particle_parameters.mBurstSpeedMin = 0.1f;
+ particle_parameters.mBurstSpeedMax = 1.f;
+ particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
+ LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK |
+ LLPartData::LL_PART_TARGET_POS_MASK );
+
+ // do not generate particles for dummy or overly-complex avatars
+ if (!mIsDummy && !isTooComplex() && !isTooSlow())
+ {
+ setParticleSource(particle_parameters, getID());
+ }
+ }
+ }
+}
void LLVOAvatar::idleUpdateWindEffect()
{
- // update wind effect
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
- {
- F32 hover_strength = 0.f;
- F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
- mRippleTimeLast = mRippleTimer.getElapsedTimeF32();
- LLVector3 velocity = getVelocity();
- F32 speed = velocity.length();
- //RN: velocity varies too much frame to frame for this to work
- mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f));
- mLastVel = velocity;
- LLVector4 wind;
- wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity);
-
- if (mInAir)
- {
- hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed);
- }
-
- if (mBelowWater)
- {
- // TODO: make cloth flow more gracefully when underwater
- hover_strength += UNDERWATER_EFFECT_STRENGTH;
- }
-
- wind.mV[VZ] += hover_strength;
- wind.normalize();
-
- wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f);
- F32 interp;
- if (wind.mV[VW] > mWindVec.mV[VW])
- {
- interp = LLSmoothInterpolation::getInterpolant(0.2f);
- }
- else
- {
- interp = LLSmoothInterpolation::getInterpolant(0.4f);
- }
- mWindVec = lerp(mWindVec, wind, interp);
-
- F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f);
- mWindFreq = lerp(mWindFreq, wind_freq, interp);
-
- if (mBelowWater)
- {
- mWindFreq *= UNDERWATER_FREQUENCY_DAMP;
- }
-
- mRipplePhase += (time_delta * mWindFreq);
- if (mRipplePhase > F_TWO_PI)
- {
- mRipplePhase = fmodf(mRipplePhase, F_TWO_PI);
- }
- }
+ // update wind effect
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
+ {
+ F32 hover_strength = 0.f;
+ F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
+ mRippleTimeLast = mRippleTimer.getElapsedTimeF32();
+ LLVector3 velocity = getVelocity();
+ F32 speed = velocity.length();
+ //RN: velocity varies too much frame to frame for this to work
+ mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f));
+ mLastVel = velocity;
+ LLVector4 wind;
+ wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity);
+
+ if (mInAir)
+ {
+ hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed);
+ }
+
+ if (mBelowWater)
+ {
+ // TODO: make cloth flow more gracefully when underwater
+ hover_strength += UNDERWATER_EFFECT_STRENGTH;
+ }
+
+ wind.mV[VZ] += hover_strength;
+ wind.normalize();
+
+ wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f);
+ F32 interp;
+ if (wind.mV[VW] > mWindVec.mV[VW])
+ {
+ interp = LLSmoothInterpolation::getInterpolant(0.2f);
+ }
+ else
+ {
+ interp = LLSmoothInterpolation::getInterpolant(0.4f);
+ }
+ mWindVec = lerp(mWindVec, wind, interp);
+
+ F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f);
+ mWindFreq = lerp(mWindFreq, wind_freq, interp);
+
+ if (mBelowWater)
+ {
+ mWindFreq *= UNDERWATER_FREQUENCY_DAMP;
+ }
+
+ mRipplePhase += (time_delta * mWindFreq);
+ if (mRipplePhase > F_TWO_PI)
+ {
+ mRipplePhase = fmodf(mRipplePhase, F_TWO_PI);
+ }
+ }
}
void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- // update chat bubble
- //--------------------------------------------------------------------
- // draw text label over character's head
- //--------------------------------------------------------------------
- if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME)
- {
- mChats.clear();
- }
-
- const F32 time_visible = mTimeVisible.getElapsedTimeF32();
+ // update chat bubble
+ //--------------------------------------------------------------------
+ // draw text label over character's head
+ //--------------------------------------------------------------------
+ if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME)
+ {
+ mChats.clear();
+ }
+
+ const F32 time_visible = mTimeVisible.getElapsedTimeF32();
static LLCachedControl<F32> NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds
static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds
static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles");
- bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
- bool render_name = visible_chat ||
- (((sRenderName == RENDER_NAME_ALWAYS) ||
- (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
- // If it's your own avatar, don't draw in mouselook, and don't
- // draw if we're specifically hiding our own name.
- if (isSelf())
- {
+ bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
+ bool render_name = visible_chat ||
+ (((sRenderName == RENDER_NAME_ALWAYS) ||
+ (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
+ // If it's your own avatar, don't draw in mouselook, and don't
+ // draw if we're specifically hiding our own name.
+ if (isSelf())
+ {
static LLCachedControl<bool> render_name_show_self(gSavedSettings, "RenderNameShowSelf");
static LLCachedControl<S32> name_tag_mode(gSavedSettings, "AvatarNameTagMode");
- render_name = render_name
- && !gAgentCamera.cameraMouselook()
- && (visible_chat || (render_name_show_self && name_tag_mode));
- }
-
- if ( !render_name )
- {
- if (mNameText)
- {
- // ...clean up old name tag
- mNameText->markDead();
- mNameText = NULL;
- sNumVisibleChatBubbles--;
- }
- return;
- }
-
- bool new_name = FALSE;
- if (visible_chat != mVisibleChat)
- {
- mVisibleChat = visible_chat;
- new_name = TRUE;
- }
-
- if (sRenderGroupTitles != mRenderGroupTitles)
- {
- mRenderGroupTitles = sRenderGroupTitles;
- new_name = TRUE;
- }
-
- // First Calculate Alpha
- // If alpha > 0, create mNameText if necessary, otherwise delete it
- F32 alpha = 0.f;
- if (mAppAngle > 5.f)
- {
- const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
- if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
- {
- alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
- }
- else
- {
- // ...not fading, full alpha
- alpha = 1.f;
- }
- }
- else if (mAppAngle > 2.f)
- {
- // far away is faded out also
- alpha = (mAppAngle-2.f)/3.f;
- }
-
- if (alpha <= 0.f)
- {
- if (mNameText)
- {
- mNameText->markDead();
- mNameText = NULL;
- sNumVisibleChatBubbles--;
- }
- return;
- }
-
- if (!mNameText)
- {
- mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
- LLHUDObject::LL_HUD_NAME_TAG) );
- //mNameText->setMass(10.f);
- mNameText->setSourceObject(this);
- mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
- mNameText->setVisibleOffScreen(TRUE);
- mNameText->setMaxLines(11);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- sNumVisibleChatBubbles++;
- new_name = TRUE;
- }
-
+ render_name = render_name
+ && !gAgentCamera.cameraMouselook()
+ && (visible_chat || (render_name_show_self && name_tag_mode));
+ }
+
+ if ( !render_name )
+ {
+ if (mNameText)
+ {
+ // ...clean up old name tag
+ mNameText->markDead();
+ mNameText = NULL;
+ sNumVisibleChatBubbles--;
+ }
+ return;
+ }
+
+ bool new_name = FALSE;
+ if (visible_chat != mVisibleChat)
+ {
+ mVisibleChat = visible_chat;
+ new_name = TRUE;
+ }
+
+ if (sRenderGroupTitles != mRenderGroupTitles)
+ {
+ mRenderGroupTitles = sRenderGroupTitles;
+ new_name = TRUE;
+ }
+
+ // First Calculate Alpha
+ // If alpha > 0, create mNameText if necessary, otherwise delete it
+ F32 alpha = 0.f;
+ if (mAppAngle > 5.f)
+ {
+ const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+ if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
+ {
+ alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
+ }
+ else
+ {
+ // ...not fading, full alpha
+ alpha = 1.f;
+ }
+ }
+ else if (mAppAngle > 2.f)
+ {
+ // far away is faded out also
+ alpha = (mAppAngle-2.f)/3.f;
+ }
+
+ if (alpha <= 0.f)
+ {
+ if (mNameText)
+ {
+ mNameText->markDead();
+ mNameText = NULL;
+ sNumVisibleChatBubbles--;
+ }
+ return;
+ }
+
+ if (!mNameText)
+ {
+ mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
+ LLHUDObject::LL_HUD_NAME_TAG) );
+ //mNameText->setMass(10.f);
+ mNameText->setSourceObject(this);
+ mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
+ mNameText->setVisibleOffScreen(TRUE);
+ mNameText->setMaxLines(11);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ sNumVisibleChatBubbles++;
+ new_name = TRUE;
+ }
+
mNameText->setPositionAgent(root_pos_last);
- idleUpdateNameTagText(new_name);
- idleUpdateNameTagAlpha(new_name, alpha);
+ idleUpdateNameTagText(new_name);
+ idleUpdateNameTagAlpha(new_name, alpha);
}
void LLVOAvatar::idleUpdateNameTagText(bool new_name)
{
- LLNameValue *title = getNVPair("Title");
- LLNameValue* firstname = getNVPair("FirstName");
- LLNameValue* lastname = getNVPair("LastName");
-
- // Avatars must have a first and last name
- if (!firstname || !lastname) return;
-
- bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
- bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end();
- bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
- bool is_muted;
- if (isSelf())
- {
- is_muted = false;
- }
- else
- {
- is_muted = isInMuteList();
- }
- bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
- bool is_cloud = getIsCloud();
-
- if (is_appearance != mNameAppearance)
- {
- if (is_appearance)
- {
- debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode");
- }
- else
- {
- debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode");
- }
- }
-
- // Rebuild name tag if state change detected
- if (!mNameIsSet
- || new_name
- || (!title && !mTitle.empty())
- || (title && mTitle != title->getString())
- || is_away != mNameAway
- || is_do_not_disturb != mNameDoNotDisturb
- || is_muted != mNameMute
- || is_appearance != mNameAppearance
- || is_friend != mNameFriend
- || is_cloud != mNameCloud)
- {
- LLColor4 name_tag_color = getNameTagColor(is_friend);
-
- clearNameTag();
-
- if (is_away || is_muted || is_do_not_disturb || is_appearance)
- {
- std::string line;
- if (is_away)
- {
- line += LLTrans::getString("AvatarAway");
- line += ", ";
- }
- if (is_do_not_disturb)
- {
- line += LLTrans::getString("AvatarDoNotDisturb");
- line += ", ";
- }
- if (is_muted)
- {
- line += LLTrans::getString("AvatarMuted");
- line += ", ";
- }
- if (is_appearance)
- {
- line += LLTrans::getString("AvatarEditingAppearance");
- line += ", ";
- }
- if (is_cloud)
- {
- line += LLTrans::getString("LoadingData");
- line += ", ";
- }
- // trim last ", "
- line.resize( line.length() - 2 );
- addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerifSmall());
- }
-
- if (sRenderGroupTitles
- && title && title->getString() && title->getString()[0] != '\0')
- {
- std::string title_str = title->getString();
- LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
- addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerifSmall(), true);
- }
-
- static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true);
- static LLUICachedControl<bool> show_usernames("NameTagShowUsernames", true);
-
- if (LLAvatarName::useDisplayNames())
- {
- LLAvatarName av_name;
- if (!LLAvatarNameCache::get(getID(), &av_name))
- {
- // Force a rebuild at next idle
- // Note: do not connect a callback on idle().
- clearNameTag();
- }
-
- // Might be blank if name not available yet, that's OK
- if (show_display_names)
- {
- addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerif(), true);
- }
- // Suppress SLID display if display name matches exactly (ugh)
- if (show_usernames && !av_name.isDisplayNameDefault())
- {
- // *HACK: Desaturate the color
- LLColor4 username_color = name_tag_color * 0.83f;
- addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerifSmall(), true);
- }
- }
- else
- {
- const LLFontGL* font = LLFontGL::getFontSansSerif();
- std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
- addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true);
- }
-
- mNameAway = is_away;
- mNameDoNotDisturb = is_do_not_disturb;
- mNameMute = is_muted;
- mNameAppearance = is_appearance;
- mNameFriend = is_friend;
- mNameCloud = is_cloud;
- mTitle = title ? title->getString() : "";
- LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
- new_name = TRUE;
- }
-
- if (mVisibleChat)
- {
- mNameText->setFont(LLFontGL::getFontSansSerif());
- mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-
- std::deque<LLChat>::iterator chat_iter = mChats.begin();
- mNameText->clearString();
-
- LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
- LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
- LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
- if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
- {
- ++chat_iter;
- }
-
- for(; chat_iter != mChats.end(); ++chat_iter)
- {
- F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
- LLFontGL::StyleFlags style;
- switch(chat_iter->mChatType)
- {
- case CHAT_TYPE_WHISPER:
- style = LLFontGL::ITALIC;
- break;
- case CHAT_TYPE_SHOUT:
- style = LLFontGL::BOLD;
- break;
- default:
- style = LLFontGL::NORMAL;
- break;
- }
- if (chat_fade_amt < 1.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
- }
- else if (chat_fade_amt < 2.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
- }
- else if (chat_fade_amt < 3.f)
- {
- // *NOTE: only remove lines down to minimum number
- mNameText->addLine(chat_iter->mText, old_chat, style);
- }
- }
- mNameText->setVisibleOffScreen(TRUE);
-
- if (mTyping)
- {
- S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
- switch(dot_count)
- {
- case 1:
- mNameText->addLine(".", new_chat);
- break;
- case 2:
- mNameText->addLine("..", new_chat);
- break;
- case 3:
- mNameText->addLine("...", new_chat);
- break;
- }
-
- }
- }
- else
- {
- // ...not using chat bubbles, just names
- mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- mNameText->setVisibleOffScreen(FALSE);
- }
+ LLNameValue *title = getNVPair("Title");
+ LLNameValue* firstname = getNVPair("FirstName");
+ LLNameValue* lastname = getNVPair("LastName");
+
+ // Avatars must have a first and last name
+ if (!firstname || !lastname) return;
+
+ bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
+ bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end();
+ bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
+ bool is_muted;
+ if (isSelf())
+ {
+ is_muted = false;
+ }
+ else
+ {
+ is_muted = isInMuteList();
+ }
+ bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
+ bool is_cloud = getIsCloud();
+
+ if (is_appearance != mNameAppearance)
+ {
+ if (is_appearance)
+ {
+ debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode");
+ }
+ else
+ {
+ debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode");
+ }
+ }
+
+ // Rebuild name tag if state change detected
+ if (!mNameIsSet
+ || new_name
+ || (!title && !mTitle.empty())
+ || (title && mTitle != title->getString())
+ || is_away != mNameAway
+ || is_do_not_disturb != mNameDoNotDisturb
+ || is_muted != mNameMute
+ || is_appearance != mNameAppearance
+ || is_friend != mNameFriend
+ || is_cloud != mNameCloud)
+ {
+ LLColor4 name_tag_color = getNameTagColor(is_friend);
+
+ clearNameTag();
+
+ if (is_away || is_muted || is_do_not_disturb || is_appearance)
+ {
+ std::string line;
+ if (is_away)
+ {
+ line += LLTrans::getString("AvatarAway");
+ line += ", ";
+ }
+ if (is_do_not_disturb)
+ {
+ line += LLTrans::getString("AvatarDoNotDisturb");
+ line += ", ";
+ }
+ if (is_muted)
+ {
+ line += LLTrans::getString("AvatarMuted");
+ line += ", ";
+ }
+ if (is_appearance)
+ {
+ line += LLTrans::getString("AvatarEditingAppearance");
+ line += ", ";
+ }
+ if (is_cloud)
+ {
+ line += LLTrans::getString("LoadingData");
+ line += ", ";
+ }
+ // trim last ", "
+ line.resize( line.length() - 2 );
+ addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall());
+ }
+
+ if (sRenderGroupTitles
+ && title && title->getString() && title->getString()[0] != '\0')
+ {
+ std::string title_str = title->getString();
+ LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
+ addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall(), true);
+ }
+
+ static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true);
+ static LLUICachedControl<bool> show_usernames("NameTagShowUsernames", true);
+
+ if (LLAvatarName::useDisplayNames())
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getID(), &av_name))
+ {
+ // Force a rebuild at next idle
+ // Note: do not connect a callback on idle().
+ clearNameTag();
+ }
+
+ // Might be blank if name not available yet, that's OK
+ if (show_display_names)
+ {
+ addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerif(), true);
+ }
+ // Suppress SLID display if display name matches exactly (ugh)
+ if (show_usernames && !av_name.isDisplayNameDefault())
+ {
+ // *HACK: Desaturate the color
+ LLColor4 username_color = name_tag_color * 0.83f;
+ addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
+ LLFontGL::getFontSansSerifSmall(), true);
+ }
+ }
+ else
+ {
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+ addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true);
+ }
+
+ mNameAway = is_away;
+ mNameDoNotDisturb = is_do_not_disturb;
+ mNameMute = is_muted;
+ mNameAppearance = is_appearance;
+ mNameFriend = is_friend;
+ mNameCloud = is_cloud;
+ mTitle = title ? title->getString() : "";
+ LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
+ new_name = TRUE;
+ }
+
+ if (mVisibleChat)
+ {
+ mNameText->setFont(LLFontGL::getFontSansSerif());
+ mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
+
+ std::deque<LLChat>::iterator chat_iter = mChats.begin();
+ mNameText->clearString();
+
+ LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+ LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+ LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+ if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
+ {
+ ++chat_iter;
+ }
+
+ for(; chat_iter != mChats.end(); ++chat_iter)
+ {
+ F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+ LLFontGL::StyleFlags style;
+ switch(chat_iter->mChatType)
+ {
+ case CHAT_TYPE_WHISPER:
+ style = LLFontGL::ITALIC;
+ break;
+ case CHAT_TYPE_SHOUT:
+ style = LLFontGL::BOLD;
+ break;
+ default:
+ style = LLFontGL::NORMAL;
+ break;
+ }
+ if (chat_fade_amt < 1.f)
+ {
+ F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+ }
+ else if (chat_fade_amt < 2.f)
+ {
+ F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+ }
+ else if (chat_fade_amt < 3.f)
+ {
+ // *NOTE: only remove lines down to minimum number
+ mNameText->addLine(chat_iter->mText, old_chat, style);
+ }
+ }
+ mNameText->setVisibleOffScreen(TRUE);
+
+ if (mTyping)
+ {
+ S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+ switch(dot_count)
+ {
+ case 1:
+ mNameText->addLine(".", new_chat);
+ break;
+ case 2:
+ mNameText->addLine("..", new_chat);
+ break;
+ case 3:
+ mNameText->addLine("...", new_chat);
+ break;
+ }
+
+ }
+ }
+ else
+ {
+ // ...not using chat bubbles, just names
+ mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ mNameText->setVisibleOffScreen(FALSE);
+ }
}
void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses)
{
// extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat
- llassert(mNameText);
- if (mVisibleChat)
- {
- mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH);
- }
- else
- {
- mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH);
- }
+ llassert(mNameText);
+ if (mVisibleChat)
+ {
+ mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH);
+ }
+ else
+ {
+ mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH);
+ }
mNameIsSet |= !line.empty();
}
void LLVOAvatar::clearNameTag()
{
mNameIsSet = false;
- if (mNameText)
- {
- mNameText->setLabel("");
- mNameText->setString("");
- }
- mTimeVisible.reset();
+ if (mNameText)
+ {
+ mNameText->setLabel("");
+ mNameText->setString("");
+ }
+ mTimeVisible.reset();
}
//static
void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id)
{
- LLViewerObject* obj = gObjectList.findObject(agent_id);
- if (!obj) return;
+ LLViewerObject* obj = gObjectList.findObject(agent_id);
+ if (!obj) return;
- LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj);
- if (!avatar) return;
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj);
+ if (!avatar) return;
- avatar->clearNameTag();
+ avatar->clearNameTag();
}
//static
void LLVOAvatar::invalidateNameTags()
{
- std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin();
- for ( ; it != LLCharacter::sInstances.end(); ++it)
- {
- LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it);
- if (!avatar) continue;
- if (avatar->isDead()) continue;
+ std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin();
+ for ( ; it != LLCharacter::sInstances.end(); ++it)
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it);
+ if (!avatar) continue;
+ if (avatar->isDead()) continue;
- avatar->clearNameTag();
- }
+ avatar->clearNameTag();
+ }
}
// Compute name tag position during idle update
LLVector3 LLVOAvatar::idleCalcNameTagPosition(const LLVector3 &root_pos_last)
{
- LLQuaternion root_rot = mRoot->getWorldRotation();
- LLQuaternion inv_root_rot = ~root_rot;
- LLVector3 pixel_right_vec;
- LLVector3 pixel_up_vec;
- LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
- LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
- camera_to_av.normalize();
- LLVector3 local_camera_at = camera_to_av * inv_root_rot;
- LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
- local_camera_up.normalize();
- local_camera_up = local_camera_up * inv_root_rot;
-
- // position is based on head position, does not require mAvatarOffset here. - Nyx
- LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
- mBodySize.mV[VY] * 0.4f,
- mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
-
- local_camera_up.scaleVec(avatar_ellipsoid);
- local_camera_at.scaleVec(avatar_ellipsoid);
-
- LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;
-
- if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
- {
- mTargetRootToHeadOffset = head_offset;
- }
-
- mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f));
-
- LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
- name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
- name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
-
- const F32 water_height = getRegion()->getWaterHeight();
- static const F32 WATER_HEIGHT_DELTA = 0.25f;
- if (name_position[VZ] < water_height + WATER_HEIGHT_DELTA)
- {
- if (LLViewerCamera::getInstance()->getOrigin()[VZ] >= water_height)
- {
- name_position[VZ] = water_height;
- }
- else if (mNameText) // both camera and HUD are below watermark
- {
- F32 name_world_height = mNameText->getWorldHeight();
- F32 max_z_position = water_height - name_world_height;
- if (name_position[VZ] > max_z_position)
- {
- name_position[VZ] = max_z_position;
- }
- }
- }
-
- return name_position;
+ LLQuaternion root_rot = mRoot->getWorldRotation();
+ LLQuaternion inv_root_rot = ~root_rot;
+ LLVector3 pixel_right_vec;
+ LLVector3 pixel_up_vec;
+ LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
+ LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
+ camera_to_av.normalize();
+ LLVector3 local_camera_at = camera_to_av * inv_root_rot;
+ LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
+ local_camera_up.normalize();
+ local_camera_up = local_camera_up * inv_root_rot;
+
+ // position is based on head position, does not require mAvatarOffset here. - Nyx
+ LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+ mBodySize.mV[VY] * 0.4f,
+ mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
+
+ local_camera_up.scaleVec(avatar_ellipsoid);
+ local_camera_at.scaleVec(avatar_ellipsoid);
+
+ LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;
+
+ if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+ {
+ mTargetRootToHeadOffset = head_offset;
+ }
+
+ mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f));
+
+ LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
+ name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
+ name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
+
+ const F32 water_height = getRegion()->getWaterHeight();
+ static const F32 WATER_HEIGHT_DELTA = 0.25f;
+ if (name_position[VZ] < water_height + WATER_HEIGHT_DELTA)
+ {
+ if (LLViewerCamera::getInstance()->getOrigin()[VZ] >= water_height)
+ {
+ name_position[VZ] = water_height;
+ }
+ else if (mNameText) // both camera and HUD are below watermark
+ {
+ F32 name_world_height = mNameText->getWorldHeight();
+ F32 max_z_position = water_height - name_world_height;
+ if (name_position[VZ] > max_z_position)
+ {
+ name_position[VZ] = max_z_position;
+ }
+ }
+ }
+
+ return name_position;
}
void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha)
{
- llassert(mNameText);
+ llassert(mNameText);
- if (new_name
- || alpha != mNameAlpha)
- {
- mNameText->setAlpha(alpha);
- mNameAlpha = alpha;
- }
+ if (new_name
+ || alpha != mNameAlpha)
+ {
+ mNameText->setAlpha(alpha);
+ mNameAlpha = alpha;
+ }
}
LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
{
- static LLUICachedControl<bool> show_friends("NameTagShowFriends", false);
- const char* color_name;
- if (show_friends && is_friend)
- {
- color_name = "NameTagFriend";
- }
- else if (LLAvatarName::useDisplayNames())
- {
- // ...color based on whether username "matches" a computed display name
- LLAvatarName av_name;
- if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault())
- {
- color_name = "NameTagMatch";
- }
- else
- {
- color_name = "NameTagMismatch";
- }
- }
- else
- {
- // ...not using display names
- color_name = "NameTagLegacy";
- }
- return LLUIColorTable::getInstance()->getColor( color_name );
+ static LLUICachedControl<bool> show_friends("NameTagShowFriends", false);
+ const char* color_name;
+ if (show_friends && is_friend)
+ {
+ color_name = "NameTagFriend";
+ }
+ else if (LLAvatarName::useDisplayNames())
+ {
+ // ...color based on whether username "matches" a computed display name
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault())
+ {
+ color_name = "NameTagMatch";
+ }
+ else
+ {
+ color_name = "NameTagMismatch";
+ }
+ }
+ else
+ {
+ // ...not using display names
+ color_name = "NameTagLegacy";
+ }
+ return LLUIColorTable::getInstance()->getColor( color_name );
}
void LLVOAvatar::idleUpdateBelowWater()
{
- F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]);
+ F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]);
- F32 water_height;
- water_height = getRegion()->getWaterHeight();
+ F32 water_height;
+ water_height = getRegion()->getWaterHeight();
- mBelowWater = avatar_height < water_height;
+ mBelowWater = avatar_height < water_height;
}
void LLVOAvatar::slamPosition()
{
- gAgent.setPositionAgent(getPositionAgent());
- // SL-315
- mRoot->setWorldPosition(getPositionAgent()); // teleport
- setChanged(TRANSLATED);
- if (mDrawable.notNull())
- {
- gPipeline.updateMoveNormalAsync(mDrawable);
- }
- mRoot->updateWorldMatrixChildren();
+ gAgent.setPositionAgent(getPositionAgent());
+ // SL-315
+ mRoot->setWorldPosition(getPositionAgent()); // teleport
+ setChanged(TRANSLATED);
+ if (mDrawable.notNull())
+ {
+ gPipeline.updateMoveNormalAsync(mDrawable);
+ }
+ mRoot->updateWorldMatrixChildren();
}
bool LLVOAvatar::isVisuallyMuted()
{
- bool muted = false;
-
- // Priority order (highest priority first)
- // * own avatar is never visually muted
- // * if on the "always draw normally" list, draw them normally
- // * if on the "always visually mute" list, mute them
- // * check against the render cost and attachment limits
- if (!isSelf())
- {
- if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
- {
- muted = false;
- }
- else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
- {
+ bool muted = false;
+
+ // Priority order (highest priority first)
+ // * own avatar is never visually muted
+ // * if on the "always draw normally" list, draw them normally
+ // * if on the "always visually mute" list, mute them
+ // * check against the render cost and attachment limits
+ if (!isSelf())
+ {
+ if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+ {
+ muted = false;
+ }
+ else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
+ {
#ifdef JELLYDOLLS_SHOULD_IMPOSTOR
- muted = true;
- // Always want to see this AV as an impostor
+ muted = true;
+ // Always want to see this AV as an impostor
#else
- muted = false;
+ muted = false;
#endif
- }
+ }
else if (isInMuteList())
{
muted = true;
@@ -3743,89 +3743,89 @@ bool LLVOAvatar::isVisuallyMuted()
{
muted = isTooSlow();
}
- else
- {
- muted = isTooComplex() || isTooSlow();
- }
- }
+ else
+ {
+ muted = isTooComplex() || isTooSlow();
+ }
+ }
- return muted;
+ return muted;
}
bool LLVOAvatar::isInMuteList() const
{
- bool muted = false;
- F64 now = LLFrameTimer::getTotalSeconds();
- if (now < mCachedMuteListUpdateTime)
- {
- muted = mCachedInMuteList;
- }
- else
- {
- muted = LLMuteList::getInstance()->isMuted(getID());
+ bool muted = false;
+ F64 now = LLFrameTimer::getTotalSeconds();
+ if (now < mCachedMuteListUpdateTime)
+ {
+ muted = mCachedInMuteList;
+ }
+ else
+ {
+ muted = LLMuteList::getInstance()->isMuted(getID());
- const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
- mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
- mCachedInMuteList = muted;
- }
- return muted;
+ const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1;
+ mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES;
+ mCachedInMuteList = muted;
+ }
+ return muted;
}
void LLVOAvatar::updateAppearanceMessageDebugText()
{
- S32 central_bake_version = -1;
- if (getRegion())
- {
- central_bake_version = getRegion()->getCentralBakeVersion();
- }
- bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
- bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
- std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
- isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
- all_baked_downloaded ? "B" : "b",
- mUseLocalAppearance, mIsEditingAppearance,
- 1, central_bake_version);
- std::string origin_string = bakedTextureOriginInfo();
- debug_line += " [" + origin_string + "]";
- S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
- S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
- S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
- if (isSelf())
- {
- debug_line += llformat(" - cof: %d req: %d rcv:%d",
- curr_cof_version, last_request_cof_version, last_received_cof_version);
- static LLCachedControl<bool> debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
- if (debug_force_failure)
- {
- debug_line += " FORCING ERRS";
- }
- }
- else
- {
- debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
- }
- debug_line += llformat(" bsz-z: %.3f", mBodySize[2]);
+ S32 central_bake_version = -1;
+ if (getRegion())
+ {
+ central_bake_version = getRegion()->getCentralBakeVersion();
+ }
+ bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
+ bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
+ std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
+ isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
+ all_baked_downloaded ? "B" : "b",
+ mUseLocalAppearance, mIsEditingAppearance,
+ 1, central_bake_version);
+ std::string origin_string = bakedTextureOriginInfo();
+ debug_line += " [" + origin_string + "]";
+ S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
+ S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
+ S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
+ if (isSelf())
+ {
+ debug_line += llformat(" - cof: %d req: %d rcv:%d",
+ curr_cof_version, last_request_cof_version, last_received_cof_version);
+ static LLCachedControl<bool> debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
+ if (debug_force_failure)
+ {
+ debug_line += " FORCING ERRS";
+ }
+ }
+ else
+ {
+ debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
+ }
+ debug_line += llformat(" bsz-z: %.3f", mBodySize[2]);
if (mAvatarOffset[2] != 0.0f)
{
debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]);
}
- bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
- debug_line += hover_enabled ? " H" : " h";
- const LLVector3& hover_offset = getHoverOffset();
- if (hover_offset[2] != 0.0)
- {
- debug_line += llformat(" hov_z: %.3f", hover_offset[2]);
- debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
- debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
- }
- if (mInAir)
- {
- debug_line += " A";
-
- }
+ bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
+ debug_line += hover_enabled ? " H" : " h";
+ const LLVector3& hover_offset = getHoverOffset();
+ if (hover_offset[2] != 0.0)
+ {
+ debug_line += llformat(" hov_z: %.3f", hover_offset[2]);
+ debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
+ debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
+ }
+ if (mInAir)
+ {
+ debug_line += " A";
+
+ }
LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
- LLVector3 normal;
+ LLVector3 normal;
LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
@@ -3835,40 +3835,40 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
LLVector3 pelvis_pos = mPelvisp->getPosition();
debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]);
- const LLVector3& scale = getScale();
- debug_line += llformat(" scale-z %.3f", scale[2]);
- S32 is_visible = (S32) isVisible();
- S32 is_m_visible = (S32) mVisible;
- debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
-
- AvatarOverallAppearance aoa = getOverallAppearance();
- if (aoa == AOA_NORMAL)
- {
- debug_line += " N";
- }
- else if (aoa == AOA_JELLYDOLL)
- {
- debug_line += " J";
- }
- else
- {
- debug_line += " I";
- }
-
- if (mMeshValid)
- {
- debug_line += "m";
- }
- else
- {
- debug_line += "-";
- }
- if (isImpostor())
- {
- debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)));
- }
-
- addDebugText(debug_line);
+ const LLVector3& scale = getScale();
+ debug_line += llformat(" scale-z %.3f", scale[2]);
+ S32 is_visible = (S32) isVisible();
+ S32 is_m_visible = (S32) mVisible;
+ debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
+
+ AvatarOverallAppearance aoa = getOverallAppearance();
+ if (aoa == AOA_NORMAL)
+ {
+ debug_line += " N";
+ }
+ else if (aoa == AOA_JELLYDOLL)
+ {
+ debug_line += " J";
+ }
+ else
+ {
+ debug_line += " I";
+ }
+
+ if (mMeshValid)
+ {
+ debug_line += "m";
+ }
+ else
+ {
+ debug_line += "-";
+ }
+ if (isImpostor())
+ {
+ debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)));
+ }
+
+ addDebugText(debug_line);
}
LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset_id)
@@ -3879,8 +3879,8 @@ LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset
{
if (vobj->getInventorySerial()<=0)
{
- vobj->requestInventory();
- }
+ vobj->requestInventory();
+ }
item = vobj->getInventoryItemByAsset(asset_id);
}
return item;
@@ -3898,23 +3898,23 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU
LLViewerObject *childp = *it;
item = getObjectInventoryItem(childp, asset_id);
if (item)
- {
+ {
break;
}
}
- }
+ }
return item;
}
void LLVOAvatar::updateAnimationDebugText()
{
- for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
- iter != mMotionController.getActiveMotions().end(); ++iter)
- {
- LLMotion* motionp = *iter;
- if (motionp->getMinPixelArea() < getPixelArea())
- {
- std::string output;
+ for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
+ iter != mMotionController.getActiveMotions().end(); ++iter)
+ {
+ LLMotion* motionp = *iter;
+ if (motionp->getMinPixelArea() < getPixelArea())
+ {
+ std::string output;
std::string motion_name = motionp->getName();
if (motion_name.empty())
{
@@ -3931,107 +3931,107 @@ void LLVOAvatar::updateAnimationDebugText()
}
}
if (motion_name.empty())
- {
- std::string name;
- if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
- {
- name = motionp->getID().asString();
- LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
- for (; anim_it != mAnimationSources.end(); ++anim_it)
- {
- if (anim_it->second == motionp->getID())
- {
- LLViewerObject* object = gObjectList.findObject(anim_it->first);
- if (!object)
- {
- break;
- }
- if (object->isAvatar())
- {
- if (mMotionController.mIsSelf)
- {
- // Searching inventory by asset id is really long
- // so just mark as inventory
- // Also item is likely to be named by LLPreviewAnim
- name += "(inventory)";
- }
- }
- else
- {
- LLViewerInventoryItem* item = NULL;
- if (!object->isInventoryDirty())
- {
- item = object->getInventoryItemByAsset(motionp->getID());
- }
- if (item)
- {
- name = item->getName();
- }
- else if (object->isAttachment())
- {
- name += "(att:" + getAttachmentItemName() + ")";
- }
- else
- {
- // in-world object, name or content unknown
- name += "(in-world)";
- }
- }
- break;
- }
- }
- }
- else
- {
- name = LLUUID::null.asString();
- }
- motion_name = name;
- }
- std::string motion_tag = "";
- if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end())
- {
- motion_tag = "*";
- }
- output = llformat("%s%s - %d",
- motion_name.c_str(),
- motion_tag.c_str(),
- (U32)motionp->getPriority());
- addDebugText(output);
- }
- }
+ {
+ std::string name;
+ if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
+ {
+ name = motionp->getID().asString();
+ LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
+ for (; anim_it != mAnimationSources.end(); ++anim_it)
+ {
+ if (anim_it->second == motionp->getID())
+ {
+ LLViewerObject* object = gObjectList.findObject(anim_it->first);
+ if (!object)
+ {
+ break;
+ }
+ if (object->isAvatar())
+ {
+ if (mMotionController.mIsSelf)
+ {
+ // Searching inventory by asset id is really long
+ // so just mark as inventory
+ // Also item is likely to be named by LLPreviewAnim
+ name += "(inventory)";
+ }
+ }
+ else
+ {
+ LLViewerInventoryItem* item = NULL;
+ if (!object->isInventoryDirty())
+ {
+ item = object->getInventoryItemByAsset(motionp->getID());
+ }
+ if (item)
+ {
+ name = item->getName();
+ }
+ else if (object->isAttachment())
+ {
+ name += "(att:" + getAttachmentItemName() + ")";
+ }
+ else
+ {
+ // in-world object, name or content unknown
+ name += "(in-world)";
+ }
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ name = LLUUID::null.asString();
+ }
+ motion_name = name;
+ }
+ std::string motion_tag = "";
+ if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end())
+ {
+ motion_tag = "*";
+ }
+ output = llformat("%s%s - %d",
+ motion_name.c_str(),
+ motion_tag.c_str(),
+ (U32)motionp->getPriority());
+ addDebugText(output);
+ }
+ }
}
void LLVOAvatar::updateDebugText()
{
// Leave mDebugText uncleared here, in case a derived class has added some state first
- if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
- {
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
updateAppearanceMessageDebugText();
- }
+ }
- if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
- {
- if (!mBakedTextureDebugText.empty())
- addDebugText(mBakedTextureDebugText);
- }
+ if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+ {
+ if (!mBakedTextureDebugText.empty())
+ addDebugText(mBakedTextureDebugText);
+ }
// Develop -> Avatar -> Animation Info
- if (LLVOAvatar::sShowAnimationDebug)
- {
+ if (LLVOAvatar::sShowAnimationDebug)
+ {
updateAnimationDebugText();
- }
+ }
- if (!mDebugText.size() && mText.notNull())
- {
- mText->markDead();
- mText = NULL;
- }
- else if (mDebugText.size())
- {
- setDebugText(mDebugText);
- }
- mDebugText.clear();
+ if (!mDebugText.size() && mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ else if (mDebugText.size())
+ {
+ setDebugText(mDebugText);
+ }
+ mDebugText.clear();
}
//------------------------------------------------------------------------
@@ -4045,82 +4045,82 @@ void LLVOAvatar::updateFootstepSounds()
{
return;
}
+
+ //-------------------------------------------------------------------------
+ // Find the ground under each foot, these are used for a variety
+ // of things that follow
+ //-------------------------------------------------------------------------
+ LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition();
+ LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
- //-------------------------------------------------------------------------
- // Find the ground under each foot, these are used for a variety
- // of things that follow
- //-------------------------------------------------------------------------
- LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition();
- LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
-
- LLVector3 ankle_left_ground_agent = ankle_left_pos_agent;
- LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
+ LLVector3 ankle_left_ground_agent = ankle_left_pos_agent;
+ LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
LLVector3 normal;
- resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal);
- resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
-
- F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]);
- F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
-
- if (!isSitting())
- {
- //-------------------------------------------------------------------------
- // Figure out which foot is on ground
- //-------------------------------------------------------------------------
- if (!mInAir)
- {
- if ((leftElev < 0.0f) || (rightElev < 0.0f))
- {
- ankle_left_pos_agent = mFootLeftp->getWorldPosition();
- ankle_right_pos_agent = mFootRightp->getWorldPosition();
- leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ];
- rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ];
- }
- }
- }
-
- const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND};
- const S32 NUM_AGENT_FOOTSTEP_ANIMS = LL_ARRAY_SIZE(AGENT_FOOTSTEP_ANIMS);
-
- if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) )
- {
- BOOL playSound = FALSE;
- LLVector3 foot_pos_agent;
-
- BOOL onGroundLeft = (leftElev <= 0.05f);
- BOOL onGroundRight = (rightElev <= 0.05f);
-
- // did left foot hit the ground?
- if ( onGroundLeft && !mWasOnGroundLeft )
- {
- foot_pos_agent = ankle_left_pos_agent;
- playSound = TRUE;
- }
-
- // did right foot hit the ground?
- if ( onGroundRight && !mWasOnGroundRight )
- {
- foot_pos_agent = ankle_right_pos_agent;
- playSound = TRUE;
- }
-
- mWasOnGroundLeft = onGroundLeft;
- mWasOnGroundRight = onGroundRight;
-
- if ( playSound )
- {
- const F32 STEP_VOLUME = 0.1f;
- const LLUUID& step_sound_id = getStepSound();
-
- LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
-
- if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global)
- && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
- {
- gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global);
- }
- }
- }
+ resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal);
+ resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
+
+ F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]);
+ F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
+
+ if (!isSitting())
+ {
+ //-------------------------------------------------------------------------
+ // Figure out which foot is on ground
+ //-------------------------------------------------------------------------
+ if (!mInAir)
+ {
+ if ((leftElev < 0.0f) || (rightElev < 0.0f))
+ {
+ ankle_left_pos_agent = mFootLeftp->getWorldPosition();
+ ankle_right_pos_agent = mFootRightp->getWorldPosition();
+ leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ];
+ rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ];
+ }
+ }
+ }
+
+ const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND};
+ const S32 NUM_AGENT_FOOTSTEP_ANIMS = LL_ARRAY_SIZE(AGENT_FOOTSTEP_ANIMS);
+
+ if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) )
+ {
+ BOOL playSound = FALSE;
+ LLVector3 foot_pos_agent;
+
+ BOOL onGroundLeft = (leftElev <= 0.05f);
+ BOOL onGroundRight = (rightElev <= 0.05f);
+
+ // did left foot hit the ground?
+ if ( onGroundLeft && !mWasOnGroundLeft )
+ {
+ foot_pos_agent = ankle_left_pos_agent;
+ playSound = TRUE;
+ }
+
+ // did right foot hit the ground?
+ if ( onGroundRight && !mWasOnGroundRight )
+ {
+ foot_pos_agent = ankle_right_pos_agent;
+ playSound = TRUE;
+ }
+
+ mWasOnGroundLeft = onGroundLeft;
+ mWasOnGroundRight = onGroundRight;
+
+ if ( playSound )
+ {
+ const F32 STEP_VOLUME = 0.1f;
+ const LLUUID& step_sound_id = getStepSound();
+
+ LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
+
+ if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global)
+ && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
+ {
+ gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global);
+ }
+ }
+ }
}
//------------------------------------------------------------------------
@@ -4137,57 +4137,57 @@ void LLVOAvatar::updateFootstepSounds()
// ------------------------------------------------------------------------
void LLVOAvatar::computeUpdatePeriod()
{
- bool visually_muted = isVisuallyMuted();
- if (mDrawable.notNull()
- && isVisible()
+ bool visually_muted = isVisuallyMuted();
+ if (mDrawable.notNull()
+ && isVisible()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
&& (sLimitNonImpostors || visually_muted)
&& !mNeedsAnimUpdate)
- {
- const LLVector4a* ext = mDrawable->getSpatialExtents();
- LLVector4a size;
- size.setSub(ext[1],ext[0]);
- F32 mag = size.getLength3().getF32()*0.5f;
-
- const S32 UPDATE_RATE_SLOW = 64;
- const S32 UPDATE_RATE_MED = 48;
- const S32 UPDATE_RATE_FAST = 32;
-
- if (visually_muted)
- { // visually muted avatars update at lowest rate
- mUpdatePeriod = UPDATE_RATE_SLOW;
- }
- else if (! shouldImpostor()
- || mDrawable->mDistanceWRTCamera < 1.f + mag)
- { // first 25% of max visible avatars are not impostored
- // also, don't impostor avatars whose bounding box may be penetrating the
- // impostor camera near clip plane
- mUpdatePeriod = 1;
- }
- else if ( shouldImpostor(4.0) )
- { //background avatars are REALLY slow updating impostors
- mUpdatePeriod = UPDATE_RATE_SLOW;
- }
- else if (mLastRezzedStatus <= 0)
- {
- // Don't update cloud avatars too often
- mUpdatePeriod = UPDATE_RATE_SLOW;
- }
- else if ( shouldImpostor(3.0) )
- { //back 25% of max visible avatars are slow updating impostors
- mUpdatePeriod = UPDATE_RATE_MED;
- }
- else
- {
- //nearby avatars, update the impostors more frequently.
- mUpdatePeriod = UPDATE_RATE_FAST;
- }
- }
- else
- {
- mUpdatePeriod = 1;
- }
+ {
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ LLVector4a size;
+ size.setSub(ext[1],ext[0]);
+ F32 mag = size.getLength3().getF32()*0.5f;
+
+ const S32 UPDATE_RATE_SLOW = 64;
+ const S32 UPDATE_RATE_MED = 48;
+ const S32 UPDATE_RATE_FAST = 32;
+
+ if (visually_muted)
+ { // visually muted avatars update at lowest rate
+ mUpdatePeriod = UPDATE_RATE_SLOW;
+ }
+ else if (! shouldImpostor()
+ || mDrawable->mDistanceWRTCamera < 1.f + mag)
+ { // first 25% of max visible avatars are not impostored
+ // also, don't impostor avatars whose bounding box may be penetrating the
+ // impostor camera near clip plane
+ mUpdatePeriod = 1;
+ }
+ else if ( shouldImpostor(4.0) )
+ { //background avatars are REALLY slow updating impostors
+ mUpdatePeriod = UPDATE_RATE_SLOW;
+ }
+ else if (mLastRezzedStatus <= 0)
+ {
+ // Don't update cloud avatars too often
+ mUpdatePeriod = UPDATE_RATE_SLOW;
+ }
+ else if ( shouldImpostor(3.0) )
+ { //back 25% of max visible avatars are slow updating impostors
+ mUpdatePeriod = UPDATE_RATE_MED;
+ }
+ else
+ {
+ //nearby avatars, update the impostors more frequently.
+ mUpdatePeriod = UPDATE_RATE_FAST;
+ }
+ }
+ else
+ {
+ mUpdatePeriod = 1;
+ }
}
//------------------------------------------------------------------------
@@ -4200,97 +4200,97 @@ void LLVOAvatar::computeUpdatePeriod()
//------------------------------------------------------------------------
void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time)
{
- LLQuaternion iQ;
- LLVector3 upDir( 0.0f, 0.0f, 1.0f );
-
- // Compute a forward direction vector derived from the primitive rotation
- // and the velocity vector. When walking or jumping, don't let body deviate
- // more than 90 from the view, if necessary, flip the velocity vector.
-
- LLVector3 primDir;
- if (isSelf())
- {
- primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector());
- primDir.normalize();
- }
- else
- {
- primDir = getRotation().getMatrix3().getFwdRow();
- }
- LLVector3 velDir = getVelocity();
- velDir.normalize();
- if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end())
- {
- F32 vpD = velDir * primDir;
- if (vpD < -0.5f)
- {
- velDir *= -1.0f;
- }
- }
- LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f));
- if (isSelf() && gAgentCamera.cameraMouselook())
- {
- // make sure fwdDir stays in same general direction as primdir
- if (gAgent.getFlying())
- {
- fwdDir = LLViewerCamera::getInstance()->getAtAxis();
- }
- else
- {
- LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis();
- LLVector3 up_vector = gAgent.getReferenceUpVector();
- at_axis -= up_vector * (at_axis * up_vector);
- at_axis.normalize();
-
- F32 dot = fwdDir * at_axis;
- if (dot < 0.f)
- {
- fwdDir -= 2.f * at_axis * dot;
- fwdDir.normalize();
- }
- }
- }
-
- LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
- F32 root_roll, root_pitch, root_yaw;
- root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
-
- // When moving very slow, the pelvis is allowed to deviate from the
+ LLQuaternion iQ;
+ LLVector3 upDir( 0.0f, 0.0f, 1.0f );
+
+ // Compute a forward direction vector derived from the primitive rotation
+ // and the velocity vector. When walking or jumping, don't let body deviate
+ // more than 90 from the view, if necessary, flip the velocity vector.
+
+ LLVector3 primDir;
+ if (isSelf())
+ {
+ primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector());
+ primDir.normalize();
+ }
+ else
+ {
+ primDir = getRotation().getMatrix3().getFwdRow();
+ }
+ LLVector3 velDir = getVelocity();
+ velDir.normalize();
+ if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end())
+ {
+ F32 vpD = velDir * primDir;
+ if (vpD < -0.5f)
+ {
+ velDir *= -1.0f;
+ }
+ }
+ LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f));
+ if (isSelf() && gAgentCamera.cameraMouselook())
+ {
+ // make sure fwdDir stays in same general direction as primdir
+ if (gAgent.getFlying())
+ {
+ fwdDir = LLViewerCamera::getInstance()->getAtAxis();
+ }
+ else
+ {
+ LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis();
+ LLVector3 up_vector = gAgent.getReferenceUpVector();
+ at_axis -= up_vector * (at_axis * up_vector);
+ at_axis.normalize();
+
+ F32 dot = fwdDir * at_axis;
+ if (dot < 0.f)
+ {
+ fwdDir -= 2.f * at_axis * dot;
+ fwdDir.normalize();
+ }
+ }
+ }
+
+ LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
+ F32 root_roll, root_pitch, root_yaw;
+ root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
+
+ // When moving very slow, the pelvis is allowed to deviate from the
// forward direction to allow it to hold its position while the torso
- // and head turn. Once in motion, it must conform however.
- BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
-
- LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
-
- static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0);
- static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0);
-
- F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast);
-
- if (self_in_mouselook)
- {
- pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR;
- }
- pelvis_rot_threshold *= DEG_TO_RAD;
-
- F32 angle = angle_between( pelvisDir, fwdDir );
-
- // The avatar's root is allowed to have a yaw that deviates widely
- // from the forward direction, but if roll or pitch are off even
- // a little bit we need to correct the rotation.
- if(root_roll < 1.f * DEG_TO_RAD
- && root_pitch < 5.f * DEG_TO_RAD)
- {
- // smaller correction vector means pelvis follows prim direction more closely
- if (!mTurning && angle > pelvis_rot_threshold*0.75f)
- {
- mTurning = TRUE;
- }
-
- // use tighter threshold when turning
- if (mTurning)
- {
- pelvis_rot_threshold *= 0.4f;
+ // and head turn. Once in motion, it must conform however.
+ BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
+
+ LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
+
+ static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0);
+ static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0);
+
+ F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast);
+
+ if (self_in_mouselook)
+ {
+ pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR;
+ }
+ pelvis_rot_threshold *= DEG_TO_RAD;
+
+ F32 angle = angle_between( pelvisDir, fwdDir );
+
+ // The avatar's root is allowed to have a yaw that deviates widely
+ // from the forward direction, but if roll or pitch are off even
+ // a little bit we need to correct the rotation.
+ if(root_roll < 1.f * DEG_TO_RAD
+ && root_pitch < 5.f * DEG_TO_RAD)
+ {
+ // smaller correction vector means pelvis follows prim direction more closely
+ if (!mTurning && angle > pelvis_rot_threshold*0.75f)
+ {
+ mTurning = TRUE;
+ }
+
+ // use tighter threshold when turning
+ if (mTurning)
+ {
+ pelvis_rot_threshold *= 0.4f;
// account for fps, assume that above value is for ~60fps
constexpr F32 default_frame_sec = 0.016f;
F32 prev_frame_sec = LLFrameTimer::getFrameDeltaTimeF32();
@@ -4300,62 +4300,62 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time)
// shorter frame means shorter turn.
pelvis_rot_threshold *= prev_frame_sec/default_frame_sec;
}
- }
-
- // am I done turning?
- if (angle < pelvis_rot_threshold)
- {
- mTurning = FALSE;
- }
-
- LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f);
- fwdDir += correction_vector;
- }
- else
- {
- mTurning = FALSE;
- }
-
- // Now compute the full world space rotation for the whole body (wQv)
- LLVector3 leftDir = upDir % fwdDir;
- leftDir.normalize();
- fwdDir = leftDir % upDir;
- LLQuaternion wQv( fwdDir, leftDir, upDir );
-
- if (isSelf() && mTurning)
- {
- if ((fwdDir % pelvisDir) * upDir > 0.f)
- {
- gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT);
- }
- else
- {
- gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT);
- }
- }
-
- // Set the root rotation, but do so incrementally so that it
- // lags in time by some fixed amount.
- //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG);
- F32 pelvis_lag_time = 0.f;
- if (self_in_mouselook)
- {
- pelvis_lag_time = PELVIS_LAG_MOUSELOOK;
- }
- else if (mInAir)
- {
- pelvis_lag_time = PELVIS_LAG_FLYING;
- // increase pelvis lag time when moving slowly
- pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f);
- }
- else
- {
- pelvis_lag_time = PELVIS_LAG_WALKING;
- }
-
- F32 u = llclamp((delta_time / pelvis_lag_time), 0.0f, 1.0f);
-
- mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );
+ }
+
+ // am I done turning?
+ if (angle < pelvis_rot_threshold)
+ {
+ mTurning = FALSE;
+ }
+
+ LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f);
+ fwdDir += correction_vector;
+ }
+ else
+ {
+ mTurning = FALSE;
+ }
+
+ // Now compute the full world space rotation for the whole body (wQv)
+ LLVector3 leftDir = upDir % fwdDir;
+ leftDir.normalize();
+ fwdDir = leftDir % upDir;
+ LLQuaternion wQv( fwdDir, leftDir, upDir );
+
+ if (isSelf() && mTurning)
+ {
+ if ((fwdDir % pelvisDir) * upDir > 0.f)
+ {
+ gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT);
+ }
+ else
+ {
+ gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT);
+ }
+ }
+
+ // Set the root rotation, but do so incrementally so that it
+ // lags in time by some fixed amount.
+ //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG);
+ F32 pelvis_lag_time = 0.f;
+ if (self_in_mouselook)
+ {
+ pelvis_lag_time = PELVIS_LAG_MOUSELOOK;
+ }
+ else if (mInAir)
+ {
+ pelvis_lag_time = PELVIS_LAG_FLYING;
+ // increase pelvis lag time when moving slowly
+ pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f);
+ }
+ else
+ {
+ pelvis_lag_time = PELVIS_LAG_WALKING;
+ }
+
+ F32 u = llclamp((delta_time / pelvis_lag_time), 0.0f, 1.0f);
+
+ mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );
}
//------------------------------------------------------------------------
@@ -4368,91 +4368,91 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time)
// ------------------------------------------------------------------------
void LLVOAvatar::updateTimeStep()
{
- if (!isSelf() && !isUIAvatar()) // ie, non-self avatars, and animated objects will be affected.
- {
+ if (!isSelf() && !isUIAvatar()) // ie, non-self avatars, and animated objects will be affected.
+ {
// Note that sInstances counts animated objects and
// standard avatars in the same bucket. Is this desirable?
- F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f);
- F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f);
- F32 time_step = time_quantum * pixel_area_scale;
+ F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f);
+ F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f);
+ F32 time_step = time_quantum * pixel_area_scale;
// Extrema:
// If number of avs is 10 or less, time_step is unmodified (flagged with 0.0).
// If area of av is 5000 or greater, time_step is unmodified (flagged with 0.0).
// If number of avs is 35 or greater, and area of av is 100 or less,
// time_step takes the maximum possible value of 0.25.
// Other situations will give values within the (0, 0.25) range.
- if (time_step != 0.f)
- {
- // disable walk motion servo controller as it doesn't work with motion timesteps
- stopMotion(ANIM_AGENT_WALK_ADJUST);
- removeAnimationData("Walk Speed");
- }
+ if (time_step != 0.f)
+ {
+ // disable walk motion servo controller as it doesn't work with motion timesteps
+ stopMotion(ANIM_AGENT_WALK_ADJUST);
+ removeAnimationData("Walk Speed");
+ }
// See SL-763 - playback with altered time step does not
// appear to work correctly, odd behavior for distant avatars.
// As of 11-2017, LLMotionController::updateMotions() will
// ignore the value here. Need to re-enable if it's every
// fixed.
- mMotionController.setTimeStep(time_step);
- }
-}
-
-void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool was_sit_ground_constrained)
-{
- if (!(isSitting() && getParent()))
- {
- // This case includes all configurations except sitting on an
- // object, so does include ground sit.
-
- //--------------------------------------------------------------------
- // get timing info
- // handle initial condition case
- //--------------------------------------------------------------------
- F32 animation_time = mAnimTimer.getElapsedTimeF32();
- if (mTimeLast == 0.0f)
- {
- mTimeLast = animation_time;
-
- // Initially put the pelvis at slaved position/mRotation
- // SL-315
- mRoot->setWorldPosition( getPositionAgent() ); // first frame
- mRoot->setWorldRotation( getRotation() );
- }
-
- //--------------------------------------------------------------------
- // dont' let dT get larger than 1/5th of a second
- //--------------------------------------------------------------------
- F32 delta_time = animation_time - mTimeLast;
-
- delta_time = llclamp( delta_time, DELTA_TIME_MIN, DELTA_TIME_MAX );
- mTimeLast = animation_time;
-
- mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f);
-
- //--------------------------------------------------------------------
- // compute the position of the avatar's root
- //--------------------------------------------------------------------
- LLVector3d root_pos;
- LLVector3d ground_under_pelvis;
-
- if (isSelf())
- {
- gAgent.setPositionAgent(getRenderPosition());
- }
-
- root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
- root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
+ mMotionController.setTimeStep(time_step);
+ }
+}
+
+void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool was_sit_ground_constrained)
+{
+ if (!(isSitting() && getParent()))
+ {
+ // This case includes all configurations except sitting on an
+ // object, so does include ground sit.
+
+ //--------------------------------------------------------------------
+ // get timing info
+ // handle initial condition case
+ //--------------------------------------------------------------------
+ F32 animation_time = mAnimTimer.getElapsedTimeF32();
+ if (mTimeLast == 0.0f)
+ {
+ mTimeLast = animation_time;
+
+ // Initially put the pelvis at slaved position/mRotation
+ // SL-315
+ mRoot->setWorldPosition( getPositionAgent() ); // first frame
+ mRoot->setWorldRotation( getRotation() );
+ }
+
+ //--------------------------------------------------------------------
+ // dont' let dT get larger than 1/5th of a second
+ //--------------------------------------------------------------------
+ F32 delta_time = animation_time - mTimeLast;
+
+ delta_time = llclamp( delta_time, DELTA_TIME_MIN, DELTA_TIME_MAX );
+ mTimeLast = animation_time;
+
+ mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f);
+
+ //--------------------------------------------------------------------
+ // compute the position of the avatar's root
+ //--------------------------------------------------------------------
+ LLVector3d root_pos;
+ LLVector3d ground_under_pelvis;
+
+ if (isSelf())
+ {
+ gAgent.setPositionAgent(getRenderPosition());
+ }
+
+ root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
+ root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
LLVector3 normal;
- resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
- F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
- BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) ||
- foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
+ resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
+ F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
+ BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) ||
+ foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
- if (in_air && !mInAir)
- {
- mTimeInAir.reset();
- }
- mInAir = in_air;
+ if (in_air && !mInAir)
+ {
+ mTimeInAir.reset();
+ }
+ mInAir = in_air;
// SL-402: with the ability to animate the position of joints
// that affect the body size calculation, computed body size
@@ -4460,40 +4460,40 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
// it frequently.
// SL-427: this appears to be too frequent, moving to only do on animation state change.
//computeBodySize();
-
- // correct for the fact that the pelvis is not necessarily the center
- // of the agent's physical representation
- root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
- if (!isSitting() && !was_sit_ground_constrained)
- {
- root_pos += LLVector3d(getHoverOffset());
- if (getOverallAppearance() == AOA_JELLYDOLL)
- {
- F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]);
- root_pos[2] += offz;
- // if (!isSelf() && !isControlAvatar())
- // {
- // LL_DEBUGS("Avatar") << "av " << getFullname()
- // << " frame " << LLFrameTimer::getFrameCount()
- // << " root adjust offz " << offz
- // << " scalez " << getScale()[VZ]
- // << " bsz " << mBodySize.mV[VZ]
- // << LL_ENDL;
- // }
- }
- }
- // if (!isSelf() && !isControlAvatar())
- // {
- // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance()
- // << " frame " << LLFrameTimer::getFrameCount()
- // << " scalez " << getScale()[VZ]
- // << " bsz " << mBodySize.mV[VZ]
- // << " root pos " << root_pos[2]
- // << " curr rootz " << mRoot->getPosition()[2]
- // << " pp-z " << mPelvisp->getPosition()[2]
- // << " renderpos " << getRenderPosition()
- // << LL_ENDL;
- // }
+
+ // correct for the fact that the pelvis is not necessarily the center
+ // of the agent's physical representation
+ root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
+ if (!isSitting() && !was_sit_ground_constrained)
+ {
+ root_pos += LLVector3d(getHoverOffset());
+ if (getOverallAppearance() == AOA_JELLYDOLL)
+ {
+ F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]);
+ root_pos[2] += offz;
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " root adjust offz " << offz
+ // << " scalez " << getScale()[VZ]
+ // << " bsz " << mBodySize.mV[VZ]
+ // << LL_ENDL;
+ // }
+ }
+ }
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " scalez " << getScale()[VZ]
+ // << " bsz " << mBodySize.mV[VZ]
+ // << " root pos " << root_pos[2]
+ // << " curr rootz " << mRoot->getPosition()[2]
+ // << " pp-z " << mPelvisp->getPosition()[2]
+ // << " renderpos " << getRenderPosition()
+ // << LL_ENDL;
+ // }
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
if (cav)
@@ -4504,73 +4504,73 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
else
{
LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
- // if (!isSelf() && !isControlAvatar())
- // {
- // LL_DEBUGS("Avatar") << "av " << getFullname()
- // << " frame " << LLFrameTimer::getFrameCount()
- // << " newPosition " << newPosition
- // << " renderpos " << getRenderPosition()
- // << LL_ENDL;
- // }
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " newPosition " << newPosition
+ // << " renderpos " << getRenderPosition()
+ // << LL_ENDL;
+ // }
if (newPosition != mRoot->getXform()->getWorldPosition())
- {
+ {
mRoot->touch();
// SL-315
- mRoot->setWorldPosition( newPosition ); // regular update
+ mRoot->setWorldPosition( newPosition ); // regular update
}
}
- //--------------------------------------------------------------------
- // Propagate viewer object rotation to root of avatar
- //--------------------------------------------------------------------
- if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
- {
+ //--------------------------------------------------------------------
+ // Propagate viewer object rotation to root of avatar
+ //--------------------------------------------------------------------
+ if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
+ {
// Rotation fixups for avatars in motion.
// Skip for animated objects.
updateOrientation(agent, speed, delta_time);
- }
- }
- else if (mDrawable.notNull())
- {
+ }
+ }
+ else if (mDrawable.notNull())
+ {
// Sitting on an object - mRoot is slaved to mDrawable orientation.
- LLVector3 pos = mDrawable->getPosition();
- pos += getHoverOffset() * mDrawable->getRotation();
- // SL-315
- mRoot->setPosition(pos);
- mRoot->setRotation(mDrawable->getRotation());
- }
+ LLVector3 pos = mDrawable->getPosition();
+ pos += getHoverOffset() * mDrawable->getRotation();
+ // SL-315
+ mRoot->setPosition(pos);
+ mRoot->setRotation(mDrawable->getRotation());
+ }
}
//------------------------------------------------------------------------
// LLVOAvatar::computeNeedsUpdate()
-//
+//
// Most of the logic here is to figure out when to periodically update impostors.
// Non-impostors have mUpdatePeriod == 1 and will need update every frame.
//------------------------------------------------------------------------
bool LLVOAvatar::computeNeedsUpdate()
{
- const F32 MAX_IMPOSTOR_INTERVAL = 4.0f;
- computeUpdatePeriod();
+ const F32 MAX_IMPOSTOR_INTERVAL = 4.0f;
+ computeUpdatePeriod();
- bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0);
+ bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0);
bool needs_update_by_max_time = ((gFrameTimeSeconds-mLastImpostorUpdateFrameTime)> MAX_IMPOSTOR_INTERVAL);
- bool needs_update = needs_update_by_frame_count || needs_update_by_max_time;
-
- if (needs_update && !isSelf())
- {
- if (needs_update_by_max_time)
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 11;
- }
- else
- {
- //mNeedsImpostorUpdate = TRUE;
- //mLastImpostorUpdateReason = 10;
- }
- }
- return needs_update;
+ bool needs_update = needs_update_by_frame_count || needs_update_by_max_time;
+
+ if (needs_update && !isSelf())
+ {
+ if (needs_update_by_max_time)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 11;
+ }
+ else
+ {
+ //mNeedsImpostorUpdate = TRUE;
+ //mLastImpostorUpdateReason = 10;
+ }
+ }
+ return needs_update;
}
// updateCharacter()
@@ -4596,153 +4596,153 @@ bool LLVOAvatar::computeNeedsUpdate()
//
//------------------------------------------------------------------------
bool LLVOAvatar::updateCharacter(LLAgent &agent)
-{
- updateDebugText();
-
- if (!mIsBuilt)
- {
- return FALSE;
- }
-
- BOOL visible = isVisible();
+{
+ updateDebugText();
+
+ if (!mIsBuilt)
+ {
+ return FALSE;
+ }
+
+ BOOL visible = isVisible();
bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing
- bool is_attachment = false;
+ bool is_attachment = false;
- if (is_control_avatar)
- {
+ if (is_control_avatar)
+ {
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
- is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects
- }
+ is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects
+ }
LLScopedContextString str("updateCharacter " + getFullname() + " is_control_avatar "
- + boost::lexical_cast<std::string>(is_control_avatar)
+ + boost::lexical_cast<std::string>(is_control_avatar)
+ " is_attachment " + boost::lexical_cast<std::string>(is_attachment));
- // For fading out the names above heads, only let the timer
- // run if we're visible.
- if (mDrawable.notNull() && !visible)
- {
- mTimeVisible.reset();
- }
+ // For fading out the names above heads, only let the timer
+ // run if we're visible.
+ if (mDrawable.notNull() && !visible)
+ {
+ mTimeVisible.reset();
+ }
- //--------------------------------------------------------------------
- // The rest should only be done occasionally for far away avatars.
+ //--------------------------------------------------------------------
+ // The rest should only be done occasionally for far away avatars.
// Set mUpdatePeriod and visible based on distance and other criteria,
- // and flag for impostor update if needed.
- //--------------------------------------------------------------------
- bool needs_update = computeNeedsUpdate();
-
- //--------------------------------------------------------------------
- // Early out if does not need update and not self
- // don't early out for your own avatar, as we rely on your animations playing reliably
- // for example, the "turn around" animation when entering customize avatar needs to trigger
- // even when your avatar is offscreen
- //--------------------------------------------------------------------
- if (!needs_update && !isSelf())
- {
- updateMotions(LLCharacter::HIDDEN_UPDATE);
- return FALSE;
- }
-
- //--------------------------------------------------------------------
- // Handle transitions between regular rendering, jellydoll, or invisible.
- // Can trigger skeleton reset or animation changes
- //--------------------------------------------------------------------
- updateOverallAppearance();
-
- //--------------------------------------------------------------------
- // change animation time quanta based on avatar render load
- //--------------------------------------------------------------------
+ // and flag for impostor update if needed.
+ //--------------------------------------------------------------------
+ bool needs_update = computeNeedsUpdate();
+
+ //--------------------------------------------------------------------
+ // Early out if does not need update and not self
+ // don't early out for your own avatar, as we rely on your animations playing reliably
+ // for example, the "turn around" animation when entering customize avatar needs to trigger
+ // even when your avatar is offscreen
+ //--------------------------------------------------------------------
+ if (!needs_update && !isSelf())
+ {
+ updateMotions(LLCharacter::HIDDEN_UPDATE);
+ return FALSE;
+ }
+
+ //--------------------------------------------------------------------
+ // Handle transitions between regular rendering, jellydoll, or invisible.
+ // Can trigger skeleton reset or animation changes
+ //--------------------------------------------------------------------
+ updateOverallAppearance();
+
+ //--------------------------------------------------------------------
+ // change animation time quanta based on avatar render load
+ //--------------------------------------------------------------------
// SL-763 the time step quantization does not currently work.
//updateTimeStep();
-
- //--------------------------------------------------------------------
+
+ //--------------------------------------------------------------------
// Update sitting state based on parent and active animation info.
- //--------------------------------------------------------------------
- if (getParent() && !isSitting())
- {
- sitOnObject((LLViewerObject*)getParent());
- }
- else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
- {
+ //--------------------------------------------------------------------
+ if (getParent() && !isSitting())
+ {
+ sitOnObject((LLViewerObject*)getParent());
+ }
+ else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
+ {
// If we are starting up, motion might be loading
LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
if (!motionp || !mMotionController.isMotionLoading(motionp))
{
getOffObject();
}
- }
+ }
+
+ //--------------------------------------------------------------------
+ // create local variables in world coords for region position values
+ //--------------------------------------------------------------------
+ LLVector3 xyVel = getVelocity();
+ xyVel.mV[VZ] = 0.0f;
+ F32 speed = xyVel.length();
+ // remembering the value here prevents a display glitch if the
+ // animation gets toggled during this update.
+ bool was_sit_ground_constrained = isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
- //--------------------------------------------------------------------
- // create local variables in world coords for region position values
- //--------------------------------------------------------------------
- LLVector3 xyVel = getVelocity();
- xyVel.mV[VZ] = 0.0f;
- F32 speed = xyVel.length();
- // remembering the value here prevents a display glitch if the
- // animation gets toggled during this update.
- bool was_sit_ground_constrained = isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
-
- //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
// This does a bunch of state updating, including figuring out
// whether av is in the air, setting mRoot position and rotation
// In some cases, calls updateOrientation() for a lot of the
// work
// --------------------------------------------------------------------
updateRootPositionAndRotation(agent, speed, was_sit_ground_constrained);
-
- //-------------------------------------------------------------------------
- // Update character motions
- //-------------------------------------------------------------------------
- // store data relevant to motions
- mSpeed = speed;
-
- // update animations
- if (!visible)
- {
- updateMotions(LLCharacter::HIDDEN_UPDATE);
- }
- else if (mSpecialRenderMode == 1) // Animation Preview
- {
- updateMotions(LLCharacter::FORCE_UPDATE);
- }
- else
- {
- // Might be better to do HIDDEN_UPDATE if cloud
- updateMotions(LLCharacter::NORMAL_UPDATE);
- }
-
- // Special handling for sitting on ground.
- if (!getParent() && (isSitting() || was_sit_ground_constrained))
- {
-
- F32 off_z = LLVector3d(getHoverOffset()).mdV[VZ];
- if (off_z != 0.0)
- {
- LLVector3 pos = mRoot->getWorldPosition();
- pos.mV[VZ] += off_z;
- mRoot->touch();
- // SL-315
- mRoot->setWorldPosition(pos);
- }
- }
-
- // update head position
- updateHeadOffset();
-
- // Generate footstep sounds when feet hit the ground
+
+ //-------------------------------------------------------------------------
+ // Update character motions
+ //-------------------------------------------------------------------------
+ // store data relevant to motions
+ mSpeed = speed;
+
+ // update animations
+ if (!visible && !isSelf()) // NOTE: never do a "hidden update" for self avatar as it interrupts controller processing
+ {
+ updateMotions(LLCharacter::HIDDEN_UPDATE);
+ }
+ else if (mSpecialRenderMode == 1) // Animation Preview
+ {
+ updateMotions(LLCharacter::FORCE_UPDATE);
+ }
+ else
+ {
+ // Might be better to do HIDDEN_UPDATE if cloud
+ updateMotions(LLCharacter::NORMAL_UPDATE);
+ }
+
+ // Special handling for sitting on ground.
+ if (!getParent() && (isSitting() || was_sit_ground_constrained))
+ {
+
+ F32 off_z = LLVector3d(getHoverOffset()).mdV[VZ];
+ if (off_z != 0.0)
+ {
+ LLVector3 pos = mRoot->getWorldPosition();
+ pos.mV[VZ] += off_z;
+ mRoot->touch();
+ // SL-315
+ mRoot->setWorldPosition(pos);
+ }
+ }
+
+ // update head position
+ updateHeadOffset();
+
+ // Generate footstep sounds when feet hit the ground
updateFootstepSounds();
- // Update child joints as needed.
- mRoot->updateWorldMatrixChildren();
+ // Update child joints as needed.
+ mRoot->updateWorldMatrixChildren();
if (visible)
{
- // System avatar mesh vertices need to be reskinned.
- mNeedsSkin = TRUE;
+ // System avatar mesh vertices need to be reskinned.
+ mNeedsSkin = TRUE;
}
- return visible;
+ return visible;
}
//-----------------------------------------------------------------------------
@@ -4750,246 +4750,246 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent)
//-----------------------------------------------------------------------------
void LLVOAvatar::updateHeadOffset()
{
- // since we only care about Z, just grab one of the eyes
- LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
- midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
- midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
-
- if (mDrawable.notNull())
- {
- midEyePt = midEyePt * ~mDrawable->getWorldRotation();
- }
- if (isSitting())
- {
- mHeadOffset = midEyePt;
- }
- else
- {
- F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped));
- mHeadOffset = lerp(midEyePt, mHeadOffset, u);
- }
+ // since we only care about Z, just grab one of the eyes
+ LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
+ midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
+ midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
+
+ if (mDrawable.notNull())
+ {
+ midEyePt = midEyePt * ~mDrawable->getWorldRotation();
+ }
+ if (isSitting())
+ {
+ mHeadOffset = midEyePt;
+ }
+ else
+ {
+ F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped));
+ mHeadOffset = lerp(midEyePt, mHeadOffset, u);
+ }
}
void LLVOAvatar::debugBodySize() const
{
- LLVector3 pelvis_scale = mPelvisp->getScale();
+ LLVector3 pelvis_scale = mPelvisp->getScale();
- // some of the joints have not been cached
- LLVector3 skull = mSkullp->getPosition();
+ // some of the joints have not been cached
+ LLVector3 skull = mSkullp->getPosition();
LL_DEBUGS("Avatar") << "skull pos " << skull << LL_ENDL;
- //LLVector3 skull_scale = mSkullp->getScale();
+ //LLVector3 skull_scale = mSkullp->getScale();
- LLVector3 neck = mNeckp->getPosition();
- LLVector3 neck_scale = mNeckp->getScale();
+ LLVector3 neck = mNeckp->getPosition();
+ LLVector3 neck_scale = mNeckp->getScale();
LL_DEBUGS("Avatar") << "neck pos " << neck << " neck_scale " << neck_scale << LL_ENDL;
- LLVector3 chest = mChestp->getPosition();
- LLVector3 chest_scale = mChestp->getScale();
+ LLVector3 chest = mChestp->getPosition();
+ LLVector3 chest_scale = mChestp->getScale();
LL_DEBUGS("Avatar") << "chest pos " << chest << " chest_scale " << chest_scale << LL_ENDL;
- // the rest of the joints have been cached
- LLVector3 head = mHeadp->getPosition();
- LLVector3 head_scale = mHeadp->getScale();
+ // the rest of the joints have been cached
+ LLVector3 head = mHeadp->getPosition();
+ LLVector3 head_scale = mHeadp->getScale();
LL_DEBUGS("Avatar") << "head pos " << head << " head_scale " << head_scale << LL_ENDL;
- LLVector3 torso = mTorsop->getPosition();
- LLVector3 torso_scale = mTorsop->getScale();
+ LLVector3 torso = mTorsop->getPosition();
+ LLVector3 torso_scale = mTorsop->getScale();
LL_DEBUGS("Avatar") << "torso pos " << torso << " torso_scale " << torso_scale << LL_ENDL;
- LLVector3 hip = mHipLeftp->getPosition();
- LLVector3 hip_scale = mHipLeftp->getScale();
+ LLVector3 hip = mHipLeftp->getPosition();
+ LLVector3 hip_scale = mHipLeftp->getScale();
LL_DEBUGS("Avatar") << "hip pos " << hip << " hip_scale " << hip_scale << LL_ENDL;
- LLVector3 knee = mKneeLeftp->getPosition();
- LLVector3 knee_scale = mKneeLeftp->getScale();
+ LLVector3 knee = mKneeLeftp->getPosition();
+ LLVector3 knee_scale = mKneeLeftp->getScale();
LL_DEBUGS("Avatar") << "knee pos " << knee << " knee_scale " << knee_scale << LL_ENDL;
- LLVector3 ankle = mAnkleLeftp->getPosition();
- LLVector3 ankle_scale = mAnkleLeftp->getScale();
+ LLVector3 ankle = mAnkleLeftp->getPosition();
+ LLVector3 ankle_scale = mAnkleLeftp->getScale();
LL_DEBUGS("Avatar") << "ankle pos " << ankle << " ankle_scale " << ankle_scale << LL_ENDL;
- LLVector3 foot = mFootLeftp->getPosition();
+ LLVector3 foot = mFootLeftp->getPosition();
LL_DEBUGS("Avatar") << "foot pos " << foot << LL_ENDL;
- F32 new_offset = (const_cast<LLVOAvatar*>(this))->getVisualParamWeight(AVATAR_HOVER);
+ F32 new_offset = (const_cast<LLVOAvatar*>(this))->getVisualParamWeight(AVATAR_HOVER);
LL_DEBUGS("Avatar") << "new_offset " << new_offset << LL_ENDL;
- F32 new_pelvis_to_foot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+ F32 new_pelvis_to_foot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
knee.mV[VZ] * hip_scale.mV[VZ] -
ankle.mV[VZ] * knee_scale.mV[VZ] -
foot.mV[VZ] * ankle_scale.mV[VZ];
LL_DEBUGS("Avatar") << "new_pelvis_to_foot " << new_pelvis_to_foot << LL_ENDL;
- LLVector3 new_body_size;
- new_body_size.mV[VZ] = new_pelvis_to_foot +
- // the sqrt(2) correction below is an approximate
- // correction to get to the top of the head
- F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
- head.mV[VZ] * neck_scale.mV[VZ] +
- neck.mV[VZ] * chest_scale.mV[VZ] +
- chest.mV[VZ] * torso_scale.mV[VZ] +
- torso.mV[VZ] * pelvis_scale.mV[VZ];
+ LLVector3 new_body_size;
+ new_body_size.mV[VZ] = new_pelvis_to_foot +
+ // the sqrt(2) correction below is an approximate
+ // correction to get to the top of the head
+ F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
+ head.mV[VZ] * neck_scale.mV[VZ] +
+ neck.mV[VZ] * chest_scale.mV[VZ] +
+ chest.mV[VZ] * torso_scale.mV[VZ] +
+ torso.mV[VZ] * pelvis_scale.mV[VZ];
- // TODO -- measure the real depth and width
- new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
- new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+ // TODO -- measure the real depth and width
+ new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+ new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
LL_DEBUGS("Avatar") << "new_body_size " << new_body_size << LL_ENDL;
}
-
+
//------------------------------------------------------------------------
// postPelvisSetRecalc
//------------------------------------------------------------------------
void LLVOAvatar::postPelvisSetRecalc()
-{
- mRoot->updateWorldMatrixChildren();
- computeBodySize();
- dirtyMesh(2);
+{
+ mRoot->updateWorldMatrixChildren();
+ computeBodySize();
+ dirtyMesh(2);
}
//------------------------------------------------------------------------
// updateVisibility()
//------------------------------------------------------------------------
void LLVOAvatar::updateVisibility()
{
- BOOL visible = FALSE;
-
- if (mIsDummy)
- {
- visible = FALSE;
- }
- else if (mDrawable.isNull())
- {
- visible = FALSE;
- }
- else
- {
- if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible())
- {
- visible = TRUE;
- }
- else
- {
- visible = FALSE;
- }
-
- if(isSelf())
- {
- if (!gAgentWearables.areWearablesLoaded())
- {
- visible = FALSE;
- }
- }
- else if( !mFirstAppearanceMessageReceived )
- {
- visible = FALSE;
- }
-
- if (sDebugInvisible)
- {
- LLNameValue* firstname = getNVPair("FirstName");
- if (firstname)
- {
- LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Avatar " << this << " updating visiblity" << LL_ENDL;
- }
-
- if (visible)
- {
- LL_INFOS() << "Visible" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Not visible" << LL_ENDL;
- }
-
- /*if (avatar_in_frustum)
- {
- LL_INFOS() << "Avatar in frustum" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Avatar not in frustum" << LL_ENDL;
- }*/
-
- /*if (LLViewerCamera::getInstance()->sphereInFrustum(sel_pos_agent, 2.0f))
- {
- LL_INFOS() << "Sel pos visible" << LL_ENDL;
- }
- if (LLViewerCamera::getInstance()->sphereInFrustum(wrist_right_pos_agent, 0.2f))
- {
- LL_INFOS() << "Wrist pos visible" << LL_ENDL;
- }
- if (LLViewerCamera::getInstance()->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f))
- {
- LL_INFOS() << "Agent visible" << LL_ENDL;
- }*/
- LL_INFOS() << "PA: " << getPositionAgent() << LL_ENDL;
- /*LL_INFOS() << "SPA: " << sel_pos_agent << LL_ENDL;
- LL_INFOS() << "WPA: " << wrist_right_pos_agent << LL_ENDL;*/
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject *attached_object = attachment_iter->get())
- {
- if(attached_object->mDrawable->isVisible())
- {
- LL_INFOS() << attachment->getName() << " visible" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << LL_ENDL;
- }
- }
- }
- }
- }
- }
-
- if (!visible && mVisible)
- {
- mMeshInvisibleTime.reset();
- }
-
- if (visible)
- {
- if (!mMeshValid)
- {
- restoreMeshData();
- }
- }
- else
- {
- if (mMeshValid &&
+ BOOL visible = FALSE;
+
+ if (mIsDummy)
+ {
+ visible = FALSE;
+ }
+ else if (mDrawable.isNull())
+ {
+ visible = FALSE;
+ }
+ else
+ {
+ if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible())
+ {
+ visible = TRUE;
+ }
+ else
+ {
+ visible = FALSE;
+ }
+
+ if(isSelf())
+ {
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ visible = FALSE;
+ }
+ }
+ else if( !mFirstAppearanceMessageReceived )
+ {
+ visible = FALSE;
+ }
+
+ if (sDebugInvisible)
+ {
+ LLNameValue* firstname = getNVPair("FirstName");
+ if (firstname)
+ {
+ LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Avatar " << this << " updating visiblity" << LL_ENDL;
+ }
+
+ if (visible)
+ {
+ LL_INFOS() << "Visible" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Not visible" << LL_ENDL;
+ }
+
+ /*if (avatar_in_frustum)
+ {
+ LL_INFOS() << "Avatar in frustum" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Avatar not in frustum" << LL_ENDL;
+ }*/
+
+ /*if (LLViewerCamera::getInstance()->sphereInFrustum(sel_pos_agent, 2.0f))
+ {
+ LL_INFOS() << "Sel pos visible" << LL_ENDL;
+ }
+ if (LLViewerCamera::getInstance()->sphereInFrustum(wrist_right_pos_agent, 0.2f))
+ {
+ LL_INFOS() << "Wrist pos visible" << LL_ENDL;
+ }
+ if (LLViewerCamera::getInstance()->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f))
+ {
+ LL_INFOS() << "Agent visible" << LL_ENDL;
+ }*/
+ LL_INFOS() << "PA: " << getPositionAgent() << LL_ENDL;
+ /*LL_INFOS() << "SPA: " << sel_pos_agent << LL_ENDL;
+ LL_INFOS() << "WPA: " << wrist_right_pos_agent << LL_ENDL;*/
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ if (LLViewerObject *attached_object = attachment_iter->get())
+ {
+ if(attached_object->mDrawable->isVisible())
+ {
+ LL_INFOS() << attachment->getName() << " visible" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!visible && mVisible)
+ {
+ mMeshInvisibleTime.reset();
+ }
+
+ if (visible)
+ {
+ if (!mMeshValid)
+ {
+ restoreMeshData();
+ }
+ }
+ else
+ {
+ if (mMeshValid &&
(isControlAvatar() || mMeshInvisibleTime.getElapsedTimeF32() > TIME_BEFORE_MESH_CLEANUP))
- {
- releaseMeshData();
- }
- }
+ {
+ releaseMeshData();
+ }
+ }
if ( visible != mVisible )
{
LL_DEBUGS("AvatarRender") << "visible was " << mVisible << " now " << visible << LL_ENDL;
}
- mVisible = visible;
+ mVisible = visible;
}
// private
bool LLVOAvatar::shouldAlphaMask()
{
- const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
- && !LLDrawPoolAvatar::sSkipTransparent;
+ const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
+ && !LLDrawPoolAvatar::sSkipTransparent;
- return should_alpha_mask;
+ return should_alpha_mask;
}
@@ -5000,237 +5000,237 @@ U32 LLVOAvatar::renderSkinned()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- U32 num_indices = 0;
+ U32 num_indices = 0;
- if (!mIsBuilt)
- {
- return num_indices;
- }
+ if (!mIsBuilt)
+ {
+ return num_indices;
+ }
if (mDrawable.isNull())
{
- return num_indices;
- }
-
- LLFace* face = mDrawable->getFace(0);
-
- bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
-
- if (needs_rebuild || mDirtyMesh)
- { //LOD changed or new mesh created, allocate new vertex buffer if needed
- if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
- {
- updateMeshData();
- mDirtyMesh = 0;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
- }
- }
-
- if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
- {
- if (mNeedsSkin)
- {
- //generate animated mesh
- LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
- LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
- LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
- LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
- LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
- LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
-
- if(upper_mesh)
- {
- upper_mesh->updateJointGeometry();
- }
- if (lower_mesh)
- {
- lower_mesh->updateJointGeometry();
- }
-
- if( isWearingWearableType( LLWearableType::WT_SKIRT ) )
- {
- if(skirt_mesh)
- {
- skirt_mesh->updateJointGeometry();
- }
- }
-
- if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
- {
- if(eyelash_mesh)
- {
- eyelash_mesh->updateJointGeometry();
- }
- if(head_mesh)
- {
- head_mesh->updateJointGeometry();
- }
- if(hair_mesh)
- {
- hair_mesh->updateJointGeometry();
- }
- }
- mNeedsSkin = FALSE;
- mLastSkinTime = gFrameTimeSeconds;
-
- LLFace * face = mDrawable->getFace(0);
- if (face)
- {
- LLVertexBuffer* vb = face->getVertexBuffer();
- if (vb)
- {
- vb->unmapBuffer();
- }
- }
- }
- }
- else
- {
- mNeedsSkin = FALSE;
- }
-
- if (sDebugInvisible)
- {
- LLNameValue* firstname = getNVPair("FirstName");
- if (firstname)
- {
- LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Avatar " << this << " in render" << LL_ENDL;
- }
- if (!mIsBuilt)
- {
- LL_INFOS() << "Not built!" << LL_ENDL;
- }
- else if (!gAgent.needsRenderAvatar())
- {
- LL_INFOS() << "Doesn't need avatar render!" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Rendering!" << LL_ENDL;
- }
- }
-
- if (!mIsBuilt)
- {
- return num_indices;
- }
-
- if (isSelf() && !gAgent.needsRenderAvatar())
- {
- return num_indices;
- }
-
- //--------------------------------------------------------------------
- // render all geometry attached to the skeleton
- //--------------------------------------------------------------------
-
- BOOL first_pass = TRUE;
- if (!LLDrawPoolAvatar::sSkipOpaque)
- {
- if (isUIAvatar() && mIsDummy)
- {
- LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
- if (hair_mesh)
- {
- num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
- if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
- {
-
- if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
- {
- LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
- if (head_mesh)
- {
- num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
- }
- if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
- {
- LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
- if (upper_mesh)
- {
- num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
-
- if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
- {
- LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
- if (lower_mesh)
- {
- num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
- }
-
- if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)
- {
- LLGLState blend(GL_BLEND, !mIsDummy);
- num_indices += renderTransparent(first_pass);
- }
-
- return num_indices;
+ return num_indices;
+ }
+
+ LLFace* face = mDrawable->getFace(0);
+
+ bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
+
+ if (needs_rebuild || mDirtyMesh)
+ { //LOD changed or new mesh created, allocate new vertex buffer if needed
+ if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
+ {
+ updateMeshData();
+ mDirtyMesh = 0;
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
+ }
+
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
+ {
+ if (mNeedsSkin)
+ {
+ //generate animated mesh
+ LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+ LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+ LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+ LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+ LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+
+ if(upper_mesh)
+ {
+ upper_mesh->updateJointGeometry();
+ }
+ if (lower_mesh)
+ {
+ lower_mesh->updateJointGeometry();
+ }
+
+ if( isWearingWearableType( LLWearableType::WT_SKIRT ) )
+ {
+ if(skirt_mesh)
+ {
+ skirt_mesh->updateJointGeometry();
+ }
+ }
+
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ {
+ if(eyelash_mesh)
+ {
+ eyelash_mesh->updateJointGeometry();
+ }
+ if(head_mesh)
+ {
+ head_mesh->updateJointGeometry();
+ }
+ if(hair_mesh)
+ {
+ hair_mesh->updateJointGeometry();
+ }
+ }
+ mNeedsSkin = FALSE;
+ mLastSkinTime = gFrameTimeSeconds;
+
+ LLFace * face = mDrawable->getFace(0);
+ if (face)
+ {
+ LLVertexBuffer* vb = face->getVertexBuffer();
+ if (vb)
+ {
+ vb->unmapBuffer();
+ }
+ }
+ }
+ }
+ else
+ {
+ mNeedsSkin = FALSE;
+ }
+
+ if (sDebugInvisible)
+ {
+ LLNameValue* firstname = getNVPair("FirstName");
+ if (firstname)
+ {
+ LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Avatar " << this << " in render" << LL_ENDL;
+ }
+ if (!mIsBuilt)
+ {
+ LL_INFOS() << "Not built!" << LL_ENDL;
+ }
+ else if (!gAgent.needsRenderAvatar())
+ {
+ LL_INFOS() << "Doesn't need avatar render!" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Rendering!" << LL_ENDL;
+ }
+ }
+
+ if (!mIsBuilt)
+ {
+ return num_indices;
+ }
+
+ if (isSelf() && !gAgent.needsRenderAvatar())
+ {
+ return num_indices;
+ }
+
+ //--------------------------------------------------------------------
+ // render all geometry attached to the skeleton
+ //--------------------------------------------------------------------
+
+ BOOL first_pass = TRUE;
+ if (!LLDrawPoolAvatar::sSkipOpaque)
+ {
+ if (isUIAvatar() && mIsDummy)
+ {
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+ if (hair_mesh)
+ {
+ num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ {
+
+ if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
+ {
+ LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+ if (head_mesh)
+ {
+ num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+ }
+ if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
+ {
+ LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+ if (upper_mesh)
+ {
+ num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+
+ if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
+ {
+ LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+ if (lower_mesh)
+ {
+ num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+ }
+
+ if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)
+ {
+ LLGLState blend(GL_BLEND, !mIsDummy);
+ num_indices += renderTransparent(first_pass);
+ }
+
+ return num_indices;
}
U32 LLVOAvatar::renderTransparent(BOOL first_pass)
{
- U32 num_indices = 0;
- if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) )
- {
+ U32 num_indices = 0;
+ if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) )
+ {
gGL.flush();
- LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
- if (skirt_mesh)
- {
- num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
- }
- first_pass = FALSE;
+ LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+ if (skirt_mesh)
+ {
+ num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
+ }
+ first_pass = FALSE;
gGL.flush();
- }
+ }
- if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
- {
- if (LLPipeline::sImpostorRender)
- {
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ {
+ if (LLPipeline::sImpostorRender)
+ {
gGL.flush();
- }
-
- if (isTextureVisible(TEX_HEAD_BAKED))
- {
- LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
- if (eyelash_mesh)
- {
- num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
- if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL))
- {
- LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
- if (hair_mesh)
- {
- num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
- }
- first_pass = FALSE;
- }
- if (LLPipeline::sImpostorRender)
- {
+ }
+
+ if (isTextureVisible(TEX_HEAD_BAKED))
+ {
+ LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+ if (eyelash_mesh)
+ {
+ num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+ if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL))
+ {
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+ if (hair_mesh)
+ {
+ num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
+ if (LLPipeline::sImpostorRender)
+ {
gGL.flush();
- }
- }
-
- return num_indices;
+ }
+ }
+
+ return num_indices;
}
//-----------------------------------------------------------------------------
@@ -5238,402 +5238,399 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
//-----------------------------------------------------------------------------
U32 LLVOAvatar::renderRigid()
{
- U32 num_indices = 0;
+ U32 num_indices = 0;
- if (!mIsBuilt)
- {
- return 0;
- }
+ if (!mIsBuilt)
+ {
+ return 0;
+ }
- if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
- {
- return 0;
- }
+ if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
+ {
+ return 0;
+ }
- bool should_alpha_mask = shouldAlphaMask();
- LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
-
- if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
- {
- LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
- LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
- if (eyeball_left)
- {
- num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy);
- }
- if(eyeball_right)
- {
- num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy);
- }
- }
+ if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
+ {
+ LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
+ LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
+ if (eyeball_left)
+ {
+ num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ }
+ if(eyeball_right)
+ {
+ num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ }
+ }
- return num_indices;
+ return num_indices;
}
U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
{
- if (!mImpostor.isComplete())
- {
- return 0;
- }
-
- LLVector3 pos(getRenderPosition()+mImpostorOffset);
- LLVector3 at = (pos - LLViewerCamera::getInstance()->getOrigin());
- at.normalize();
- LLVector3 left = LLViewerCamera::getInstance()->getUpAxis() % at;
- LLVector3 up = at%left;
-
- left *= mImpostorDim.mV[0];
- up *= mImpostorDim.mV[1];
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_IMPOSTORS))
- {
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ADD);
- gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
-
- // gGL.begin(LLRender::QUADS);
- // gGL.vertex3fv((pos+left-up).mV);
- // gGL.vertex3fv((pos-left-up).mV);
- // gGL.vertex3fv((pos-left+up).mV);
- // gGL.vertex3fv((pos+left+up).mV);
- // gGL.end();
-
-
- gGL.begin(LLRender::LINES);
- gGL.color4f(1.f,1.f,1.f,1.f);
- F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f);
- glLineWidth(thickness);
- gGL.vertex3fv((pos+left-up).mV);
- gGL.vertex3fv((pos-left-up).mV);
- gGL.vertex3fv((pos-left-up).mV);
- gGL.vertex3fv((pos-left+up).mV);
- gGL.vertex3fv((pos-left+up).mV);
- gGL.vertex3fv((pos+left+up).mV);
- gGL.vertex3fv((pos+left+up).mV);
- gGL.vertex3fv((pos+left-up).mV);
- gGL.end();
- gGL.flush();
- }
- {
- gGL.flush();
-
- gGL.color4ubv(color.mV);
- gGL.getTexUnit(diffuse_channel)->bind(&mImpostor);
- gGL.begin(LLRender::QUADS);
- gGL.texCoord2f(0,0);
- gGL.vertex3fv((pos+left-up).mV);
- gGL.texCoord2f(1,0);
- gGL.vertex3fv((pos-left-up).mV);
- gGL.texCoord2f(1,1);
- gGL.vertex3fv((pos-left+up).mV);
- gGL.texCoord2f(0,1);
- gGL.vertex3fv((pos+left+up).mV);
- gGL.end();
- gGL.flush();
- }
-
- return 6;
+ if (!mImpostor.isComplete())
+ {
+ return 0;
+ }
+
+ LLVector3 pos(getRenderPosition()+mImpostorOffset);
+ LLVector3 at = (pos - LLViewerCamera::getInstance()->getOrigin());
+ at.normalize();
+ LLVector3 left = LLViewerCamera::getInstance()->getUpAxis() % at;
+ LLVector3 up = at%left;
+
+ left *= mImpostorDim.mV[0];
+ up *= mImpostorDim.mV[1];
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_IMPOSTORS))
+ {
+ LLGLEnable blend(GL_BLEND);
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // gGL.begin(LLRender::QUADS);
+ // gGL.vertex3fv((pos+left-up).mV);
+ // gGL.vertex3fv((pos-left-up).mV);
+ // gGL.vertex3fv((pos-left+up).mV);
+ // gGL.vertex3fv((pos+left+up).mV);
+ // gGL.end();
+
+
+ gGL.begin(LLRender::LINES);
+ gGL.color4f(1.f,1.f,1.f,1.f);
+ F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f);
+ glLineWidth(thickness);
+ gGL.vertex3fv((pos+left-up).mV);
+ gGL.vertex3fv((pos-left-up).mV);
+ gGL.vertex3fv((pos-left-up).mV);
+ gGL.vertex3fv((pos-left+up).mV);
+ gGL.vertex3fv((pos-left+up).mV);
+ gGL.vertex3fv((pos+left+up).mV);
+ gGL.vertex3fv((pos+left+up).mV);
+ gGL.vertex3fv((pos+left-up).mV);
+ gGL.end();
+ gGL.flush();
+ }
+ {
+ gGL.flush();
+
+ gGL.color4ubv(color.mV);
+ gGL.getTexUnit(diffuse_channel)->bind(&mImpostor);
+ gGL.begin(LLRender::QUADS);
+ gGL.texCoord2f(0,0);
+ gGL.vertex3fv((pos+left-up).mV);
+ gGL.texCoord2f(1,0);
+ gGL.vertex3fv((pos-left-up).mV);
+ gGL.texCoord2f(1,1);
+ gGL.vertex3fv((pos-left+up).mV);
+ gGL.texCoord2f(0,1);
+ gGL.vertex3fv((pos+left+up).mV);
+ gGL.end();
+ gGL.flush();
+ }
+
+ return 6;
}
bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
{
- for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
- if (imagep && imagep->getDiscardLevel()!=0)
- {
- return false;
- }
- }
- return true;
+ for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
+ if (imagep && imagep->getDiscardLevel()!=0)
+ {
+ return false;
+ }
+ }
+ return true;
}
bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const
{
- std::set<LLUUID> local_ids;
- collectLocalTextureUUIDs(local_ids);
- return allTexturesCompletelyDownloaded(local_ids);
+ std::set<LLUUID> local_ids;
+ collectLocalTextureUUIDs(local_ids);
+ return allTexturesCompletelyDownloaded(local_ids);
}
bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const
{
- std::set<LLUUID> baked_ids;
- collectBakedTextureUUIDs(baked_ids);
- return allTexturesCompletelyDownloaded(baked_ids);
+ std::set<LLUUID> baked_ids;
+ collectBakedTextureUUIDs(baked_ids);
+ return allTexturesCompletelyDownloaded(baked_ids);
}
std::string LLVOAvatar::bakedTextureOriginInfo()
{
- std::string result;
-
- std::set<LLUUID> baked_ids;
- collectBakedTextureUUIDs(baked_ids);
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex;
- LLViewerFetchedTexture *imagep =
- LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
- if (!imagep ||
- imagep->getID() == IMG_DEFAULT ||
- imagep->getID() == IMG_DEFAULT_AVATAR)
-
- {
- result += "-";
- }
- else
- {
- bool has_url = false, has_host = false;
- if (!imagep->getUrl().empty())
- {
- has_url = true;
- }
- if (imagep->getTargetHost().isOk())
- {
- has_host = true;
- }
- S32 discard = imagep->getDiscardLevel();
- if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url
- else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim
- else if (has_host && has_url) result += discard ? "x" : "X"; // both origins?
- else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin?
- if (discard != 0)
- {
- result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel());
- }
- }
-
- }
- return result;
+ std::string result;
+
+ std::set<LLUUID> baked_ids;
+ collectBakedTextureUUIDs(baked_ids);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex;
+ LLViewerFetchedTexture *imagep =
+ LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+ if (!imagep ||
+ imagep->getID() == IMG_DEFAULT ||
+ imagep->getID() == IMG_DEFAULT_AVATAR)
+
+ {
+ result += "-";
+ }
+ else
+ {
+ bool has_url = false, has_host = false;
+ if (!imagep->getUrl().empty())
+ {
+ has_url = true;
+ }
+ if (imagep->getTargetHost().isOk())
+ {
+ has_host = true;
+ }
+ S32 discard = imagep->getDiscardLevel();
+ if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url
+ else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim
+ else if (has_host && has_url) result += discard ? "x" : "X"; // both origins?
+ else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin?
+ if (discard != 0)
+ {
+ result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel());
+ }
+ }
+
+ }
+ return result;
}
S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
{
- S32Bytes result(0);
- for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
- if (imagep)
- {
- result += imagep->getTextureMemory();
- }
- }
- return result;
-}
-
+ S32Bytes result(0);
+ for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
+ if (imagep)
+ {
+ result += imagep->getTextureMemory();
+ }
+ }
+ return result;
+}
+
void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
{
- for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
- {
- LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
- U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
-
- LLViewerFetchedTexture *imagep = NULL;
- for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
- {
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
- if (imagep)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
- if (texture_dict && texture_dict->mIsLocalTexture)
- {
- ids.insert(imagep->getID());
- }
- }
- }
- }
- ids.erase(IMG_DEFAULT);
- ids.erase(IMG_DEFAULT_AVATAR);
- ids.erase(IMG_INVISIBLE);
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+ {
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
+ U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+
+ LLViewerFetchedTexture *imagep = NULL;
+ for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
+ {
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
+ if (imagep)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
+ if (texture_dict && texture_dict->mIsLocalTexture)
+ {
+ ids.insert(imagep->getID());
+ }
+ }
+ }
+ }
+ ids.erase(IMG_DEFAULT);
+ ids.erase(IMG_DEFAULT_AVATAR);
+ ids.erase(IMG_INVISIBLE);
}
void LLVOAvatar::collectBakedTextureUUIDs(std::set<LLUUID>& ids) const
{
- for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
- {
- LLViewerFetchedTexture *imagep = NULL;
- if (isIndexBakedTexture((ETextureIndex) texture_index))
- {
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
- if (imagep)
- {
- ids.insert(imagep->getID());
- }
- }
- }
- ids.erase(IMG_DEFAULT);
- ids.erase(IMG_DEFAULT_AVATAR);
- ids.erase(IMG_INVISIBLE);
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+ {
+ LLViewerFetchedTexture *imagep = NULL;
+ if (isIndexBakedTexture((ETextureIndex) texture_index))
+ {
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+ if (imagep)
+ {
+ ids.insert(imagep->getID());
+ }
+ }
+ }
+ ids.erase(IMG_DEFAULT);
+ ids.erase(IMG_DEFAULT_AVATAR);
+ ids.erase(IMG_INVISIBLE);
}
void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& ids)
{
- collectLocalTextureUUIDs(ids);
- collectBakedTextureUUIDs(ids);
+ collectLocalTextureUUIDs(ids);
+ collectBakedTextureUUIDs(ids);
}
void LLVOAvatar::releaseOldTextures()
{
- S32Bytes current_texture_mem;
-
- // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE"
- std::set<LLUUID> baked_texture_ids;
- collectBakedTextureUUIDs(baked_texture_ids);
- S32Bytes new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids);
-
- std::set<LLUUID> local_texture_ids;
- collectLocalTextureUUIDs(local_texture_ids);
- //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids);
-
- std::set<LLUUID> new_texture_ids;
- new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end());
- new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end());
- S32Bytes new_total_mem = totalTextureMemForUUIDS(new_texture_ids);
-
- //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs);
- //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL;
- if (!isSelf() && new_total_mem > new_baked_mem)
- {
- LL_WARNS() << "extra local textures stored for non-self av" << LL_ENDL;
- }
- for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it)
- {
- if (new_texture_ids.find(*it) == new_texture_ids.end())
- {
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
- if (imagep)
- {
- current_texture_mem += imagep->getTextureMemory();
- if (imagep->getTextureState() == LLGLTexture::NO_DELETE)
- {
- // This will allow the texture to be deleted if not in use.
- imagep->forceActive();
-
- // This resets the clock to texture being flagged
- // as unused, preventing the texture from being
- // deleted immediately. If other avatars or
- // objects are using it, it can still be flagged
- // no-delete by them.
- imagep->forceUpdateBindStats();
- }
- }
- }
- }
- mTextureIDs = new_texture_ids;
+ S32Bytes current_texture_mem;
+
+ // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE"
+ std::set<LLUUID> baked_texture_ids;
+ collectBakedTextureUUIDs(baked_texture_ids);
+ S32Bytes new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids);
+
+ std::set<LLUUID> local_texture_ids;
+ collectLocalTextureUUIDs(local_texture_ids);
+ //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids);
+
+ std::set<LLUUID> new_texture_ids;
+ new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end());
+ new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end());
+ S32Bytes new_total_mem = totalTextureMemForUUIDS(new_texture_ids);
+
+ //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs);
+ //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL;
+ if (!isSelf() && new_total_mem > new_baked_mem)
+ {
+ LL_WARNS() << "extra local textures stored for non-self av" << LL_ENDL;
+ }
+ for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it)
+ {
+ if (new_texture_ids.find(*it) == new_texture_ids.end())
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
+ if (imagep)
+ {
+ current_texture_mem += imagep->getTextureMemory();
+ if (imagep->getTextureState() == LLGLTexture::NO_DELETE)
+ {
+ // This will allow the texture to be deleted if not in use.
+ imagep->forceActive();
+
+ // This resets the clock to texture being flagged
+ // as unused, preventing the texture from being
+ // deleted immediately. If other avatars or
+ // objects are using it, it can still be flagged
+ // no-delete by them.
+ imagep->forceUpdateBindStats();
+ }
+ }
+ }
+ }
+ mTextureIDs = new_texture_ids;
}
void LLVOAvatar::updateTextures()
{
- releaseOldTextures();
-
- BOOL render_avatar = TRUE;
-
- if (mIsDummy)
- {
- return;
- }
-
- if( isSelf() )
- {
- render_avatar = TRUE;
- }
- else
- {
- if(!isVisible())
- {
- return ;//do not update for invisible avatar.
- }
-
- render_avatar = !mCulled; //visible and not culled.
- }
-
- std::vector<BOOL> layer_baked;
- // GL NOT ACTIVE HERE - *TODO
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex));
- // bind the texture so that they'll be decoded slightly
- // inefficient, we can short-circuit this if we have to
- if (render_avatar && !gGLManager.mIsDisabled)
- {
- if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded)
- {
- gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ));
- }
- }
- }
-
- mMaxPixelArea = 0.f;
- mMinPixelArea = 99999999.f;
- mHasGrey = FALSE; // debug
- for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
- {
- LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
- U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
- const LLTextureEntry *te = getTE(texture_index);
-
- // getTE can return 0.
- // Not sure yet why it does, but of course it crashes when te->mScale? gets used.
- // Put safeguard in place so this corner case get better handling and does not result in a crash.
- F32 texel_area_ratio = 1.0f;
- if( te )
- {
- texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
- }
- else
- {
- LL_WARNS() << "getTE( " << texture_index << " ) returned 0" <<LL_ENDL;
- }
-
- LLViewerFetchedTexture *imagep = NULL;
- for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
- {
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
- if (imagep)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
- const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES;
- if (texture_dict && texture_dict->mIsLocalTexture)
- {
- addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
- }
- }
- }
- if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar)
- {
- const S32 boost_level = getAvatarBakedBoostLevel();
- imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
- addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
- }
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
- {
- setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea)));
- }
+ releaseOldTextures();
+
+ BOOL render_avatar = TRUE;
+
+ if (mIsDummy)
+ {
+ return;
+ }
+
+ if( isSelf() )
+ {
+ render_avatar = TRUE;
+ }
+ else
+ {
+ if(!isVisible())
+ {
+ return ;//do not update for invisible avatar.
+ }
+
+ render_avatar = !mCulled; //visible and not culled.
+ }
+
+ std::vector<BOOL> layer_baked;
+ // GL NOT ACTIVE HERE - *TODO
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex));
+ // bind the texture so that they'll be decoded slightly
+ // inefficient, we can short-circuit this if we have to
+ if (render_avatar && !gGLManager.mIsDisabled)
+ {
+ if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded)
+ {
+ gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ));
+ }
+ }
+ }
+
+ mMaxPixelArea = 0.f;
+ mMinPixelArea = 99999999.f;
+ mHasGrey = FALSE; // debug
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+ {
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
+ U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+ const LLTextureEntry *te = getTE(texture_index);
+
+ // getTE can return 0.
+ // Not sure yet why it does, but of course it crashes when te->mScale? gets used.
+ // Put safeguard in place so this corner case get better handling and does not result in a crash.
+ F32 texel_area_ratio = 1.0f;
+ if( te )
+ {
+ texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
+ }
+ else
+ {
+ LL_WARNS() << "getTE( " << texture_index << " ) returned 0" <<LL_ENDL;
+ }
+
+ LLViewerFetchedTexture *imagep = NULL;
+ for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
+ {
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
+ if (imagep)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
+ const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES;
+ if (texture_dict && texture_dict->mIsLocalTexture)
+ {
+ addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
+ }
+ }
+ }
+ if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar)
+ {
+ const S32 boost_level = getAvatarBakedBoostLevel();
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+ addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
+ }
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
+ {
+ setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea)));
+ }
}
void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep,
- F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
{
- // No local texture stats for non-self avatars
- return;
+ // No local texture stats for non-self avatars
+ return;
}
-const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.
+const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.
const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL = S32_MAX ; //frames
void LLVOAvatar::checkTextureLoading()
{
- static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds
+ static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds
- BOOL pause = !isVisible() ;
- if(!pause)
- {
- mInvisibleTimer.reset() ;
- }
- if(mLoadedCallbacksPaused == pause)
- {
+ BOOL pause = !isVisible() ;
+ if(!pause)
+ {
+ mInvisibleTimer.reset() ;
+ }
+ if(mLoadedCallbacksPaused == pause)
+ {
if (!pause && mFirstFullyVisible && mLoadedCallbackTextures < mCallbackTextureList.size())
{
// We still need to update 'loaded' textures count to decide on 'cloud' visibility
@@ -5649,120 +5646,120 @@ void LLVOAvatar::checkTextureLoading()
}
}
}
- return ;
- }
-
- if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty.
- {
- mLoadedCallbacksPaused = pause ;
- mLoadedCallbackTextures = 0;
- return ; //nothing to check.
- }
-
- if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)
- {
- return ; //have not been invisible for enough time.
- }
-
- mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0;
-
- for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
- iter != mCallbackTextureList.end(); ++iter)
- {
- LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
- if(tex)
- {
- if(pause)//pause texture fetching.
- {
- tex->pauseLoadedCallbacks(&mCallbackTextureList) ;
-
- //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames.
- tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL);
- tex->resetMaxVirtualSizeResetCounter() ;
- }
- else//unpause
- {
- static const F32 START_AREA = 100.f ;
-
- tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
- tex->addTextureStats(START_AREA); //jump start the fetching again
-
- // technically shouldn't need to account for missing, but callback might not have happened yet
- if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset())
- {
- mLoadedCallbackTextures++; // consider it loaded (we have at least some data)
- }
- }
- }
- }
-
- if(!pause)
- {
- updateTextures() ; //refresh texture stats.
- }
- mLoadedCallbacksPaused = pause ;
- return ;
+ return ;
+ }
+
+ if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty.
+ {
+ mLoadedCallbacksPaused = pause ;
+ mLoadedCallbackTextures = 0;
+ return ; //nothing to check.
+ }
+
+ if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)
+ {
+ return ; //have not been invisible for enough time.
+ }
+
+ mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0;
+
+ for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
+ iter != mCallbackTextureList.end(); ++iter)
+ {
+ LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
+ if(tex)
+ {
+ if(pause)//pause texture fetching.
+ {
+ tex->pauseLoadedCallbacks(&mCallbackTextureList) ;
+
+ //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames.
+ tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL);
+ tex->resetMaxVirtualSizeResetCounter() ;
+ }
+ else//unpause
+ {
+ static const F32 START_AREA = 100.f ;
+
+ tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
+ tex->addTextureStats(START_AREA); //jump start the fetching again
+
+ // technically shouldn't need to account for missing, but callback might not have happened yet
+ if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset())
+ {
+ mLoadedCallbackTextures++; // consider it loaded (we have at least some data)
+ }
+ }
+ }
+ }
+
+ if(!pause)
+ {
+ updateTextures() ; //refresh texture stats.
+ }
+ mLoadedCallbacksPaused = pause ;
+ return ;
}
const F32 SELF_ADDITIONAL_PRI = 0.75f ;
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
- //Note:
- //if this function is not called for the last MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL frames,
- //the texture pipeline will stop fetching this texture.
+ //Note:
+ //if this function is not called for the last MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL frames,
+ //the texture pipeline will stop fetching this texture.
- imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
- imagep->resetMaxVirtualSizeResetCounter() ;
+ imagep->resetTextureStats();
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
+ imagep->resetMaxVirtualSizeResetCounter() ;
- mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
- mMinPixelArea = llmin(pixel_area, mMinPixelArea);
- imagep->addTextureStats(pixel_area / texel_area_ratio);
- imagep->setBoostLevel(boost_level);
+ mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
+ mMinPixelArea = llmin(pixel_area, mMinPixelArea);
+ imagep->addTextureStats(pixel_area / texel_area_ratio);
+ imagep->setBoostLevel(boost_level);
}
-//virtual
+//virtual
void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep, const U32 index)
{
- setTEImage(te, imagep);
+ setTEImage(te, imagep);
}
-//virtual
+//virtual
LLViewerTexture* LLVOAvatar::getImage(const U8 te, const U32 index) const
{
- return getTEImage(te);
+ return getTEImage(te);
}
-//virtual
+//virtual
const LLTextureEntry* LLVOAvatar::getTexEntry(const U8 te_num) const
{
- return getTE(te_num);
+ return getTE(te_num);
}
-//virtual
+//virtual
void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)
{
- setTE(index, te);
+ setTE(index, te);
}
const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
{
- llassert(isIndexBakedTexture(ETextureIndex(te)));
- std::string url = "";
- const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL();
- if (appearance_service_url.empty())
- {
- // Probably a server-side issue if we get here:
- LL_WARNS() << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << LL_ENDL;
- return url;
- }
-
- const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
- if (texture_entry != NULL)
- {
- url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
- //LL_INFOS() << "baked texture url: " << url << LL_ENDL;
- }
- return url;
+ llassert(isIndexBakedTexture(ETextureIndex(te)));
+ std::string url = "";
+ const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL();
+ if (appearance_service_url.empty())
+ {
+ // Probably a server-side issue if we get here:
+ LL_WARNS() << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << LL_ENDL;
+ return url;
+ }
+
+ const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
+ if (texture_entry != NULL)
+ {
+ url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
+ //LL_INFOS() << "baked texture url: " << url << LL_ENDL;
+ }
+ return url;
}
//-----------------------------------------------------------------------------
@@ -5771,47 +5768,47 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
void LLVOAvatar::resolveHeightAgent(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &out_norm)
{
- LLVector3d in_pos_global, out_pos_global;
+ LLVector3d in_pos_global, out_pos_global;
- in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent);
- resolveHeightGlobal(in_pos_global, out_pos_global, out_norm);
- out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
+ in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent);
+ resolveHeightGlobal(in_pos_global, out_pos_global, out_norm);
+ out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
}
void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm)
{
- LLViewerObject *obj;
- LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj);
+ LLViewerObject *obj;
+ LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj);
}
void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm)
{
- LLVector3d zVec(0.0f, 0.0f, 0.5f);
- LLVector3d p0 = inPos + zVec;
- LLVector3d p1 = inPos - zVec;
- LLViewerObject *obj;
- LLWorld::getInstance()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj);
- if (!obj)
- {
- mStepOnLand = TRUE;
- mStepMaterial = 0;
- mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f);
- }
- else
- {
- mStepOnLand = FALSE;
- mStepMaterial = obj->getMaterial();
+ LLVector3d zVec(0.0f, 0.0f, 0.5f);
+ LLVector3d p0 = inPos + zVec;
+ LLVector3d p1 = inPos - zVec;
+ LLViewerObject *obj;
+ LLWorld::getInstance()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj);
+ if (!obj)
+ {
+ mStepOnLand = TRUE;
+ mStepMaterial = 0;
+ mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f);
+ }
+ else
+ {
+ mStepOnLand = FALSE;
+ mStepMaterial = obj->getMaterial();
- // We want the primitive velocity, not our velocity... (which actually subtracts the
- // step object velocity)
- LLVector3 angularVelocity = obj->getAngularVelocity();
- LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent();
+ // We want the primitive velocity, not our velocity... (which actually subtracts the
+ // step object velocity)
+ LLVector3 angularVelocity = obj->getAngularVelocity();
+ LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent();
- LLVector3 linearComponent = angularVelocity % relativePos;
-// LL_INFOS() << "Linear Component of Rotation Velocity " << linearComponent << LL_ENDL;
- mStepObjectVelocity = obj->getVelocity() + linearComponent;
- }
+ LLVector3 linearComponent = angularVelocity % relativePos;
+// LL_INFOS() << "Linear Component of Rotation Velocity " << linearComponent << LL_ENDL;
+ mStepObjectVelocity = obj->getVelocity() + linearComponent;
+ }
}
@@ -5820,12 +5817,12 @@ void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos
//-----------------------------------------------------------------------------
const LLUUID& LLVOAvatar::getStepSound() const
{
- if ( mStepOnLand )
- {
- return sStepSoundOnLand;
- }
+ if ( mStepOnLand )
+ {
+ return sStepSoundOnLand;
+ }
- return sStepSounds[mStepMaterial];
+ return sStepSounds[mStepMaterial];
}
@@ -5834,106 +5831,106 @@ const LLUUID& LLVOAvatar::getStepSound() const
//-----------------------------------------------------------------------------
void LLVOAvatar::processAnimationStateChanges()
{
- if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
- {
- startMotion(ANIM_AGENT_WALK_ADJUST);
- stopMotion(ANIM_AGENT_FLY_ADJUST);
- }
- else if (mInAir && !isSitting())
- {
- stopMotion(ANIM_AGENT_WALK_ADJUST);
+ if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
+ {
+ startMotion(ANIM_AGENT_WALK_ADJUST);
+ stopMotion(ANIM_AGENT_FLY_ADJUST);
+ }
+ else if (mInAir && !isSitting())
+ {
+ stopMotion(ANIM_AGENT_WALK_ADJUST);
if (mEnableDefaultMotions)
{
- startMotion(ANIM_AGENT_FLY_ADJUST);
- }
- }
- else
- {
- stopMotion(ANIM_AGENT_WALK_ADJUST);
- stopMotion(ANIM_AGENT_FLY_ADJUST);
- }
-
- if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
- {
+ startMotion(ANIM_AGENT_FLY_ADJUST);
+ }
+ }
+ else
+ {
+ stopMotion(ANIM_AGENT_WALK_ADJUST);
+ stopMotion(ANIM_AGENT_FLY_ADJUST);
+ }
+
+ if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
+ {
if (mEnableDefaultMotions)
{
- startMotion(ANIM_AGENT_TARGET);
+ startMotion(ANIM_AGENT_TARGET);
}
- stopMotion(ANIM_AGENT_BODY_NOISE);
- }
- else
- {
- stopMotion(ANIM_AGENT_TARGET);
+ stopMotion(ANIM_AGENT_BODY_NOISE);
+ }
+ else
+ {
+ stopMotion(ANIM_AGENT_TARGET);
if (mEnableDefaultMotions)
{
- startMotion(ANIM_AGENT_BODY_NOISE);
- }
- }
-
- // clear all current animations
- AnimIterator anim_it;
- for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();)
- {
- AnimIterator found_anim = mSignaledAnimations.find(anim_it->first);
-
- // playing, but not signaled, so stop
- if (found_anim == mSignaledAnimations.end())
- {
- processSingleAnimationStateChange(anim_it->first, FALSE);
- mPlayingAnimations.erase(anim_it++);
- continue;
- }
-
- ++anim_it;
- }
-
- // if jellydolled, shelve all playing animations
- if (getOverallAppearance() != AOA_NORMAL)
- {
- mPlayingAnimations.clear();
- }
-
- // start up all new anims
- if (getOverallAppearance() == AOA_NORMAL)
- {
- for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
- {
- AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
-
- // signaled but not playing, or different sequence id, start motion
- if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
- {
- if (processSingleAnimationStateChange(anim_it->first, TRUE))
- {
- mPlayingAnimations[anim_it->first] = anim_it->second;
- ++anim_it;
- continue;
- }
- }
-
- ++anim_it;
- }
- }
-
- // clear source information for animations which have been stopped
- if (isSelf())
- {
- AnimSourceIterator source_it = mAnimationSources.begin();
-
- for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();)
- {
- if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end())
- {
- mAnimationSources.erase(source_it++);
- }
- else
- {
- ++source_it;
- }
- }
- }
-
- stop_glerror();
+ startMotion(ANIM_AGENT_BODY_NOISE);
+ }
+ }
+
+ // clear all current animations
+ AnimIterator anim_it;
+ for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();)
+ {
+ AnimIterator found_anim = mSignaledAnimations.find(anim_it->first);
+
+ // playing, but not signaled, so stop
+ if (found_anim == mSignaledAnimations.end())
+ {
+ processSingleAnimationStateChange(anim_it->first, FALSE);
+ mPlayingAnimations.erase(anim_it++);
+ continue;
+ }
+
+ ++anim_it;
+ }
+
+ // if jellydolled, shelve all playing animations
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ mPlayingAnimations.clear();
+ }
+
+ // start up all new anims
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
+ {
+ AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
+
+ // signaled but not playing, or different sequence id, start motion
+ if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
+ {
+ if (processSingleAnimationStateChange(anim_it->first, TRUE))
+ {
+ mPlayingAnimations[anim_it->first] = anim_it->second;
+ ++anim_it;
+ continue;
+ }
+ }
+
+ ++anim_it;
+ }
+ }
+
+ // clear source information for animations which have been stopped
+ if (isSelf())
+ {
+ AnimSourceIterator source_it = mAnimationSources.begin();
+
+ for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();)
+ {
+ if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end())
+ {
+ mAnimationSources.erase(source_it++);
+ }
+ else
+ {
+ ++source_it;
+ }
+ }
+ }
+
+ stop_glerror();
}
@@ -5947,66 +5944,66 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
// cause constant jiggling of the body or camera. Possible
// compromise is to do it on animation changes:
computeBodySize();
-
- BOOL result = FALSE;
-
- if ( start ) // start animation
- {
- if (anim_id == ANIM_AGENT_TYPE)
- {
- if (gAudiop)
- {
- LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition());
- if (LLViewerParcelMgr::getInstance()->canHearSound(char_pos_global)
- && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
- {
- // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed
- // to support both spatialized and non-spatialized instances of the same sound
- //if (isSelf())
- //{
- // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
- //}
- //else
- {
+
+ BOOL result = FALSE;
+
+ if ( start ) // start animation
+ {
+ if (anim_id == ANIM_AGENT_TYPE)
+ {
+ if (gAudiop)
+ {
+ LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition());
+ if (LLViewerParcelMgr::getInstance()->canHearSound(char_pos_global)
+ && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
+ {
+ // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed
+ // to support both spatialized and non-spatialized instances of the same sound
+ //if (isSelf())
+ //{
+ // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ //}
+ //else
+ {
static LLCachedControl<std::string> ui_snd_string(gSavedSettings, "UISndTyping");
- LLUUID sound_id = LLUUID(ui_snd_string);
- gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
- }
- }
- }
- }
- else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
- {
- sitDown(TRUE);
- }
-
-
- if (startMotion(anim_id))
- {
- result = TRUE;
- }
- else
- {
- LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL;
- }
- }
- else //stop animation
- {
- if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
- {
- sitDown(FALSE);
- }
- if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb())
- {
- // re-assert DND tag animation
- gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START);
- return result;
- }
- stopMotion(anim_id);
- result = TRUE;
- }
-
- return result;
+ LLUUID sound_id = LLUUID(ui_snd_string);
+ gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
+ }
+ }
+ }
+ }
+ else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
+ {
+ sitDown(TRUE);
+ }
+
+
+ if (startMotion(anim_id))
+ {
+ result = TRUE;
+ }
+ else
+ {
+ LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL;
+ }
+ }
+ else //stop animation
+ {
+ if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
+ {
+ sitDown(FALSE);
+ }
+ if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb())
+ {
+ // re-assert DND tag animation
+ gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START);
+ return result;
+ }
+ stopMotion(anim_id);
+ result = TRUE;
+ }
+
+ return result;
}
//-----------------------------------------------------------------------------
@@ -6014,14 +6011,14 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims) const
{
- for (S32 i = 0; i < num_anims; i++)
- {
- if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end())
- {
- return TRUE;
- }
- }
- return FALSE;
+ for (S32 i = 0; i < num_anims; i++)
+ {
+ if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -6029,8 +6026,8 @@ BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_
//-----------------------------------------------------------------------------
void LLVOAvatar::resetAnimations()
{
- LLKeyframeMotion::flushKeyframeCache();
- flushAllMotions();
+ LLKeyframeMotion::flushKeyframeCache();
+ flushAllMotions();
}
// Override selectively based on avatar sex and whether we're using new
@@ -6038,52 +6035,52 @@ void LLVOAvatar::resetAnimations()
LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
{
static LLCachedControl<bool> use_new_walk_run(gSavedSettings, "UseNewWalkRun");
- LLUUID result = id;
-
- // start special case female walk for female avatars
- if (getSex() == SEX_FEMALE)
- {
- if (id == ANIM_AGENT_WALK)
- {
- if (use_new_walk_run)
- result = ANIM_AGENT_FEMALE_WALK_NEW;
- else
- result = ANIM_AGENT_FEMALE_WALK;
- }
- else if (id == ANIM_AGENT_RUN)
- {
- // There is no old female run animation, so only override
- // in one case.
- if (use_new_walk_run)
- result = ANIM_AGENT_FEMALE_RUN_NEW;
- }
- else if (id == ANIM_AGENT_SIT)
- {
- result = ANIM_AGENT_SIT_FEMALE;
- }
- }
- else
- {
- // Male avatar.
- if (id == ANIM_AGENT_WALK)
- {
- if (use_new_walk_run)
- result = ANIM_AGENT_WALK_NEW;
- }
- else if (id == ANIM_AGENT_RUN)
- {
- if (use_new_walk_run)
- result = ANIM_AGENT_RUN_NEW;
- }
- // keeps in sync with setSex() related code (viewer controls sit's sex)
- else if (id == ANIM_AGENT_SIT_FEMALE)
- {
- result = ANIM_AGENT_SIT;
- }
-
- }
-
- return result;
+ LLUUID result = id;
+
+ // start special case female walk for female avatars
+ if (getSex() == SEX_FEMALE)
+ {
+ if (id == ANIM_AGENT_WALK)
+ {
+ if (use_new_walk_run)
+ result = ANIM_AGENT_FEMALE_WALK_NEW;
+ else
+ result = ANIM_AGENT_FEMALE_WALK;
+ }
+ else if (id == ANIM_AGENT_RUN)
+ {
+ // There is no old female run animation, so only override
+ // in one case.
+ if (use_new_walk_run)
+ result = ANIM_AGENT_FEMALE_RUN_NEW;
+ }
+ else if (id == ANIM_AGENT_SIT)
+ {
+ result = ANIM_AGENT_SIT_FEMALE;
+ }
+ }
+ else
+ {
+ // Male avatar.
+ if (id == ANIM_AGENT_WALK)
+ {
+ if (use_new_walk_run)
+ result = ANIM_AGENT_WALK_NEW;
+ }
+ else if (id == ANIM_AGENT_RUN)
+ {
+ if (use_new_walk_run)
+ result = ANIM_AGENT_RUN_NEW;
+ }
+ // keeps in sync with setSex() related code (viewer controls sit's sex)
+ else if (id == ANIM_AGENT_SIT_FEMALE)
+ {
+ result = ANIM_AGENT_SIT;
+ }
+
+ }
+
+ return result;
}
@@ -6094,21 +6091,21 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
{
- LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
- LLUUID remap_id = remapMotionID(id);
+ LLUUID remap_id = remapMotionID(id);
- if (remap_id != id)
- {
- LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
- }
+ if (remap_id != id)
+ {
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ }
- if (isSelf() && remap_id == ANIM_AGENT_AWAY)
- {
- gAgent.setAFK();
- }
+ if (isSelf() && remap_id == ANIM_AGENT_AWAY)
+ {
+ gAgent.setAFK();
+ }
- return LLCharacter::startMotion(remap_id, time_offset);
+ return LLCharacter::startMotion(remap_id, time_offset);
}
//-----------------------------------------------------------------------------
@@ -6116,21 +6113,21 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
{
- LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
- LLUUID remap_id = remapMotionID(id);
+ LLUUID remap_id = remapMotionID(id);
+
+ if (remap_id != id)
+ {
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ }
- if (remap_id != id)
- {
- LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
- }
+ if (isSelf())
+ {
+ gAgent.onAnimStop(remap_id);
+ }
- if (isSelf())
- {
- gAgent.onAnimStop(remap_id);
- }
-
- return LLCharacter::stopMotion(remap_id, stop_immediate);
+ return LLCharacter::stopMotion(remap_id, stop_immediate);
}
//-----------------------------------------------------------------------------
@@ -6139,7 +6136,7 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
// virtual
bool LLVOAvatar::hasMotionFromSource(const LLUUID& source_id)
{
- return false;
+ return false;
}
//-----------------------------------------------------------------------------
@@ -6155,8 +6152,8 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
//-----------------------------------------------------------------------------
void LLVOAvatar::addDebugText(const std::string& text)
{
- mDebugText.append(1, '\n');
- mDebugText.append(text);
+ mDebugText.append(1, '\n');
+ mDebugText.append(text);
}
//-----------------------------------------------------------------------------
@@ -6164,7 +6161,7 @@ void LLVOAvatar::addDebugText(const std::string& text)
//-----------------------------------------------------------------------------
const LLUUID& LLVOAvatar::getID() const
{
- return mID;
+ return mID;
}
//-----------------------------------------------------------------------------
@@ -6173,33 +6170,33 @@ const LLUUID& LLVOAvatar::getID() const
// RN: avatar joints are multi-rooted to include screen-based attachments
LLJoint *LLVOAvatar::getJoint( const std::string &name )
{
- joint_map_t::iterator iter = mJointMap.find(name);
-
- LLJoint* jointp = NULL;
-
- if (iter == mJointMap.end() || iter->second == NULL)
- { //search for joint and cache found joint in lookup table
- if (mJointAliasMap.empty())
- {
- getJointAliases();
- }
- joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
- std::string canonical_name;
- if (alias_iter != mJointAliasMap.end())
- {
- canonical_name = alias_iter->second;
- }
- else
- {
- canonical_name = name;
- }
- jointp = mRoot->findJoint(canonical_name);
- mJointMap[name] = jointp;
- }
- else
- { //return cached pointer
- jointp = iter->second;
- }
+ joint_map_t::iterator iter = mJointMap.find(name);
+
+ LLJoint* jointp = NULL;
+
+ if (iter == mJointMap.end() || iter->second == NULL)
+ { //search for joint and cache found joint in lookup table
+ if (mJointAliasMap.empty())
+ {
+ getJointAliases();
+ }
+ joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
+ std::string canonical_name;
+ if (alias_iter != mJointAliasMap.end())
+ {
+ canonical_name = alias_iter->second;
+ }
+ else
+ {
+ canonical_name = name;
+ }
+ jointp = mRoot->findJoint(canonical_name);
+ mJointMap[name] = jointp;
+ }
+ else
+ { //return cached pointer
+ jointp = iter->second;
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot")
@@ -6207,7 +6204,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
llassert(getJoint(jointp->getJointNum())==jointp);
}
#endif
- return jointp;
+ return jointp;
}
LLJoint *LLVOAvatar::getJoint( S32 joint_num )
@@ -6235,8 +6232,8 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num )
}
}
}
-
- llassert(!pJoint || pJoint->getJointNum() == joint_num);
+
+ llassert(!pJoint || pJoint->getJointNum() == joint_num);
return pJoint;
}
@@ -6249,31 +6246,31 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num )
// static
bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id)
{
- mesh_id.setNull();
-
- //If a VO has a skin that we'll reset the joint positions to their default
- if ( pVO && pVO->mDrawable )
- {
- LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
- if ( pVObj )
- {
- const LLMeshSkinInfo* pSkinData = pVObj->getSkinInfo();
- if (pSkinData
- && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
- && pSkinData->mAlternateBindMatrix.size() > 0 )
- {
- mesh_id = pSkinData->mMeshID;
- return true;
- }
- }
- }
- return false;
+ mesh_id.setNull();
+
+ //If a VO has a skin that we'll reset the joint positions to their default
+ if ( pVO && pVO->mDrawable )
+ {
+ LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
+ if ( pVObj )
+ {
+ const LLMeshSkinInfo* pSkinData = pVObj->getSkinInfo();
+ if (pSkinData
+ && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
+ && pSkinData->mAlternateBindMatrix.size() > 0 )
+ {
+ mesh_id = pSkinData->mMeshID;
+ return true;
+ }
+ }
+ }
+ return false;
}
bool LLVOAvatar::jointIsRiggedTo(const LLJoint *joint) const
{
if (joint)
- {
+ {
const LLJointRiggingInfoTab& tab = mJointRiggingInfoTab;
S32 joint_num = joint->getJointNum();
if (joint_num < tab.size() && tab[joint_num].isRiggedTo())
@@ -6289,25 +6286,25 @@ void LLVOAvatar::clearAttachmentOverrides()
LLScopedContextString str("clearAttachmentOverrides " + getFullname());
for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++)
- {
+ {
LLJoint *pJoint = getJoint(i);
if (pJoint)
{
- pJoint->clearAttachmentPosOverrides();
- pJoint->clearAttachmentScaleOverrides();
+ pJoint->clearAttachmentPosOverrides();
+ pJoint->clearAttachmentScaleOverrides();
}
- }
+ }
if (mPelvisFixups.count()>0)
{
mPelvisFixups.clear();
LLJoint* pJointPelvis = getJoint("mPelvis");
if (pJointPelvis)
- {
- pJointPelvis->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
+ {
+ pJointPelvis->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
}
- postPelvisSetRecalc();
- }
+ postPelvisSetRecalc();
+ }
mActiveOverrideMeshes.clear();
onActiveOverrideMeshesChanged();
@@ -6322,32 +6319,32 @@ void LLVOAvatar::rebuildAttachmentOverrides()
LL_DEBUGS("AnimatedObjects") << "rebuilding" << LL_ENDL;
dumpStack("AnimatedObjectsStack");
-
+
clearAttachmentOverrides();
// Handle the case that we're resetting the skeleton of an animated object.
LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this);
if (control_av)
- {
+ {
LLVOVolume *volp = control_av->mRootVolp;
if (volp)
{
- LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
+ LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
<< (S32) (1+volp->numChildren()) << LL_ENDL;
addAttachmentOverridesForObject(volp);
}
}
// Attached objects
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment *attachment_pt = (*iter).second;
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment_pt = (*iter).second;
if (attachment_pt)
{
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
- at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
+ at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
@@ -6375,7 +6372,7 @@ void LLVOAvatar::updateAttachmentOverrides()
dumpStack("AnimatedObjectsStack");
std::set<LLUUID> meshes_seen;
-
+
// Handle the case that we're updating the skeleton of an animated object.
LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this);
if (control_av)
@@ -6383,22 +6380,22 @@ void LLVOAvatar::updateAttachmentOverrides()
LLVOVolume *volp = control_av->mRootVolp;
if (volp)
{
- LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
+ LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
<< (S32) (1+volp->numChildren()) << LL_ENDL;
addAttachmentOverridesForObject(volp, &meshes_seen);
}
}
// Attached objects
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment *attachment_pt = (*iter).second;
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment_pt = (*iter).second;
if (attachment_pt)
{
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
- at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
+ at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
@@ -6412,8 +6409,8 @@ void LLVOAvatar::updateAttachmentOverrides()
}
// Remove meshes that are no longer present on the skeleton
- // have to work with a copy because removeAttachmentOverrides() will change mActiveOverrideMeshes.
- std::set<LLUUID> active_override_meshes = mActiveOverrideMeshes;
+ // have to work with a copy because removeAttachmentOverrides() will change mActiveOverrideMeshes.
+ std::set<LLUUID> active_override_meshes = mActiveOverrideMeshes;
for (std::set<LLUUID>::iterator it = active_override_meshes.begin(); it != active_override_meshes.end(); ++it)
{
if (meshes_seen.find(*it) == meshes_seen.end())
@@ -6496,63 +6493,63 @@ void LLVOAvatar::notifyAttachmentMeshLoaded()
void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen, bool recursive)
{
if (vo->getAvatar() != this && vo->getAvatarAncestor() != this)
- {
- LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ {
+ LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
return;
- }
+ }
LLScopedContextString str("addAttachmentOverridesForObject " + getFullname());
- if (getOverallAppearance() != AOA_NORMAL)
- {
- return;
- }
-
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ return;
+ }
+
LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;
dumpStack("AnimatedObjectsStack");
-
- // Process all children
+
+ // Process all children
if (recursive)
{
- LLViewerObject::const_child_list_t& children = vo->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
- it != children.end(); ++it)
- {
- LLViewerObject *childp = *it;
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
addAttachmentOverridesForObject(childp, meshes_seen, true);
}
- }
+ }
- LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
- bool pelvisGotSet = false;
+ LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
+ bool pelvisGotSet = false;
- if (!vobj)
- {
- return;
- }
+ if (!vobj)
+ {
+ return;
+ }
- LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot();
+ LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot();
LL_DEBUGS("AnimatedObjects") << "trying to add attachment overrides for root object " << root_object->getID() << " prim is " << vobj << LL_ENDL;
- if (vobj->isMesh() &&
- ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
- {
+ if (vobj->isMesh() &&
+ ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
+ {
LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " mesh asset not loaded" << LL_ENDL;
- return;
- }
- const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo();
+ return;
+ }
+ const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo();
- if ( vobj && vobj->isMesh() && pSkinData )
- {
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( vobj && vobj->isMesh() && pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
const int jointCnt = pSkinData->mJointNames.size();
if ((bindCnt > 0) && (bindCnt != jointCnt))
{
LL_WARNS_ONCE() << "invalid mesh, bindCnt " << bindCnt << "!= jointCnt " << jointCnt << ", joint overrides will be ignored." << LL_ENDL;
}
- if ((bindCnt > 0) && (bindCnt == jointCnt))
- {
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- const LLUUID& mesh_id = pSkinData->mMeshID;
+ if ((bindCnt > 0) && (bindCnt == jointCnt))
+ {
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ const LLUUID& mesh_id = pSkinData->mMeshID;
if (meshes_seen)
{
@@ -6561,38 +6558,38 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
bool mesh_overrides_loaded = (mActiveOverrideMeshes.find(mesh_id) != mActiveOverrideMeshes.end());
if (mesh_overrides_loaded)
{
- LL_DEBUGS("AnimatedObjects") << "skipping add attachment overrides for " << mesh_id
+ LL_DEBUGS("AnimatedObjects") << "skipping add attachment overrides for " << mesh_id
<< " to root object " << root_object->getID()
<< ", already loaded"
<< LL_ENDL;
}
else
{
- LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id
+ LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id
<< " to root object " << root_object->getID() << LL_ENDL;
}
- bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
- if ( fullRig && !mesh_overrides_loaded )
- {
- for ( int i=0; i<jointCnt; ++i )
- {
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- LLJoint* pJoint = getJoint( lookingForJoint );
- if (pJoint)
- {
- const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation());
+ bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
+ if ( fullRig && !mesh_overrides_loaded )
+ {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ LLJoint* pJoint = getJoint( lookingForJoint );
+ if (pJoint)
+ {
+ const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation());
if (pJoint->aboveJointPosThreshold(jointPos))
{
bool override_changed;
pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed );
-
+
if (override_changed)
{
//If joint is a pelvis then handle old/new pelvis to foot values
if ( lookingForJoint == "mPelvis" )
- {
- pelvisGotSet = true;
- }
+ {
+ pelvisGotSet = true;
+ }
}
if (pSkinData->mLockScaleIfJointPosition)
{
@@ -6601,36 +6598,36 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString());
}
}
- }
- }
- if (pelvisZOffset != 0.0F)
- {
+ }
+ }
+ if (pelvisZOffset != 0.0F)
+ {
F32 pelvis_fixup_before;
bool has_fixup_before = hasPelvisFixup(pelvis_fixup_before);
- addPelvisFixup( pelvisZOffset, mesh_id );
- F32 pelvis_fixup_after;
+ addPelvisFixup( pelvisZOffset, mesh_id );
+ F32 pelvis_fixup_after;
hasPelvisFixup(pelvis_fixup_after); // Don't have to check bool here because we just added it...
if (!has_fixup_before || (pelvis_fixup_before != pelvis_fixup_after))
{
- pelvisGotSet = true;
+ pelvisGotSet = true;
}
-
- }
+
+ }
mActiveOverrideMeshes.insert(mesh_id);
onActiveOverrideMeshesChanged();
- }
- }
- }
+ }
+ }
+ }
else
{
LL_DEBUGS("AnimatedObjects") << "failed to add attachment overrides for root object " << root_object->getID() << " not mesh or no pSkinData" << LL_ENDL;
}
-
- //Rebuild body data if we altered joints/pelvis
- if ( pelvisGotSet )
- {
- postPelvisSetRecalc();
- }
+
+ //Rebuild body data if we altered joints/pelvis
+ if ( pelvisGotSet )
+ {
+ postPelvisSetRecalc();
+ }
}
//-----------------------------------------------------------------------------
@@ -6643,26 +6640,26 @@ void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& pos_names, st
LLUUID mesh_id;
// Bones
- for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+ for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
iter != mSkeleton.end(); ++iter)
- {
- const LLJoint* pJoint = (*iter);
- if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
- {
+ {
+ const LLJoint* pJoint = (*iter);
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
pos_names.insert(pJoint->getName());
- }
- if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
- {
+ }
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
+ {
scale_names.insert(pJoint->getName());
- }
- }
+ }
+ }
// Attachment points
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id))
{
pos_names.insert(attachment_pt->getName());
@@ -6710,28 +6707,28 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const
S32 count = 0;
// Bones
- for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+ for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
iter != mSkeleton.end(); ++iter)
- {
- const LLJoint* pJoint = (*iter);
- if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
- {
- pJoint->showAttachmentPosOverrides(getFullname());
+ {
+ const LLJoint* pJoint = (*iter);
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ pJoint->showAttachmentPosOverrides(getFullname());
count++;
- }
- if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
- {
- pJoint->showAttachmentScaleOverrides(getFullname());
+ }
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
+ {
+ pJoint->showAttachmentScaleOverrides(getFullname());
count++;
}
- }
+ }
// Attachment points
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id))
{
attachment_pt->showAttachmentPosOverrides(getFullname());
@@ -6752,53 +6749,53 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const
void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo)
{
if (vo->getAvatar() != this && vo->getAvatarAncestor() != this)
- {
- LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ {
+ LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
return;
- }
-
- // Process all children
- LLViewerObject::const_child_list_t& children = vo->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
- it != children.end(); ++it)
- {
- LLViewerObject *childp = *it;
- removeAttachmentOverridesForObject(childp);
- }
-
- // Process self.
- LLUUID mesh_id;
- if (getRiggedMeshID(vo,mesh_id))
- {
- removeAttachmentOverridesForObject(mesh_id);
- }
+ }
+
+ // Process all children
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
+ removeAttachmentOverridesForObject(childp);
+ }
+
+ // Process self.
+ LLUUID mesh_id;
+ if (getRiggedMeshID(vo,mesh_id))
+ {
+ removeAttachmentOverridesForObject(mesh_id);
+ }
}
//-----------------------------------------------------------------------------
// removeAttachmentOverridesForObject
//-----------------------------------------------------------------------------
void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id)
-{
- LLJoint* pJointPelvis = getJoint("mPelvis");
+{
+ LLJoint* pJointPelvis = getJoint("mPelvis");
const std::string av_string = avString();
for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
- {
+ {
LLJoint *pJoint = getJoint(joint_num);
- if ( pJoint )
- {
+ if ( pJoint )
+ {
bool dummy; // unused
- pJoint->removeAttachmentPosOverride(mesh_id, av_string, dummy);
- pJoint->removeAttachmentScaleOverride(mesh_id, av_string);
- }
- if ( pJoint && pJoint == pJointPelvis)
- {
- removePelvisFixup( mesh_id );
- // SL-315
- pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
- }
- }
-
- postPelvisSetRecalc();
+ pJoint->removeAttachmentPosOverride(mesh_id, av_string, dummy);
+ pJoint->removeAttachmentScaleOverride(mesh_id, av_string);
+ }
+ if ( pJoint && pJoint == pJointPelvis)
+ {
+ removePelvisFixup( mesh_id );
+ // SL-315
+ pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
+ }
+ }
+
+ postPelvisSetRecalc();
mActiveOverrideMeshes.erase(mesh_id);
onActiveOverrideMeshesChanged();
@@ -6808,14 +6805,14 @@ void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id)
//-----------------------------------------------------------------------------
LLVector3 LLVOAvatar::getCharacterPosition()
{
- if (mDrawable.notNull())
- {
- return mDrawable->getPositionAgent();
- }
- else
- {
- return getPositionAgent();
- }
+ if (mDrawable.notNull())
+ {
+ return mDrawable->getPositionAgent();
+ }
+ else
+ {
+ return getPositionAgent();
+ }
}
@@ -6824,7 +6821,7 @@ LLVector3 LLVOAvatar::getCharacterPosition()
//-----------------------------------------------------------------------------
LLQuaternion LLVOAvatar::getCharacterRotation()
{
- return getRotation();
+ return getRotation();
}
@@ -6833,7 +6830,7 @@ LLQuaternion LLVOAvatar::getCharacterRotation()
//-----------------------------------------------------------------------------
LLVector3 LLVOAvatar::getCharacterVelocity()
{
- return getVelocity() - mStepObjectVelocity;
+ return getVelocity() - mStepObjectVelocity;
}
@@ -6842,7 +6839,7 @@ LLVector3 LLVOAvatar::getCharacterVelocity()
//-----------------------------------------------------------------------------
LLVector3 LLVOAvatar::getCharacterAngularVelocity()
{
- return getAngularVelocity();
+ return getAngularVelocity();
}
//-----------------------------------------------------------------------------
@@ -6850,22 +6847,22 @@ LLVector3 LLVOAvatar::getCharacterAngularVelocity()
//-----------------------------------------------------------------------------
void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &outNorm)
{
- LLVector3d z_vec(0.0f, 0.0f, 1.0f);
- LLVector3d p0_global, p1_global;
-
- if (isUIAvatar())
- {
- outNorm.setVec(z_vec);
- out_pos_agent = in_pos_agent;
- return;
- }
+ LLVector3d z_vec(0.0f, 0.0f, 1.0f);
+ LLVector3d p0_global, p1_global;
- p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec;
- p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec;
- LLViewerObject *obj;
- LLVector3d out_pos_global;
- LLWorld::getInstance()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj);
- out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
+ if (isUIAvatar())
+ {
+ outNorm.setVec(z_vec);
+ out_pos_agent = in_pos_agent;
+ return;
+ }
+
+ p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec;
+ p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec;
+ LLViewerObject *obj;
+ LLVector3d out_pos_global;
+ LLWorld::getInstance()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj);
+ out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
}
//-----------------------------------------------------------------------------
@@ -6873,7 +6870,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age
//-----------------------------------------------------------------------------
F32 LLVOAvatar::getTimeDilation()
{
- return mRegionp ? mRegionp->getTimeDilation() : 1.f;
+ return mRegionp ? mRegionp->getTimeDilation() : 1.f;
}
@@ -6882,11 +6879,11 @@ F32 LLVOAvatar::getTimeDilation()
//-----------------------------------------------------------------------------
F32 LLVOAvatar::getPixelArea() const
{
- if (isUIAvatar())
- {
- return 100000.f;
- }
- return mPixelArea;
+ if (isUIAvatar())
+ {
+ return 100000.f;
+ }
+ return mPixelArea;
}
@@ -6894,17 +6891,17 @@ F32 LLVOAvatar::getPixelArea() const
//-----------------------------------------------------------------------------
// LLVOAvatar::getPosGlobalFromAgent()
//-----------------------------------------------------------------------------
-LLVector3d LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position)
+LLVector3d LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position)
{
- return gAgent.getPosGlobalFromAgent(position);
+ return gAgent.getPosGlobalFromAgent(position);
}
//-----------------------------------------------------------------------------
// getPosAgentFromGlobal()
//-----------------------------------------------------------------------------
-LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
+LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
{
- return gAgent.getPosAgentFromGlobal(position);
+ return gAgent.getPosAgentFromGlobal(position);
}
@@ -6914,7 +6911,7 @@ LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
// virtual
void LLVOAvatar::requestStopMotion( LLMotion* motion )
{
- // Only agent avatars should handle the stop motion notifications.
+ // Only agent avatars should handle the stop motion notifications.
}
//-----------------------------------------------------------------------------
@@ -6923,31 +6920,31 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion )
//virtual
BOOL LLVOAvatar::loadSkeletonNode ()
{
- if (!LLAvatarAppearance::loadSkeletonNode())
- {
- return FALSE;
- }
-
+ if (!LLAvatarAppearance::loadSkeletonNode())
+ {
+ return FALSE;
+ }
+
bool ignore_hud_joints = false;
initAttachmentPoints(ignore_hud_joints);
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
-// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml.
+// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml.
//-----------------------------------------------------------------------------
void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
{
LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
- iter != sAvatarXmlInfo->mAttachmentInfoList.end();
+ iter != sAvatarXmlInfo->mAttachmentInfoList.end();
++iter)
{
LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints))
{
- //don't process hud joint for other avatars.
+ //don't process hud joint for other avatars.
continue;
}
@@ -6984,7 +6981,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
attachment->setOriginalPosition(info->mPosition);
attachment->setDefaultPosition(info->mPosition);
}
-
+
if (info->mHasRotation)
{
LLQuaternion rotation;
@@ -7016,7 +7013,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
if (newly_created)
{
mAttachmentPoints[attachmentID] = attachment;
-
+
// now add attachment joint
parent_joint->addChild(attachment);
}
@@ -7028,45 +7025,45 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
//-----------------------------------------------------------------------------
void LLVOAvatar::updateVisualParams()
{
- ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE;
- if (getSex() != avatar_sex)
- {
- if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL)
- {
- // In some cases of gender change server changes sit motion with motion message,
- // but in case of some avatars (legacy?) there is no update from server side,
- // likely because server doesn't know about difference between motions
- // (female and male sit ids are same server side, so it is likely unaware that it
- // need to send update)
- // Make sure motion is up to date
- stopMotion(ANIM_AGENT_SIT);
- setSex(avatar_sex);
- startMotion(ANIM_AGENT_SIT);
- }
- else
- {
- setSex(avatar_sex);
- }
- }
-
- LLCharacter::updateVisualParams();
-
- if (mLastSkeletonSerialNum != mSkeletonSerialNum)
- {
- computeBodySize();
- mLastSkeletonSerialNum = mSkeletonSerialNum;
- mRoot->updateWorldMatrixChildren();
- }
-
- dirtyMesh();
- updateHeadOffset();
+ ESex avatar_sex = (getVisualParamWeight("male") > 0.5f) ? SEX_MALE : SEX_FEMALE;
+ if (getSex() != avatar_sex)
+ {
+ if (mIsSitting && findMotion(avatar_sex == SEX_MALE ? ANIM_AGENT_SIT_FEMALE : ANIM_AGENT_SIT) != NULL)
+ {
+ // In some cases of gender change server changes sit motion with motion message,
+ // but in case of some avatars (legacy?) there is no update from server side,
+ // likely because server doesn't know about difference between motions
+ // (female and male sit ids are same server side, so it is likely unaware that it
+ // need to send update)
+ // Make sure motion is up to date
+ stopMotion(ANIM_AGENT_SIT);
+ setSex(avatar_sex);
+ startMotion(ANIM_AGENT_SIT);
+ }
+ else
+ {
+ setSex(avatar_sex);
+ }
+ }
+
+ LLCharacter::updateVisualParams();
+
+ if (mLastSkeletonSerialNum != mSkeletonSerialNum)
+ {
+ computeBodySize();
+ mLastSkeletonSerialNum = mSkeletonSerialNum;
+ mRoot->updateWorldMatrixChildren();
+ }
+
+ dirtyMesh();
+ updateHeadOffset();
}
//-----------------------------------------------------------------------------
// isActive()
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::isActive() const
{
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -7074,39 +7071,39 @@ BOOL LLVOAvatar::isActive() const
//-----------------------------------------------------------------------------
void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
{
- if (mDrawable.isNull())
- {
- return;
- }
+ if (mDrawable.isNull())
+ {
+ return;
+ }
- const LLVector4a* ext = mDrawable->getSpatialExtents();
- LLVector4a center;
- center.setAdd(ext[1], ext[0]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ LLVector4a center;
+ center.setAdd(ext[1], ext[0]);
+ center.mul(0.5f);
+ LLVector4a size;
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
- mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
+ mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
mPixelArea = mImpostorPixelArea;
- F32 range = mDrawable->mDistanceWRTCamera;
+ F32 range = mDrawable->mDistanceWRTCamera;
- if (range < 0.001f) // range == zero
- {
- mAppAngle = 180.f;
- }
- else
- {
- F32 radius = size.getLength3().getF32();
- mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG;
- }
+ if (range < 0.001f) // range == zero
+ {
+ mAppAngle = 180.f;
+ }
+ else
+ {
+ F32 radius = size.getLength3().getF32();
+ mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG;
+ }
- // We always want to look good to ourselves
- if( isSelf() )
- {
- mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) );
- }
+ // We always want to look good to ourselves
+ if( isSelf() )
+ {
+ mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) );
+ }
}
//-----------------------------------------------------------------------------
@@ -7114,48 +7111,48 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::updateJointLODs()
{
- const F32 MAX_PIXEL_AREA = 100000000.f;
- F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE));
- F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f);
- F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
- F32 area_scale = 0.16f;
-
- if (isSelf())
- {
- if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
- {
- mAdjustedPixelArea = MAX_PIXEL_AREA;
- }
- else
- {
- mAdjustedPixelArea = mPixelArea*area_scale;
- }
- }
- else if (mIsDummy)
- {
- mAdjustedPixelArea = MAX_PIXEL_AREA;
- }
- else
- {
- // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
- mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
- }
-
- // now select meshes to render based on adjusted pixel area
- LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot);
- BOOL res = FALSE;
- if (root)
- {
- res = root->updateLOD(mAdjustedPixelArea, TRUE);
- }
- if (res)
- {
- sNumLODChangesThisFrame++;
- dirtyMesh(2);
- return TRUE;
- }
-
- return FALSE;
+ const F32 MAX_PIXEL_AREA = 100000000.f;
+ F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE));
+ F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f);
+ F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
+ F32 area_scale = 0.16f;
+
+ if (isSelf())
+ {
+ if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
+ {
+ mAdjustedPixelArea = MAX_PIXEL_AREA;
+ }
+ else
+ {
+ mAdjustedPixelArea = mPixelArea*area_scale;
+ }
+ }
+ else if (mIsDummy)
+ {
+ mAdjustedPixelArea = MAX_PIXEL_AREA;
+ }
+ else
+ {
+ // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
+ mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+ }
+
+ // now select meshes to render based on adjusted pixel area
+ LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot);
+ BOOL res = FALSE;
+ if (root)
+ {
+ res = root->updateLOD(mAdjustedPixelArea, TRUE);
+ }
+ if (res)
+ {
+ sNumLODChangesThisFrame++;
+ dirtyMesh(2);
+ return TRUE;
+ }
+
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -7163,32 +7160,32 @@ BOOL LLVOAvatar::updateJointLODs()
//-----------------------------------------------------------------------------
LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
{
- pipeline->allocDrawable(this);
- mDrawable->setLit(FALSE);
-
- LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR);
+ pipeline->allocDrawable(this);
+ mDrawable->setLit(FALSE);
- // Only a single face (one per avatar)
- //this face will be splitted into several if its vertex buffer is too long.
- mDrawable->setState(LLDrawable::ACTIVE);
- mDrawable->addFace(poolp, NULL);
- mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR);
+ LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR);
- mNumInitFaces = mDrawable->getNumFaces() ;
+ // Only a single face (one per avatar)
+ //this face will be splitted into several if its vertex buffer is too long.
+ mDrawable->setState(LLDrawable::ACTIVE);
+ mDrawable->addFace(poolp, NULL);
+ mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR);
+
+ mNumInitFaces = mDrawable->getNumFaces() ;
- dirtyMesh(2);
- return mDrawable;
+ dirtyMesh(2);
+ return mDrawable;
}
void LLVOAvatar::updateGL()
{
- if (mMeshTexturesDirty)
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
- updateMeshTextures();
- mMeshTexturesDirty = FALSE;
- }
+ if (mMeshTexturesDirty)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
+ updateMeshTextures();
+ mMeshTexturesDirty = FALSE;
+ }
}
//-----------------------------------------------------------------------------
@@ -7197,22 +7194,22 @@ void LLVOAvatar::updateGL()
BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))
- {
- return TRUE;
- }
+ if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))
+ {
+ return TRUE;
+ }
+
+ if (!mMeshValid)
+ {
+ return TRUE;
+ }
- if (!mMeshValid)
- {
- return TRUE;
- }
-
- if (!drawable)
- {
- LL_ERRS() << "LLVOAvatar::updateGeometry() called with NULL drawable" << LL_ENDL;
- }
+ if (!drawable)
+ {
+ LL_ERRS() << "LLVOAvatar::updateGeometry() called with NULL drawable" << LL_ENDL;
+ }
- return TRUE;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -7220,9 +7217,9 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
//-----------------------------------------------------------------------------
void LLVOAvatar::updateSexDependentLayerSets()
{
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
- invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet);
- invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet);
}
//-----------------------------------------------------------------------------
@@ -7230,19 +7227,19 @@ void LLVOAvatar::updateSexDependentLayerSets()
//-----------------------------------------------------------------------------
void LLVOAvatar::dirtyMesh()
{
- dirtyMesh(1);
+ dirtyMesh(1);
}
void LLVOAvatar::dirtyMesh(S32 priority)
{
- mDirtyMesh = llmax(mDirtyMesh, priority);
+ mDirtyMesh = llmax(mDirtyMesh, priority);
}
//-----------------------------------------------------------------------------
// getViewerJoint()
//-----------------------------------------------------------------------------
-LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
+LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
{
- return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]);
+ return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]);
}
//-----------------------------------------------------------------------------
@@ -7258,111 +7255,111 @@ void LLVOAvatar::hideHair()
//-----------------------------------------------------------------------------
void LLVOAvatar::hideSkirt()
{
- mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE);
+ mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE);
}
BOOL LLVOAvatar::setParent(LLViewerObject* parent)
{
- BOOL ret ;
- if (parent == NULL)
- {
- getOffObject();
- ret = LLViewerObject::setParent(parent);
- if (isSelf())
- {
- gAgentCamera.resetCamera();
- }
- }
- else
- {
- ret = LLViewerObject::setParent(parent);
- if(ret)
- {
- sitOnObject(parent);
- }
- }
- return ret ;
+ BOOL ret ;
+ if (parent == NULL)
+ {
+ getOffObject();
+ ret = LLViewerObject::setParent(parent);
+ if (isSelf())
+ {
+ gAgentCamera.resetCamera();
+ }
+ }
+ else
+ {
+ ret = LLViewerObject::setParent(parent);
+ if(ret)
+ {
+ sitOnObject(parent);
+ }
+ }
+ return ret ;
}
void LLVOAvatar::addChild(LLViewerObject *childp)
{
- childp->extractAttachmentItemID(); // find the inventory item this object is associated with.
- if (isSelf())
- {
- const LLUUID& item_id = childp->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_DEBUGS("Avatar") << "ATT attachment child added " << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
-
- }
-
- LLViewerObject::addChild(childp);
- if (childp->mDrawable)
- {
- if (!attachObject(childp))
- {
- LL_WARNS() << "ATT addChild() failed for "
- << childp->getID()
- << " item " << childp->getAttachmentItemID()
- << LL_ENDL;
- // MAINT-3312 backout
- // mPendingAttachment.push_back(childp);
- }
- }
- else
- {
- mPendingAttachment.push_back(childp);
- }
+ childp->extractAttachmentItemID(); // find the inventory item this object is associated with.
+ if (isSelf())
+ {
+ const LLUUID& item_id = childp->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_DEBUGS("Avatar") << "ATT attachment child added " << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+
+ }
+
+ LLViewerObject::addChild(childp);
+ if (childp->mDrawable)
+ {
+ if (!attachObject(childp))
+ {
+ LL_WARNS() << "ATT addChild() failed for "
+ << childp->getID()
+ << " item " << childp->getAttachmentItemID()
+ << LL_ENDL;
+ // MAINT-3312 backout
+ // mPendingAttachment.push_back(childp);
+ }
+ }
+ else
+ {
+ mPendingAttachment.push_back(childp);
+ }
}
void LLVOAvatar::removeChild(LLViewerObject *childp)
{
- LLViewerObject::removeChild(childp);
- if (!detachObject(childp))
- {
- LL_WARNS() << "Calling detach on non-attached object " << LL_ENDL;
- }
+ LLViewerObject::removeChild(childp);
+ if (!detachObject(childp))
+ {
+ LL_WARNS() << "Calling detach on non-attached object " << LL_ENDL;
+ }
}
LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object)
{
- S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState());
-
- // This should never happen unless the server didn't process the attachment point
- // correctly, but putting this check in here to be safe.
- if (attachmentID & ATTACHMENT_ADD)
- {
- LL_WARNS() << "Got an attachment with ATTACHMENT_ADD mask, removing ( attach pt:" << attachmentID << " )" << LL_ENDL;
- attachmentID &= ~ATTACHMENT_ADD;
- }
-
- LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
-
- if (!attachment)
- {
- LL_WARNS() << "Object attachment point invalid: " << attachmentID
- << " trying to use 1 (chest)"
- << LL_ENDL;
-
- attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
- if (attachment)
- {
- LL_WARNS() << "Object attachment point invalid: " << attachmentID
- << " on object " << viewer_object->getID()
- << " attachment item " << viewer_object->getAttachmentItemID()
- << " falling back to 1 (chest)"
- << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Object attachment point invalid: " << attachmentID
- << " on object " << viewer_object->getID()
- << " attachment item " << viewer_object->getAttachmentItemID()
- << "Unable to use fallback attachment point 1 (chest)"
- << LL_ENDL;
- }
- }
-
- return attachment;
+ S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState());
+
+ // This should never happen unless the server didn't process the attachment point
+ // correctly, but putting this check in here to be safe.
+ if (attachmentID & ATTACHMENT_ADD)
+ {
+ LL_WARNS() << "Got an attachment with ATTACHMENT_ADD mask, removing ( attach pt:" << attachmentID << " )" << LL_ENDL;
+ attachmentID &= ~ATTACHMENT_ADD;
+ }
+
+ LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
+
+ if (!attachment)
+ {
+ LL_WARNS() << "Object attachment point invalid: " << attachmentID
+ << " trying to use 1 (chest)"
+ << LL_ENDL;
+
+ attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
+ if (attachment)
+ {
+ LL_WARNS() << "Object attachment point invalid: " << attachmentID
+ << " on object " << viewer_object->getID()
+ << " attachment item " << viewer_object->getAttachmentItemID()
+ << " falling back to 1 (chest)"
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Object attachment point invalid: " << attachmentID
+ << " on object " << viewer_object->getID()
+ << " attachment item " << viewer_object->getAttachmentItemID()
+ << "Unable to use fallback attachment point 1 (chest)"
+ << LL_ENDL;
+ }
+ }
+
+ return attachment;
}
//-----------------------------------------------------------------------------
@@ -7370,54 +7367,54 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
//-----------------------------------------------------------------------------
const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object)
{
- if (isSelf())
- {
- const LLUUID& item_id = viewer_object->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_DEBUGS("Avatar") << "ATT attaching object "
- << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
- }
- LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object);
-
- if (!attachment || !attachment->addObject(viewer_object))
- {
- const LLUUID& item_id = viewer_object->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_WARNS("Avatar") << "ATT attach failed "
- << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
- return 0;
- }
+ if (isSelf())
+ {
+ const LLUUID& item_id = viewer_object->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_DEBUGS("Avatar") << "ATT attaching object "
+ << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ }
+ LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object);
+
+ if (!attachment || !attachment->addObject(viewer_object))
+ {
+ const LLUUID& item_id = viewer_object->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_WARNS("Avatar") << "ATT attach failed "
+ << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ return 0;
+ }
if (!viewer_object->isAnimatedObject())
{
updateAttachmentOverrides();
}
- updateVisualComplexity();
+ updateVisualComplexity();
- if (viewer_object->isSelected())
- {
- LLSelectMgr::getInstance()->updateSelectionCenter();
- LLSelectMgr::getInstance()->updatePointAt();
- }
+ if (viewer_object->isSelected())
+ {
+ LLSelectMgr::getInstance()->updateSelectionCenter();
+ LLSelectMgr::getInstance()->updatePointAt();
+ }
- viewer_object->refreshBakeTexture();
+ viewer_object->refreshBakeTexture();
- LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- if (objectp)
- {
- objectp->refreshBakeTexture();
- }
- }
+ LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ if (objectp)
+ {
+ objectp->refreshBakeTexture();
+ }
+ }
- updateMeshVisibility();
+ updateMeshVisibility();
- return attachment;
+ return attachment;
}
//-----------------------------------------------------------------------------
@@ -7425,15 +7422,15 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
//-----------------------------------------------------------------------------
U32 LLVOAvatar::getNumAttachments() const
{
- U32 num_attachments = 0;
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment *attachment_pt = (*iter).second;
- num_attachments += attachment_pt->getNumObjects();
- }
- return num_attachments;
+ U32 num_attachments = 0;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ num_attachments += attachment_pt->getNumObjects();
+ }
+ return num_attachments;
}
//-----------------------------------------------------------------------------
@@ -7441,7 +7438,7 @@ U32 LLVOAvatar::getNumAttachments() const
//-----------------------------------------------------------------------------
S32 LLVOAvatar::getMaxAttachments() const
{
- return LLAgentBenefitsMgr::current().getAttachmentLimit();
+ return LLAgentBenefitsMgr::current().getAttachmentLimit();
}
//-----------------------------------------------------------------------------
@@ -7450,7 +7447,7 @@ S32 LLVOAvatar::getMaxAttachments() const
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const
{
- return (getNumAttachments() + n) <= getMaxAttachments();
+ return (getNumAttachments() + n) <= getMaxAttachments();
}
//-----------------------------------------------------------------------------
@@ -7458,15 +7455,15 @@ BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const
//-----------------------------------------------------------------------------
U32 LLVOAvatar::getNumAnimatedObjectAttachments() const
{
- U32 num_attachments = 0;
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment *attachment_pt = (*iter).second;
- num_attachments += attachment_pt->getNumAnimatedObjects();
- }
- return num_attachments;
+ U32 num_attachments = 0;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ num_attachments += attachment_pt->getNumAnimatedObjects();
+ }
+ return num_attachments;
}
//-----------------------------------------------------------------------------
@@ -7475,7 +7472,7 @@ U32 LLVOAvatar::getNumAnimatedObjectAttachments() const
//-----------------------------------------------------------------------------
S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const
{
- return LLAgentBenefitsMgr::current().getAnimatedObjectLimit();
+ return LLAgentBenefitsMgr::current().getAnimatedObjectLimit();
}
//-----------------------------------------------------------------------------
@@ -7484,7 +7481,7 @@ S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::canAttachMoreAnimatedObjects(U32 n) const
{
- return (getNumAnimatedObjectAttachments() + n) <= getMaxAnimatedObjectAttachments();
+ return (getNumAnimatedObjectAttachments() + n) <= getMaxAnimatedObjectAttachments();
}
//-----------------------------------------------------------------------------
@@ -7492,101 +7489,101 @@ BOOL LLVOAvatar::canAttachMoreAnimatedObjects(U32 n) const
//-----------------------------------------------------------------------------
void LLVOAvatar::lazyAttach()
{
- std::vector<LLPointer<LLViewerObject> > still_pending;
-
- for (U32 i = 0; i < mPendingAttachment.size(); i++)
- {
- LLPointer<LLViewerObject> cur_attachment = mPendingAttachment[i];
- // Object might have died while we were waiting for drawable
- if (!cur_attachment->isDead())
- {
- if (cur_attachment->mDrawable)
- {
- if (isSelf())
- {
- const LLUUID& item_id = cur_attachment->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_DEBUGS("Avatar") << "ATT attaching object "
- << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
- }
- if (!attachObject(cur_attachment))
- { // Drop it
- LL_WARNS() << "attachObject() failed for "
- << cur_attachment->getID()
- << " item " << cur_attachment->getAttachmentItemID()
- << LL_ENDL;
- // MAINT-3312 backout
- //still_pending.push_back(cur_attachment);
- }
- }
- else
- {
- still_pending.push_back(cur_attachment);
- }
- }
- }
-
- mPendingAttachment = still_pending;
+ std::vector<LLPointer<LLViewerObject> > still_pending;
+
+ for (U32 i = 0; i < mPendingAttachment.size(); i++)
+ {
+ LLPointer<LLViewerObject> cur_attachment = mPendingAttachment[i];
+ // Object might have died while we were waiting for drawable
+ if (!cur_attachment->isDead())
+ {
+ if (cur_attachment->mDrawable)
+ {
+ if (isSelf())
+ {
+ const LLUUID& item_id = cur_attachment->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_DEBUGS("Avatar") << "ATT attaching object "
+ << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ }
+ if (!attachObject(cur_attachment))
+ { // Drop it
+ LL_WARNS() << "attachObject() failed for "
+ << cur_attachment->getID()
+ << " item " << cur_attachment->getAttachmentItemID()
+ << LL_ENDL;
+ // MAINT-3312 backout
+ //still_pending.push_back(cur_attachment);
+ }
+ }
+ else
+ {
+ still_pending.push_back(cur_attachment);
+ }
+ }
+ }
+
+ mPendingAttachment = still_pending;
}
void LLVOAvatar::resetHUDAttachments()
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getIsHUDAttachment())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object && attached_object->mDrawable.notNull())
- {
- gPipeline.markMoved(attached_object->mDrawable);
- }
- }
- }
- }
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getIsHUDAttachment())
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ const LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->mDrawable.notNull())
+ {
+ gPipeline.markMoved(attached_object->mDrawable);
+ }
+ }
+ }
+ }
}
void LLVOAvatar::rebuildRiggedAttachments( void )
{
- for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
- {
- LLViewerJointAttachment* pAttachment = iter->second;
- LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIterEnd = pAttachment->mAttachedObjects.end();
-
- for ( LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIter = pAttachment->mAttachedObjects.begin();
- attachmentIter != attachmentIterEnd; ++attachmentIter)
- {
- const LLViewerObject* pAttachedObject = *attachmentIter;
- if ( pAttachment && pAttachedObject->mDrawable.notNull() )
- {
- gPipeline.markRebuild(pAttachedObject->mDrawable);
- }
- }
- }
+ for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
+ {
+ LLViewerJointAttachment* pAttachment = iter->second;
+ LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIterEnd = pAttachment->mAttachedObjects.end();
+
+ for ( LLViewerJointAttachment::attachedobjs_vec_t::iterator attachmentIter = pAttachment->mAttachedObjects.begin();
+ attachmentIter != attachmentIterEnd; ++attachmentIter)
+ {
+ const LLViewerObject* pAttachedObject = *attachmentIter;
+ if ( pAttachment && pAttachedObject->mDrawable.notNull() )
+ {
+ gPipeline.markRebuild(pAttachedObject->mDrawable);
+ }
+ }
+ }
}
//-----------------------------------------------------------------------------
// cleanupAttachedMesh()
//-----------------------------------------------------------------------------
void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
{
- LLUUID mesh_id;
- if (getRiggedMeshID(pVO, mesh_id))
- {
+ LLUUID mesh_id;
+ if (getRiggedMeshID(pVO, mesh_id))
+ {
// FIXME this seems like an odd place for this code.
- if ( gAgentCamera.cameraCustomizeAvatar() )
- {
- gAgent.unpauseAnimation();
- //Still want to refocus on head bone
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
- }
+ if ( gAgentCamera.cameraCustomizeAvatar() )
+ {
+ gAgent.unpauseAnimation();
+ //Still want to refocus on head bone
+ gAgentCamera.changeCameraToCustomizeAvatar();
+ }
+ }
}
bool LLVOAvatar::hasPendingAttachedMeshes()
@@ -7673,51 +7670,51 @@ bool LLVOAvatar::hasPendingAttachedMeshes()
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- if (attachment->isObjectAttached(viewer_object))
- {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ if (attachment->isObjectAttached(viewer_object))
+ {
updateVisualComplexity();
bool is_animated_object = viewer_object->isAnimatedObject();
- cleanupAttachedMesh(viewer_object);
+ cleanupAttachedMesh(viewer_object);
- attachment->removeObject(viewer_object);
+ attachment->removeObject(viewer_object);
if (!is_animated_object)
{
updateAttachmentOverrides();
}
- viewer_object->refreshBakeTexture();
-
- LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
- iter1 != child_list.end(); ++iter1)
- {
- LLViewerObject* objectp = *iter1;
- if (objectp)
+ viewer_object->refreshBakeTexture();
+
+ LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+ iter1 != child_list.end(); ++iter1)
+ {
+ LLViewerObject* objectp = *iter1;
+ if (objectp)
{
- objectp->refreshBakeTexture();
- }
+ objectp->refreshBakeTexture();
+ }
}
- updateMeshVisibility();
+ updateMeshVisibility();
- LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL;
- return TRUE;
- }
- }
+ LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL;
+ return TRUE;
+ }
+ }
- std::vector<LLPointer<LLViewerObject> >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object);
- if (iter != mPendingAttachment.end())
- {
- mPendingAttachment.erase(iter);
- return TRUE;
- }
-
- return FALSE;
+ std::vector<LLPointer<LLViewerObject> >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object);
+ if (iter != mPendingAttachment.end())
+ {
+ mPendingAttachment.erase(iter);
+ return TRUE;
+ }
+
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -7725,12 +7722,12 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
//-----------------------------------------------------------------------------
void LLVOAvatar::sitDown(BOOL bSitting)
{
- mIsSitting = bSitting;
- if (isSelf())
- {
- // Update Movement Controls according to own Sitting mode
- LLFloaterMove::setSittingMode(bSitting);
- }
+ mIsSitting = bSitting;
+ if (isSelf())
+ {
+ // Update Movement Controls according to own Sitting mode
+ LLFloaterMove::setSittingMode(bSitting);
+ }
}
//-----------------------------------------------------------------------------
@@ -7738,22 +7735,22 @@ void LLVOAvatar::sitDown(BOOL bSitting)
//-----------------------------------------------------------------------------
void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
{
- if (isSelf())
- {
- // Might be first sit
- //LLFirstUse::useSit();
-
- gAgent.setFlying(FALSE);
- gAgentCamera.setThirdPersonHeadOffset(LLVector3::zero);
- //interpolate to new camera position
- gAgentCamera.startCameraAnimation();
- // make sure we are not trying to autopilot
- gAgent.stopAutoPilot();
- gAgentCamera.setupSitCamera();
- if (gAgentCamera.getForceMouselook())
- {
- gAgentCamera.changeCameraToMouselook();
- }
+ if (isSelf())
+ {
+ // Might be first sit
+ //LLFirstUse::useSit();
+
+ gAgent.setFlying(FALSE);
+ gAgentCamera.setThirdPersonHeadOffset(LLVector3::zero);
+ //interpolate to new camera position
+ gAgentCamera.startCameraAnimation();
+ // make sure we are not trying to autopilot
+ gAgent.stopAutoPilot();
+ gAgentCamera.setupSitCamera();
+ if (gAgentCamera.getForceMouselook())
+ {
+ gAgentCamera.changeCameraToMouselook();
+ }
if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit())
{
@@ -7767,33 +7764,33 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
}
}
}
- }
-
- if (mDrawable.isNull())
- {
- return;
- }
- LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation();
- LLVector3 obj_pos = sit_object->getRenderPosition();
+ }
- LLVector3 rel_pos = getRenderPosition() - obj_pos;
- rel_pos.rotVec(inv_obj_rot);
+ if (mDrawable.isNull())
+ {
+ return;
+ }
+ LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation();
+ LLVector3 obj_pos = sit_object->getRenderPosition();
- mDrawable->mXform.setPosition(rel_pos);
- mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);
+ LLVector3 rel_pos = getRenderPosition() - obj_pos;
+ rel_pos.rotVec(inv_obj_rot);
- gPipeline.markMoved(mDrawable, TRUE);
- // Notice that removing sitDown() from here causes avatars sitting on
- // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
- sitDown(TRUE);
- mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
- // SL-315
- mRoot->setPosition(getPosition());
- mRoot->updateWorldMatrixChildren();
+ mDrawable->mXform.setPosition(rel_pos);
+ mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);
- stopMotion(ANIM_AGENT_BODY_NOISE);
+ gPipeline.markMoved(mDrawable, TRUE);
+ // Notice that removing sitDown() from here causes avatars sitting on
+ // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
+ sitDown(TRUE);
+ mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
+ // SL-315
+ mRoot->setPosition(getPosition());
+ mRoot->updateWorldMatrixChildren();
- gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion());
+ stopMotion(ANIM_AGENT_BODY_NOISE);
+
+ gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion());
}
//-----------------------------------------------------------------------------
@@ -7801,168 +7798,168 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
//-----------------------------------------------------------------------------
void LLVOAvatar::getOffObject()
{
- if (mDrawable.isNull())
- {
- return;
- }
-
- LLViewerObject* sit_object = (LLViewerObject*)getParent();
-
- if (sit_object)
- {
- stopMotionFromSource(sit_object->getID());
- LLFollowCamMgr::getInstance()->setCameraActive(sit_object->getID(), FALSE);
-
- LLViewerObject::const_child_list_t& child_list = sit_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* child_objectp = *iter;
-
- stopMotionFromSource(child_objectp->getID());
- LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE);
- }
- }
-
- // assumes that transform will not be updated with drawable still having a parent
- // or that drawable had no parent from the start
- LLVector3 cur_position_world = mDrawable->getWorldPosition();
- LLQuaternion cur_rotation_world = mDrawable->getWorldRotation();
-
- if (mLastRootPos.length() >= MAX_STANDOFF_FROM_ORIGIN
- && (cur_position_world.length() < MAX_STANDOFF_FROM_ORIGIN
- || dist_vec(cur_position_world, mLastRootPos) > MAX_STANDOFF_DISTANCE_CHANGE))
- {
- // Most likely drawable got updated too early or some updates were missed - we got relative position to non-existing parent
- // restore coordinates from cache
- cur_position_world = mLastRootPos;
- }
-
- // set *local* position based on last *world* position, since we're unparenting the avatar
- mDrawable->mXform.setPosition(cur_position_world);
- mDrawable->mXform.setRotation(cur_rotation_world);
-
- gPipeline.markMoved(mDrawable, TRUE);
-
- sitDown(FALSE);
-
- mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
- // SL-315
- mRoot->setPosition(cur_position_world);
- mRoot->setRotation(cur_rotation_world);
- mRoot->getXform()->update();
+ if (mDrawable.isNull())
+ {
+ return;
+ }
+
+ LLViewerObject* sit_object = (LLViewerObject*)getParent();
+
+ if (sit_object)
+ {
+ stopMotionFromSource(sit_object->getID());
+ LLFollowCamMgr::getInstance()->setCameraActive(sit_object->getID(), FALSE);
+
+ LLViewerObject::const_child_list_t& child_list = sit_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* child_objectp = *iter;
+
+ stopMotionFromSource(child_objectp->getID());
+ LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE);
+ }
+ }
+
+ // assumes that transform will not be updated with drawable still having a parent
+ // or that drawable had no parent from the start
+ LLVector3 cur_position_world = mDrawable->getWorldPosition();
+ LLQuaternion cur_rotation_world = mDrawable->getWorldRotation();
+
+ if (mLastRootPos.length() >= MAX_STANDOFF_FROM_ORIGIN
+ && (cur_position_world.length() < MAX_STANDOFF_FROM_ORIGIN
+ || dist_vec(cur_position_world, mLastRootPos) > MAX_STANDOFF_DISTANCE_CHANGE))
+ {
+ // Most likely drawable got updated too early or some updates were missed - we got relative position to non-existing parent
+ // restore coordinates from cache
+ cur_position_world = mLastRootPos;
+ }
+
+ // set *local* position based on last *world* position, since we're unparenting the avatar
+ mDrawable->mXform.setPosition(cur_position_world);
+ mDrawable->mXform.setRotation(cur_rotation_world);
+
+ gPipeline.markMoved(mDrawable, TRUE);
+
+ sitDown(FALSE);
+
+ mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
+ // SL-315
+ mRoot->setPosition(cur_position_world);
+ mRoot->setRotation(cur_rotation_world);
+ mRoot->getXform()->update();
if (mEnableDefaultMotions)
{
- startMotion(ANIM_AGENT_BODY_NOISE);
+ startMotion(ANIM_AGENT_BODY_NOISE);
}
- if (isSelf())
- {
- LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
- LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
- av_rot = av_rot * obj_rot;
- LLVector3 at_axis = LLVector3::x_axis;
- at_axis = at_axis * av_rot;
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis);
- gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
- gAgentCamera.setSitCamera(LLUUID::null);
- }
+ if (isSelf())
+ {
+ LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
+ LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
+ av_rot = av_rot * obj_rot;
+ LLVector3 at_axis = LLVector3::x_axis;
+ at_axis = at_axis * av_rot;
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis);
+ gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
+ gAgentCamera.setSitCamera(LLUUID::null);
+ }
}
//-----------------------------------------------------------------------------
// findAvatarFromAttachment()
//-----------------------------------------------------------------------------
-// static
+// static
LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj )
{
- if( obj->isAttachment() )
- {
- do
- {
- obj = (LLViewerObject*) obj->getParent();
- }
- while( obj && !obj->isAvatar() );
+ if( obj->isAttachment() )
+ {
+ do
+ {
+ obj = (LLViewerObject*) obj->getParent();
+ }
+ while( obj && !obj->isAvatar() );
- if( obj && !obj->isDead() )
- {
- return (LLVOAvatar*)obj;
- }
- }
- return NULL;
+ if( obj && !obj->isDead() )
+ {
+ return (LLVOAvatar*)obj;
+ }
+ }
+ return NULL;
}
S32 LLVOAvatar::getAttachmentCount()
{
- S32 count = mAttachmentPoints.size();
- return count;
+ S32 count = mAttachmentPoints.size();
+ return count;
}
BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
{
- if (mIsDummy) return TRUE;
-
- if (isSelf())
- {
- return LLAvatarAppearance::isWearingWearableType(type);
- }
-
- switch(type)
- {
- case LLWearableType::WT_SHAPE:
- case LLWearableType::WT_SKIN:
- case LLWearableType::WT_HAIR:
- case LLWearableType::WT_EYES:
- return TRUE; // everyone has all bodyparts
- default:
- break; // Do nothing
- }
-
- for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++tex_iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
- if (texture_dict->mWearableType == type)
- {
- // Thus, you must check to see if the corresponding baked texture is defined.
- // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
- // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
- // gets baked into a texture that always exists (upper or lower).
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex);
- }
- return FALSE;
- }
- }
- return FALSE;
-}
-
-LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const
-{
- for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin();
- attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end();
- ++attachment_points_iter)
- {
- LLViewerJointAttachment* attachment = attachment_points_iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = attachment_iter->get();
- if (attached_object &&
- attached_object->getID() == target_id)
- {
- return attached_object;
- }
- }
- }
-
- return NULL;
+ if (mIsDummy) return TRUE;
+
+ if (isSelf())
+ {
+ return LLAvatarAppearance::isWearingWearableType(type);
+ }
+
+ switch(type)
+ {
+ case LLWearableType::WT_SHAPE:
+ case LLWearableType::WT_SKIN:
+ case LLWearableType::WT_HAIR:
+ case LLWearableType::WT_EYES:
+ return TRUE; // everyone has all bodyparts
+ default:
+ break; // Do nothing
+ }
+
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end();
+ ++tex_iter)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
+ if (texture_dict->mWearableType == type)
+ {
+ // Thus, you must check to see if the corresponding baked texture is defined.
+ // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
+ // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
+ // gets baked into a texture that always exists (upper or lower).
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex);
+ }
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const
+{
+ for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin();
+ attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end();
+ ++attachment_points_iter)
+ {
+ LLViewerJointAttachment* attachment = attachment_points_iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = attachment_iter->get();
+ if (attached_object &&
+ attached_object->getID() == target_id)
+ {
+ return attached_object;
+ }
+ }
+ }
+
+ return NULL;
}
// virtual
@@ -7977,40 +7974,40 @@ void LLVOAvatar::invalidateAll()
// virtual
void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)
{
- if (global_color == mTexSkinColor)
- {
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
- invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet);
- invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet);
- }
- else if (global_color == mTexHairColor)
- {
- invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
- invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet);
-
- // ! BACKWARDS COMPATIBILITY !
- // Fix for dealing with avatars from viewers that don't bake hair.
- if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
- {
- LLColor4 color = mTexHairColor->getColor();
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setColor( color );
- }
- }
- }
- }
- else if (global_color == mTexEyeColor)
- {
- // LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL;
- invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet);
- }
- updateMeshTextures();
+ if (global_color == mTexSkinColor)
+ {
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet);
+ }
+ else if (global_color == mTexHairColor)
+ {
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet);
+ invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet);
+
+ // ! BACKWARDS COMPATIBILITY !
+ // Fix for dealing with avatars from viewers that don't bake hair.
+ if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
+ {
+ LLColor4 color = mTexHairColor->getColor();
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setColor( color );
+ }
+ }
+ }
+ }
+ else if (global_color == mTexEyeColor)
+ {
+ // LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL;
+ invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet);
+ }
+ updateMeshTextures();
}
// virtual
@@ -8019,12 +8016,12 @@ bool LLVOAvatar::shouldRenderRigged() const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (getOverallAppearance() == AOA_NORMAL)
- {
- return true;
- }
- // TBD - render for AOA_JELLYDOLL?
- return false;
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ return true;
+ }
+ // TBD - render for AOA_JELLYDOLL?
+ return false;
}
// FIXME: We have an mVisible member, set in updateVisibility(), but this
@@ -8035,207 +8032,207 @@ bool LLVOAvatar::shouldRenderRigged() const
// Maybe better naming could make this clearer?
BOOL LLVOAvatar::isVisible() const
{
- return mDrawable.notNull()
- && (!mOrphaned || isSelf())
- && (mDrawable->isVisible() || mIsDummy);
+ return mDrawable.notNull()
+ && (!mOrphaned || isSelf())
+ && (mDrawable->isVisible() || mIsDummy);
}
// Determine if we have enough avatar data to render
bool LLVOAvatar::getIsCloud() const
{
- if (mIsDummy)
- {
- return false;
- }
+ if (mIsDummy)
+ {
+ return false;
+ }
- return ( ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())// Do we have a shape?
- || ( !isTextureDefined(TEX_LOWER_BAKED)
- || !isTextureDefined(TEX_UPPER_BAKED)
- || !isTextureDefined(TEX_HEAD_BAKED)
- )
- );
+ return ( ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())// Do we have a shape?
+ || ( !isTextureDefined(TEX_LOWER_BAKED)
+ || !isTextureDefined(TEX_UPPER_BAKED)
+ || !isTextureDefined(TEX_HEAD_BAKED)
+ )
+ );
}
void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status)
{
- // State machine for rezzed status. Statuses are -1 on startup, 0
- // = cloud, 1 = gray, 2 = downloading, 3 = full.
- // Purpose is to collect time data for each it takes avatar to reach
- // various loading landmarks: gray, textured (partial), textured fully.
-
- if (rez_status != mLastRezzedStatus)
- {
- LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
-
- if (mLastRezzedStatus == -1 && rez_status != -1)
- {
- // First time initialization, start all timers.
- for (S32 i = 1; i < 4; i++)
- {
- startPhase("load_" + LLVOAvatar::rezStatusToString(i));
- startPhase("first_load_" + LLVOAvatar::rezStatusToString(i));
- }
- }
- if (rez_status < mLastRezzedStatus)
- {
- // load level has decreased. start phase timers for higher load levels.
- for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
- {
- startPhase("load_" + LLVOAvatar::rezStatusToString(i));
- }
- }
- else if (rez_status > mLastRezzedStatus)
- {
- // load level has increased. stop phase timers for lower and equal load levels.
- for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++)
- {
- stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
- stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
- }
- if (rez_status == 3)
- {
- // "fully loaded", mark any pending appearance change complete.
- selfStopPhase("update_appearance_from_cof");
- selfStopPhase("wear_inventory_category", false);
- selfStopPhase("process_initial_wearables_update", false);
+ // State machine for rezzed status. Statuses are -1 on startup, 0
+ // = cloud, 1 = gray, 2 = downloading, 3 = full.
+ // Purpose is to collect time data for each it takes avatar to reach
+ // various loading landmarks: gray, textured (partial), textured fully.
+
+ if (rez_status != mLastRezzedStatus)
+ {
+ LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
+
+ if (mLastRezzedStatus == -1 && rez_status != -1)
+ {
+ // First time initialization, start all timers.
+ for (S32 i = 1; i < 4; i++)
+ {
+ startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ startPhase("first_load_" + LLVOAvatar::rezStatusToString(i));
+ }
+ }
+ if (rez_status < mLastRezzedStatus)
+ {
+ // load level has decreased. start phase timers for higher load levels.
+ for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
+ {
+ startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ }
+ }
+ else if (rez_status > mLastRezzedStatus)
+ {
+ // load level has increased. stop phase timers for lower and equal load levels.
+ for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++)
+ {
+ stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
+ }
+ if (rez_status == 3)
+ {
+ // "fully loaded", mark any pending appearance change complete.
+ selfStopPhase("update_appearance_from_cof");
+ selfStopPhase("wear_inventory_category", false);
+ selfStopPhase("process_initial_wearables_update", false);
updateVisualComplexity();
- }
- }
- mLastRezzedStatus = rez_status;
- }
+ }
+ }
+ mLastRezzedStatus = rez_status;
+ }
}
void LLVOAvatar::clearPhases()
{
- getPhases().clearPhases();
+ getPhases().clearPhases();
}
void LLVOAvatar::startPhase(const std::string& phase_name)
{
- F32 elapsed = 0.0;
- bool completed = false;
- bool found = getPhases().getPhaseValues(phase_name, elapsed, completed);
- //LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name
- // << " found " << found << " elapsed " << elapsed << " completed " << completed << LL_ENDL;
- if (found)
- {
- if (!completed)
- {
- LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << LL_ENDL;
- return;
- }
- }
- LL_DEBUGS("Avatar") << "started phase " << phase_name << LL_ENDL;
- getPhases().startPhase(phase_name);
+ F32 elapsed = 0.0;
+ bool completed = false;
+ bool found = getPhases().getPhaseValues(phase_name, elapsed, completed);
+ //LL_DEBUGS("Avatar") << avString() << " phase state " << phase_name
+ // << " found " << found << " elapsed " << elapsed << " completed " << completed << LL_ENDL;
+ if (found)
+ {
+ if (!completed)
+ {
+ LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << LL_ENDL;
+ return;
+ }
+ }
+ LL_DEBUGS("Avatar") << "started phase " << phase_name << LL_ENDL;
+ getPhases().startPhase(phase_name);
}
void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
{
- F32 elapsed = 0.0;
- bool completed = false;
- if (getPhases().getPhaseValues(phase_name, elapsed, completed))
- {
- if (!completed)
- {
- getPhases().stopPhase(phase_name);
- completed = true;
- logMetricsTimerRecord(phase_name, elapsed, completed);
- LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << LL_ENDL;
- }
- else
- {
- if (err_check)
- {
- LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << LL_ENDL;
- }
- }
- }
- else
- {
- if (err_check)
- {
- LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << LL_ENDL;
- }
- }
+ F32 elapsed = 0.0;
+ bool completed = false;
+ if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+ {
+ if (!completed)
+ {
+ getPhases().stopPhase(phase_name);
+ completed = true;
+ logMetricsTimerRecord(phase_name, elapsed, completed);
+ LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << LL_ENDL;
+ }
+ else
+ {
+ if (err_check)
+ {
+ LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ if (err_check)
+ {
+ LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << LL_ENDL;
+ }
+ }
}
void LLVOAvatar::logPendingPhases()
{
- if (!isAgentAvatarValid())
- {
- return;
- }
-
- for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
- it != getPhases().end();
- ++it)
- {
- const std::string& phase_name = it->first;
- F32 elapsed;
- bool completed;
- if (getPhases().getPhaseValues(phase_name, elapsed, completed))
- {
- if (!completed)
- {
- logMetricsTimerRecord(phase_name, elapsed, completed);
- }
- }
- }
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
+ for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
+ it != getPhases().end();
+ ++it)
+ {
+ const std::string& phase_name = it->first;
+ F32 elapsed;
+ bool completed;
+ if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+ {
+ if (!completed)
+ {
+ logMetricsTimerRecord(phase_name, elapsed, completed);
+ }
+ }
+ }
}
//static
void LLVOAvatar::logPendingPhasesAllAvatars()
{
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- if( inst->isDead() )
- {
- continue;
- }
- inst->logPendingPhases();
- }
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if( inst->isDead() )
+ {
+ continue;
+ }
+ inst->logPendingPhases();
+ }
}
void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
{
- if (!isAgentAvatarValid())
- {
- return;
- }
-
- LLSD record;
- record["timer_name"] = phase_name;
- record["avatar_id"] = getID();
- record["elapsed"] = elapsed;
- record["completed"] = completed;
- U32 grid_x(0), grid_y(0);
- if (getRegion() && LLWorld::instance().isRegionListed(getRegion()))
- {
- record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
- grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
- }
- record["grid_x"] = LLSD::Integer(grid_x);
- record["grid_y"] = LLSD::Integer(grid_y);
- record["is_using_server_bakes"] = true;
- record["is_self"] = isSelf();
-
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->addMetricsTimerRecord(record);
- }
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
+ LLSD record;
+ record["timer_name"] = phase_name;
+ record["avatar_id"] = getID();
+ record["elapsed"] = elapsed;
+ record["completed"] = completed;
+ U32 grid_x(0), grid_y(0);
+ if (getRegion() && LLWorld::instance().isRegionListed(getRegion()))
+ {
+ record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
+ grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
+ }
+ record["grid_x"] = LLSD::Integer(grid_x);
+ record["grid_y"] = LLSD::Integer(grid_y);
+ record["is_using_server_bakes"] = true;
+ record["is_self"] = isSelf();
+
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->addMetricsTimerRecord(record);
+ }
}
// call periodically to keep isFullyLoaded up to date.
// returns true if the value has changed.
BOOL LLVOAvatar::updateIsFullyLoaded()
{
- S32 rez_status = getRezzedStatus();
- bool loading = getIsCloud();
- if (mFirstFullyVisible && !mIsControlAvatar)
- {
+ S32 rez_status = getRezzedStatus();
+ bool loading = getIsCloud();
+ if (mFirstFullyVisible && !mIsControlAvatar)
+ {
loading = ((rez_status < 2)
// Wait at least 60s for unfinished textures to finish on first load,
// don't wait forever, it might fail. Even if it will eventually load by
@@ -8246,56 +8243,56 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
|| (rez_status < 3 && !isFullyBaked())
|| hasPendingAttachedMeshes()
);
- }
- updateRezzedStatusTimers(rez_status);
- updateRuthTimer(loading);
- return processFullyLoadedChange(loading);
+ }
+ updateRezzedStatusTimers(rez_status);
+ updateRuthTimer(loading);
+ return processFullyLoadedChange(loading);
}
void LLVOAvatar::updateRuthTimer(bool loading)
{
- if (isSelf() || !loading)
- {
- return;
- }
-
- if (mPreviousFullyLoaded)
- {
- mRuthTimer.reset();
- debugAvatarRezTime("AvatarRezCloudNotification","became cloud");
- }
-
- const F32 LOADING_TIMEOUT__SECONDS = 120.f;
- if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS)
- {
- LL_DEBUGS("Avatar") << avString()
- << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "
- << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) "
- << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) "
- << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) "
- << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )."
- << LL_ENDL;
-
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
- mRuthTimer.reset();
- }
+ if (isSelf() || !loading)
+ {
+ return;
+ }
+
+ if (mPreviousFullyLoaded)
+ {
+ mRuthTimer.reset();
+ debugAvatarRezTime("AvatarRezCloudNotification","became cloud");
+ }
+
+ const F32 LOADING_TIMEOUT__SECONDS = 120.f;
+ if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS)
+ {
+ LL_DEBUGS("Avatar") << avString()
+ << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "
+ << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) "
+ << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) "
+ << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) "
+ << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )."
+ << LL_ENDL;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
+ mRuthTimer.reset();
+ }
}
BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
{
- // We wait a little bit before giving the 'all clear', to let things to
- // settle down (models to snap into place, textures to get first packets).
+ // We wait a little bit before giving the 'all clear', to let things to
+ // settle down (models to snap into place, textures to get first packets).
// And if viewer isn't aware of some parts yet, this gives them a chance
// to arrive.
- const F32 LOADED_DELAY = 1.f;
+ const F32 LOADED_DELAY = 1.f;
if (loading)
{
mFullyLoadedTimer.reset();
}
- if (mFirstFullyVisible)
- {
+ if (mFirstFullyVisible)
+ {
if (!isSelf() && loading)
{
// Note that textures can causes 60s delay on thier own
@@ -8312,31 +8309,31 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
mFirstUseDelaySeconds *= 1.25;
}
}
- mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds);
- }
- else
- {
- mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY);
- }
-
- if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
- {
- debugAvatarRezTime("AvatarRezNotification","fully loaded");
- }
-
- // did our loading state "change" from last call?
- // FIXME runway - why are we updating every 30 calls even if nothing has changed?
- // This causes updateLOD() to run every 30 frames, among other things.
- const S32 UPDATE_RATE = 30;
- BOOL changed =
- ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call
- (!mFullyLoadedInitialized) || // if we've never been called before
- (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change
- BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded);
-
- mPreviousFullyLoaded = mFullyLoaded;
- mFullyLoadedInitialized = TRUE;
- mFullyLoadedFrameCounter++;
+ mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds);
+ }
+ else
+ {
+ mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY);
+ }
+
+ if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
+ {
+ debugAvatarRezTime("AvatarRezNotification","fully loaded");
+ }
+
+ // did our loading state "change" from last call?
+ // FIXME runway - why are we updating every 30 calls even if nothing has changed?
+ // This causes updateLOD() to run every 30 frames, among other things.
+ const S32 UPDATE_RATE = 30;
+ BOOL changed =
+ ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call
+ (!mFullyLoadedInitialized) || // if we've never been called before
+ (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change
+ BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded);
+
+ mPreviousFullyLoaded = mFullyLoaded;
+ mFullyLoadedInitialized = TRUE;
+ mFullyLoadedFrameCounter++;
if (changed && isSelf())
{
@@ -8344,45 +8341,45 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
LLAvatarRenderNotifier::getInstance()->updateNotificationState();
}
- if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor())
- {
- // Fix for jellydoll initially invisible
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 6;
- }
- return changed;
+ if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor())
+ {
+ // Fix for jellydoll initially invisible
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 6;
+ }
+ return changed;
}
BOOL LLVOAvatar::isFullyLoaded() const
{
- return (mRenderUnloadedAvatar || mFullyLoaded);
+ return (mRenderUnloadedAvatar || mFullyLoaded);
}
bool LLVOAvatar::isTooComplex() const
{
- bool too_complex;
+ bool too_complex;
static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends");
- bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
-
- if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
- {
- too_complex = false;
- }
- else
- {
- // Determine if visually muted or not
- static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U);
- static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f);
- // If the user has chosen unlimited max complexity, we also disregard max attachment area
+ bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
+
+ if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+ {
+ too_complex = false;
+ }
+ else
+ {
+ // Determine if visually muted or not
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U);
+ static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f);
+ // If the user has chosen unlimited max complexity, we also disregard max attachment area
// so that unlimited will completely disable the overly complex impostor rendering
// yes, this leaves them vulnerable to griefing objects... their choice
too_complex = ( max_render_cost > 0
&& (mVisualComplexity > max_render_cost
|| (max_attachment_area > 0.0f && mAttachmentSurfaceArea > max_attachment_area)
));
- }
+ }
- return too_complex;
+ return too_complex;
}
bool LLVOAvatar::isTooSlow() const
@@ -8407,13 +8404,13 @@ void LLVOAvatar::updateTooSlow()
// mTooSlow - Is the avatar flagged as being slow (includes shadow time)
// mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
-
+
// get max render time in ms
F32 max_art_ms = (F32) (LLPerfStats::renderAvatarMaxART_ns / 1000000.0);
- bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
+ bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
- bool ignore_tune = false;
+ bool ignore_tune = false;
if (autotune && sAVsIgnoringARTLimit.size() > 0)
{
auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID);
@@ -8424,18 +8421,18 @@ void LLVOAvatar::updateTooSlow()
}
}
- bool exceeds_max_ART =
- ((LLPerfStats::renderAvatarMaxART_ns > 0) &&
+ bool exceeds_max_ART =
+ ((LLPerfStats::renderAvatarMaxART_ns > 0) &&
(mGPURenderTime >= max_art_ms)); // NOTE: don't use getGPURenderTime accessor here to avoid "isTooSlow" feedback loop
if (exceeds_max_ART && !ignore_tune)
{
mTooSlow = true;
-
+
if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
{
- bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
- ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );
+ bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
+ ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );
if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception )
{
// Note: slow rendering Friends still get their shadows zapped.
@@ -8448,10 +8445,10 @@ void LLVOAvatar::updateTooSlow()
mTooSlow = false;
mTooSlowWithoutShadows = false;
- if (ignore_tune)
- {
+ if (ignore_tune)
+ {
return;
- }
+ }
}
if(mTooSlow && !mTuned)
{
@@ -8470,26 +8467,26 @@ void LLVOAvatar::updateTooSlow()
//-----------------------------------------------------------------------------
LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
{
- return mMotionController.findMotion(id);
+ return mMotionController.findMotion(id);
}
// This is a semi-deprecated debugging tool - meshes will not show as
// colorized if using deferred rendering.
void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
{
- if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
- {
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setColor(color);
- }
- }
- }
+ if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+ {
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setColor(color);
+ }
+ }
+ }
}
@@ -8499,109 +8496,109 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
//-----------------------------------------------------------------------------
void LLVOAvatar::updateMeshVisibility()
{
- bool bake_flag[BAKED_NUM_INDICES];
- memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool));
-
- if (getOverallAppearance() == AOA_NORMAL)
- {
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment)
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *objectp = attachment_iter->get();
- if (objectp)
- {
- for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
- {
- LLTextureEntry* tex_entry = objectp->getTE(face_index);
- bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
- bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
- bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
- bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
- bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
- bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
- bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
- bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
- bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
- bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
- bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
- }
- }
-
- LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
- iter1 != child_list.end(); ++iter1)
- {
- LLViewerObject* objectchild = *iter1;
- if (objectchild)
- {
- for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
- {
- LLTextureEntry* tex_entry = objectchild->getTE(face_index);
- bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
- bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
- bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
- bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
- bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
- bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
- bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
- bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
- bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
- bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
- bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
- }
- }
- }
- }
- }
- }
- }
-
- //LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL;
-
- for (S32 i = 0; i < mMeshLOD.size(); i++)
- {
- LLAvatarJoint* joint = mMeshLOD[i];
- if (i == MESH_ID_HAIR)
- {
- joint->setVisible(!bake_flag[BAKED_HAIR], TRUE);
- }
- else if (i == MESH_ID_HEAD)
- {
- joint->setVisible(!bake_flag[BAKED_HEAD], TRUE);
- }
- else if (i == MESH_ID_SKIRT)
- {
- joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE);
- }
- else if (i == MESH_ID_UPPER_BODY)
- {
- joint->setVisible(!bake_flag[BAKED_UPPER], TRUE);
- }
- else if (i == MESH_ID_LOWER_BODY)
- {
- joint->setVisible(!bake_flag[BAKED_LOWER], TRUE);
- }
- else if (i == MESH_ID_EYEBALL_LEFT)
- {
- joint->setVisible(!bake_flag[BAKED_EYES], TRUE);
- }
- else if (i == MESH_ID_EYEBALL_RIGHT)
- {
- joint->setVisible(!bake_flag[BAKED_EYES], TRUE);
- }
- else if (i == MESH_ID_EYELASH)
- {
- joint->setVisible(!bake_flag[BAKED_HEAD], TRUE);
- }
- }
+ bool bake_flag[BAKED_NUM_INDICES];
+ memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool));
+
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *objectp = attachment_iter->get();
+ if (objectp)
+ {
+ for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
+ {
+ LLTextureEntry* tex_entry = objectp->getTE(face_index);
+ bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
+ bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
+ bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
+ bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
+ bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
+ bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
+ bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
+ bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
+ bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
+ bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
+ bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
+ }
+ }
+
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+ iter1 != child_list.end(); ++iter1)
+ {
+ LLViewerObject* objectchild = *iter1;
+ if (objectchild)
+ {
+ for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
+ {
+ LLTextureEntry* tex_entry = objectchild->getTE(face_index);
+ bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
+ bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
+ bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
+ bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
+ bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
+ bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
+ bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
+ bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
+ bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
+ bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
+ bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL;
+
+ for (S32 i = 0; i < mMeshLOD.size(); i++)
+ {
+ LLAvatarJoint* joint = mMeshLOD[i];
+ if (i == MESH_ID_HAIR)
+ {
+ joint->setVisible(!bake_flag[BAKED_HAIR], TRUE);
+ }
+ else if (i == MESH_ID_HEAD)
+ {
+ joint->setVisible(!bake_flag[BAKED_HEAD], TRUE);
+ }
+ else if (i == MESH_ID_SKIRT)
+ {
+ joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE);
+ }
+ else if (i == MESH_ID_UPPER_BODY)
+ {
+ joint->setVisible(!bake_flag[BAKED_UPPER], TRUE);
+ }
+ else if (i == MESH_ID_LOWER_BODY)
+ {
+ joint->setVisible(!bake_flag[BAKED_LOWER], TRUE);
+ }
+ else if (i == MESH_ID_EYEBALL_LEFT)
+ {
+ joint->setVisible(!bake_flag[BAKED_EYES], TRUE);
+ }
+ else if (i == MESH_ID_EYEBALL_RIGHT)
+ {
+ joint->setVisible(!bake_flag[BAKED_EYES], TRUE);
+ }
+ else if (i == MESH_ID_EYELASH)
+ {
+ joint->setVisible(!bake_flag[BAKED_HEAD], TRUE);
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -8611,256 +8608,256 @@ void LLVOAvatar::updateMeshVisibility()
// virtual
void LLVOAvatar::updateMeshTextures()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
- static S32 update_counter = 0;
- mBakedTextureDebugText.clear();
-
- // if user has never specified a texture, assign the default
- for (U32 i=0; i < getNumTEs(); i++)
- {
- const LLViewerTexture* te_image = getImage(i, 0);
- if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
- {
- // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
- const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR);
- setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0);
- }
- }
-
- const BOOL other_culled = !isSelf() && mCulled;
- LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
- BOOL paused = FALSE;
- if(!isSelf())
- {
- src_callback_list = &mCallbackTextureList ;
- paused = !isVisible();
- }
-
- std::vector<BOOL> is_layer_baked;
- is_layer_baked.resize(mBakedTextureDatas.size(), false);
-
- std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
- use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
-
- mBakedTextureDebugText += llformat("%06d\n",update_counter++);
- mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
- for (U32 i=0; i < mBakedTextureDatas.size(); i++)
- {
- is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
- LLViewerTexLayerSet* layerset = NULL;
- bool layerset_invalid = false;
- if (!other_culled)
- {
- // When an avatar is changing clothes and not in Appearance mode,
- // use the last-known good baked texture until it finishes the first
- // render of the new layerset.
- layerset = getTexLayerSet(i);
- layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized()
- || !layerset->isLocalTextureDataAvailable() );
- use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR)
- && layerset_invalid);
- if (use_lkg_baked_layer[i])
- {
- layerset->setUpdatesEnabled(TRUE);
- }
- }
- else
- {
- use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR);
- }
-
- std::string last_id_string;
- if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR)
- last_id_string = "A";
- else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT)
- last_id_string = "D";
- else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE)
- last_id_string = "I";
- else
- last_id_string = "*";
- bool is_ltda = layerset
- && layerset->getViewerComposite()->isInitialized()
- && layerset->isLocalTextureDataAvailable();
- mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n",
- i,
- (layerset?"*":"0"),
- layerset_invalid,
- is_ltda,
- is_layer_baked[i],
- use_lkg_baked_layer[i],
- last_id_string.c_str());
- }
-
- for (U32 i=0; i < mBakedTextureDatas.size(); i++)
- {
- debugColorizeSubMeshes(i, LLColor4::white);
-
- LLViewerTexLayerSet* layerset = getTexLayerSet(i);
- if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
- {
- // use last known good layer (no new one)
- LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
- mBakedTextureDatas[i].mIsUsed = TRUE;
-
- debugColorizeSubMeshes(i,LLColor4::red);
-
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setTexture( baked_img );
- }
- }
- }
- else if (!isUsingLocalAppearance() && is_layer_baked[i])
- {
- // use new layer
- LLViewerFetchedTexture* baked_img =
- LLViewerTextureManager::staticCastToFetchedTexture(
- getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
- if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID )
- {
- // Even though the file may not be finished loading,
- // we'll consider it loaded and use it (rather than
- // doing compositing).
- useBakedTexture( baked_img->getID() );
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
+ static S32 update_counter = 0;
+ mBakedTextureDebugText.clear();
+
+ // if user has never specified a texture, assign the default
+ for (U32 i=0; i < getNumTEs(); i++)
+ {
+ const LLViewerTexture* te_image = getImage(i, 0);
+ if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
+ {
+ // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+ const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR);
+ setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0);
+ }
+ }
+
+ const BOOL other_culled = !isSelf() && mCulled;
+ LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
+ BOOL paused = FALSE;
+ if(!isSelf())
+ {
+ src_callback_list = &mCallbackTextureList ;
+ paused = !isVisible();
+ }
+
+ std::vector<BOOL> is_layer_baked;
+ is_layer_baked.resize(mBakedTextureDatas.size(), false);
+
+ std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
+ use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
+
+ mBakedTextureDebugText += llformat("%06d\n",update_counter++);
+ mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
+ for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+ {
+ is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
+ LLViewerTexLayerSet* layerset = NULL;
+ bool layerset_invalid = false;
+ if (!other_culled)
+ {
+ // When an avatar is changing clothes and not in Appearance mode,
+ // use the last-known good baked texture until it finishes the first
+ // render of the new layerset.
+ layerset = getTexLayerSet(i);
+ layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized()
+ || !layerset->isLocalTextureDataAvailable() );
+ use_lkg_baked_layer[i] = (!is_layer_baked[i]
+ && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR)
+ && layerset_invalid);
+ if (use_lkg_baked_layer[i])
+ {
+ layerset->setUpdatesEnabled(TRUE);
+ }
+ }
+ else
+ {
+ use_lkg_baked_layer[i] = (!is_layer_baked[i]
+ && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR);
+ }
+
+ std::string last_id_string;
+ if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR)
+ last_id_string = "A";
+ else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT)
+ last_id_string = "D";
+ else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE)
+ last_id_string = "I";
+ else
+ last_id_string = "*";
+ bool is_ltda = layerset
+ && layerset->getViewerComposite()->isInitialized()
+ && layerset->isLocalTextureDataAvailable();
+ mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n",
+ i,
+ (layerset?"*":"0"),
+ layerset_invalid,
+ is_ltda,
+ is_layer_baked[i],
+ use_lkg_baked_layer[i],
+ last_id_string.c_str());
+ }
+
+ for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+ {
+ debugColorizeSubMeshes(i, LLColor4::white);
+
+ LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+ if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
+ {
+ // use last known good layer (no new one)
+ LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
+ mBakedTextureDatas[i].mIsUsed = TRUE;
+
+ debugColorizeSubMeshes(i,LLColor4::red);
+
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setTexture( baked_img );
+ }
+ }
+ }
+ else if (!isUsingLocalAppearance() && is_layer_baked[i])
+ {
+ // use new layer
+ LLViewerFetchedTexture* baked_img =
+ LLViewerTextureManager::staticCastToFetchedTexture(
+ getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
+ if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID )
+ {
+ // Even though the file may not be finished loading,
+ // we'll consider it loaded and use it (rather than
+ // doing compositing).
+ useBakedTexture( baked_img->getID() );
mLoadedCallbacksPaused |= !isVisible();
checkTextureLoading();
- }
- else
- {
- mBakedTextureDatas[i].mIsLoaded = FALSE;
- if ( (baked_img->getID() != IMG_INVISIBLE) &&
- ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
- {
- baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
- src_callback_list, paused);
- }
- baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),
- src_callback_list, paused );
- if (baked_img->getDiscardLevel() < 0 && !paused)
- {
- // mLoadedCallbackTextures will be updated by checkTextureLoading() below
- mLastTexCallbackAddedTime.reset();
- }
-
- // this could add paused texture callbacks
- mLoadedCallbacksPaused |= paused;
- checkTextureLoading();
- }
- }
- else if (layerset && isUsingLocalAppearance())
- {
- debugColorizeSubMeshes(i,LLColor4::yellow );
-
- layerset->createComposite();
- layerset->setUpdatesEnabled( TRUE );
- mBakedTextureDatas[i].mIsUsed = FALSE;
-
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setLayerSet( layerset );
- }
- }
- }
- else
- {
- debugColorizeSubMeshes(i,LLColor4::blue);
- }
- }
-
- // set texture and color of hair manually if we are not using a baked image.
- // This can happen while loading hair for yourself, or for clients that did not
- // bake a hair texture. Still needed for yourself after 1.22 is depricated.
- if (!is_layer_baked[BAKED_HAIR])
- {
- const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
- LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setColor( color );
- mesh->setTexture( hair_img );
- }
- }
- }
-
-
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
- ++baked_iter)
- {
- const EBakedTextureIndex baked_index = baked_iter->first;
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
-
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex texture_index = *local_tex_iter;
- const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled;
- if (isSelf())
- {
- setBakedReady(texture_index, is_baked_ready);
- }
- }
- }
-
- // removeMissingBakedTextures() will call back into this rountine if something is removed, and can blow up the stack
- static bool call_remove_missing = true;
- if (call_remove_missing)
- {
- call_remove_missing = false;
- removeMissingBakedTextures(); // May call back into this function if anything is removed
- call_remove_missing = true;
- }
-
- //refresh bakes on any attached objects
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object && !attached_object->isDead())
- {
- attached_object->refreshBakeTexture();
-
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- if (objectp && !objectp->isDead())
- {
- objectp->refreshBakeTexture();
- }
- }
- }
- }
- }
-
-
+ }
+ else
+ {
+ mBakedTextureDatas[i].mIsLoaded = FALSE;
+ if ( (baked_img->getID() != IMG_INVISIBLE) &&
+ ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
+ {
+ baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
+ src_callback_list, paused);
+ }
+ baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),
+ src_callback_list, paused );
+ if (baked_img->getDiscardLevel() < 0 && !paused)
+ {
+ // mLoadedCallbackTextures will be updated by checkTextureLoading() below
+ mLastTexCallbackAddedTime.reset();
+ }
+
+ // this could add paused texture callbacks
+ mLoadedCallbacksPaused |= paused;
+ checkTextureLoading();
+ }
+ }
+ else if (layerset && isUsingLocalAppearance())
+ {
+ debugColorizeSubMeshes(i,LLColor4::yellow );
+
+ layerset->createComposite();
+ layerset->setUpdatesEnabled( TRUE );
+ mBakedTextureDatas[i].mIsUsed = FALSE;
+
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setLayerSet( layerset );
+ }
+ }
+ }
+ else
+ {
+ debugColorizeSubMeshes(i,LLColor4::blue);
+ }
+ }
+
+ // set texture and color of hair manually if we are not using a baked image.
+ // This can happen while loading hair for yourself, or for clients that did not
+ // bake a hair texture. Still needed for yourself after 1.22 is depricated.
+ if (!is_layer_baked[BAKED_HAIR])
+ {
+ const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
+ LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setColor( color );
+ mesh->setTexture( hair_img );
+ }
+ }
+ }
+
+
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+ LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex texture_index = *local_tex_iter;
+ const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled;
+ if (isSelf())
+ {
+ setBakedReady(texture_index, is_baked_ready);
+ }
+ }
+ }
+
+ // removeMissingBakedTextures() will call back into this rountine if something is removed, and can blow up the stack
+ static bool call_remove_missing = true;
+ if (call_remove_missing)
+ {
+ call_remove_missing = false;
+ removeMissingBakedTextures(); // May call back into this function if anything is removed
+ call_remove_missing = true;
+ }
+
+ //refresh bakes on any attached objects
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isDead())
+ {
+ attached_object->refreshBakeTexture();
+
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* objectp = *iter;
+ if (objectp && !objectp->isDead())
+ {
+ objectp->refreshBakeTexture();
+ }
+ }
+ }
+ }
+ }
+
+
}
@@ -8870,92 +8867,92 @@ void LLVOAvatar::updateMeshTextures()
//-----------------------------------------------------------------------------
void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready, U32 index )
{
- // invalid for anyone but self
- llassert(0);
+ // invalid for anyone but self
+ llassert(0);
}
-//virtual
+//virtual
void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
- // invalid for anyone but self
- llassert(0);
+ // invalid for anyone but self
+ llassert(0);
}
void LLVOAvatar::addChat(const LLChat& chat)
{
- std::deque<LLChat>::iterator chat_iter;
+ std::deque<LLChat>::iterator chat_iter;
- mChats.push_back(chat);
+ mChats.push_back(chat);
- S32 chat_length = 0;
- for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter)
- {
- chat_length += chat_iter->mText.size();
- }
+ S32 chat_length = 0;
+ for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter)
+ {
+ chat_length += chat_iter->mText.size();
+ }
- // remove any excess chat
- chat_iter = mChats.begin();
- while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end())
- {
- chat_length -= chat_iter->mText.size();
- mChats.pop_front();
- chat_iter = mChats.begin();
- }
+ // remove any excess chat
+ chat_iter = mChats.begin();
+ while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end())
+ {
+ chat_length -= chat_iter->mText.size();
+ mChats.pop_front();
+ chat_iter = mChats.begin();
+ }
- mChatTimer.reset();
+ mChatTimer.reset();
}
void LLVOAvatar::clearChat()
{
- mChats.clear();
+ mChats.clear();
}
void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
{
- if (index >= BAKED_NUM_INDICES)
- {
- LL_WARNS() << "invalid baked texture index passed to applyMorphMask" << LL_ENDL;
- return;
- }
+ if (index >= BAKED_NUM_INDICES)
+ {
+ LL_WARNS() << "invalid baked texture index passed to applyMorphMask" << LL_ENDL;
+ return;
+ }
- for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
- iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
- {
- const LLMaskedMorph* maskedMorph = (*iter);
- LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
- if (morph_target)
- {
- morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
- }
- }
+ for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
+ iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
+ {
+ const LLMaskedMorph* maskedMorph = (*iter);
+ LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
+ if (morph_target)
+ {
+ morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
+ }
+ }
}
// returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)
{
- if (index >= BAKED_NUM_INDICES)
- {
- return FALSE;
- }
+ if (index >= BAKED_NUM_INDICES)
+ {
+ return FALSE;
+ }
- if (!mBakedTextureDatas[index].mMaskedMorphs.empty())
- {
- if (isSelf())
- {
- LLViewerTexLayerSet *layer_set = getTexLayerSet(index);
- if (layer_set)
- {
- return !layer_set->isMorphValid();
- }
- }
- else
- {
- return FALSE;
- }
- }
+ if (!mBakedTextureDatas[index].mMaskedMorphs.empty())
+ {
+ if (isSelf())
+ {
+ LLViewerTexLayerSet *layer_set = getTexLayerSet(index);
+ if (layer_set)
+ {
+ return !layer_set->isMorphValid();
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -8967,66 +8964,66 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIn
//-----------------------------------------------------------------------------
void LLVOAvatar::releaseComponentTextures()
{
- // ! BACKWARDS COMPATIBILITY !
- // Detect if the baked hair texture actually wasn't sent, and if so set to default
- if (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED,0)->getID() == getImage(TEX_SKIRT_BAKED,0)->getID())
- {
- if (getImage(TEX_HAIR_BAKED,0)->getID() != IMG_INVISIBLE)
- {
- // Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default
- setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR);
- }
- }
-
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
- {
- const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
- // skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
- if (!isTextureDefined(bakedDicEntry->mTextureIndex)
- && ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
- {
- continue;
- }
-
- for (U8 texture = 0; texture < bakedDicEntry->mLocalTextures.size(); texture++)
- {
- const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture];
- setTETexture(te, IMG_DEFAULT_AVATAR);
- }
- }
+ // ! BACKWARDS COMPATIBILITY !
+ // Detect if the baked hair texture actually wasn't sent, and if so set to default
+ if (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED,0)->getID() == getImage(TEX_SKIRT_BAKED,0)->getID())
+ {
+ if (getImage(TEX_HAIR_BAKED,0)->getID() != IMG_INVISIBLE)
+ {
+ // Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default
+ setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR);
+ }
+ }
+
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
+ // skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
+ if (!isTextureDefined(bakedDicEntry->mTextureIndex)
+ && ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
+ {
+ continue;
+ }
+
+ for (U8 texture = 0; texture < bakedDicEntry->mLocalTextures.size(); texture++)
+ {
+ const U8 te = (ETextureIndex)bakedDicEntry->mLocalTextures[texture];
+ setTETexture(te, IMG_DEFAULT_AVATAR);
+ }
+ }
}
void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
-{
- LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- // TODO: MULTI-WEARABLE: handle multiple textures for self
- const LLViewerTexture* te_image = getImage(iter->first,0);
- if( !te_image )
- {
- LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL;
- }
- else if( te_image->getID().isNull() )
- {
- LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL;
- }
- else if( te_image->getID() == IMG_DEFAULT )
- {
- LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;
- }
- else if( te_image->getID() == IMG_DEFAULT_AVATAR )
- {
- LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;
- }
- }
+{
+ LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
+ ++iter)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ // TODO: MULTI-WEARABLE: handle multiple textures for self
+ const LLViewerTexture* te_image = getImage(iter->first,0);
+ if( !te_image )
+ {
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL;
+ }
+ else if( te_image->getID().isNull() )
+ {
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL;
+ }
+ else if( te_image->getID() == IMG_DEFAULT )
+ {
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;
+ }
+ else if( te_image->getID() == IMG_DEFAULT_AVATAR )
+ {
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -9034,74 +9031,74 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
//-----------------------------------------------------------------------------
void LLVOAvatar::clampAttachmentPositions()
{
- if (isDead())
- {
- return;
- }
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment)
- {
- attachment->clampObjectPosition();
- }
- }
+ if (isDead())
+ {
+ return;
+ }
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment)
+ {
+ attachment->clampObjectPosition();
+ }
+ }
}
BOOL LLVOAvatar::hasHUDAttachment() const
{
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0)
- {
- return TRUE;
- }
- }
- return FALSE;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getIsHUDAttachment() && attachment->getNumObjects() > 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
LLBBox LLVOAvatar::getHUDBBox() const
{
- LLBBox bbox;
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getIsHUDAttachment())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object == NULL)
- {
- LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL;
- continue;
- }
- // initialize bounding box to contain identity orientation and center point for attached object
- bbox.addPointLocal(attached_object->getPosition());
- // add rotated bounding box for attached object
- bbox.addBBoxAgent(attached_object->getBoundingBoxAgent());
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end();
- ++iter)
- {
- const LLViewerObject* child_objectp = *iter;
- bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent());
- }
- }
- }
- }
-
- return bbox;
+ LLBBox bbox;
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getIsHUDAttachment())
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ const LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object == NULL)
+ {
+ LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL;
+ continue;
+ }
+ // initialize bounding box to contain identity orientation and center point for attached object
+ bbox.addPointLocal(attached_object->getPosition());
+ // add rotated bounding box for attached object
+ bbox.addBBoxAgent(attached_object->getBoundingBoxAgent());
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end();
+ ++iter)
+ {
+ const LLViewerObject* child_objectp = *iter;
+ bbox.addBBoxAgent(child_objectp->getBoundingBoxAgent());
+ }
+ }
+ }
+ }
+
+ return bbox;
}
//-----------------------------------------------------------------------------
@@ -9109,53 +9106,53 @@ LLBBox LLVOAvatar::getHUDBBox() const
//-----------------------------------------------------------------------------
void LLVOAvatar::onFirstTEMessageReceived()
{
- LL_DEBUGS("Avatar") << avString() << LL_ENDL;
- if( !mFirstTEMessageReceived )
- {
- mFirstTEMessageReceived = TRUE;
-
- LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
- BOOL paused = FALSE ;
- if(!isSelf())
- {
- src_callback_list = &mCallbackTextureList ;
- paused = !isVisible();
- }
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
-
- // Use any baked textures that we have even if they haven't downloaded yet.
- // (That is, don't do a transition from unbaked to baked.)
- if (layer_baked)
- {
- LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
- mBakedTextureDatas[i].mLastTextureID = image->getID();
- // If we have more than one texture for the other baked layers, we'll want to call this for them too.
- if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
- {
- image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
- src_callback_list, paused);
- }
- LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;
- image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
- src_callback_list, paused );
- if (image->getDiscardLevel() < 0 && !paused)
- {
- mLastTexCallbackAddedTime.reset();
- }
+ LL_DEBUGS("Avatar") << avString() << LL_ENDL;
+ if( !mFirstTEMessageReceived )
+ {
+ mFirstTEMessageReceived = TRUE;
+
+ LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
+ BOOL paused = FALSE ;
+ if(!isSelf())
+ {
+ src_callback_list = &mCallbackTextureList ;
+ paused = !isVisible();
+ }
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
+
+ // Use any baked textures that we have even if they haven't downloaded yet.
+ // (That is, don't do a transition from unbaked to baked.)
+ if (layer_baked)
+ {
+ LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
+ mBakedTextureDatas[i].mLastTextureID = image->getID();
+ // If we have more than one texture for the other baked layers, we'll want to call this for them too.
+ if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
+ {
+ image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
+ src_callback_list, paused);
+ }
+ LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;
+ image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
+ src_callback_list, paused );
+ if (image->getDiscardLevel() < 0 && !paused)
+ {
+ mLastTexCallbackAddedTime.reset();
+ }
// this could add paused texture callbacks
- mLoadedCallbacksPaused |= paused;
- }
- }
+ mLoadedCallbacksPaused |= paused;
+ }
+ }
mMeshTexturesDirty = TRUE;
- gPipeline.markGLRebuild(this);
+ gPipeline.markGLRebuild(this);
mFirstAppearanceMessageTimer.reset();
mFullyLoadedTimer.reset();
- }
+ }
}
//-----------------------------------------------------------------------------
@@ -9163,240 +9160,240 @@ void LLVOAvatar::onFirstTEMessageReceived()
//-----------------------------------------------------------------------------
bool LLVOAvatar::visualParamWeightsAreDefault()
{
- bool rtn = true;
-
- bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT);
- for (LLVisualParam *param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
- {
- if (param->isTweakable())
- {
- LLViewerVisualParam* vparam = dynamic_cast<LLViewerVisualParam*>(param);
- llassert(vparam);
- bool is_skirt_param = vparam &&
- LLWearableType::WT_SKIRT == vparam->getWearableType();
- if (param->getWeight() != param->getDefaultWeight() &&
- // we have to not care whether skirt weights are default, if we're not actually wearing a skirt
- (is_wearing_skirt || !is_skirt_param))
- {
- //LL_INFOS() << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << LL_ENDL;
- rtn = false;
- break;
- }
- }
- }
-
- //LL_INFOS() << "params are default ? " << int(rtn) << LL_ENDL;
-
- return rtn;
+ bool rtn = true;
+
+ bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT);
+ for (LLVisualParam *param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ if (param->isTweakable())
+ {
+ LLViewerVisualParam* vparam = dynamic_cast<LLViewerVisualParam*>(param);
+ llassert(vparam);
+ bool is_skirt_param = vparam &&
+ LLWearableType::WT_SKIRT == vparam->getWearableType();
+ if (param->getWeight() != param->getDefaultWeight() &&
+ // we have to not care whether skirt weights are default, if we're not actually wearing a skirt
+ (is_wearing_skirt || !is_skirt_param))
+ {
+ //LL_INFOS() << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << LL_ENDL;
+ rtn = false;
+ break;
+ }
+ }
+ }
+
+ //LL_INFOS() << "params are default ? " << int(rtn) << LL_ENDL;
+
+ return rtn;
}
void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
{
- std::string type_string = "unknown";
- if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param))
- type_string = "param_alpha";
- if (dynamic_cast<LLTexLayerParamColor*>(viewer_param))
- type_string = "param_color";
- if (dynamic_cast<LLDriverParam*>(viewer_param))
- type_string = "param_driver";
- if (dynamic_cast<LLPolyMorphTarget*>(viewer_param))
- type_string = "param_morph";
- if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param))
- type_string = "param_skeleton";
- S32 wtype = -1;
- LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param);
- if (vparam)
- {
- wtype = vparam->getWearableType();
- }
- S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
- apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n",
- viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(),
- LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(),
- viewer_param->getGroup());
- }
-
+ std::string type_string = "unknown";
+ if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param))
+ type_string = "param_alpha";
+ if (dynamic_cast<LLTexLayerParamColor*>(viewer_param))
+ type_string = "param_color";
+ if (dynamic_cast<LLDriverParam*>(viewer_param))
+ type_string = "param_driver";
+ if (dynamic_cast<LLPolyMorphTarget*>(viewer_param))
+ type_string = "param_morph";
+ if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param))
+ type_string = "param_skeleton";
+ S32 wtype = -1;
+ LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param);
+ if (vparam)
+ {
+ wtype = vparam->getWearableType();
+ }
+ S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
+ apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n",
+ viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(),
+ LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(),
+ viewer_param->getGroup());
+ }
+
void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
- const LLAppearanceMessageContents& contents)
-{
- std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
- const std::vector<F32>& params_for_dump = contents.mParamWeights;
- const LLTEContents& tec = contents.mTEContents;
-
- LLAPRFile outfile;
- std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
- outfile.open(fullpath, LL_APR_WB );
- apr_file_t* file = outfile.getFileHandle();
- if (!file)
- {
- return;
- }
- else
- {
- LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL;
- }
-
- apr_file_printf(file, "<header>\n");
- apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion);
- apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion);
- apr_file_printf(file, "</header>\n");
-
- apr_file_printf(file, "\n<params>\n");
- LLVisualParam* param = getFirstVisualParam();
- for (S32 i = 0; i < params_for_dump.size(); i++)
- {
- while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) &&
- (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
- {
- param = getNextVisualParam();
- }
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- F32 value = params_for_dump[i];
- dump_visual_param(file, viewer_param, value);
- param = getNextVisualParam();
- }
- apr_file_printf(file, "</params>\n");
-
- apr_file_printf(file, "\n<textures>\n");
- for (U32 i = 0; i < tec.face_count; i++)
- {
- std::string uuid_str;
- ((LLUUID*)tec.image_data)[i].toString(uuid_str);
- apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
- }
- apr_file_printf(file, "</textures>\n");
+ const LLAppearanceMessageContents& contents)
+{
+ std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+ const std::vector<F32>& params_for_dump = contents.mParamWeights;
+ const LLTEContents& tec = contents.mTEContents;
+
+ LLAPRFile outfile;
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ outfile.open(fullpath, LL_APR_WB );
+ apr_file_t* file = outfile.getFileHandle();
+ if (!file)
+ {
+ return;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL;
+ }
+
+ apr_file_printf(file, "<header>\n");
+ apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion);
+ apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion);
+ apr_file_printf(file, "</header>\n");
+
+ apr_file_printf(file, "\n<params>\n");
+ LLVisualParam* param = getFirstVisualParam();
+ for (S32 i = 0; i < params_for_dump.size(); i++)
+ {
+ while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) &&
+ (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ {
+ param = getNextVisualParam();
+ }
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ F32 value = params_for_dump[i];
+ dump_visual_param(file, viewer_param, value);
+ param = getNextVisualParam();
+ }
+ apr_file_printf(file, "</params>\n");
+
+ apr_file_printf(file, "\n<textures>\n");
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ std::string uuid_str;
+ ((LLUUID*)tec.image_data)[i].toString(uuid_str);
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
+ }
+ apr_file_printf(file, "</textures>\n");
}
void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
{
- parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents);
-
- // Parse the AppearanceData field, if any.
- if (mesgsys->has(_PREHASH_AppearanceData))
- {
- U8 av_u8;
- mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
- contents.mAppearanceVersion = av_u8;
- //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL;
- mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
- // For future use:
- //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
- }
-
- // Parse the AppearanceData field, if any.
- contents.mHoverOffsetWasSet = false;
- if (mesgsys->has(_PREHASH_AppearanceHover))
- {
- LLVector3 hover;
- mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover);
- //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL;
- contents.mHoverOffset = hover;
- contents.mHoverOffsetWasSet = true;
- }
-
- // Parse visual params, if any.
- S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
+ parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents);
+
+ // Parse the AppearanceData field, if any.
+ if (mesgsys->has(_PREHASH_AppearanceData))
+ {
+ U8 av_u8;
+ mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
+ contents.mAppearanceVersion = av_u8;
+ //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL;
+ mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
+ // For future use:
+ //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
+ }
+
+ // Parse the AppearanceData field, if any.
+ contents.mHoverOffsetWasSet = false;
+ if (mesgsys->has(_PREHASH_AppearanceHover))
+ {
+ LLVector3 hover;
+ mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover);
+ //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL;
+ contents.mHoverOffset = hover;
+ contents.mHoverOffsetWasSet = true;
+ }
+
+ // Parse visual params, if any.
+ S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams");
- bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
- if( num_blocks > 1 && !drop_visual_params_debug)
- {
- //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
-
- LLVisualParam* param = getFirstVisualParam();
- llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
- if (!param)
- {
- LL_WARNS() << "No visual params!" << LL_ENDL;
- }
- else
- {
- for( S32 i = 0; i < num_blocks; i++ )
- {
- while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) &&
- (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
- {
- param = getNextVisualParam();
- }
-
- if( !param )
- {
- // more visual params supplied than expected - just process what we know about
- break;
- }
-
- U8 value;
- mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
- F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
- contents.mParamWeights.push_back(newWeight);
- contents.mParams.push_back(param);
-
- param = getNextVisualParam();
- }
- }
-
- const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) +
- getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
- if (num_blocks != expected_tweakable_count)
- {
- LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL;
- }
- }
- else
- {
- if (drop_visual_params_debug)
- {
- LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL;
- }
- }
-
- LLVisualParam* appearance_version_param = getVisualParam(11000);
- if (appearance_version_param)
- {
- std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param);
- if (it != contents.mParams.end())
- {
- S32 index = it - contents.mParams.begin();
- contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]);
- //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL;
- }
- }
+ bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
+ if( num_blocks > 1 && !drop_visual_params_debug)
+ {
+ //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
+
+ LLVisualParam* param = getFirstVisualParam();
+ llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
+ if (!param)
+ {
+ LL_WARNS() << "No visual params!" << LL_ENDL;
+ }
+ else
+ {
+ for( S32 i = 0; i < num_blocks; i++ )
+ {
+ while( param && ((param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) &&
+ (param->getGroup() != VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE)) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ {
+ param = getNextVisualParam();
+ }
+
+ if( !param )
+ {
+ // more visual params supplied than expected - just process what we know about
+ break;
+ }
+
+ U8 value;
+ mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
+ F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+ contents.mParamWeights.push_back(newWeight);
+ contents.mParams.push_back(param);
+
+ param = getNextVisualParam();
+ }
+ }
+
+ const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) +
+ getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ if (num_blocks != expected_tweakable_count)
+ {
+ LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL;
+ }
+ }
+ else
+ {
+ if (drop_visual_params_debug)
+ {
+ LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL;
+ }
+ }
+
+ LLVisualParam* appearance_version_param = getVisualParam(11000);
+ if (appearance_version_param)
+ {
+ std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param);
+ if (it != contents.mParams.end())
+ {
+ S32 index = it - contents.mParams.begin();
+ contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]);
+ //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL;
+ }
+ }
}
bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version)
{
- appearance_version = -1;
-
- if ((contents.mAppearanceVersion) >= 0 &&
- (contents.mParamAppearanceVersion >= 0) &&
- (contents.mAppearanceVersion != contents.mParamAppearanceVersion))
- {
- LL_WARNS() << "inconsistent appearance_version settings - field: " <<
- contents.mAppearanceVersion << ", param: " << contents.mParamAppearanceVersion << LL_ENDL;
- return false;
- }
- if (contents.mParamAppearanceVersion >= 0) // use visual param if available.
- {
- appearance_version = contents.mParamAppearanceVersion;
- }
- else if (contents.mAppearanceVersion > 0)
- {
- appearance_version = contents.mAppearanceVersion;
- }
- else // still not set, go with 1.
- {
- appearance_version = 1;
- }
- //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
- // << " param: " << contents.mParamAppearanceVersion
- // << " final: " << appearance_version << LL_ENDL;
- return true;
+ appearance_version = -1;
+
+ if ((contents.mAppearanceVersion) >= 0 &&
+ (contents.mParamAppearanceVersion >= 0) &&
+ (contents.mAppearanceVersion != contents.mParamAppearanceVersion))
+ {
+ LL_WARNS() << "inconsistent appearance_version settings - field: " <<
+ contents.mAppearanceVersion << ", param: " << contents.mParamAppearanceVersion << LL_ENDL;
+ return false;
+ }
+ if (contents.mParamAppearanceVersion >= 0) // use visual param if available.
+ {
+ appearance_version = contents.mParamAppearanceVersion;
+ }
+ else if (contents.mAppearanceVersion > 0)
+ {
+ appearance_version = contents.mAppearanceVersion;
+ }
+ else // still not set, go with 1.
+ {
+ appearance_version = 1;
+ }
+ //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
+ // << " param: " << contents.mParamAppearanceVersion
+ // << " final: " << appearance_version << LL_ENDL;
+ return true;
}
//-----------------------------------------------------------------------------
@@ -9404,46 +9401,46 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32
//-----------------------------------------------------------------------------
void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
- LL_DEBUGS("Avatar") << "starts" << LL_ENDL;
+ LL_DEBUGS("Avatar") << "starts" << LL_ENDL;
static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage");
static LLCachedControl<bool> block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages");
- std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
- if (block_avatar_appearance_messages)
- {
- LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL;
- return;
- }
-
- mLastAppearanceMessageTimer.reset();
-
- LLPointer<LLAppearanceMessageContents> contents(new LLAppearanceMessageContents);
- parseAppearanceMessage(mesgsys, *contents);
- if (enable_verbose_dumps)
- {
- dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents);
- }
-
- S32 appearance_version;
- if (!resolve_appearance_version(*contents, appearance_version))
- {
- LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL;
- return;
- }
- llassert(appearance_version > 0);
- if (appearance_version > 1)
- {
- LL_WARNS() << "unsupported appearance version " << appearance_version << ", discarding appearance message" << LL_ENDL;
- return;
- }
+ std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
+ if (block_avatar_appearance_messages)
+ {
+ LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL;
+ return;
+ }
+
+ mLastAppearanceMessageTimer.reset();
+
+ LLPointer<LLAppearanceMessageContents> contents(new LLAppearanceMessageContents);
+ parseAppearanceMessage(mesgsys, *contents);
+ if (enable_verbose_dumps)
+ {
+ dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents);
+ }
+
+ S32 appearance_version;
+ if (!resolve_appearance_version(*contents, appearance_version))
+ {
+ LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL;
+ return;
+ }
+ llassert(appearance_version > 0);
+ if (appearance_version > 1)
+ {
+ LL_WARNS() << "unsupported appearance version " << appearance_version << ", discarding appearance message" << LL_ENDL;
+ return;
+ }
S32 thisAppearanceVersion(contents->mCOFVersion);
if (isSelf())
- { // In the past this was considered to be the canonical COF version,
- // that is no longer the case. The canonical version is maintained
+ { // In the past this was considered to be the canonical COF version,
+ // that is no longer the case. The canonical version is maintained
// by the AIS code and should match the COF version there. Even so,
- // we must prevent rolling this one backwards backwards or processing
+ // we must prevent rolling this one backwards backwards or processing
// stale versions.
S32 aisCOFVersion(LLAppearanceMgr::instance().getCOFVersion());
@@ -9467,23 +9464,23 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
- // SUNSHINE CLEANUP - is this case OK now?
- S32 num_params = contents->mParamWeights.size();
- if (num_params <= 1)
- {
- // In this case, we have no reliable basis for knowing
- // appearance version, which may cause us to look for baked
- // textures in the wrong place and flag them as missing
- // assets.
- LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << LL_ENDL;
- return;
- }
+ // SUNSHINE CLEANUP - is this case OK now?
+ S32 num_params = contents->mParamWeights.size();
+ if (num_params <= 1)
+ {
+ // In this case, we have no reliable basis for knowing
+ // appearance version, which may cause us to look for baked
+ // textures in the wrong place and flag them as missing
+ // assets.
+ LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << LL_ENDL;
+ return;
+ }
- // No backsies zone - if we get here, the message should be valid and usable, will be processed.
- // Note:
- // RequestAgentUpdateAppearanceResponder::onRequestRequested()
- // assumes that cof version is only updated with server-bake
- // appearance messages.
+ // No backsies zone - if we get here, the message should be valid and usable, will be processed.
+ // Note:
+ // RequestAgentUpdateAppearanceResponder::onRequestRequested()
+ // assumes that cof version is only updated with server-bake
+ // appearance messages.
if (isSelf())
{
LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
@@ -9495,202 +9492,202 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// Note:
// locally the COF is maintained via LLInventoryModel::accountForUpdate
- // which is called from various places. This should match the simhost's
+ // which is called from various places. This should match the simhost's
// idea of what the COF version is. AIS however maintains its own version
- // of the COF that should be considered canonical.
+ // of the COF that should be considered canonical.
mLastUpdateReceivedCOFVersion = thisAppearanceVersion;
mLastProcessedAppearance = contents;
bool slam_params = false;
- applyParsedAppearanceMessage(*contents, slam_params);
- if (getOverallAppearance() != AOA_NORMAL)
- {
- resetSkeleton(false);
- }
+ applyParsedAppearanceMessage(*contents, slam_params);
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ resetSkeleton(false);
+ }
}
void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params)
{
- S32 num_params = contents.mParamWeights.size();
- ESex old_sex = getSex();
+ S32 num_params = contents.mParamWeights.size();
+ ESex old_sex = getSex();
if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE))
{
updateVisualComplexity();
}
- // prevent the overwriting of valid baked textures with invalid baked textures
- for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
- {
- if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)
- && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT
- && baked_index != BAKED_SKIRT && baked_index != BAKED_LEFT_ARM && baked_index != BAKED_LEFT_LEG && baked_index != BAKED_AUX1 && baked_index != BAKED_AUX2 && baked_index != BAKED_AUX3)
- {
- LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using mLastTextureID " << mBakedTextureDatas[baked_index].mLastTextureID << LL_ENDL;
- setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
- LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
- }
- else
- {
- LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using texture id "
- << getTE(mBakedTextureDatas[baked_index].mTextureIndex)->getID() << LL_ENDL;
- }
- }
-
- // runway - was
- // if (!is_first_appearance_message )
- // which means it would be called on second appearance message - probably wrong.
- BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
- mFirstAppearanceMessageReceived = TRUE;
-
- //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
+ // prevent the overwriting of valid baked textures with invalid baked textures
+ for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
+ {
+ if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)
+ && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT
+ && baked_index != BAKED_SKIRT && baked_index != BAKED_LEFT_ARM && baked_index != BAKED_LEFT_LEG && baked_index != BAKED_AUX1 && baked_index != BAKED_AUX2 && baked_index != BAKED_AUX3)
+ {
+ LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using mLastTextureID " << mBakedTextureDatas[baked_index].mLastTextureID << LL_ENDL;
+ setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
+ LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using texture id "
+ << getTE(mBakedTextureDatas[baked_index].mTextureIndex)->getID() << LL_ENDL;
+ }
+ }
+
+ // runway - was
+ // if (!is_first_appearance_message )
+ // which means it would be called on second appearance message - probably wrong.
+ BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
+ mFirstAppearanceMessageReceived = TRUE;
+
+ //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
// << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
- if (is_first_appearance_message )
- {
- onFirstTEMessageReceived();
- }
-
- setCompositeUpdatesEnabled( FALSE );
- gPipeline.markGLRebuild(this);
-
- // Apply visual params
- if( num_params > 1)
- {
- //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
- BOOL params_changed = FALSE;
- BOOL interp_params = FALSE;
- S32 params_changed_count = 0;
-
- for( S32 i = 0; i < num_params; i++ )
- {
- LLVisualParam* param = contents.mParams[i];
- F32 newWeight = contents.mParamWeights[i];
-
- if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight))
- {
- params_changed = TRUE;
- params_changed_count++;
-
- if(is_first_appearance_message || slam_params)
- {
- //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL;
- param->setWeight(newWeight);
- }
- else
- {
- interp_params = TRUE;
- param->setAnimationTarget(newWeight);
- }
- }
- }
- const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) +
- getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
- if (num_params != expected_tweakable_count)
- {
- LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL;
- }
-
- LL_DEBUGS("Avatar") << "Changed " << params_changed_count << " params" << LL_ENDL;
- if (params_changed)
- {
- if (interp_params)
- {
- startAppearanceAnimation();
- }
- updateVisualParams();
-
- ESex new_sex = getSex();
- if( old_sex != new_sex )
- {
- updateSexDependentLayerSets();
- }
- }
-
- llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) );
- }
- else
- {
- // AvatarAppearance message arrived without visual params
- LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;
-
- const F32 LOADING_TIMEOUT_SECONDS = 60.f;
- // this isn't really a problem if we already have a non-default shape
- if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS)
- {
- // re-request appearance, hoping that it comes back with a shape next time
- LL_INFOS() << "Re-requesting AvatarAppearance for object: " << getID() << LL_ENDL;
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
- mRuthTimer.reset();
- }
- else
- {
- LL_INFOS() << "That's okay, we already have a non-default shape for object: " << getID() << LL_ENDL;
- // we don't really care.
- }
- }
-
- if (contents.mHoverOffsetWasSet && !isSelf())
- {
- // Got an update for some other avatar
- // Ignore updates for self, because we have a more authoritative value in the preferences.
- setHoverOffset(contents.mHoverOffset);
- LL_DEBUGS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL;
- }
-
- if (!contents.mHoverOffsetWasSet && !isSelf())
- {
- // If we don't get a value at all, we are presumably in a
- // region that does not support hover height.
- LL_WARNS() << avString() << "zeroing hover because not defined in appearance message" << LL_ENDL;
- setHoverOffset(LLVector3(0.0, 0.0, 0.0));
- }
-
- setCompositeUpdatesEnabled( TRUE );
-
- // If all of the avatars are completely baked, release the global image caches to conserve memory.
- LLVOAvatar::cullAvatarsByPixelArea();
-
- if (isSelf())
- {
- mUseLocalAppearance = false;
- }
-
- updateMeshTextures();
- updateMeshVisibility();
+ if (is_first_appearance_message )
+ {
+ onFirstTEMessageReceived();
+ }
+
+ setCompositeUpdatesEnabled( FALSE );
+ gPipeline.markGLRebuild(this);
+
+ // Apply visual params
+ if( num_params > 1)
+ {
+ //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
+ BOOL params_changed = FALSE;
+ BOOL interp_params = FALSE;
+ S32 params_changed_count = 0;
+
+ for( S32 i = 0; i < num_params; i++ )
+ {
+ LLVisualParam* param = contents.mParams[i];
+ F32 newWeight = contents.mParamWeights[i];
+
+ if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight))
+ {
+ params_changed = TRUE;
+ params_changed_count++;
+
+ if(is_first_appearance_message || slam_params)
+ {
+ //LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL;
+ param->setWeight(newWeight);
+ }
+ else
+ {
+ interp_params = TRUE;
+ param->setAnimationTarget(newWeight);
+ }
+ }
+ }
+ const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE) +
+ getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TRANSMIT_NOT_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ if (num_params != expected_tweakable_count)
+ {
+ LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << LL_ENDL;
+ }
+
+ LL_DEBUGS("Avatar") << "Changed " << params_changed_count << " params" << LL_ENDL;
+ if (params_changed)
+ {
+ if (interp_params)
+ {
+ startAppearanceAnimation();
+ }
+ updateVisualParams();
+
+ ESex new_sex = getSex();
+ if( old_sex != new_sex )
+ {
+ updateSexDependentLayerSets();
+ }
+ }
+
+ llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) );
+ }
+ else
+ {
+ // AvatarAppearance message arrived without visual params
+ LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;
+
+ const F32 LOADING_TIMEOUT_SECONDS = 60.f;
+ // this isn't really a problem if we already have a non-default shape
+ if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS)
+ {
+ // re-request appearance, hoping that it comes back with a shape next time
+ LL_INFOS() << "Re-requesting AvatarAppearance for object: " << getID() << LL_ENDL;
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
+ mRuthTimer.reset();
+ }
+ else
+ {
+ LL_INFOS() << "That's okay, we already have a non-default shape for object: " << getID() << LL_ENDL;
+ // we don't really care.
+ }
+ }
+
+ if (contents.mHoverOffsetWasSet && !isSelf())
+ {
+ // Got an update for some other avatar
+ // Ignore updates for self, because we have a more authoritative value in the preferences.
+ setHoverOffset(contents.mHoverOffset);
+ LL_DEBUGS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL;
+ }
+
+ if (!contents.mHoverOffsetWasSet && !isSelf())
+ {
+ // If we don't get a value at all, we are presumably in a
+ // region that does not support hover height.
+ LL_WARNS() << avString() << "zeroing hover because not defined in appearance message" << LL_ENDL;
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+ }
+
+ setCompositeUpdatesEnabled( TRUE );
+
+ // If all of the avatars are completely baked, release the global image caches to conserve memory.
+ LLVOAvatar::cullAvatarsByPixelArea();
+
+ if (isSelf())
+ {
+ mUseLocalAppearance = false;
+ }
+
+ updateMeshTextures();
+ updateMeshVisibility();
}
LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)
{
- if (te < 0 || te >= BAKED_NUM_INDICES)
- {
- return NULL;
- }
-
- BOOL is_layer_baked = isTextureDefined(mBakedTextureDatas[te].mTextureIndex);
-
- LLViewerTexLayerSet* layerset = NULL;
- layerset = getTexLayerSet(te);
+ if (te < 0 || te >= BAKED_NUM_INDICES)
+ {
+ return NULL;
+ }
+ BOOL is_layer_baked = isTextureDefined(mBakedTextureDatas[te].mTextureIndex);
+
+ LLViewerTexLayerSet* layerset = NULL;
+ layerset = getTexLayerSet(te);
+
- if (!isEditingAppearance() && is_layer_baked)
- {
- LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage(mBakedTextureDatas[te].mTextureIndex, 0), TRUE);
- return baked_img;
- }
- else if (layerset && isEditingAppearance())
- {
- layerset->createComposite();
- layerset->setUpdatesEnabled(TRUE);
+ if (!isEditingAppearance() && is_layer_baked)
+ {
+ LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage(mBakedTextureDatas[te].mTextureIndex, 0), TRUE);
+ return baked_img;
+ }
+ else if (layerset && isEditingAppearance())
+ {
+ layerset->createComposite();
+ layerset->setUpdatesEnabled(TRUE);
- return layerset->getViewerComposite();
- }
-
- return NULL;
+ return layerset->getViewerComposite();
+ }
+ return NULL;
+
}
const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin)
@@ -9744,262 +9741,262 @@ const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(co
// static
void LLVOAvatar::getAnimLabels( std::vector<std::string>* labels )
{
- S32 i;
- labels->reserve(gUserAnimStatesCount);
- for( i = 0; i < gUserAnimStatesCount; i++ )
- {
- labels->push_back( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) );
- }
+ S32 i;
+ labels->reserve(gUserAnimStatesCount);
+ for( i = 0; i < gUserAnimStatesCount; i++ )
+ {
+ labels->push_back( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) );
+ }
- // Special case to trigger away (AFK) state
- labels->push_back( "Away From Keyboard" );
+ // Special case to trigger away (AFK) state
+ labels->push_back( "Away From Keyboard" );
}
-// static
+// static
void LLVOAvatar::getAnimNames( std::vector<std::string>* names )
{
- S32 i;
+ S32 i;
- names->reserve(gUserAnimStatesCount);
- for( i = 0; i < gUserAnimStatesCount; i++ )
- {
- names->push_back( std::string(gUserAnimStates[i].mName) );
- }
+ names->reserve(gUserAnimStatesCount);
+ for( i = 0; i < gUserAnimStatesCount; i++ )
+ {
+ names->push_back( std::string(gUserAnimStates[i].mName) );
+ }
- // Special case to trigger away (AFK) state
- names->push_back( "enter_away_from_keyboard_state" );
+ // Special case to trigger away (AFK) state
+ names->push_back( "enter_away_from_keyboard_state" );
}
// static
void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
- if (!userdata) return;
-
- //LL_INFOS() << "onBakedTextureMasksLoaded: " << src_vi->getID() << LL_ENDL;
- const LLUUID id = src_vi->getID();
-
- LLTextureMaskData* maskData = (LLTextureMaskData*) userdata;
- LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID );
-
- // if discard level is 2 less than last discard level we processed, or we hit 0,
- // then generate morph masks
- if(self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0))
- {
- if(aux_src && aux_src->getComponents() == 1)
- {
- if (!aux_src->getData())
- {
- LL_ERRS() << "No auxiliary source (morph mask) data for image id " << id << LL_ENDL;
- return;
- }
-
- U32 gl_name;
- LLImageGL::generateTextures(1, &gl_name );
- stop_glerror();
-
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
- stop_glerror();
-
- LLImageGL::setManualImage(
- GL_TEXTURE_2D, 0, GL_ALPHA8,
- aux_src->getWidth(), aux_src->getHeight(),
- GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData());
- stop_glerror();
-
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-
- /* if( id == head_baked->getID() )
- if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
- //LL_INFOS() << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << LL_ENDL;
- self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
- maskData->mLastDiscardLevel = discard_level; */
- BOOL found_texture_id = false;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++iter)
- {
-
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const ETextureIndex texture_index = iter->first;
- const LLViewerTexture *baked_img = self->getImage(texture_index, 0);
- if (baked_img && id == baked_img->getID())
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index);
- maskData->mLastDiscardLevel = discard_level;
- if (self->mBakedTextureDatas[baked_index].mMaskTexName)
- {
- LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
- }
- self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
- found_texture_id = true;
- break;
- }
- }
- }
- if (!found_texture_id)
- {
- LL_INFOS() << "unexpected image id: " << id << LL_ENDL;
- }
- self->dirtyMesh();
- }
- else
- {
- // this can happen when someone uses an old baked texture possibly provided by
+ if (!userdata) return;
+
+ //LL_INFOS() << "onBakedTextureMasksLoaded: " << src_vi->getID() << LL_ENDL;
+ const LLUUID id = src_vi->getID();
+
+ LLTextureMaskData* maskData = (LLTextureMaskData*) userdata;
+ LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID );
+
+ // if discard level is 2 less than last discard level we processed, or we hit 0,
+ // then generate morph masks
+ if(self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0))
+ {
+ if(aux_src && aux_src->getComponents() == 1)
+ {
+ if (!aux_src->getData())
+ {
+ LL_ERRS() << "No auxiliary source (morph mask) data for image id " << id << LL_ENDL;
+ return;
+ }
+
+ U32 gl_name;
+ LLImageGL::generateTextures(1, &gl_name );
+ stop_glerror();
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
+ stop_glerror();
+
+ LLImageGL::setManualImage(
+ GL_TEXTURE_2D, 0, GL_ALPHA8,
+ aux_src->getWidth(), aux_src->getHeight(),
+ GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData());
+ stop_glerror();
+
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+
+ /* if( id == head_baked->getID() )
+ if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
+ //LL_INFOS() << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << LL_ENDL;
+ self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
+ maskData->mLastDiscardLevel = discard_level; */
+ BOOL found_texture_id = false;
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
+ ++iter)
+ {
+
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const ETextureIndex texture_index = iter->first;
+ const LLViewerTexture *baked_img = self->getImage(texture_index, 0);
+ if (baked_img && id == baked_img->getID())
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index);
+ maskData->mLastDiscardLevel = discard_level;
+ if (self->mBakedTextureDatas[baked_index].mMaskTexName)
+ {
+ LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
+ }
+ self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
+ found_texture_id = true;
+ break;
+ }
+ }
+ }
+ if (!found_texture_id)
+ {
+ LL_INFOS() << "unexpected image id: " << id << LL_ENDL;
+ }
+ self->dirtyMesh();
+ }
+ else
+ {
+ // this can happen when someone uses an old baked texture possibly provided by
// viewer-side baked texture caching
- LL_WARNS() << "Masks loaded callback but NO aux source, id " << id << LL_ENDL;
- }
- }
+ LL_WARNS() << "Masks loaded callback but NO aux source, id " << id << LL_ENDL;
+ }
+ }
- if (final || !success)
- {
- delete maskData;
- }
+ if (final || !success)
+ {
+ delete maskData;
+ }
}
// static
void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
- LLUUID *avatar_idp = (LLUUID *)userdata;
- LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
+ LLUUID *avatar_idp = (LLUUID *)userdata;
+ LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
- if (selfp)
- {
- //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
- }
+ if (selfp)
+ {
+ //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
+ }
- if (!success && selfp)
- {
- selfp->removeMissingBakedTextures();
- }
- if (final || !success )
- {
- delete avatar_idp;
- }
+ if (!success && selfp)
+ {
+ selfp->removeMissingBakedTextures();
+ }
+ if (final || !success )
+ {
+ delete avatar_idp;
+ }
}
// Static
void LLVOAvatar::onBakedTextureLoaded(BOOL success,
- LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
- S32 discard_level, BOOL final, void* userdata)
+ LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
+ S32 discard_level, BOOL final, void* userdata)
{
- //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
+ //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
- LLUUID id = src_vi->getID();
- LLUUID *avatar_idp = (LLUUID *)userdata;
- LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
- if (selfp)
- {
- //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL;
- }
+ LLUUID id = src_vi->getID();
+ LLUUID *avatar_idp = (LLUUID *)userdata;
+ LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
+ if (selfp)
+ {
+ //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL;
+ }
- if (selfp && !success)
- {
- selfp->removeMissingBakedTextures();
- }
+ if (selfp && !success)
+ {
+ selfp->removeMissingBakedTextures();
+ }
- if( final || !success )
- {
- delete avatar_idp;
- }
+ if( final || !success )
+ {
+ delete avatar_idp;
+ }
- if( selfp && success && final )
- {
- selfp->useBakedTexture( id );
- }
+ if( selfp && success && final )
+ {
+ selfp->useBakedTexture( id );
+ }
}
// Called when baked texture is loaded and also when we start up with a baked texture
void LLVOAvatar::useBakedTexture( const LLUUID& id )
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
- if (id == image_baked->getID())
- {
- //LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;
- mBakedTextureDatas[i].mIsLoaded = true;
- mBakedTextureDatas[i].mLastTextureID = id;
- mBakedTextureDatas[i].mIsUsed = true;
-
- if (isUsingLocalAppearance())
- {
- LL_INFOS() << "not changing to baked texture while isUsingLocalAppearance" << LL_ENDL;
- }
- else
- {
- debugColorizeSubMeshes(i,LLColor4::green);
-
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setTexture( image_baked );
- }
- }
- }
-
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
- LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i);
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- if (isSelf()) setBakedReady(*local_tex_iter, TRUE);
- }
-
- // ! BACKWARDS COMPATIBILITY !
- // Workaround for viewing avatars from old viewers that haven't baked hair textures.
- // This is paired with similar code in updateMeshTextures that sets hair mesh color.
- if (i == BAKED_HAIR)
- {
- avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
- avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
- for (; iter != end; ++iter)
- {
- LLAvatarJointMesh* mesh = (*iter);
- if (mesh)
- {
- mesh->setColor( LLColor4::white );
- }
- }
- }
- }
- }
-
- dirtyMesh();
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
+ if (id == image_baked->getID())
+ {
+ //LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;
+ mBakedTextureDatas[i].mIsLoaded = true;
+ mBakedTextureDatas[i].mLastTextureID = id;
+ mBakedTextureDatas[i].mIsUsed = true;
+
+ if (isUsingLocalAppearance())
+ {
+ LL_INFOS() << "not changing to baked texture while isUsingLocalAppearance" << LL_ENDL;
+ }
+ else
+ {
+ debugColorizeSubMeshes(i,LLColor4::green);
+
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setTexture( image_baked );
+ }
+ }
+ }
+
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
+ LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i);
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ if (isSelf()) setBakedReady(*local_tex_iter, TRUE);
+ }
+
+ // ! BACKWARDS COMPATIBILITY !
+ // Workaround for viewing avatars from old viewers that haven't baked hair textures.
+ // This is paired with similar code in updateMeshTextures that sets hair mesh color.
+ if (i == BAKED_HAIR)
+ {
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setColor( LLColor4::white );
+ }
+ }
+ }
+ }
+ }
+
+ dirtyMesh();
}
std::string get_sequential_numbered_file_name(const std::string& prefix,
- const std::string& suffix)
-{
- typedef std::map<std::string,S32> file_num_type;
- static file_num_type file_nums;
- file_num_type::iterator it = file_nums.find(prefix);
- S32 num = 0;
- if (it != file_nums.end())
- {
- num = it->second;
- }
- file_nums[prefix] = num+1;
- std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml";
- std::replace(outfilename.begin(),outfilename.end(),' ','_');
- return outfilename;
+ const std::string& suffix)
+{
+ typedef std::map<std::string,S32> file_num_type;
+ static file_num_type file_nums;
+ file_num_type::iterator it = file_nums.find(prefix);
+ S32 num = 0;
+ if (it != file_nums.end())
+ {
+ num = it->second;
+ }
+ file_nums[prefix] = num+1;
+ std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml";
+ std::replace(outfilename.begin(),outfilename.end(),' ','_');
+ return outfilename;
}
void dump_sequential_xml(const std::string outprefix, const LLSD& content)
{
- std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
- std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
- llofstream ofs(fullpath.c_str(), std::ios_base::out);
- ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY);
- LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
+ std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ llofstream ofs(fullpath.c_str(), std::ios_base::out);
+ ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY);
+ LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
}
void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const
@@ -10009,9 +10006,9 @@ void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& r
{
avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
avatar_joint_list_t::const_iterator end = mSkeleton.end();
- for (; iter != end; ++iter)
- {
- LLJoint* pJoint = (*iter);
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
result.push_back(pJoint->getName());
}
}
@@ -10025,11 +10022,11 @@ void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& r
}
else if (joint_type==2)
{
- for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); ++iter)
- {
- LLViewerJointAttachment* pJoint = iter->second;
- if (!pJoint) continue;
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* pJoint = iter->second;
+ if (!pJoint) continue;
result.push_back(pJoint->getName());
}
}
@@ -10038,96 +10035,96 @@ void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& r
void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )
{
- std::string outprefix(prefix);
- if (outprefix.empty())
- {
- outprefix = getFullname() + (isSelf()?"_s":"_o");
- }
- if (outprefix.empty())
- {
- outprefix = std::string("new_archetype");
- }
- std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
-
- LLAPRFile outfile;
+ std::string outprefix(prefix);
+ if (outprefix.empty())
+ {
+ outprefix = getFullname() + (isSelf()?"_s":"_o");
+ }
+ if (outprefix.empty())
+ {
+ outprefix = std::string("new_archetype");
+ }
+ std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+
+ LLAPRFile outfile;
LLWearableType *wr_inst = LLWearableType::getInstance();
- std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
- if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB ))
- {
- apr_file_t* file = outfile.getFileHandle();
- LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL;
-
- apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
- apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
- apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
-
- bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery();
-
- if (group_by_wearables)
- {
- for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
- {
- const std::string& wearable_name = wr_inst->getTypeName((LLWearableType::EType)type);
- apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
-
- for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
- {
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- if( (viewer_param->getWearableType() == type) &&
- (viewer_param->isTweakable() ) )
- {
- dump_visual_param(file, viewer_param, viewer_param->getWeight());
- }
- }
-
- for (U8 te = 0; te < TEX_NUM_INDICES; te++)
- {
- if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type)
- {
- // MULTIPLE_WEARABLES: extend to multiple wearables?
- LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
- if( te_image )
- {
- std::string uuid_str = LLUUID().asString();
- if (agent_is_godlike)
- {
- te_image->getID().toString(uuid_str);
- }
- apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
- }
- }
- }
- }
- }
- else
- {
- // Just dump all params sequentially.
- for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
- {
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- dump_visual_param(file, viewer_param, viewer_param->getWeight());
- }
-
- for (U8 te = 0; te < TEX_NUM_INDICES; te++)
- {
- // MULTIPLE_WEARABLES: extend to multiple wearables?
- LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
- if( te_image )
- {
- std::string uuid_str = LLUUID().asString();
- if (agent_is_godlike)
- {
- te_image->getID().toString(uuid_str);
- }
- apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
- }
- }
- }
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB ))
+ {
+ apr_file_t* file = outfile.getFileHandle();
+ LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL;
+
+ apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
+ apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
+ apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
+
+ bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery();
+
+ if (group_by_wearables)
+ {
+ for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
+ {
+ const std::string& wearable_name = wr_inst->getTypeName((LLWearableType::EType)type);
+ apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
+
+ for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
+ {
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ if( (viewer_param->getWearableType() == type) &&
+ (viewer_param->isTweakable() ) )
+ {
+ dump_visual_param(file, viewer_param, viewer_param->getWeight());
+ }
+ }
+
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
+ {
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type)
+ {
+ // MULTIPLE_WEARABLES: extend to multiple wearables?
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+ if( te_image )
+ {
+ std::string uuid_str = LLUUID().asString();
+ if (agent_is_godlike)
+ {
+ te_image->getID().toString(uuid_str);
+ }
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Just dump all params sequentially.
+ for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
+ {
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ dump_visual_param(file, viewer_param, viewer_param->getWeight());
+ }
+
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
+ {
+ // MULTIPLE_WEARABLES: extend to multiple wearables?
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+ if( te_image )
+ {
+ std::string uuid_str = LLUUID().asString();
+ if (agent_is_godlike)
+ {
+ te_image->getID().toString(uuid_str);
+ }
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ }
+ }
+ }
// Root joint
const LLVector3& pos = mRoot->getPosition();
const LLVector3& scale = mRoot->getScale();
- apr_file_printf( file, "\t\t<root name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ apr_file_printf( file, "\t\t<root name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
mRoot->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
// Bones
@@ -10143,10 +10140,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
name_iter != bone_names.end(); ++name_iter)
{
LLJoint *pJoint = getJoint(*name_iter);
- const LLVector3& pos = pJoint->getPosition();
- const LLVector3& scale = pJoint->getScale();
- apr_file_printf( file, "\t\t<bone name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
- pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<bone name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
}
// Collision volumes
@@ -10154,10 +10151,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
name_iter != cv_names.end(); ++name_iter)
{
LLJoint *pJoint = getJoint(*name_iter);
- const LLVector3& pos = pJoint->getPosition();
- const LLVector3& scale = pJoint->getScale();
- apr_file_printf( file, "\t\t<collision_volume name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
- pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<collision_volume name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
}
// Attachment joints
@@ -10165,63 +10162,63 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
name_iter != attach_names.end(); ++name_iter)
{
LLJoint *pJoint = getJoint(*name_iter);
- if (!pJoint) continue;
- const LLVector3& pos = pJoint->getPosition();
- const LLVector3& scale = pJoint->getScale();
- apr_file_printf( file, "\t\t<attachment_point name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
- pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ if (!pJoint) continue;
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<attachment_point name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
}
-
+
// Joint pos overrides
for (std::vector<std::string>::iterator name_iter = all_names.begin();
name_iter != all_names.end(); ++name_iter)
{
LLJoint *pJoint = getJoint(*name_iter);
+
+ LLVector3 pos;
+ LLUUID mesh_id;
- LLVector3 pos;
- LLUUID mesh_id;
-
- if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
- {
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
S32 num_pos_overrides;
std::set<LLVector3> distinct_pos_overrides;
pJoint->getAllAttachmentPosOverrides(num_pos_overrides, distinct_pos_overrides);
- apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
- pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(),
+ apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(),
num_pos_overrides, (S32) distinct_pos_overrides.size());
- }
- }
+ }
+ }
// Joint scale overrides
for (std::vector<std::string>::iterator name_iter = all_names.begin();
name_iter != all_names.end(); ++name_iter)
{
LLJoint *pJoint = getJoint(*name_iter);
+
+ LLVector3 scale;
+ LLUUID mesh_id;
- LLVector3 scale;
- LLUUID mesh_id;
-
- if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
- {
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
+ {
S32 num_scale_overrides;
std::set<LLVector3> distinct_scale_overrides;
pJoint->getAllAttachmentPosOverrides(num_scale_overrides, distinct_scale_overrides);
- apr_file_printf( file, "\t\t<joint_scale name=\"%s\" scale=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
- pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(),
+ apr_file_printf( file, "\t\t<joint_scale name=\"%s\" scale=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
+ pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(),
num_scale_overrides, (S32) distinct_scale_overrides.size());
- }
- }
- F32 pelvis_fixup;
- LLUUID mesh_id;
- if (hasPelvisFixup(pelvis_fixup, mesh_id))
- {
- apr_file_printf( file, "\t\t<pelvis_fixup z=\"%f\" mesh_id=\"%s\"/>\n",
- pelvis_fixup, mesh_id.asString().c_str());
- }
+ }
+ }
+ F32 pelvis_fixup;
+ LLUUID mesh_id;
+ if (hasPelvisFixup(pelvis_fixup, mesh_id))
+ {
+ apr_file_printf( file, "\t\t<pelvis_fixup z=\"%f\" mesh_id=\"%s\"/>\n",
+ pelvis_fixup, mesh_id.asString().c_str());
+ }
LLVector3 rp = getRootJoint()->getWorldPosition();
LLVector4a rpv;
rpv.load3(rp.mV);
-
+
for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
{
LLJoint *joint = getJoint(joint_num);
@@ -10237,7 +10234,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
LLVector4a rrp[2];
rrp[0].setSub(new_extents[0],rpv);
rrp[1].setSub(new_extents[1],rpv);
- apr_file_printf( file, "\t\t<joint_rig_info num=\"%d\" name=\"%s\" min=\"%f %f %f\" max=\"%f %f %f\" tmin=\"%f %f %f\" tmax=\"%f %f %f\"/>\n",
+ apr_file_printf( file, "\t\t<joint_rig_info num=\"%d\" name=\"%s\" min=\"%f %f %f\" max=\"%f %f %f\" tmin=\"%f %f %f\" tmax=\"%f %f %f\"/>\n",
joint_num,
joint->getName().c_str(),
rig_info.getRiggedExtents()[0][0],
@@ -10256,134 +10253,134 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
}
}
- bool ultra_verbose = false;
- if (isSelf() && ultra_verbose)
- {
- // show the cloned params inside the wearables as well.
- gAgentAvatarp->dumpWearableInfo(outfile);
- }
+ bool ultra_verbose = false;
+ if (isSelf() && ultra_verbose)
+ {
+ // show the cloned params inside the wearables as well.
+ gAgentAvatarp->dumpWearableInfo(outfile);
+ }
- apr_file_printf( file, "\t</archetype>\n" );
- apr_file_printf( file, "\n</linden_genepool>\n" );
+ apr_file_printf( file, "\t</archetype>\n" );
+ apr_file_printf( file, "\n</linden_genepool>\n" );
- LLSD args;
- args["PATH"] = fullpath;
- LLNotificationsUtil::add("AppearanceToXMLSaved", args);
- }
- else
- {
- LLNotificationsUtil::add("AppearanceToXMLFailed");
- }
- // File will close when handle goes out of scope
+ LLSD args;
+ args["PATH"] = fullpath;
+ LLNotificationsUtil::add("AppearanceToXMLSaved", args);
+ }
+ else
+ {
+ LLNotificationsUtil::add("AppearanceToXMLFailed");
+ }
+ // File will close when handle goes out of scope
}
void LLVOAvatar::setVisibilityRank(U32 rank)
{
- if (mDrawable.isNull() || mDrawable->isDead())
- {
- // do nothing
- return;
- }
- mVisibilityRank = rank;
+ if (mDrawable.isNull() || mDrawable->isDead())
+ {
+ // do nothing
+ return;
+ }
+ mVisibilityRank = rank;
}
// Assumes LLVOAvatar::sInstances has already been sorted.
S32 LLVOAvatar::getUnbakedPixelAreaRank()
{
- S32 rank = 1;
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- if (inst == this)
- {
- return rank;
- }
- else if (!inst->isDead() && !inst->isFullyBaked())
- {
- rank++;
- }
- }
-
- llassert(0);
- return 0;
+ S32 rank = 1;
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if (inst == this)
+ {
+ return rank;
+ }
+ else if (!inst->isDead() && !inst->isFullyBaked())
+ {
+ rank++;
+ }
+ }
+
+ llassert(0);
+ return 0;
}
struct CompareScreenAreaGreater
{
- BOOL operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs)
- {
- return lhs->getPixelArea() > rhs->getPixelArea();
- }
+ BOOL operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs)
+ {
+ return lhs->getPixelArea() > rhs->getPixelArea();
+ }
};
// static
void LLVOAvatar::cullAvatarsByPixelArea()
{
- std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
-
- // Update the avatars that have changed status
- U32 rank = 2; //1 is reserved for self.
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- BOOL culled;
- if (inst->isSelf() || inst->isFullyBaked())
- {
- culled = FALSE;
- }
- else
- {
- culled = TRUE;
- }
-
- if (inst->mCulled != culled)
- {
- inst->mCulled = culled;
- LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL;
- inst->updateMeshTextures();
- }
-
- if (inst->isSelf())
- {
- inst->setVisibilityRank(1);
- }
- else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible())
- {
- inst->setVisibilityRank(rank++);
- }
- }
-
- // runway - this doesn't really detect gray/grey state.
- S32 grey_avatars = 0;
- if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
- {
- if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
- {
- sUnbakedUpdateTime = gFrameTimeSeconds;
- sUnbakedTime += gFrameIntervalSeconds.value();
- }
- if (grey_avatars > 0)
- {
- if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame
- {
- sGreyUpdateTime = gFrameTimeSeconds;
- sGreyTime += gFrameIntervalSeconds.value();
- }
- }
- }
+ std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
+
+ // Update the avatars that have changed status
+ U32 rank = 2; //1 is reserved for self.
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ BOOL culled;
+ if (inst->isSelf() || inst->isFullyBaked())
+ {
+ culled = FALSE;
+ }
+ else
+ {
+ culled = TRUE;
+ }
+
+ if (inst->mCulled != culled)
+ {
+ inst->mCulled = culled;
+ LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL;
+ inst->updateMeshTextures();
+ }
+
+ if (inst->isSelf())
+ {
+ inst->setVisibilityRank(1);
+ }
+ else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible())
+ {
+ inst->setVisibilityRank(rank++);
+ }
+ }
+
+ // runway - this doesn't really detect gray/grey state.
+ S32 grey_avatars = 0;
+ if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
+ {
+ if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
+ {
+ sUnbakedUpdateTime = gFrameTimeSeconds;
+ sUnbakedTime += gFrameIntervalSeconds.value();
+ }
+ if (grey_avatars > 0)
+ {
+ if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame
+ {
+ sGreyUpdateTime = gFrameTimeSeconds;
+ sGreyTime += gFrameIntervalSeconds.value();
+ }
+ }
+ }
}
void LLVOAvatar::startAppearanceAnimation()
{
- if(!mAppearanceAnimating)
- {
- mAppearanceAnimating = TRUE;
- mAppearanceMorphTimer.reset();
- mLastAppearanceBlendTime = 0.f;
- }
+ if(!mAppearanceAnimating)
+ {
+ mAppearanceAnimating = TRUE;
+ mAppearanceMorphTimer.reset();
+ mLastAppearanceBlendTime = 0.f;
+ }
}
// virtual
@@ -10394,35 +10391,35 @@ void LLVOAvatar::removeMissingBakedTextures()
//virtual
void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
{
- LLViewerObject::updateRegion(regionp);
+ LLViewerObject::updateRegion(regionp);
}
// virtual
std::string LLVOAvatar::getFullname() const
{
- std::string name;
+ std::string name;
- LLNameValue* first = getNVPair("FirstName");
- LLNameValue* last = getNVPair("LastName");
- if (first && last)
- {
- name = LLCacheName::buildFullName( first->getString(), last->getString() );
- }
+ LLNameValue* first = getNVPair("FirstName");
+ LLNameValue* last = getNVPair("LastName");
+ if (first && last)
+ {
+ name = LLCacheName::buildFullName( first->getString(), last->getString() );
+ }
- return name;
+ return name;
}
LLHost LLVOAvatar::getObjectHost() const
{
- LLViewerRegion* region = getRegion();
- if (region && !isDead())
- {
- return region->getHost();
- }
- else
- {
- return LLHost();
- }
+ LLViewerRegion* region = getRegion();
+ if (region && !isDead())
+ {
+ return region->getHost();
+ }
+ else
+ {
+ return LLHost();
+ }
}
BOOL LLVOAvatar::updateLOD()
@@ -10431,36 +10428,36 @@ BOOL LLVOAvatar::updateLOD()
{
return FALSE;
}
+
+ if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
+ {
+ return TRUE;
+ }
- if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
- {
- return TRUE;
- }
-
- BOOL res = updateJointLODs();
+ BOOL res = updateJointLODs();
- LLFace* facep = mDrawable->getFace(0);
- if (!facep || !facep->getVertexBuffer())
- {
- dirtyMesh(2);
- }
+ LLFace* facep = mDrawable->getFace(0);
+ if (!facep || !facep->getVertexBuffer())
+ {
+ dirtyMesh(2);
+ }
- if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
- { //LOD changed or new mesh created, allocate new vertex buffer if needed
- updateMeshData();
- mDirtyMesh = 0;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
- }
- updateVisibility();
+ if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ { //LOD changed or new mesh created, allocate new vertex buffer if needed
+ updateMeshData();
+ mDirtyMesh = 0;
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
+ updateVisibility();
- return res;
+ return res;
}
void LLVOAvatar::updateLODRiggedAttachments()
{
- updateLOD();
- rebuildRiggedAttachments();
+ updateLOD();
+ rebuildRiggedAttachments();
}
void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& count_rigged, S32& count_box)
@@ -10474,7 +10471,7 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32&
{
count_rigged++;
LLJoint *joint = avatar->getJoint(i);
- LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box "
+ LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box "
<< tab[i].getRiggedExtents()[0] << ", " << tab[i].getRiggedExtents()[1] << LL_ENDL;
if ((!tab[i].getRiggedExtents()[0].equals3(zero_vec)) ||
(!tab[i].getRiggedExtents()[1].equals3(zero_vec)))
@@ -10488,15 +10485,15 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32&
void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
- {
- LLViewerJointAttachment* attachment = iter->second;
- LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end();
-
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin();
- attach_iter != attach_end; ++attach_iter)
- {
- LLViewerObject* attached_object = attach_iter->get();
+ for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter )
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end();
+
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin();
+ attach_iter != attach_end; ++attach_iter)
+ {
+ LLViewerObject* attached_object = attach_iter->get();
LLVOVolume *volume = dynamic_cast<LLVOVolume*>(attached_object);
if (volume)
{
@@ -10554,31 +10551,31 @@ void LLVOAvatar::updateRiggingInfo()
std::vector<LLVOVolume*> volumes;
- getAssociatedVolumes(volumes);
-
- std::map<LLUUID,S32> curr_rigging_info_key;
- {
- // Get current rigging info key
- for (std::vector<LLVOVolume*>::iterator it = volumes.begin(); it != volumes.end(); ++it)
- {
- LLVOVolume *vol = *it;
- if (vol->isMesh() && vol->getVolume())
- {
- const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID();
- S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD);
- curr_rigging_info_key[mesh_id] = max_lod;
- }
- }
-
- // Check for key change, which indicates some change in volume composition or LOD.
- if (curr_rigging_info_key == mLastRiggingInfoKey)
- {
- return;
- }
- }
-
- // Something changed. Update.
- mLastRiggingInfoKey = curr_rigging_info_key;
+ getAssociatedVolumes(volumes);
+
+ std::map<LLUUID,S32> curr_rigging_info_key;
+ {
+ // Get current rigging info key
+ for (std::vector<LLVOVolume*>::iterator it = volumes.begin(); it != volumes.end(); ++it)
+ {
+ LLVOVolume *vol = *it;
+ if (vol->isMesh() && vol->getVolume())
+ {
+ const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID();
+ S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD);
+ curr_rigging_info_key[mesh_id] = max_lod;
+ }
+ }
+
+ // Check for key change, which indicates some change in volume composition or LOD.
+ if (curr_rigging_info_key == mLastRiggingInfoKey)
+ {
+ return;
+ }
+ }
+
+ // Something changed. Update.
+ mLastRiggingInfoKey = curr_rigging_info_key;
mJointRiggingInfoTab.clear();
for (std::vector<LLVOVolume*>::iterator it = volumes.begin(); it != volumes.end(); ++it)
{
@@ -10601,112 +10598,112 @@ void LLVOAvatar::onActiveOverrideMeshesChanged()
}
U32 LLVOAvatar::getPartitionType() const
-{
- // Avatars merely exist as drawables in the bridge partition
- return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR;
+{
+ // Avatars merely exist as drawables in the bridge partition
+ return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR;
}
//static
void LLVOAvatar::updateImpostors()
{
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
std::vector<LLCharacter*> instances_copy = LLCharacter::sInstances;
- for (std::vector<LLCharacter*>::iterator iter = instances_copy.begin();
- iter != instances_copy.end(); ++iter)
- {
- LLVOAvatar* avatar = (LLVOAvatar*) *iter;
- if (!avatar->isDead()
- && avatar->isVisible()
- && avatar->isImpostor()
- && avatar->needsImpostorUpdate())
- {
+ for (std::vector<LLCharacter*>::iterator iter = instances_copy.begin();
+ iter != instances_copy.end(); ++iter)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*) *iter;
+ if (!avatar->isDead()
+ && avatar->isVisible()
+ && avatar->isImpostor()
+ && avatar->needsImpostorUpdate())
+ {
avatar->calcMutedAVColor();
- gPipeline.generateImpostor(avatar);
- }
- }
+ gPipeline.generateImpostor(avatar);
+ }
+ }
- LLCharacter::sAllowInstancesChange = TRUE;
+ LLCharacter::sAllowInstancesChange = TRUE;
}
// virtual
BOOL LLVOAvatar::isImpostor()
{
- return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
+ return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
}
BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
{
- if (isSelf())
- {
- return false;
- }
- if (isVisuallyMuted())
- {
- return true;
- }
- return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
+ if (isSelf())
+ {
+ return false;
+ }
+ if (isVisuallyMuted())
+ {
+ return true;
+ }
+ return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
}
BOOL LLVOAvatar::needsImpostorUpdate() const
{
- return mNeedsImpostorUpdate;
+ return mNeedsImpostorUpdate;
}
const LLVector3& LLVOAvatar::getImpostorOffset() const
{
- return mImpostorOffset;
+ return mImpostorOffset;
}
const LLVector2& LLVOAvatar::getImpostorDim() const
{
- return mImpostorDim;
+ return mImpostorDim;
}
void LLVOAvatar::setImpostorDim(const LLVector2& dim)
{
- mImpostorDim = dim;
+ mImpostorDim = dim;
}
void LLVOAvatar::cacheImpostorValues()
{
- getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance);
+ getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance);
}
void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const
{
- const LLVector4a* ext = mDrawable->getSpatialExtents();
- extents[0] = ext[0];
- extents[1] = ext[1];
+ const LLVector4a* ext = mDrawable->getSpatialExtents();
+ extents[0] = ext[0];
+ extents[1] = ext[1];
- LLVector3 at = LLViewerCamera::getInstance()->getOrigin()-(getRenderPosition()+mImpostorOffset);
- distance = at.normalize();
- F32 da = 1.f - (at*LLViewerCamera::getInstance()->getAtAxis());
- angle.mV[0] = LLViewerCamera::getInstance()->getYaw()*da;
- angle.mV[1] = LLViewerCamera::getInstance()->getPitch()*da;
- angle.mV[2] = da;
+ LLVector3 at = LLViewerCamera::getInstance()->getOrigin()-(getRenderPosition()+mImpostorOffset);
+ distance = at.normalize();
+ F32 da = 1.f - (at*LLViewerCamera::getInstance()->getAtAxis());
+ angle.mV[0] = LLViewerCamera::getInstance()->getYaw()*da;
+ angle.mV[1] = LLViewerCamera::getInstance()->getPitch()*da;
+ angle.mV[2] = da;
}
// static
const U32 LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
- * slider in panel_preferences_graphics1.xml */
+ * slider in panel_preferences_graphics1.xml */
// static
void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
{
- U32 oldmax = sMaxNonImpostors;
- bool oldflg = sLimitNonImpostors;
-
- if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue)
- {
- sMaxNonImpostors = 0;
- }
- else
- {
- sMaxNonImpostors = newMaxNonImpostorsValue;
- }
- // the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
- sLimitNonImpostors = (0 != sMaxNonImpostors);
+ U32 oldmax = sMaxNonImpostors;
+ bool oldflg = sLimitNonImpostors;
+
+ if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue)
+ {
+ sMaxNonImpostors = 0;
+ }
+ else
+ {
+ sMaxNonImpostors = newMaxNonImpostorsValue;
+ }
+ // the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
+ sLimitNonImpostors = (0 != sMaxNonImpostors);
if ( oldflg != sLimitNonImpostors )
{
LL_DEBUGS("AvatarRender")
@@ -10732,9 +10729,9 @@ void LLVOAvatar::idleUpdateRenderComplexity()
}
// Render Complexity
- calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed
+ calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed
- bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
+ bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
if (autotune && !isDead())
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
@@ -10767,7 +10764,7 @@ void LLVOAvatar::updateNearbyAvatarCount()
{
static LLFrameTimer agent_update_timer;
- if (agent_update_timer.getElapsedTimeF32() > 1.0f)
+ if (agent_update_timer.getElapsedTimeF32() > 1.0f)
{
S32 avs_nearby = 0;
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
@@ -10795,90 +10792,90 @@ void LLVOAvatar::updateNearbyAvatarCount()
void LLVOAvatar::idleUpdateDebugInfo()
{
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO))
- {
- std::string info_line;
- F32 red_level;
- F32 green_level;
- LLColor4 info_color;
- LLFontGL::StyleFlags info_style;
-
- if ( !mText )
- {
- initHudText();
- mText->setFadeDistance(20.0, 5.0); // limit clutter in large crowds
- }
- else
- {
- mText->clearString(); // clear debug text
- }
-
- /*
- * NOTE: the logic for whether or not each of the values below
- * controls muting MUST match that in the isVisuallyMuted and isTooComplex methods.
- */
-
- static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
- info_line = llformat("%d Complexity", mVisualComplexity);
-
- if (max_render_cost != 0) // zero means don't care, so don't bother coloring based on this
- {
- green_level = 1.f-llclamp(((F32) mVisualComplexity-(F32)max_render_cost)/(F32)max_render_cost, 0.f, 1.f);
- red_level = llmin((F32) mVisualComplexity/(F32)max_render_cost, 1.f);
- info_color.set(red_level, green_level, 0.0, 1.0);
- info_style = ( mVisualComplexity > max_render_cost
- ? LLFontGL::BOLD : LLFontGL::NORMAL );
- }
- else
- {
- info_color.set(LLColor4::grey);
- info_style = LLFontGL::NORMAL;
- }
- mText->addLine(info_line, info_color, info_style);
-
- // Visual rank
- info_line = llformat("%d rank", mVisibilityRank);
- // Use grey for imposters, white for normal rendering or no impostors
- info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white));
- info_style = LLFontGL::NORMAL;
- mText->addLine(info_line, info_color, info_style);
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO))
+ {
+ std::string info_line;
+ F32 red_level;
+ F32 green_level;
+ LLColor4 info_color;
+ LLFontGL::StyleFlags info_style;
+
+ if ( !mText )
+ {
+ initHudText();
+ mText->setFadeDistance(20.0, 5.0); // limit clutter in large crowds
+ }
+ else
+ {
+ mText->clearString(); // clear debug text
+ }
+
+ /*
+ * NOTE: the logic for whether or not each of the values below
+ * controls muting MUST match that in the isVisuallyMuted and isTooComplex methods.
+ */
+
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
+ info_line = llformat("%d Complexity", mVisualComplexity);
+
+ if (max_render_cost != 0) // zero means don't care, so don't bother coloring based on this
+ {
+ green_level = 1.f-llclamp(((F32) mVisualComplexity-(F32)max_render_cost)/(F32)max_render_cost, 0.f, 1.f);
+ red_level = llmin((F32) mVisualComplexity/(F32)max_render_cost, 1.f);
+ info_color.set(red_level, green_level, 0.0, 1.0);
+ info_style = ( mVisualComplexity > max_render_cost
+ ? LLFontGL::BOLD : LLFontGL::NORMAL );
+ }
+ else
+ {
+ info_color.set(LLColor4::grey);
+ info_style = LLFontGL::NORMAL;
+ }
+ mText->addLine(info_line, info_color, info_style);
+
+ // Visual rank
+ info_line = llformat("%d rank", mVisibilityRank);
+ // Use grey for imposters, white for normal rendering or no impostors
+ info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white));
+ info_style = LLFontGL::NORMAL;
+ mText->addLine(info_line, info_color, info_style);
// Triangle count
- mText->addLine(std::string("VisTris ") + LLStringOps::getReadableNumber(mAttachmentVisibleTriangleCount),
+ mText->addLine(std::string("VisTris ") + LLStringOps::getReadableNumber(mAttachmentVisibleTriangleCount),
info_color, info_style);
- mText->addLine(std::string("EstMaxTris ") + LLStringOps::getReadableNumber(mAttachmentEstTriangleCount),
+ mText->addLine(std::string("EstMaxTris ") + LLStringOps::getReadableNumber(mAttachmentEstTriangleCount),
info_color, info_style);
- // Attachment Surface Area
- static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f);
- info_line = llformat("%.0f m^2", mAttachmentSurfaceArea);
+ // Attachment Surface Area
+ static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f);
+ info_line = llformat("%.0f m^2", mAttachmentSurfaceArea);
- if (max_render_cost != 0 && max_attachment_area != 0) // zero means don't care, so don't bother coloring based on this
- {
- green_level = 1.f-llclamp((mAttachmentSurfaceArea-max_attachment_area)/max_attachment_area, 0.f, 1.f);
- red_level = llmin(mAttachmentSurfaceArea/max_attachment_area, 1.f);
- info_color.set(red_level, green_level, 0.0, 1.0);
- info_style = ( mAttachmentSurfaceArea > max_attachment_area
- ? LLFontGL::BOLD : LLFontGL::NORMAL );
+ if (max_render_cost != 0 && max_attachment_area != 0) // zero means don't care, so don't bother coloring based on this
+ {
+ green_level = 1.f-llclamp((mAttachmentSurfaceArea-max_attachment_area)/max_attachment_area, 0.f, 1.f);
+ red_level = llmin(mAttachmentSurfaceArea/max_attachment_area, 1.f);
+ info_color.set(red_level, green_level, 0.0, 1.0);
+ info_style = ( mAttachmentSurfaceArea > max_attachment_area
+ ? LLFontGL::BOLD : LLFontGL::NORMAL );
- }
- else
- {
- info_color.set(LLColor4::grey);
- info_style = LLFontGL::NORMAL;
- }
+ }
+ else
+ {
+ info_color.set(LLColor4::grey);
+ info_style = LLFontGL::NORMAL;
+ }
- mText->addLine(info_line, info_color, info_style);
+ mText->addLine(info_line, info_color, info_style);
- updateText(); // corrects position
- }
+ updateText(); // corrects position
+ }
}
void LLVOAvatar::updateVisualComplexity()
{
- LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL;
- // Set the cache time to in the past so it's updated ASAP
- mVisualComplexityStale = true;
+ LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL;
+ // Set the cache time to in the past so it's updated ASAP
+ mVisualComplexityStale = true;
}
@@ -11045,7 +11042,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
* the official viewer for consideration.
*****************************************************************/
if (mVisualComplexityStale)
- {
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
static const U32 COMPLEXITY_BODY_PART_COST = 200;
@@ -11056,18 +11053,18 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Diagnostic list of all textures on our avatar
static std::unordered_set<const LLViewerTexture*> all_textures;
- U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
- LLVOVolume::texture_cost_t textures;
- hud_complexity_list_t hud_complexity_list;
+ U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
+ LLVOVolume::texture_cost_t textures;
+ hud_complexity_list_t hud_complexity_list;
object_complexity_list_t object_complexity_list;
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
- = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
- ETextureIndex tex_index = baked_dict->mTextureIndex;
- if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
- {
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
+ = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
+ ETextureIndex tex_index = baked_dict->mTextureIndex;
+ if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
+ {
// Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars
if (isIndexLocalTexture(tex_index))
{
@@ -11085,14 +11082,14 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
cost += COMPLEXITY_BODY_PART_COST;
}
}
- }
- }
+ }
+ }
LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
mAttachmentVisibleTriangleCount = 0;
mAttachmentEstTriangleCount = 0.f;
mAttachmentSurfaceArea = 0.f;
-
+
// A standalone animated object needs to be accounted for
// using its associated volume. Attached animated objects
// will be covered by the subsequent loop over attachments.
@@ -11108,20 +11105,20 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
// Account for complexity of all attachments.
- for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin();
- attachment_point != mAttachmentPoints.end();
- ++attachment_point)
- {
- LLViewerJointAttachment* attachment = attachment_point->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
+ for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin();
+ attachment_point != mAttachmentPoints.end();
+ ++attachment_point)
+ {
+ LLViewerJointAttachment* attachment = attachment_point->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
LLViewerObject* attached_object = attachment_iter->get();
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
textures, cost, hud_complexity_list, object_complexity_list);
- }
- }
+ }
+ }
if ( cost != mVisualComplexity )
{
@@ -11137,8 +11134,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
<< " reported " << mReportedVisualComplexity
<< LL_ENDL;
}
- mVisualComplexity = cost;
- mVisualComplexityStale = false;
+ mVisualComplexity = cost;
+ mVisualComplexityStale = false;
static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
@@ -11152,7 +11149,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
//schedule an update to ART next frame if needed
- if (LLPerfStats::tunables.userAutoTuneEnabled &&
+ if (LLPerfStats::tunables.userAutoTuneEnabled &&
LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY &&
!isVisuallyMuted())
{
@@ -11172,7 +11169,7 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
{
mVisuallyMuteSetting = set;
mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 7;
+ mLastImpostorUpdateReason = 7;
LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
}
@@ -11180,51 +11177,51 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
void LLVOAvatar::setOverallAppearanceNormal()
{
- if (isControlAvatar())
- return;
+ if (isControlAvatar())
+ return;
LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
- resetSkeleton(false);
+ resetSkeleton(false);
getJoint("mPelvis")->setPosition(pelvis_pos);
- for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
- {
- bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
- LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
- if (!is_playing)
- {
- // Anim was not requested for this av by sim, but may be playing locally
- stopMotion(*it);
- }
- }
- mJellyAnims.clear();
+ for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
+ {
+ bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+ LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+ if (!is_playing)
+ {
+ // Anim was not requested for this av by sim, but may be playing locally
+ stopMotion(*it);
+ }
+ }
+ mJellyAnims.clear();
- processAnimationStateChanges();
+ processAnimationStateChanges();
}
void LLVOAvatar::setOverallAppearanceJellyDoll()
{
- if (isControlAvatar())
- return;
-
- // stop current animations
- {
- for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin();
- anim_it != mPlayingAnimations.end();
- ++anim_it)
- {
- {
- stopMotion(anim_it->first, TRUE);
- }
- }
- }
- processAnimationStateChanges();
-
- // Start any needed anims for jellydoll
- updateOverallAppearanceAnimations();
-
+ if (isControlAvatar())
+ return;
+
+ // stop current animations
+ {
+ for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin();
+ anim_it != mPlayingAnimations.end();
+ ++anim_it)
+ {
+ {
+ stopMotion(anim_it->first, TRUE);
+ }
+ }
+ }
+ processAnimationStateChanges();
+
+ // Start any needed anims for jellydoll
+ updateOverallAppearanceAnimations();
+
LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
- resetSkeleton(false);
+ resetSkeleton(false);
getJoint("mPelvis")->setPosition(pelvis_pos);
}
@@ -11235,114 +11232,114 @@ void LLVOAvatar::setOverallAppearanceInvisible()
void LLVOAvatar::updateOverallAppearance()
{
- AvatarOverallAppearance new_overall = getOverallAppearance();
- if (new_overall != mOverallAppearance)
- {
- switch (new_overall)
- {
- case AOA_NORMAL:
- setOverallAppearanceNormal();
- break;
- case AOA_JELLYDOLL:
- setOverallAppearanceJellyDoll();
- break;
- case AOA_INVISIBLE:
- setOverallAppearanceInvisible();
- break;
- }
- mOverallAppearance = new_overall;
- if (!isSelf())
- {
- mNeedsImpostorUpdate = TRUE;
- mLastImpostorUpdateReason = 8;
- }
- updateMeshVisibility();
- }
-
- // This needs to be done even if overall appearance has not
- // changed, since sit/stand status can be different.
- updateOverallAppearanceAnimations();
+ AvatarOverallAppearance new_overall = getOverallAppearance();
+ if (new_overall != mOverallAppearance)
+ {
+ switch (new_overall)
+ {
+ case AOA_NORMAL:
+ setOverallAppearanceNormal();
+ break;
+ case AOA_JELLYDOLL:
+ setOverallAppearanceJellyDoll();
+ break;
+ case AOA_INVISIBLE:
+ setOverallAppearanceInvisible();
+ break;
+ }
+ mOverallAppearance = new_overall;
+ if (!isSelf())
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 8;
+ }
+ updateMeshVisibility();
+ }
+
+ // This needs to be done even if overall appearance has not
+ // changed, since sit/stand status can be different.
+ updateOverallAppearanceAnimations();
}
void LLVOAvatar::updateOverallAppearanceAnimations()
{
- if (isControlAvatar())
- return;
-
- if (getOverallAppearance() == AOA_JELLYDOLL)
- {
- LLUUID motion_id;
- if (isSitting() && getParent()) // sitting on object
- {
- motion_id = ANIM_AGENT_SIT_FEMALE;
- }
- else if (isSitting()) // sitting on ground
- {
- motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED;
- }
- else // standing
- {
- motion_id = ANIM_AGENT_STAND;
- }
- if (mJellyAnims.find(motion_id) == mJellyAnims.end())
- {
- for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
- {
- bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
- LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
- if (!is_playing)
- {
- // Anim was not requested for this av by sim, but may be playing locally
- stopMotion(*it, TRUE);
- }
- }
- mJellyAnims.clear();
-
- startMotion(motion_id);
- mJellyAnims.insert(motion_id);
-
- processAnimationStateChanges();
- }
- }
+ if (isControlAvatar())
+ return;
+
+ if (getOverallAppearance() == AOA_JELLYDOLL)
+ {
+ LLUUID motion_id;
+ if (isSitting() && getParent()) // sitting on object
+ {
+ motion_id = ANIM_AGENT_SIT_FEMALE;
+ }
+ else if (isSitting()) // sitting on ground
+ {
+ motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED;
+ }
+ else // standing
+ {
+ motion_id = ANIM_AGENT_STAND;
+ }
+ if (mJellyAnims.find(motion_id) == mJellyAnims.end())
+ {
+ for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
+ {
+ bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+ LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+ if (!is_playing)
+ {
+ // Anim was not requested for this av by sim, but may be playing locally
+ stopMotion(*it, TRUE);
+ }
+ }
+ mJellyAnims.clear();
+
+ startMotion(motion_id);
+ mJellyAnims.insert(motion_id);
+
+ processAnimationStateChanges();
+ }
+ }
}
// Based on isVisuallyMuted(), but has 3 possible results.
LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- AvatarOverallAppearance result = AOA_NORMAL;
-
- // Priority order (highest priority first)
- // * own avatar is always drawn normally
- // * if on the "always draw normally" list, draw them normally
- // * if on the "always visually mute" list, show as jellydoll
- // * if explicitly muted (blocked), show as invisible
- // * check against the render cost and attachment limits - if too complex, show as jellydoll
- if (isSelf())
- {
- result = AOA_NORMAL;
- }
- else // !isSelf()
- {
- if (isInMuteList())
- {
- result = AOA_INVISIBLE;
- }
- else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
- {
- result = AOA_NORMAL;
- }
- else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
- { // Always want to see this AV as an impostor
- result = AOA_JELLYDOLL;
- }
- else if (isTooComplex() || isTooSlow())
- {
- result = AOA_JELLYDOLL;
- }
- }
-
- return result;
+ AvatarOverallAppearance result = AOA_NORMAL;
+
+ // Priority order (highest priority first)
+ // * own avatar is always drawn normally
+ // * if on the "always draw normally" list, draw them normally
+ // * if on the "always visually mute" list, show as jellydoll
+ // * if explicitly muted (blocked), show as invisible
+ // * check against the render cost and attachment limits - if too complex, show as jellydoll
+ if (isSelf())
+ {
+ result = AOA_NORMAL;
+ }
+ else // !isSelf()
+ {
+ if (isInMuteList())
+ {
+ result = AOA_INVISIBLE;
+ }
+ else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+ {
+ result = AOA_NORMAL;
+ }
+ else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
+ { // Always want to see this AV as an impostor
+ result = AOA_JELLYDOLL;
+ }
+ else if (isTooComplex() || isTooSlow())
+ {
+ result = AOA_JELLYDOLL;
+ }
+ }
+
+ return result;
}
void LLVOAvatar::calcMutedAVColor()
@@ -11370,7 +11367,7 @@ void LLVOAvatar::calcMutedAVColor()
}
#ifdef COLORIZE_JELLYDOLLS
else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
- {
+ {
// select a color based on the first byte of the agents uuid so any muted agent is always the same color
F32 color_value = (F32) (av_id.mData[0]);
F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f
@@ -11386,17 +11383,17 @@ void LLVOAvatar::calcMutedAVColor()
F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1)
new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
- new_color.normalize();
+ new_color.normalize();
new_color *= 0.28f; // Tone it down
- }
+ }
#endif
else
{
- new_color = LLColor4::grey4;
+ new_color = LLColor4::grey4;
change_msg = " over limit color ";
}
- if (mMutedAVColor != new_color)
+ if (mMutedAVColor != new_color)
{
LL_DEBUGS("AvatarRender") << "avatar "<< av_id << change_msg << std::setprecision(3) << new_color << LL_ENDL;
mMutedAVColor = new_color;
@@ -11406,40 +11403,40 @@ void LLVOAvatar::calcMutedAVColor()
// static
BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
{
- return (index < 0 || index >= TEX_NUM_INDICES)
- ? false
- : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture;
+ return (index < 0 || index >= TEX_NUM_INDICES)
+ ? false
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture;
}
// static
BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
{
- return (index < 0 || index >= TEX_NUM_INDICES)
- ? false
- : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture;
+ return (index < 0 || index >= TEX_NUM_INDICES)
+ ? false
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture;
}
const std::string LLVOAvatar::getBakedStatusForPrintout() const
{
- std::string line;
+ std::string line;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++iter)
- {
- const ETextureIndex index = iter->first;
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- if (texture_dict->mIsBakedTexture)
- {
- line += texture_dict->mName;
- if (isTextureDefined(index))
- {
- line += "_baked";
- }
- line += " ";
- }
- }
- return line;
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
+ ++iter)
+ {
+ const ETextureIndex index = iter->first;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsBakedTexture)
+ {
+ line += texture_dict->mName;
+ if (isTextureDefined(index))
+ {
+ line += "_baked";
+ }
+ line += " ";
+ }
+ }
+ return line;
}
@@ -11447,7 +11444,7 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const
//virtual
S32 LLVOAvatar::getTexImageSize() const
{
- return TEX_IMAGE_SIZE_OTHER;
+ return TEX_IMAGE_SIZE_OTHER;
}
//-----------------------------------------------------------------------------
@@ -11456,48 +11453,48 @@ S32 LLVOAvatar::getTexImageSize() const
F32 calc_bouncy_animation(F32 x)
{
- return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
+ return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
}
//virtual
BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const
{
- if (isIndexLocalTexture(te))
- {
- return FALSE;
- }
-
- if( !getImage( te, index ) )
- {
- LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL;
- return FALSE;
- }
+ if (isIndexLocalTexture(te))
+ {
+ return FALSE;
+ }
+
+ if( !getImage( te, index ) )
+ {
+ LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL;
+ return FALSE;
+ }
- return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR &&
- getImage(te, index)->getID() != IMG_DEFAULT);
+ return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR &&
+ getImage(te, index)->getID() != IMG_DEFAULT);
}
//virtual
BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
- if (isIndexLocalTexture(type))
- {
- return isTextureDefined(type, index);
- }
- else
- {
- // baked textures can use TE images directly
- return ((isTextureDefined(type) || isSelf())
- && (getTEImage(type)->getID() != IMG_INVISIBLE
- || LLDrawPoolAlpha::sShowDebugAlpha));
- }
+ if (isIndexLocalTexture(type))
+ {
+ return isTextureDefined(type, index);
+ }
+ else
+ {
+ // baked textures can use TE images directly
+ return ((isTextureDefined(type) || isSelf())
+ && (getTEImage(type)->getID() != IMG_INVISIBLE
+ || LLDrawPoolAlpha::sShowDebugAlpha));
+ }
}
//virtual
BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
{
- // non-self avatars don't have wearables
- return FALSE;
+ // non-self avatars don't have wearables
+ return FALSE;
}
void LLVOAvatar::placeProfileQuery()
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 38742c9c64..01e030a300 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
*
* $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$
*/
@@ -47,7 +47,7 @@
#include "lllocaltextureobject.h"
#include "llnotificationsutil.h"
#include "llselectmgr.h"
-#include "lltoolgrab.h" // for needsRenderBeam
+#include "lltoolgrab.h" // for needsRenderBeam
#include "lltoolmgr.h" // for needsRenderBeam
#include "lltoolmorph.h"
#include "lltrans.h"
@@ -80,31 +80,31 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;
BOOL isAgentAvatarValid()
{
- return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());
+ return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());
}
void selfStartPhase(const std::string& phase_name)
{
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->startPhase(phase_name);
- }
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->startPhase(phase_name);
+ }
}
void selfStopPhase(const std::string& phase_name, bool err_check)
{
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->stopPhase(phase_name, err_check);
- }
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->stopPhase(phase_name, err_check);
+ }
}
void selfClearPhases()
{
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->clearPhases();
- }
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->clearPhases();
+ }
}
using namespace LLAvatarAppearanceDefines;
@@ -120,18 +120,18 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records, std::vector<std::string>
struct LocalTextureData
{
- LocalTextureData() :
- mIsBakedReady(false),
- mDiscard(MAX_DISCARD_LEVEL+1),
- mImage(NULL),
- mWearableID(IMG_DEFAULT_AVATAR),
- mTexEntry(NULL)
- {}
- LLPointer<LLViewerFetchedTexture> mImage;
- bool mIsBakedReady;
- S32 mDiscard;
- LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself
- LLTextureEntry *mTexEntry;
+ LocalTextureData() :
+ mIsBakedReady(false),
+ mDiscard(MAX_DISCARD_LEVEL+1),
+ mImage(NULL),
+ mWearableID(IMG_DEFAULT_AVATAR),
+ mTexEntry(NULL)
+ {}
+ LLPointer<LLViewerFetchedTexture> mImage;
+ bool mIsBakedReady;
+ S32 mDiscard;
+ LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself
+ LLTextureEntry *mTexEntry;
};
//-----------------------------------------------------------------------------
@@ -160,512 +160,512 @@ std::map< LLGLenum, LLGLuint*> LLVOAvatarSelf::sScratchTexNames;
**/
LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
- const LLPCode pcode,
- LLViewerRegion* regionp) :
- LLVOAvatar(id, pcode, regionp),
- mScreenp(NULL),
- mLastRegionHandle(0),
- mRegionCrossingCount(0),
- // Value outside legal range, so will always be a mismatch the
- // first time through.
- mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)),
+ const LLPCode pcode,
+ LLViewerRegion* regionp) :
+ LLVOAvatar(id, pcode, regionp),
+ mScreenp(NULL),
+ mLastRegionHandle(0),
+ mRegionCrossingCount(0),
+ // Value outside legal range, so will always be a mismatch the
+ // first time through.
+ mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)),
mInitialMetric(true),
mMetricSequence(0)
{
- mMotionController.mIsSelf = TRUE;
+ mMotionController.mIsSelf = TRUE;
- LL_DEBUGS() << "Marking avatar as self " << id << LL_ENDL;
+ LL_DEBUGS() << "Marking avatar as self " << id << LL_ENDL;
}
// Called periodically for diagnostics, return true when done.
bool output_self_av_texture_diagnostics()
{
- if (!isAgentAvatarValid())
- return true; // done checking
+ if (!isAgentAvatarValid())
+ return true; // done checking
- gAgentAvatarp->outputRezDiagnostics();
+ gAgentAvatarp->outputRezDiagnostics();
- return false;
+ return false;
}
bool update_avatar_rez_metrics()
{
- if (!isAgentAvatarValid())
- return true;
-
- gAgentAvatarp->updateAvatarRezMetrics(false);
+ if (!isAgentAvatarValid())
+ return true;
+
+ gAgentAvatarp->updateAvatarRezMetrics(false);
- return false;
+ return false;
}
void LLVOAvatarSelf::initInstance()
{
- BOOL status = TRUE;
- // creates hud joint(mScreen) among other things
- status &= loadAvatarSelf();
-
- // adds attachment points to mScreen among other things
- LLVOAvatar::initInstance();
-
- LL_INFOS() << "Self avatar object created. Starting timer." << LL_ENDL;
- mDebugSelfLoadTimer.reset();
- // clear all times to -1 for debugging
- for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
- {
- for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j)
- {
- mDebugTextureLoadTimes[i][j] = -1.0f;
- }
- }
-
- for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
- {
- mDebugBakedTextureTimes[i][0] = -1.0f;
- mDebugBakedTextureTimes[i][1] = -1.0f;
- }
-
- status &= buildMenus();
- if (!status)
- {
- LL_ERRS() << "Unable to load user's avatar" << LL_ENDL;
- return;
- }
-
- setHoverIfRegionEnabled();
-
- //doPeriodically(output_self_av_texture_diagnostics, 30.0);
- doPeriodically(update_avatar_rez_metrics, 5.0);
- doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0);
+ BOOL status = TRUE;
+ // creates hud joint(mScreen) among other things
+ status &= loadAvatarSelf();
+
+ // adds attachment points to mScreen among other things
+ LLVOAvatar::initInstance();
+
+ LL_INFOS() << "Self avatar object created. Starting timer." << LL_ENDL;
+ mDebugSelfLoadTimer.reset();
+ // clear all times to -1 for debugging
+ for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
+ {
+ for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j)
+ {
+ mDebugTextureLoadTimes[i][j] = -1.0f;
+ }
+ }
+
+ for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
+ {
+ mDebugBakedTextureTimes[i][0] = -1.0f;
+ mDebugBakedTextureTimes[i][1] = -1.0f;
+ }
+
+ status &= buildMenus();
+ if (!status)
+ {
+ LL_ERRS() << "Unable to load user's avatar" << LL_ENDL;
+ return;
+ }
+
+ setHoverIfRegionEnabled();
+
+ //doPeriodically(output_self_av_texture_diagnostics, 30.0);
+ doPeriodically(update_avatar_rez_metrics, 5.0);
+ doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0);
mInitFlags |= 1<<2;
}
void LLVOAvatarSelf::setHoverIfRegionEnabled()
{
- if (getRegion() && getRegion()->simulatorFeaturesReceived())
- {
- if (getRegion()->avatarHoverHeightEnabled())
- {
- F32 hover_z = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
- setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z)));
- LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL;
- }
- else
- {
- setHoverOffset(LLVector3(0.0, 0.0, 0.0));
- LL_INFOS("Avatar") << avString() << " zeroing hover height, region does not support" << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("Avatar") << avString() << " region or simulator features not known, no change on hover" << LL_ENDL;
- if (getRegion())
- {
- getRegion()->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
- }
-
- }
+ if (getRegion() && getRegion()->simulatorFeaturesReceived())
+ {
+ if (getRegion()->avatarHoverHeightEnabled())
+ {
+ F32 hover_z = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
+ setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z)));
+ LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL;
+ }
+ else
+ {
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+ LL_INFOS("Avatar") << avString() << " zeroing hover height, region does not support" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("Avatar") << avString() << " region or simulator features not known, no change on hover" << LL_ENDL;
+ if (getRegion())
+ {
+ getRegion()->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
+ }
+
+ }
}
bool LLVOAvatarSelf::checkStuckAppearance()
{
- const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0;
- const F32 UNCONDITIONAL_UNSTICK_INTERVAL = 600.0;
-
- if (gAgentWearables.isCOFChangeInProgress())
- {
- LL_DEBUGS("Avatar") << "checking for stuck appearance" << LL_ENDL;
- F32 change_time = gAgentWearables.getCOFChangeTime();
- LL_DEBUGS("Avatar") << "change in progress for " << change_time << " seconds" << LL_ENDL;
- S32 active_hp = LLAppearanceMgr::instance().countActiveHoldingPatterns();
- LL_DEBUGS("Avatar") << "active holding patterns " << active_hp << " seconds" << LL_ENDL;
- S32 active_copies = LLAppearanceMgr::instance().getActiveCopyOperations();
- LL_DEBUGS("Avatar") << "active copy operations " << active_copies << LL_ENDL;
-
- if ((change_time > CONDITIONAL_UNSTICK_INTERVAL && active_copies == 0) ||
- (change_time > UNCONDITIONAL_UNSTICK_INTERVAL))
- {
- gAgentWearables.notifyLoadingFinished();
- }
- }
-
- // Return false to continue running check periodically.
- return LLApp::isExiting();
+ const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0;
+ const F32 UNCONDITIONAL_UNSTICK_INTERVAL = 600.0;
+
+ if (gAgentWearables.isCOFChangeInProgress())
+ {
+ LL_DEBUGS("Avatar") << "checking for stuck appearance" << LL_ENDL;
+ F32 change_time = gAgentWearables.getCOFChangeTime();
+ LL_DEBUGS("Avatar") << "change in progress for " << change_time << " seconds" << LL_ENDL;
+ S32 active_hp = LLAppearanceMgr::instance().countActiveHoldingPatterns();
+ LL_DEBUGS("Avatar") << "active holding patterns " << active_hp << " seconds" << LL_ENDL;
+ S32 active_copies = LLAppearanceMgr::instance().getActiveCopyOperations();
+ LL_DEBUGS("Avatar") << "active copy operations " << active_copies << LL_ENDL;
+
+ if ((change_time > CONDITIONAL_UNSTICK_INTERVAL && active_copies == 0) ||
+ (change_time > UNCONDITIONAL_UNSTICK_INTERVAL))
+ {
+ gAgentWearables.notifyLoadingFinished();
+ }
+ }
+
+ // Return false to continue running check periodically.
+ return LLApp::isExiting();
}
// virtual
void LLVOAvatarSelf::markDead()
{
- mBeam = NULL;
- LLVOAvatar::markDead();
+ mBeam = NULL;
+ LLVOAvatar::markDead();
}
/*virtual*/ BOOL LLVOAvatarSelf::loadAvatar()
{
- BOOL success = LLVOAvatar::loadAvatar();
+ BOOL success = LLVOAvatar::loadAvatar();
- // set all parameters stored directly in the avatar to have
- // the isSelfParam to be TRUE - this is used to prevent
- // them from being animated or trigger accidental rebakes
- // when we copy params from the wearable to the base avatar.
- for (LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) getNextVisualParam())
- {
- if (param->getWearableType() != LLWearableType::WT_INVALID)
- {
- param->setIsDummy(TRUE);
- }
- }
+ // set all parameters stored directly in the avatar to have
+ // the isSelfParam to be TRUE - this is used to prevent
+ // them from being animated or trigger accidental rebakes
+ // when we copy params from the wearable to the base avatar.
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) getNextVisualParam())
+ {
+ if (param->getWearableType() != LLWearableType::WT_INVALID)
+ {
+ param->setIsDummy(TRUE);
+ }
+ }
- return success;
+ return success;
}
BOOL LLVOAvatarSelf::loadAvatarSelf()
{
- BOOL success = TRUE;
- // avatar_skeleton.xml
- if (!buildSkeletonSelf(sAvatarSkeletonInfo))
- {
- LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL;
- return FALSE;
- }
+ BOOL success = TRUE;
+ // avatar_skeleton.xml
+ if (!buildSkeletonSelf(sAvatarSkeletonInfo))
+ {
+ LL_WARNS() << "avatar file: buildSkeleton() failed" << LL_ENDL;
+ return FALSE;
+ }
- return success;
+ return success;
}
BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)
{
- // add special-purpose "screen" joint
- mScreenp = new LLViewerJoint("mScreen", NULL);
- // for now, put screen at origin, as it is only used during special
- // HUD rendering mode
- F32 aspect = LLViewerCamera::getInstance()->getAspect();
- LLVector3 scale(1.f, aspect, 1.f);
- mScreenp->setScale(scale);
- // SL-315
- mScreenp->setWorldPosition(LLVector3::zero);
- // need to update screen agressively when sidebar opens/closes, for example
- mScreenp->mUpdateXform = TRUE;
- return TRUE;
+ // add special-purpose "screen" joint
+ mScreenp = new LLViewerJoint("mScreen", NULL);
+ // for now, put screen at origin, as it is only used during special
+ // HUD rendering mode
+ F32 aspect = LLViewerCamera::getInstance()->getAspect();
+ LLVector3 scale(1.f, aspect, 1.f);
+ mScreenp->setScale(scale);
+ // SL-315
+ mScreenp->setWorldPosition(LLVector3::zero);
+ // need to update screen agressively when sidebar opens/closes, for example
+ mScreenp->mUpdateXform = TRUE;
+ return TRUE;
}
BOOL LLVOAvatarSelf::buildMenus()
{
- //-------------------------------------------------------------------------
- // build the attach and detach menus
- //-------------------------------------------------------------------------
- gAttachBodyPartPieMenus[0] = NULL;
-
- LLContextMenu::Params params;
- params.label(LLTrans::getString("BodyPartsRightArm"));
- params.name(params.label);
- params.visible(false);
- gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsHead"));
- params.name(params.label);
- gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsLeftArm"));
- params.name(params.label);
- gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- gAttachBodyPartPieMenus[4] = NULL;
-
- params.label(LLTrans::getString("BodyPartsLeftLeg"));
- params.name(params.label);
- gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsTorso"));
- params.name(params.label);
- gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsRightLeg"));
- params.name(params.label);
- gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
- params.name(params.label);
- gAttachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params);
-
- gDetachBodyPartPieMenus[0] = NULL;
-
- params.label(LLTrans::getString("BodyPartsRightArm"));
- params.name(params.label);
- gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsHead"));
- params.name(params.label);
- gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsLeftArm"));
- params.name(params.label);
- gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- gDetachBodyPartPieMenus[4] = NULL;
-
- params.label(LLTrans::getString("BodyPartsLeftLeg"));
- params.name(params.label);
- gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsTorso"));
- params.name(params.label);
- gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsRightLeg"));
- params.name(params.label);
- gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
-
- params.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
- params.name(params.label);
- gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params);
-
- for (S32 i = 0; i < 9; i++)
- {
- if (gAttachBodyPartPieMenus[i])
- {
- gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] );
- }
- else
- {
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment && attachment->getGroup() == i)
- {
- LLMenuItemCallGL::Params item_params;
-
- std::string sub_piemenu_name = attachment->getName();
- if (LLTrans::getString(sub_piemenu_name) != "")
- {
- item_params.label = LLTrans::getString(sub_piemenu_name);
- }
- else
- {
- item_params.label = sub_piemenu_name;
- }
- item_params.name =(item_params.label );
- item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = iter->first;
- LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
-
- gAttachPieMenu->addChild(item);
-
- break;
-
- }
- }
- }
-
- if (gDetachBodyPartPieMenus[i])
- {
- gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
- gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
- gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
- }
- else
- {
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment && attachment->getGroup() == i)
- {
- LLMenuItemCallGL::Params item_params;
- std::string sub_piemenu_name = attachment->getName();
- if (LLTrans::getString(sub_piemenu_name) != "")
- {
- item_params.label = LLTrans::getString(sub_piemenu_name);
- }
- else
- {
- item_params.label = sub_piemenu_name;
- }
- item_params.name =(item_params.label );
- item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = iter->first;
- LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
-
- gDetachPieMenu->addChild(item);
- gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
- gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
- break;
- }
- }
- }
- }
-
-
- // add screen attachments
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getGroup() == 9)
- {
- LLMenuItemCallGL::Params item_params;
- std::string sub_piemenu_name = attachment->getName();
- if (LLTrans::getString(sub_piemenu_name) != "")
- {
- item_params.label = LLTrans::getString(sub_piemenu_name);
- }
- else
- {
- item_params.label = sub_piemenu_name;
- }
- item_params.name =(item_params.label );
- item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = iter->first;
- LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gAttachScreenPieMenu->addChild(item);
-
- item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = iter->first;
- item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gDetachScreenPieMenu->addChild(item);
- gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
- gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
- }
- }
-
- for (S32 pass = 0; pass < 2; pass++)
- {
- // *TODO: Skinning - gAttachSubMenu is an awful, awful hack
- if (!gAttachSubMenu)
- {
- break;
- }
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getIsHUDAttachment() != (pass == 1))
- {
- continue;
- }
- LLMenuItemCallGL::Params item_params;
- std::string sub_piemenu_name = attachment->getName();
- if (LLTrans::getString(sub_piemenu_name) != "")
- {
- item_params.label = LLTrans::getString(sub_piemenu_name);
- }
- else
- {
- item_params.label = sub_piemenu_name;
- }
- item_params.name =(item_params.label );
- item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = iter->first;
- //* TODO: Skinning:
- //LLSD params;
- //params["index"] = iter->first;
- //params["label"] = attachment->getName();
- //item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
-
- LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gAttachSubMenu->addChild(item);
-
- item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = iter->first;
- item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = iter->first;
- //* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
-
- item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gDetachSubMenu->addChild(item);
- }
- if (pass == 0)
- {
- // put separator between non-hud and hud attachments
- gAttachSubMenu->addSeparator();
- gDetachSubMenu->addSeparator();
- }
- }
-
- for (S32 group = 0; group < 9; group++)
- {
- // skip over groups that don't have sub menus
- if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group])
- {
- continue;
- }
-
- std::multimap<S32, S32> attachment_pie_menu_map;
-
- // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if(attachment && attachment->getGroup() == group)
- {
- // use multimap to provide a partial order off of the pie slice key
- S32 pie_index = attachment->getPieSlice();
- attachment_pie_menu_map.insert(std::make_pair(pie_index, iter->first));
- }
- }
-
- // add in requested order to pie menu, inserting separators as necessary
- for (std::multimap<S32, S32>::iterator attach_it = attachment_pie_menu_map.begin();
- attach_it != attachment_pie_menu_map.end(); ++attach_it)
- {
- S32 attach_index = attach_it->second;
-
- LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL);
- if (attachment)
- {
- LLMenuItemCallGL::Params item_params;
- item_params.name = attachment->getName();
- item_params.label = LLTrans::getString(attachment->getName());
- item_params.on_click.function_name = "Object.AttachToAvatar";
- item_params.on_click.parameter = attach_index;
- item_params.on_enable.function_name = "Object.EnableWear";
- item_params.on_enable.parameter = attach_index;
-
- LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gAttachBodyPartPieMenus[group]->addChild(item);
-
- item_params.on_click.function_name = "Attachment.DetachFromPoint";
- item_params.on_click.parameter = attach_index;
- item_params.on_enable.function_name = "Attachment.PointFilled";
- item_params.on_enable.parameter = attach_index;
- item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
- gDetachBodyPartPieMenus[group]->addChild(item);
- }
- }
- }
- return TRUE;
+ //-------------------------------------------------------------------------
+ // build the attach and detach menus
+ //-------------------------------------------------------------------------
+ gAttachBodyPartPieMenus[0] = NULL;
+
+ LLContextMenu::Params params;
+ params.label(LLTrans::getString("BodyPartsRightArm"));
+ params.name(params.label);
+ params.visible(false);
+ gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsHead"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsLeftArm"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ gAttachBodyPartPieMenus[4] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsLeftLeg"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsTorso"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsRightLeg"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
+ params.name(params.label);
+ gAttachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params);
+
+ gDetachBodyPartPieMenus[0] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsRightArm"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsHead"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsLeftArm"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ gDetachBodyPartPieMenus[4] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsLeftLeg"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsTorso"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsRightLeg"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsEnhancedSkeleton"));
+ params.name(params.label);
+ gDetachBodyPartPieMenus[8] = LLUICtrlFactory::create<LLContextMenu>(params);
+
+ for (S32 i = 0; i < 9; i++)
+ {
+ if (gAttachBodyPartPieMenus[i])
+ {
+ gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] );
+ }
+ else
+ {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment && attachment->getGroup() == i)
+ {
+ LLMenuItemCallGL::Params item_params;
+
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = iter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+ gAttachPieMenu->addChild(item);
+
+ break;
+
+ }
+ }
+ }
+
+ if (gDetachBodyPartPieMenus[i])
+ {
+ gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
+ gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
+ gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
+ }
+ else
+ {
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment && attachment->getGroup() == i)
+ {
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = iter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+ gDetachPieMenu->addChild(item);
+ gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ break;
+ }
+ }
+ }
+ }
+
+
+ // add screen attachments
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getGroup() == 9)
+ {
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = iter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachScreenPieMenu->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = iter->first;
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachScreenPieMenu->addChild(item);
+ gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ }
+ }
+
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ // *TODO: Skinning - gAttachSubMenu is an awful, awful hack
+ if (!gAttachSubMenu)
+ {
+ break;
+ }
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getIsHUDAttachment() != (pass == 1))
+ {
+ continue;
+ }
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = iter->first;
+ //* TODO: Skinning:
+ //LLSD params;
+ //params["index"] = iter->first;
+ //params["label"] = attachment->getName();
+ //item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
+
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachSubMenu->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = iter->first;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = iter->first;
+ //* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
+
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachSubMenu->addChild(item);
+ }
+ if (pass == 0)
+ {
+ // put separator between non-hud and hud attachments
+ gAttachSubMenu->addSeparator();
+ gDetachSubMenu->addSeparator();
+ }
+ }
+
+ for (S32 group = 0; group < 9; group++)
+ {
+ // skip over groups that don't have sub menus
+ if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group])
+ {
+ continue;
+ }
+
+ std::multimap<S32, S32> attachment_pie_menu_map;
+
+ // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if(attachment && attachment->getGroup() == group)
+ {
+ // use multimap to provide a partial order off of the pie slice key
+ S32 pie_index = attachment->getPieSlice();
+ attachment_pie_menu_map.insert(std::make_pair(pie_index, iter->first));
+ }
+ }
+
+ // add in requested order to pie menu, inserting separators as necessary
+ for (std::multimap<S32, S32>::iterator attach_it = attachment_pie_menu_map.begin();
+ attach_it != attachment_pie_menu_map.end(); ++attach_it)
+ {
+ S32 attach_index = attach_it->second;
+
+ LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL);
+ if (attachment)
+ {
+ LLMenuItemCallGL::Params item_params;
+ item_params.name = attachment->getName();
+ item_params.label = LLTrans::getString(attachment->getName());
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = attach_index;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = attach_index;
+
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachBodyPartPieMenus[group]->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = attach_index;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = attach_index;
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachBodyPartPieMenus[group]->addChild(item);
+ }
+ }
+ }
+ return TRUE;
}
void LLVOAvatarSelf::cleanup()
{
- markDead();
- delete mScreenp;
- mScreenp = NULL;
- mRegionp = NULL;
+ markDead();
+ delete mScreenp;
+ mScreenp = NULL;
+ mRegionp = NULL;
}
LLVOAvatarSelf::~LLVOAvatarSelf()
{
- cleanup();
+ cleanup();
}
/**
@@ -677,33 +677,33 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
// virtual
bool LLVOAvatarSelf::updateCharacter(LLAgent &agent)
{
- // update screen joint size
- if (mScreenp)
- {
- F32 aspect = LLViewerCamera::getInstance()->getAspect();
- LLVector3 scale(1.f, aspect, 1.f);
- mScreenp->setScale(scale);
- mScreenp->updateWorldMatrixChildren();
- resetHUDAttachments();
- }
-
- return LLVOAvatar::updateCharacter(agent);
+ // update screen joint size
+ if (mScreenp)
+ {
+ F32 aspect = LLViewerCamera::getInstance()->getAspect();
+ LLVector3 scale(1.f, aspect, 1.f);
+ mScreenp->setScale(scale);
+ mScreenp->updateWorldMatrixChildren();
+ resetHUDAttachments();
+ }
+
+ return LLVOAvatar::updateCharacter(agent);
}
// virtual
BOOL LLVOAvatarSelf::isValid() const
{
- return ((getRegion() != NULL) && !isDead());
+ return ((getRegion() != NULL) && !isDead());
}
// virtual
void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time)
{
- if (isValid())
- {
- LLVOAvatar::idleUpdate(agent, time);
- idleUpdateTractorBeam();
- }
+ if (isValid())
+ {
+ LLVOAvatar::idleUpdate(agent, time);
+ idleUpdateTractorBeam();
+ }
}
// virtual
@@ -711,14 +711,14 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
{
LLJoint *jointp = NULL;
jointp = LLVOAvatar::getJoint(name);
- if (!jointp && mScreenp)
- {
- jointp = mScreenp->findJoint(name);
+ if (!jointp && mScreenp)
+ {
+ jointp = mScreenp->findJoint(name);
if (jointp)
{
mJointMap[name] = jointp;
}
- }
+ }
if (jointp && jointp != mScreenp && jointp != mRoot)
{
llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp);
@@ -729,238 +729,238 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
// virtual
BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight)
{
- if (!which_param)
- {
- return FALSE;
- }
- LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID());
- return setParamWeight(param,weight);
+ if (!which_param)
+ {
+ return FALSE;
+ }
+ LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID());
+ return setParamWeight(param,weight);
}
// virtual
BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight)
{
- if (!param_name)
- {
- return FALSE;
- }
- LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name);
- return setParamWeight(param,weight);
+ if (!param_name)
+ {
+ return FALSE;
+ }
+ LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name);
+ return setParamWeight(param,weight);
}
// virtual
BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight)
{
- LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index);
- return setParamWeight(param,weight);
+ LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index);
+ return setParamWeight(param,weight);
}
BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight)
{
- if (!param)
- {
- return FALSE;
- }
-
- if (param->getCrossWearable())
- {
- LLWearableType::EType type = (LLWearableType::EType)param->getWearableType();
- U32 size = gAgentWearables.getWearableCount(type);
- for (U32 count = 0; count < size; ++count)
- {
- LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);
- if (wearable)
- {
- wearable->setVisualParamWeight(param->getID(), weight);
- }
- }
- }
-
- return LLCharacter::setVisualParamWeight(param,weight);
-}
-
-/*virtual*/
+ if (!param)
+ {
+ return FALSE;
+ }
+
+ if (param->getCrossWearable())
+ {
+ LLWearableType::EType type = (LLWearableType::EType)param->getWearableType();
+ U32 size = gAgentWearables.getWearableCount(type);
+ for (U32 count = 0; count < size; ++count)
+ {
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);
+ if (wearable)
+ {
+ wearable->setVisualParamWeight(param->getID(), weight);
+ }
+ }
+ }
+
+ return LLCharacter::setVisualParamWeight(param,weight);
+}
+
+/*virtual*/
void LLVOAvatarSelf::updateVisualParams()
{
- LLVOAvatar::updateVisualParams();
+ LLVOAvatar::updateVisualParams();
}
void LLVOAvatarSelf::writeWearablesToAvatar()
{
- for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)
- {
- LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
- if (wearable)
- {
- wearable->writeToAvatar(this);
- }
- }
+ for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)
+ {
+ LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
+ if (wearable)
+ {
+ wearable->writeToAvatar(this);
+ }
+ }
}
/*virtual*/
void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
{
- // Animate all top-level wearable visual parameters
- gAgentWearables.animateAllWearableParams(calcMorphAmount());
+ // Animate all top-level wearable visual parameters
+ gAgentWearables.animateAllWearableParams(calcMorphAmount());
- // Apply wearable visual params to avatar
- writeWearablesToAvatar();
+ // Apply wearable visual params to avatar
+ writeWearablesToAvatar();
- //allow avatar to process updates
- LLVOAvatar::idleUpdateAppearanceAnimation();
+ //allow avatar to process updates
+ LLVOAvatar::idleUpdateAppearanceAnimation();
}
// virtual
void LLVOAvatarSelf::requestStopMotion(LLMotion* motion)
{
- // Only agent avatars should handle the stop motion notifications.
+ // Only agent avatars should handle the stop motion notifications.
- // Notify agent that motion has stopped
- gAgent.requestStopMotion(motion);
+ // Notify agent that motion has stopped
+ gAgent.requestStopMotion(motion);
}
// virtual
bool LLVOAvatarSelf::hasMotionFromSource(const LLUUID& source_id)
{
- AnimSourceIterator motion_it = mAnimationSources.find(source_id);
- return motion_it != mAnimationSources.end();
+ AnimSourceIterator motion_it = mAnimationSources.find(source_id);
+ return motion_it != mAnimationSources.end();
}
// virtual
void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
{
- for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
- {
- gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
- mAnimationSources.erase(motion_it);
- // Must find() after each erase() to deal with potential iterator invalidation
- // This also ensures that we don't go past the end of this source's animations
- // into those of another source.
- motion_it = mAnimationSources.find(source_id);
- }
+ for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
+ {
+ gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
+ mAnimationSources.erase(motion_it);
+ // Must find() after each erase() to deal with potential iterator invalidation
+ // This also ensures that we don't go past the end of this source's animations
+ // into those of another source.
+ motion_it = mAnimationSources.find(source_id);
+ }
- LLViewerObject* object = gObjectList.findObject(source_id);
- if (object)
- {
- object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE);
- }
+ LLViewerObject* object = gObjectList.findObject(source_id);
+ if (object)
+ {
+ object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE);
+ }
}
void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index)
{
- if (te >= TEX_NUM_INDICES)
- {
- llassert(0);
- return;
- }
+ if (te >= TEX_NUM_INDICES)
+ {
+ llassert(0);
+ return;
+ }
- if (getTEImage(te)->getID() == image->getID())
- {
- return;
- }
+ if (getTEImage(te)->getID() == image->getID())
+ {
+ return;
+ }
- if (isIndexBakedTexture((ETextureIndex)te))
- {
- llassert(0);
- return;
- }
+ if (isIndexBakedTexture((ETextureIndex)te))
+ {
+ llassert(0);
+ return;
+ }
- setTEImage(te, image);
+ setTEImage(te, image);
}
//virtual
void LLVOAvatarSelf::removeMissingBakedTextures()
-{
- BOOL removed = FALSE;
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- const S32 te = mBakedTextureDatas[i].mTextureIndex;
- const LLViewerTexture* tex = getTEImage(te);
-
- // Replace with default if we can't find the asset, assuming the
- // default is actually valid (which it should be unless something
- // is seriously wrong).
- if (!tex || tex->isMissingAsset())
- {
- LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
- if (imagep && imagep != tex)
- {
- setTEImage(te, imagep);
- removed = TRUE;
- }
- }
- }
-
- if (removed)
- {
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- LLViewerTexLayerSet *layerset = getTexLayerSet(i);
- layerset->setUpdatesEnabled(TRUE);
- invalidateComposite(layerset);
- }
- updateMeshTextures();
- }
+{
+ BOOL removed = FALSE;
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const S32 te = mBakedTextureDatas[i].mTextureIndex;
+ const LLViewerTexture* tex = getTEImage(te);
+
+ // Replace with default if we can't find the asset, assuming the
+ // default is actually valid (which it should be unless something
+ // is seriously wrong).
+ if (!tex || tex->isMissingAsset())
+ {
+ LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
+ if (imagep && imagep != tex)
+ {
+ setTEImage(te, imagep);
+ removed = TRUE;
+ }
+ }
+ }
+
+ if (removed)
+ {
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ layerset->setUpdatesEnabled(TRUE);
+ invalidateComposite(layerset);
+ }
+ updateMeshTextures();
+ }
}
void LLVOAvatarSelf::onSimulatorFeaturesReceived(const LLUUID& region_id)
{
- LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL;
- setHoverIfRegionEnabled();
+ LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL;
+ setHoverIfRegionEnabled();
}
//virtual
void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
{
- // Save the global position
- LLVector3d global_pos_from_old_region = getPositionGlobal();
-
- // Change the region
- setRegion(regionp);
-
- if (regionp)
- { // Set correct region-relative position from global coordinates
- setPositionGlobal(global_pos_from_old_region);
-
- // Diagnostic info
- //LLVector3d pos_from_new_region = getPositionGlobal();
- //LL_INFOS() << "pos_from_old_region is " << global_pos_from_old_region
- // << " while pos_from_new_region is " << pos_from_new_region
- // << LL_ENDL;
-
- // Update hover height, or schedule callback, based on whether
- // it's supported in this region.
- if (regionp->simulatorFeaturesReceived())
- {
- setHoverIfRegionEnabled();
- }
- else
- {
- regionp->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
- }
- }
-
- if (!regionp || (regionp->getHandle() != mLastRegionHandle))
- {
- if (mLastRegionHandle != 0)
- {
- ++mRegionCrossingCount;
- F64Seconds delta(mRegionCrossingTimer.getElapsedTimeF32());
- record(LLStatViewer::REGION_CROSSING_TIME, delta);
-
- // Diagnostics
- LL_INFOS() << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << LL_ENDL;
- }
- if (regionp)
- {
- mLastRegionHandle = regionp->getHandle();
- }
- }
- mRegionCrossingTimer.reset();
- LLViewerObject::updateRegion(regionp);
+ // Save the global position
+ LLVector3d global_pos_from_old_region = getPositionGlobal();
+
+ // Change the region
+ setRegion(regionp);
+
+ if (regionp)
+ { // Set correct region-relative position from global coordinates
+ setPositionGlobal(global_pos_from_old_region);
+
+ // Diagnostic info
+ //LLVector3d pos_from_new_region = getPositionGlobal();
+ //LL_INFOS() << "pos_from_old_region is " << global_pos_from_old_region
+ // << " while pos_from_new_region is " << pos_from_new_region
+ // << LL_ENDL;
+
+ // Update hover height, or schedule callback, based on whether
+ // it's supported in this region.
+ if (regionp->simulatorFeaturesReceived())
+ {
+ setHoverIfRegionEnabled();
+ }
+ else
+ {
+ regionp->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
+ }
+ }
+
+ if (!regionp || (regionp->getHandle() != mLastRegionHandle))
+ {
+ if (mLastRegionHandle != 0)
+ {
+ ++mRegionCrossingCount;
+ F64Seconds delta(mRegionCrossingTimer.getElapsedTimeF32());
+ record(LLStatViewer::REGION_CROSSING_TIME, delta);
+
+ // Diagnostics
+ LL_INFOS() << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << LL_ENDL;
+ }
+ if (regionp)
+ {
+ mLastRegionHandle = regionp->getHandle();
+ }
+ }
+ mRegionCrossingTimer.reset();
+ LLViewerObject::updateRegion(regionp);
}
//--------------------------------------------------------------------
@@ -969,65 +969,65 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
//virtual
void LLVOAvatarSelf::idleUpdateTractorBeam()
{
- // This is only done for yourself (maybe it should be in the agent?)
- if (!needsRenderBeam() || !isBuilt())
- {
- mBeam = NULL;
- }
- else if (!mBeam || mBeam->isDead())
- {
- // VEFFECT: Tractor Beam
- mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM);
- mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
- mBeam->setSourceObject(this);
- mBeamTimer.reset();
- }
-
- if (!mBeam.isNull())
- {
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- if (gAgentCamera.mPointAt.notNull())
- {
- // get point from pointat effect
- mBeam->setPositionGlobal(gAgentCamera.mPointAt->getPointAtPosGlobal());
- mBeam->triggerLocal();
- }
- else if (selection->getFirstRootObject() &&
- selection->getSelectType() != SELECT_TYPE_HUD)
- {
- LLViewerObject* objectp = selection->getFirstRootObject();
- mBeam->setTargetObject(objectp);
- }
- else
- {
- mBeam->setTargetObject(NULL);
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
- if (tool->isEditing())
- {
- if (tool->getEditingObject())
- {
- mBeam->setTargetObject(tool->getEditingObject());
- }
- else
- {
- mBeam->setPositionGlobal(tool->getEditingPointGlobal());
- }
- }
- else
- {
- const LLPickInfo& pick = gViewerWindow->getLastPick();
- mBeam->setPositionGlobal(pick.mPosGlobal);
- }
-
- }
- if (mBeamTimer.getElapsedTimeF32() > 0.25f)
- {
- mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
- mBeam->setNeedsSendToSim(TRUE);
- mBeamTimer.reset();
- }
- }
+ // This is only done for yourself (maybe it should be in the agent?)
+ if (!needsRenderBeam() || !isBuilt())
+ {
+ mBeam = NULL;
+ }
+ else if (!mBeam || mBeam->isDead())
+ {
+ // VEFFECT: Tractor Beam
+ mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM);
+ mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
+ mBeam->setSourceObject(this);
+ mBeamTimer.reset();
+ }
+
+ if (!mBeam.isNull())
+ {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (gAgentCamera.mPointAt.notNull())
+ {
+ // get point from pointat effect
+ mBeam->setPositionGlobal(gAgentCamera.mPointAt->getPointAtPosGlobal());
+ mBeam->triggerLocal();
+ }
+ else if (selection->getFirstRootObject() &&
+ selection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ LLViewerObject* objectp = selection->getFirstRootObject();
+ mBeam->setTargetObject(objectp);
+ }
+ else
+ {
+ mBeam->setTargetObject(NULL);
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (tool->isEditing())
+ {
+ if (tool->getEditingObject())
+ {
+ mBeam->setTargetObject(tool->getEditingObject());
+ }
+ else
+ {
+ mBeam->setPositionGlobal(tool->getEditingPointGlobal());
+ }
+ }
+ else
+ {
+ const LLPickInfo& pick = gViewerWindow->getLastPick();
+ mBeam->setPositionGlobal(pick.mPosGlobal);
+ }
+
+ }
+ if (mBeamTimer.getElapsedTimeF32() > 0.25f)
+ {
+ mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
+ mBeam->setNeedsSendToSim(TRUE);
+ mBeamTimer.reset();
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -1036,13 +1036,13 @@ void LLVOAvatarSelf::idleUpdateTractorBeam()
// virtual
void LLVOAvatarSelf::restoreMeshData()
{
- //LL_INFOS() << "Restoring" << LL_ENDL;
- mMeshValid = TRUE;
- updateJointLODs();
- updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ //LL_INFOS() << "Restoring" << LL_ENDL;
+ mMeshValid = TRUE;
+ updateJointLODs();
+ updateAttachmentVisibility(gAgentCamera.getCameraMode());
- // force mesh update as LOD might not have changed to trigger this
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ // force mesh update as LOD might not have changed to trigger this
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
@@ -1052,35 +1052,35 @@ void LLVOAvatarSelf::restoreMeshData()
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getIsHUDAttachment())
- {
- attachment->setAttachmentVisibility(TRUE);
- }
- else
- {
- switch (camera_mode)
- {
- case CAMERA_MODE_MOUSELOOK:
- if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson())
- {
- attachment->setAttachmentVisibility(TRUE);
- }
- else
- {
- attachment->setAttachmentVisibility(FALSE);
- }
- break;
- default:
- attachment->setAttachmentVisibility(TRUE);
- break;
- }
- }
- }
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getIsHUDAttachment())
+ {
+ attachment->setAttachmentVisibility(TRUE);
+ }
+ else
+ {
+ switch (camera_mode)
+ {
+ case CAMERA_MODE_MOUSELOOK:
+ if ((LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) || gPipeline.mHeroProbeManager.isMirrorPass())
+ {
+ attachment->setAttachmentVisibility(TRUE);
+ }
+ else
+ {
+ attachment->setAttachmentVisibility(FALSE);
+ }
+ break;
+ default:
+ attachment->setAttachmentVisibility(TRUE);
+ break;
+ }
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -1090,33 +1090,33 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type)
{
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
- const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first;
-
- if (baked_dict)
- {
- for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
- type_iter != baked_dict->mWearables.end();
- ++type_iter)
- {
- const LLWearableType::EType comp_type = *type_iter;
- if (comp_type == type)
- {
- LLViewerTexLayerSet *layerset = getLayerSet(index);
- if (layerset)
- {
- layerset->setUpdatesEnabled(true);
- invalidateComposite(layerset);
- }
- break;
- }
- }
- }
- }
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first;
+
+ if (baked_dict)
+ {
+ for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+ type_iter != baked_dict->mWearables.end();
+ ++type_iter)
+ {
+ const LLWearableType::EType comp_type = *type_iter;
+ if (comp_type == type)
+ {
+ LLViewerTexLayerSet *layerset = getLayerSet(index);
+ if (layerset)
+ {
+ layerset->setUpdatesEnabled(true);
+ invalidateComposite(layerset);
+ }
+ break;
+ }
+ }
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -1124,18 +1124,18 @@ void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type)
//-----------------------------------------------------------------------------
BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const
{
- const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getAttachedObject(base_inv_item_id))
- {
- return TRUE;
- }
- }
- return FALSE;
+ const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getAttachedObject(base_inv_item_id))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -1143,113 +1143,113 @@ BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const
//-----------------------------------------------------------------------------
LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
{
- const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id))
- {
- return attached_object;
- }
- }
- return NULL;
+ const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id))
+ {
+ return attached_object;
+ }
+ }
+ return NULL;
}
bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (!gInventory.getItem(inv_item_id))
- {
- name = "ATTACHMENT_MISSING_ITEM";
- return false;
- }
- const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
- if (!gInventory.getItem(base_inv_item_id))
- {
- name = "ATTACHMENT_MISSING_BASE_ITEM";
- return false;
- }
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- const LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getAttachedObject(base_inv_item_id))
- {
- name = attachment->getName();
- return true;
- }
- }
-
- name = "ATTACHMENT_NOT_ATTACHED";
- return false;
+ if (!gInventory.getItem(inv_item_id))
+ {
+ name = "ATTACHMENT_MISSING_ITEM";
+ return false;
+ }
+ const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
+ if (!gInventory.getItem(base_inv_item_id))
+ {
+ name = "ATTACHMENT_MISSING_BASE_ITEM";
+ return false;
+ }
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment* attachment = iter->second;
+ if (attachment->getAttachedObject(base_inv_item_id))
+ {
+ name = attachment->getName();
+ return true;
+ }
+ }
+
+ name = "ATTACHMENT_NOT_ATTACHED";
+ return false;
}
//virtual
const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object)
{
- const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object);
- if (!attachment)
- {
- return 0;
- }
-
- updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object);
+ if (!attachment)
+ {
+ return 0;
+ }
- // Then make sure the inventory is in sync with the avatar.
+ updateAttachmentVisibility(gAgentCamera.getCameraMode());
+
+ // Then make sure the inventory is in sync with the avatar.
- // Should just be the last object added
- if (attachment->isObjectAttached(viewer_object))
- {
- const LLUUID& attachment_id = viewer_object->getAttachmentItemID();
- LLAppearanceMgr::instance().registerAttachment(attachment_id);
- updateLODRiggedAttachments();
- }
+ // Should just be the last object added
+ if (attachment->isObjectAttached(viewer_object))
+ {
+ const LLUUID& attachment_id = viewer_object->getAttachmentItemID();
+ LLAppearanceMgr::instance().registerAttachment(attachment_id);
+ updateLODRiggedAttachments();
+ }
- return attachment;
+ return attachment;
}
//virtual
BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
{
- const LLUUID attachment_id = viewer_object->getAttachmentItemID();
- if ( LLVOAvatar::detachObject(viewer_object) )
- {
- // the simulator should automatically handle permission revocation
-
- stopMotionFromSource(attachment_id);
- LLFollowCamMgr::getInstance()->setCameraActive(viewer_object->getID(), FALSE);
-
- LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end();
- ++iter)
- {
- LLViewerObject* child_objectp = *iter;
- // the simulator should automatically handle
- // permissions revocation
-
- stopMotionFromSource(child_objectp->getID());
- LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE);
- }
-
- // Make sure the inventory is in sync with the avatar.
-
- // Update COF contents, don't trigger appearance update.
- if (!isValid())
- {
- LL_INFOS() << "removeItemLinks skipped, avatar is under destruction" << LL_ENDL;
- }
- else
- {
- LLAppearanceMgr::instance().unregisterAttachment(attachment_id);
- }
-
- return TRUE;
- }
- return FALSE;
+ const LLUUID attachment_id = viewer_object->getAttachmentItemID();
+ if ( LLVOAvatar::detachObject(viewer_object) )
+ {
+ // the simulator should automatically handle permission revocation
+
+ stopMotionFromSource(attachment_id);
+ LLFollowCamMgr::getInstance()->setCameraActive(viewer_object->getID(), FALSE);
+
+ LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end();
+ ++iter)
+ {
+ LLViewerObject* child_objectp = *iter;
+ // the simulator should automatically handle
+ // permissions revocation
+
+ stopMotionFromSource(child_objectp->getID());
+ LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE);
+ }
+
+ // Make sure the inventory is in sync with the avatar.
+
+ // Update COF contents, don't trigger appearance update.
+ if (!isValid())
+ {
+ LL_INFOS() << "removeItemLinks skipped, avatar is under destruction" << LL_ENDL;
+ }
+ else
+ {
+ LLAppearanceMgr::instance().unregisterAttachment(attachment_id);
+ }
+
+ return TRUE;
+ }
+ return FALSE;
}
bool LLVOAvatarSelf::hasAttachmentsInTrash()
@@ -1276,140 +1276,140 @@ bool LLVOAvatarSelf::hasAttachmentsInTrash()
// static
BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
{
- LLInventoryItem* item = gInventory.getItem(item_id);
- if (item)
- {
- gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
- gMessageSystem->sendReliable(gAgent.getRegionHost());
-
- // This object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject(item_id);
- if (found_obj)
- {
- LLSelectMgr::getInstance()->remove(found_obj);
- }
-
- // Error checking in case this object was attached to an invalid point
- // In that case, just remove the item from COF preemptively since detach
- // will fail.
- if (isAgentAvatarValid())
- {
- const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
- if (!attached_obj)
- {
- LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
- }
- }
- return TRUE;
- }
- return FALSE;
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
+ gMessageSystem->sendReliable(gAgent.getRegionHost());
+
+ // This object might have been selected, so let the selection manager know it's gone now
+ LLViewerObject *found_obj = gObjectList.findObject(item_id);
+ if (found_obj)
+ {
+ LLSelectMgr::getInstance()->remove(found_obj);
+ }
+
+ // Error checking in case this object was attached to an invalid point
+ // In that case, just remove the item from COF preemptively since detach
+ // will fail.
+ if (isAgentAvatarValid())
+ {
+ const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
+ if (!attached_obj)
+ {
+ LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
}
U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
{
- LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
- return gAgentWearables.getWearableCount(type);
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
+ return gAgentWearables.getWearableCount(type);
}
// virtual
void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
-{
-
- const LLUUID& src_id = src_vi->getID();
- LLAvatarTexData *data = (LLAvatarTexData *)userdata;
- ETextureIndex index = data->mIndex;
- if (!isIndexLocalTexture(index)) return;
-
- LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0);
-
- // fix for EXT-268. Preventing using of NULL pointer
- if(NULL == local_tex_obj)
- {
- LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index
- << ", final: " << final
- << LL_ENDL;
- return;
- }
- if (success)
- {
- if (!local_tex_obj->getBakedReady() &&
- local_tex_obj->getImage() != NULL &&
- (local_tex_obj->getID() == src_id) &&
- discard_level < local_tex_obj->getDiscard())
- {
- local_tex_obj->setDiscard(discard_level);
- requestLayerSetUpdate(index);
- if (isEditingAppearance())
- {
- LLVisualParamHint::requestHintUpdates();
- }
- updateMeshTextures();
- }
- }
- else if (final)
- {
- // Failed: asset is missing
- if (!local_tex_obj->getBakedReady() &&
- local_tex_obj->getImage() != NULL &&
- local_tex_obj->getImage()->getID() == src_id)
- {
- local_tex_obj->setDiscard(0);
- requestLayerSetUpdate(index);
- updateMeshTextures();
- }
- }
+{
+
+ const LLUUID& src_id = src_vi->getID();
+ LLAvatarTexData *data = (LLAvatarTexData *)userdata;
+ ETextureIndex index = data->mIndex;
+ if (!isIndexLocalTexture(index)) return;
+
+ LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0);
+
+ // fix for EXT-268. Preventing using of NULL pointer
+ if(NULL == local_tex_obj)
+ {
+ LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index
+ << ", final: " << final
+ << LL_ENDL;
+ return;
+ }
+ if (success)
+ {
+ if (!local_tex_obj->getBakedReady() &&
+ local_tex_obj->getImage() != NULL &&
+ (local_tex_obj->getID() == src_id) &&
+ discard_level < local_tex_obj->getDiscard())
+ {
+ local_tex_obj->setDiscard(discard_level);
+ requestLayerSetUpdate(index);
+ if (isEditingAppearance())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+ updateMeshTextures();
+ }
+ }
+ else if (final)
+ {
+ // Failed: asset is missing
+ if (!local_tex_obj->getBakedReady() &&
+ local_tex_obj->getImage() != NULL &&
+ local_tex_obj->getImage()->getID() == src_id)
+ {
+ local_tex_obj->setDiscard(0);
+ requestLayerSetUpdate(index);
+ updateMeshTextures();
+ }
+ }
}
// virtual
BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const
{
- *tex_pp = NULL;
+ *tex_pp = NULL;
- if (!isIndexLocalTexture(type)) return FALSE;
- if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE;
+ if (!isIndexLocalTexture(type)) return FALSE;
+ if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE;
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
- if (!local_tex_obj)
- {
- return FALSE;
- }
- *tex_pp = dynamic_cast<LLViewerTexture*> (local_tex_obj->getImage());
- return TRUE;
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (!local_tex_obj)
+ {
+ return FALSE;
+ }
+ *tex_pp = dynamic_cast<LLViewerTexture*> (local_tex_obj->getImage());
+ return TRUE;
}
LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
- if (!isIndexLocalTexture(type))
- {
- return NULL;
- }
+ if (!isIndexLocalTexture(type))
+ {
+ return NULL;
+ }
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
- if (!local_tex_obj)
- {
- return NULL;
- }
- if (local_tex_obj->getID() == IMG_DEFAULT_AVATAR)
- {
- return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
- }
- return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (!local_tex_obj)
+ {
+ return NULL;
+ }
+ if (local_tex_obj->getID() == IMG_DEFAULT_AVATAR)
+ {
+ return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
+ }
+ return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());
}
const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const
{
- if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR;
+ if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR;
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
- if (local_tex_obj && local_tex_obj->getImage() != NULL)
- {
- return local_tex_obj->getImage()->getID();
- }
- return IMG_DEFAULT_AVATAR;
-}
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (local_tex_obj && local_tex_obj->getImage() != NULL)
+ {
+ return local_tex_obj->getImage()->getID();
+ }
+ return IMG_DEFAULT_AVATAR;
+}
//-----------------------------------------------------------------------------
@@ -1419,35 +1419,35 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c
//-----------------------------------------------------------------------------
BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const
{
- /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
- return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const EBakedTextureIndex baked_index = baked_iter->first;
- if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
- {
- BOOL ret = true;
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
- ret &= tex_avail;
- }
- }
- return ret;
- }
- }
- llassert(0);
- return FALSE;
+ /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
+ return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ BOOL ret = true;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+ ret &= tex_avail;
+ }
+ }
+ return ret;
+ }
+ }
+ llassert(0);
+ return FALSE;
}
//-----------------------------------------------------------------------------
@@ -1458,159 +1458,159 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye
//-----------------------------------------------------------------------------
BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const
{
- const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
- // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- if (layerset == mBakedTextureDatas[i].mTexLayerSet)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
- if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
- (local_discard_level < 0 ))
- {
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- }
- llassert(0);
- return FALSE;
+ const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
+ // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (layerset == mBakedTextureDatas[i].mTexLayerSet)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+ if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+ (local_discard_level < 0 ))
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+ }
+ }
+ llassert(0);
+ return FALSE;
}
BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
{
- const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
- // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
- if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
- (local_discard_level < 0 ))
- {
- return FALSE;
- }
- }
- }
- }
- return TRUE;
+ const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
+ // const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+ if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+ (local_discard_level < 0 ))
+ {
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
}
BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
- LLUUID id;
- BOOL isDefined = TRUE;
- if (isIndexLocalTexture(type))
- {
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- if (index >= wearable_count)
- {
- // invalid index passed in. check all textures of a given type
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- id = getLocalTextureID(type, wearable_index);
- isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
- }
- }
- else
- {
- id = getLocalTextureID(type, index);
- isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
- }
- }
- else
- {
- id = getTEImage(type)->getID();
- isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
- }
-
- return isDefined;
+ LLUUID id;
+ BOOL isDefined = TRUE;
+ if (isIndexLocalTexture(type))
+ {
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ if (index >= wearable_count)
+ {
+ // invalid index passed in. check all textures of a given type
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ id = getLocalTextureID(type, wearable_index);
+ isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
+ }
+ }
+ else
+ {
+ id = getLocalTextureID(type, index);
+ isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
+ }
+ }
+ else
+ {
+ id = getTEImage(type)->getID();
+ isDefined &= (id != IMG_DEFAULT_AVATAR && id != IMG_DEFAULT);
+ }
+
+ return isDefined;
}
//virtual
BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
- if (isIndexBakedTexture(type))
- {
- return LLVOAvatar::isTextureVisible(type, (U32)0);
- }
+ if (isIndexBakedTexture(type))
+ {
+ return LLVOAvatar::isTextureVisible(type, (U32)0);
+ }
- LLUUID tex_id = getLocalTextureID(type,index);
- return (tex_id != IMG_INVISIBLE)
- || (LLDrawPoolAlpha::sShowDebugAlpha);
+ LLUUID tex_id = getLocalTextureID(type,index);
+ return (tex_id != IMG_INVISIBLE)
+ || (LLDrawPoolAlpha::sShowDebugAlpha);
}
//virtual
BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
{
- if (isIndexBakedTexture(type))
- {
- return LLVOAvatar::isTextureVisible(type);
- }
+ if (isIndexBakedTexture(type))
+ {
+ return LLVOAvatar::isTextureVisible(type);
+ }
- U32 index;
- if (gAgentWearables.getWearableIndex(wearable,index))
- {
- return isTextureVisible(type,index);
- }
- else
- {
- LL_WARNS() << "Wearable not found" << LL_ENDL;
- return FALSE;
- }
+ U32 index;
+ if (gAgentWearables.getWearableIndex(wearable,index))
+ {
+ return isTextureVisible(type,index);
+ }
+ else
+ {
+ LL_WARNS() << "Wearable not found" << LL_ENDL;
+ return FALSE;
+ }
}
bool LLVOAvatarSelf::areTexturesCurrent() const
{
- return gAgentWearables.areWearablesLoaded();
+ return gAgentWearables.areWearablesLoaded();
}
void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset)
{
- LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(layerset);
- if( !layer_set || !layer_set->getUpdatesEnabled() )
- {
- return;
- }
- // LL_INFOS() << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << LL_ENDL;
+ LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(layerset);
+ if( !layer_set || !layer_set->getUpdatesEnabled() )
+ {
+ return;
+ }
+ // LL_INFOS() << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << LL_ENDL;
- layer_set->requestUpdate();
- layer_set->invalidateMorphMasks();
+ layer_set->requestUpdate();
+ layer_set->invalidateMorphMasks();
}
void LLVOAvatarSelf::invalidateAll()
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- LLViewerTexLayerSet *layerset = getTexLayerSet(i);
- invalidateComposite(layerset);
- }
- //mDebugSelfLoadTimer.reset();
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ invalidateComposite(layerset);
+ }
+ //mDebugSelfLoadTimer.reset();
}
//-----------------------------------------------------------------------------
@@ -1618,593 +1618,593 @@ void LLVOAvatarSelf::invalidateAll()
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b )
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- setCompositeUpdatesEnabled(i, b);
- }
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ setCompositeUpdatesEnabled(i, b);
+ }
}
void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b)
{
- LLViewerTexLayerSet *layerset = getTexLayerSet(index);
- if (layerset )
- {
- layerset->setUpdatesEnabled( b );
- }
+ LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+ if (layerset )
+ {
+ layerset->setUpdatesEnabled( b );
+ }
}
bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index)
{
- LLViewerTexLayerSet *layerset = getTexLayerSet(index);
- if (layerset)
- {
- return layerset->getUpdatesEnabled();
- }
- return false;
+ LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+ if (layerset)
+ {
+ return layerset->getUpdatesEnabled();
+ }
+ return false;
}
void LLVOAvatarSelf::setupComposites()
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
- BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
- LLViewerTexLayerSet *layerset = getTexLayerSet(i);
- if (layerset)
- {
- layerset->setUpdatesEnabled(!layer_baked);
- }
- }
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
+ BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ if (layerset)
+ {
+ layerset->setUpdatesEnabled(!layer_baked);
+ }
+ }
}
void LLVOAvatarSelf::updateComposites()
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- LLViewerTexLayerSet *layerset = getTexLayerSet(i);
- if (layerset
- && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)))
- {
- layerset->updateComposite();
- }
- }
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ if (layerset
+ && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)))
+ {
+ layerset->updateComposite();
+ }
+ }
}
// virtual
S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index) const
{
- if (!isIndexLocalTexture(type)) return FALSE;
-
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index);
- if (local_tex_obj)
- {
- const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
- if (type >= 0
- && local_tex_obj->getID() != IMG_DEFAULT_AVATAR
- && !image->isMissingAsset())
- {
- return image->getDiscardLevel();
- }
- else
- {
- // We don't care about this (no image associated with the layer) treat as fully loaded.
- return 0;
- }
- }
- return 0;
+ if (!isIndexLocalTexture(type)) return FALSE;
+
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index);
+ if (local_tex_obj)
+ {
+ const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+ if (type >= 0
+ && local_tex_obj->getID() != IMG_DEFAULT_AVATAR
+ && !image->isMissingAsset())
+ {
+ return image->getDiscardLevel();
+ }
+ else
+ {
+ // We don't care about this (no image associated with the layer) treat as fully loaded.
+ return 0;
+ }
+ }
+ return 0;
}
// virtual
// Counts the memory footprint of local textures.
void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const
{
- *gl_bytes = 0;
- for (S32 type = 0; type < TEX_NUM_INDICES; type++)
- {
- if (!isIndexLocalTexture((ETextureIndex)type)) continue;
- U32 max_tex = getNumWearables((ETextureIndex) type);
- for (U32 num = 0; num < max_tex; num++)
- {
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
- if (local_tex_obj)
- {
- const LLViewerFetchedTexture* image_gl = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
- if (image_gl)
- {
- S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
-
- if (image_gl->hasGLTexture())
- {
- *gl_bytes += bytes;
- }
- }
- }
- }
- }
-}
-
-// virtual
+ *gl_bytes = 0;
+ for (S32 type = 0; type < TEX_NUM_INDICES; type++)
+ {
+ if (!isIndexLocalTexture((ETextureIndex)type)) continue;
+ U32 max_tex = getNumWearables((ETextureIndex) type);
+ for (U32 num = 0; num < max_tex; num++)
+ {
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
+ if (local_tex_obj)
+ {
+ const LLViewerFetchedTexture* image_gl = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+ if (image_gl)
+ {
+ S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
+
+ if (image_gl->hasGLTexture())
+ {
+ *gl_bytes += bytes;
+ }
+ }
+ }
+ }
+ }
+}
+
+// virtual
void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready, U32 index)
{
- if (!isIndexLocalTexture(type)) return;
-
- LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ;
- if(!tex)
- {
- return ;
- }
-
- S32 desired_discard = isSelf() ? 0 : 2;
- LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
- if (!local_tex_obj)
- {
- if (type >= TEX_NUM_INDICES)
- {
- LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL;
- return;
- }
- LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
- if (!gAgentWearables.getViewerWearable(wearable_type,index))
- {
- // no wearable is loaded, cannot set the texture.
- return;
- }
- gAgentWearables.addLocalTextureObject(wearable_type,type,index);
- local_tex_obj = getLocalTextureObject(type,index);
- if (!local_tex_obj)
- {
- LL_ERRS() << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << LL_ENDL;
- return;
- }
-
- LLViewerTexLayerSet *layer_set = getLayerSet(type);
- if (layer_set)
- {
- layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));
- }
-
- }
- if (!baked_version_ready)
- {
- if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady())
- {
- local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1);
- }
- if (tex->getID() != IMG_DEFAULT_AVATAR)
- {
- if (local_tex_obj->getDiscard() > desired_discard)
- {
- S32 tex_discard = tex->getDiscardLevel();
- if (tex_discard >= 0 && tex_discard <= desired_discard)
- {
- local_tex_obj->setDiscard(tex_discard);
- if (isSelf())
- {
- requestLayerSetUpdate(type);
- if (isEditingAppearance())
- {
- LLVisualParamHint::requestHintUpdates();
- }
- }
- }
- else
- {
- tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
- }
- }
- tex->setMinDiscardLevel(desired_discard);
- }
- }
- local_tex_obj->setImage(tex);
- local_tex_obj->setID(tex->getID());
- setBakedReady(type,baked_version_ready,index);
+ if (!isIndexLocalTexture(type)) return;
+
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ;
+ if(!tex)
+ {
+ return ;
+ }
+
+ S32 desired_discard = isSelf() ? 0 : 2;
+ LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
+ if (!local_tex_obj)
+ {
+ if (type >= TEX_NUM_INDICES)
+ {
+ LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL;
+ return;
+ }
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
+ if (!gAgentWearables.getViewerWearable(wearable_type,index))
+ {
+ // no wearable is loaded, cannot set the texture.
+ return;
+ }
+ gAgentWearables.addLocalTextureObject(wearable_type,type,index);
+ local_tex_obj = getLocalTextureObject(type,index);
+ if (!local_tex_obj)
+ {
+ LL_ERRS() << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << LL_ENDL;
+ return;
+ }
+
+ LLViewerTexLayerSet *layer_set = getLayerSet(type);
+ if (layer_set)
+ {
+ layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));
+ }
+
+ }
+ if (!baked_version_ready)
+ {
+ if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady())
+ {
+ local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1);
+ }
+ if (tex->getID() != IMG_DEFAULT_AVATAR)
+ {
+ if (local_tex_obj->getDiscard() > desired_discard)
+ {
+ S32 tex_discard = tex->getDiscardLevel();
+ if (tex_discard >= 0 && tex_discard <= desired_discard)
+ {
+ local_tex_obj->setDiscard(tex_discard);
+ if (isSelf())
+ {
+ requestLayerSetUpdate(type);
+ if (isEditingAppearance())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+ }
+ }
+ else
+ {
+ tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
+ }
+ }
+ tex->setMinDiscardLevel(desired_discard);
+ }
+ }
+ local_tex_obj->setImage(tex);
+ local_tex_obj->setID(tex->getID());
+ setBakedReady(type,baked_version_ready,index);
}
//virtual
void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
- if (!isIndexLocalTexture(type)) return;
- LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
- if (local_tex_obj)
- {
- local_tex_obj->setBakedReady( baked_version_exists );
- }
+ if (!isIndexLocalTexture(type)) return;
+ LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
+ if (local_tex_obj)
+ {
+ local_tex_obj->setBakedReady( baked_version_exists );
+ }
}
// virtual
void LLVOAvatarSelf::dumpLocalTextures() const
{
- LL_INFOS() << "Local Textures:" << LL_ENDL;
-
- /* ETextureIndex baked_equiv[] = {
- TEX_UPPER_BAKED,
- if (isTextureDefined(baked_equiv[i])) */
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
- iter != sAvatarDictionary->getTextures().end();
- ++iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
- continue;
-
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex;
-
- const std::string &name = texture_dict->mName;
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
- // index is baked texture - index is not relevant. putting in 0 as placeholder
- if (isTextureDefined(baked_equiv, 0))
- {
+ LL_INFOS() << "Local Textures:" << LL_ENDL;
+
+ /* ETextureIndex baked_equiv[] = {
+ TEX_UPPER_BAKED,
+ if (isTextureDefined(baked_equiv[i])) */
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
+ ++iter)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
+ continue;
+
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex;
+
+ const std::string &name = texture_dict->mName;
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
+ // index is baked texture - index is not relevant. putting in 0 as placeholder
+ if (isTextureDefined(baked_equiv, 0))
+ {
#if LL_RELEASE_FOR_DOWNLOAD
- // End users don't get to trivially see avatar texture IDs, makes textures
- // easier to steal. JC
- LL_INFOS() << "LocTex " << name << ": Baked " << LL_ENDL;
+ // End users don't get to trivially see avatar texture IDs, makes textures
+ // easier to steal. JC
+ LL_INFOS() << "LocTex " << name << ": Baked " << LL_ENDL;
#else
- LL_INFOS() << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << LL_ENDL;
+ LL_INFOS() << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << LL_ENDL;
#endif
- }
- else if (local_tex_obj && local_tex_obj->getImage() != NULL)
- {
- if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR)
- {
- LL_INFOS() << "LocTex " << name << ": None" << LL_ENDL;
- }
- else
- {
- LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
-
- LL_INFOS() << "LocTex " << name << ": "
- << "Discard " << image->getDiscardLevel() << ", "
- << "(" << image->getWidth() << ", " << image->getHeight() << ") "
+ }
+ else if (local_tex_obj && local_tex_obj->getImage() != NULL)
+ {
+ if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR)
+ {
+ LL_INFOS() << "LocTex " << name << ": None" << LL_ENDL;
+ }
+ else
+ {
+ LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+
+ LL_INFOS() << "LocTex " << name << ": "
+ << "Discard " << image->getDiscardLevel() << ", "
+ << "(" << image->getWidth() << ", " << image->getHeight() << ") "
#if !LL_RELEASE_FOR_DOWNLOAD
- // End users don't get to trivially see avatar texture IDs,
- // makes textures easier to steal
- << image->getID() << " "
+ // End users don't get to trivially see avatar texture IDs,
+ // makes textures easier to steal
+ << image->getID() << " "
#endif
- << "Priority: " << image->getMaxVirtualSize()
- << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS() << "LocTex " << name << ": No LLViewerTexture" << LL_ENDL;
- }
- }
+ << "Priority: " << image->getMaxVirtualSize()
+ << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS() << "LocTex " << name << ": No LLViewerTexture" << LL_ENDL;
+ }
+ }
}
//-----------------------------------------------------------------------------
-// static
+// static
// onLocalTextureLoaded()
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
- LLAvatarTexData *data = (LLAvatarTexData *)userdata;
- LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID);
- if (self)
- {
- // We should only be handling local textures for ourself
- self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata);
- }
- // ensure data is cleaned up
- if (final || !success)
- {
- delete data;
- }
+ LLAvatarTexData *data = (LLAvatarTexData *)userdata;
+ LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID);
+ if (self)
+ {
+ // We should only be handling local textures for ourself
+ self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata);
+ }
+ // ensure data is cleaned up
+ if (final || !success)
+ {
+ delete data;
+ }
}
-/*virtual*/ void LLVOAvatarSelf::setImage(const U8 te, LLViewerTexture *imagep, const U32 index)
+/*virtual*/ void LLVOAvatarSelf::setImage(const U8 te, LLViewerTexture *imagep, const U32 index)
{
- if (isIndexLocalTexture((ETextureIndex)te))
- {
- setLocalTexture((ETextureIndex)te, imagep, FALSE ,index);
- }
- else
- {
- setTEImage(te,imagep);
- }
+ if (isIndexLocalTexture((ETextureIndex)te))
+ {
+ setLocalTexture((ETextureIndex)te, imagep, FALSE ,index);
+ }
+ else
+ {
+ setTEImage(te,imagep);
+ }
}
/*virtual*/ LLViewerTexture* LLVOAvatarSelf::getImage(const U8 te, const U32 index) const
{
- if (isIndexLocalTexture((ETextureIndex)te))
- {
- return getLocalTextureGL((ETextureIndex)te,index);
- }
- else
- {
- return getTEImage(te);
- }
+ if (isIndexLocalTexture((ETextureIndex)te))
+ {
+ return getLocalTextureGL((ETextureIndex)te,index);
+ }
+ else
+ {
+ return getTEImage(te);
+ }
}
// static
void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
{
- S32 gl_bytes = 0;
- gAgentAvatarp->getLocalTextureByteCount(&gl_bytes);
- LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL;
+ S32 gl_bytes = 0;
+ gAgentAvatarp->getLocalTextureByteCount(&gl_bytes);
+ LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL;
}
bool LLVOAvatarSelf::getIsCloud() const
{
- // Let people know why they're clouded without spamming them into oblivion.
- bool do_warn = false;
- static LLTimer time_since_notice;
- F32 update_freq = 30.0;
- if (time_since_notice.getElapsedTimeF32() > update_freq)
- {
- time_since_notice.reset();
- do_warn = true;
- }
-
- // do we have our body parts?
- S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
- S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
- S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
- S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
- if (!shape_count || !hair_count || !eye_count || !skin_count)
- {
- if (do_warn)
- {
- LL_INFOS() << "Self is clouded due to missing one or more required body parts: "
- << (shape_count ? "" : "SHAPE ")
- << (hair_count ? "" : "HAIR ")
- << (eye_count ? "" : "EYES ")
- << (skin_count ? "" : "SKIN ")
- << LL_ENDL;
- }
- return true;
- }
-
- if (!isTextureDefined(TEX_HAIR, 0))
- {
- if (do_warn)
- {
- LL_INFOS() << "Self is clouded because of no hair texture" << LL_ENDL;
- }
- return true;
- }
-
- if (!mPreviousFullyLoaded)
- {
- if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&
- (!isTextureDefined(TEX_LOWER_BAKED, 0)))
- {
- if (do_warn)
- {
- LL_INFOS() << "Self is clouded because lower textures not baked" << LL_ENDL;
- }
- return true;
- }
-
- if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) &&
- (!isTextureDefined(TEX_UPPER_BAKED, 0)))
- {
- if (do_warn)
- {
- LL_INFOS() << "Self is clouded because upper textures not baked" << LL_ENDL;
- }
- return true;
- }
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- if (i == BAKED_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
- continue;
-
- const BakedTextureData& texture_data = mBakedTextureDatas[i];
- if (!isTextureDefined(texture_data.mTextureIndex, 0))
- continue;
-
- // Check for the case that texture is defined but not sufficiently loaded to display anything.
- const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
- if (!baked_img || !baked_img->hasGLTexture())
- {
- if (do_warn)
- {
- LL_INFOS() << "Self is clouded because texture at index " << i
- << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << LL_ENDL;
- }
- return true;
- }
- }
-
- LL_DEBUGS() << "Avatar de-clouded" << LL_ENDL;
- }
- return false;
+ // Let people know why they're clouded without spamming them into oblivion.
+ bool do_warn = false;
+ static LLTimer time_since_notice;
+ F32 update_freq = 30.0;
+ if (time_since_notice.getElapsedTimeF32() > update_freq)
+ {
+ time_since_notice.reset();
+ do_warn = true;
+ }
+
+ // do we have our body parts?
+ S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+ S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+ S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+ S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+ if (!shape_count || !hair_count || !eye_count || !skin_count)
+ {
+ if (do_warn)
+ {
+ LL_INFOS() << "Self is clouded due to missing one or more required body parts: "
+ << (shape_count ? "" : "SHAPE ")
+ << (hair_count ? "" : "HAIR ")
+ << (eye_count ? "" : "EYES ")
+ << (skin_count ? "" : "SKIN ")
+ << LL_ENDL;
+ }
+ return true;
+ }
+
+ if (!isTextureDefined(TEX_HAIR, 0))
+ {
+ if (do_warn)
+ {
+ LL_INFOS() << "Self is clouded because of no hair texture" << LL_ENDL;
+ }
+ return true;
+ }
+
+ if (!mPreviousFullyLoaded)
+ {
+ if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&
+ (!isTextureDefined(TEX_LOWER_BAKED, 0)))
+ {
+ if (do_warn)
+ {
+ LL_INFOS() << "Self is clouded because lower textures not baked" << LL_ENDL;
+ }
+ return true;
+ }
+
+ if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) &&
+ (!isTextureDefined(TEX_UPPER_BAKED, 0)))
+ {
+ if (do_warn)
+ {
+ LL_INFOS() << "Self is clouded because upper textures not baked" << LL_ENDL;
+ }
+ return true;
+ }
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (i == BAKED_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
+ continue;
+
+ const BakedTextureData& texture_data = mBakedTextureDatas[i];
+ if (!isTextureDefined(texture_data.mTextureIndex, 0))
+ continue;
+
+ // Check for the case that texture is defined but not sufficiently loaded to display anything.
+ const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
+ if (!baked_img || !baked_img->hasGLTexture())
+ {
+ if (do_warn)
+ {
+ LL_INFOS() << "Self is clouded because texture at index " << i
+ << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << LL_ENDL;
+ }
+ return true;
+ }
+ }
+
+ LL_DEBUGS() << "Avatar de-clouded" << LL_ENDL;
+ }
+ return false;
}
/*static*/
void LLVOAvatarSelf::debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
- if (gAgentAvatarp.notNull())
- {
- gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata);
- }
+ if (gAgentAvatarp.notNull())
+ {
+ gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata);
+ }
}
void LLVOAvatarSelf::debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
- LLAvatarTexData *data = (LLAvatarTexData *)userdata;
- if (!data)
- {
- return;
- }
-
- ETextureIndex index = data->mIndex;
-
- if (index < 0 || index >= TEX_NUM_INDICES)
- {
- return;
- }
-
- if (discard_level >=0 && discard_level <= MAX_DISCARD_LEVEL) // ignore discard level -1, as it means we have no data.
- {
- mDebugTextureLoadTimes[(U32)index][(U32)discard_level] = mDebugSelfLoadTimer.getElapsedTimeF32();
- }
- if (final)
- {
- delete data;
- }
+ LLAvatarTexData *data = (LLAvatarTexData *)userdata;
+ if (!data)
+ {
+ return;
+ }
+
+ ETextureIndex index = data->mIndex;
+
+ if (index < 0 || index >= TEX_NUM_INDICES)
+ {
+ return;
+ }
+
+ if (discard_level >=0 && discard_level <= MAX_DISCARD_LEVEL) // ignore discard level -1, as it means we have no data.
+ {
+ mDebugTextureLoadTimes[(U32)index][(U32)discard_level] = mDebugSelfLoadTimer.getElapsedTimeF32();
+ }
+ if (final)
+ {
+ delete data;
+ }
}
void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL finished)
{
- U32 done = 0;
- if (finished)
- {
- done = 1;
- }
- mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
+ U32 done = 0;
+ if (finished)
+ {
+ done = 1;
+ }
+ mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
}
const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
{
- std::ostringstream outbuf;
+ std::ostringstream outbuf;
LLWearableType *wr_inst = LLWearableType::getInstance();
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const EBakedTextureIndex baked_index = baked_iter->first;
- if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
- {
- outbuf << "baked_index: " << baked_index << "\n";
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName;
- outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n";
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- if (wearable_count > 0)
- {
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- outbuf << " " << wr_inst->getTypeName(wearable_type) << " " << wearable_index << ":";
- const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);
- if (local_tex_obj)
- {
- LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
- if (tex_index >= 0
- && local_tex_obj->getID() != IMG_DEFAULT_AVATAR
- && !image->isMissingAsset())
- {
- outbuf << " id: " << image->getID()
- << " refs: " << image->getNumRefs()
- << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
- << " discard: " << image->getDiscardLevel()
- << " desired: " << image->getDesiredDiscardLevel()
- << " vsize: " << image->getMaxVirtualSize()
- << " ts: " << image->getTextureState()
- << " bl: " << image->getBoostLevel()
- << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
- << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded"
- << " mvs: " << image->getMaxVirtualSize()
- << " mvsc: " << image->getMaxVirtualSizeResetCounter()
- << " mem: " << image->getTextureMemory();
- }
- }
- outbuf << "\n";
- }
- }
- }
- break;
- }
- }
- return outbuf.str();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+ sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ outbuf << "baked_index: " << baked_index << "\n";
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName;
+ outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n";
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ if (wearable_count > 0)
+ {
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ outbuf << " " << wr_inst->getTypeName(wearable_type) << " " << wearable_index << ":";
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);
+ if (local_tex_obj)
+ {
+ LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+ if (tex_index >= 0
+ && local_tex_obj->getID() != IMG_DEFAULT_AVATAR
+ && !image->isMissingAsset())
+ {
+ outbuf << " id: " << image->getID()
+ << " refs: " << image->getNumRefs()
+ << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
+ << " discard: " << image->getDiscardLevel()
+ << " desired: " << image->getDesiredDiscardLevel()
+ << " vsize: " << image->getMaxVirtualSize()
+ << " ts: " << image->getTextureState()
+ << " bl: " << image->getBoostLevel()
+ << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
+ << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded"
+ << " mvs: " << image->getMaxVirtualSize()
+ << " mvsc: " << image->getMaxVirtualSizeResetCounter()
+ << " mem: " << image->getTextureMemory();
+ }
+ }
+ outbuf << "\n";
+ }
+ }
+ }
+ break;
+ }
+ }
+ return outbuf.str();
}
void LLVOAvatarSelf::dumpAllTextures() const
{
- std::string vd_text = "Local textures per baked index and wearable:\n";
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
- const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
- if (!layerset) continue;
- const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
- if (!layerset_buffer) continue;
- vd_text += verboseDebugDumpLocalTextureDataInfo(layerset);
- }
- LL_DEBUGS("Avatar") << vd_text << LL_ENDL;
+ std::string vd_text = "Local textures per baked index and wearable:\n";
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+ const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
+ if (!layerset) continue;
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
+ if (!layerset_buffer) continue;
+ vd_text += verboseDebugDumpLocalTextureDataInfo(layerset);
+ }
+ LL_DEBUGS("Avatar") << vd_text << LL_ENDL;
}
const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
{
- std::string text="";
+ std::string text="";
LLWearableType *wr_inst = LLWearableType::getInstance();
- text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset));
-
- /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
- return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const EBakedTextureIndex baked_index = baked_iter->first;
- if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
- text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- if (wearable_count > 0)
- {
- text += wr_inst->getTypeName(wearable_type) + ":";
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index);
- std::string discard_str = llformat("%d ",discard_level);
- text += llformat("%d ",discard_level);
- }
- }
- }
- text += ")";
- break;
- }
- }
- return text;
+ text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset));
+
+ /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
+ return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ if (wearable_count > 0)
+ {
+ text += wr_inst->getTypeName(wearable_type) + ":";
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index);
+ std::string discard_str = llformat("%d ",discard_level);
+ text += llformat("%d ",discard_level);
+ }
+ }
+ }
+ text += ")";
+ break;
+ }
+ }
+ return text;
}
const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
{
- std::string text;
- const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
- BOOL is_texture_final = TRUE;
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- ++local_tex_iter)
- {
- const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
- const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
- for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
- {
- is_texture_final &= (getLocalDiscardLevel(*local_tex_iter, wearable_index) <= (S32)(override_tex_discard_level));
- }
- }
- text += llformat("%s:%d ",baked_dict->mName.c_str(),is_texture_final);
- }
- return text;
+ std::string text;
+ const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
+ BOOL is_texture_final = TRUE;
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ is_texture_final &= (getLocalDiscardLevel(*local_tex_iter, wearable_index) <= (S32)(override_tex_discard_level));
+ }
+ }
+ text += llformat("%s:%d ",baked_dict->mName.c_str(),is_texture_final);
+ }
+ return text;
}
void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
@@ -2241,7 +2241,7 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
msg["nearby"][rez_status_name] = rez_counts[rez_stat];
}
- // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+ // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
std::vector<std::string> by_fields;
by_fields.push_back("timer_name");
by_fields.push_back("completed");
@@ -2280,233 +2280,233 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
{
- const F32 AV_METRICS_INTERVAL_QA = 30.0;
- F32 send_period = 300.0;
+ const F32 AV_METRICS_INTERVAL_QA = 30.0;
+ F32 send_period = 300.0;
- static LLCachedControl<bool> qa_mode_metrics(gSavedSettings,"QAModeMetrics");
- if (qa_mode_metrics)
- {
- send_period = AV_METRICS_INTERVAL_QA;
- }
+ static LLCachedControl<bool> qa_mode_metrics(gSavedSettings,"QAModeMetrics");
+ if (qa_mode_metrics)
+ {
+ send_period = AV_METRICS_INTERVAL_QA;
+ }
- if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period)
- {
- // Stats for completed phases have been getting logged as they
- // complete. This will give us stats for any timers that
- // haven't finished as of the metric's being sent.
-
- if (force_send)
- {
- LLVOAvatar::logPendingPhasesAllAvatars();
- }
- sendViewerAppearanceChangeMetrics();
- }
+ if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period)
+ {
+ // Stats for completed phases have been getting logged as they
+ // complete. This will give us stats for any timers that
+ // haven't finished as of the metric's being sent.
+
+ if (force_send)
+ {
+ LLVOAvatar::logPendingPhasesAllAvatars();
+ }
+ sendViewerAppearanceChangeMetrics();
+ }
- return false;
+ return false;
}
void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record)
{
- mPendingTimerRecords.push_back(record);
+ mPendingTimerRecords.push_back(record);
}
bool operator<(const LLSD& a, const LLSD& b)
{
- std::ostringstream aout, bout;
- aout << LLSDNotationStreamer(a);
- bout << LLSDNotationStreamer(b);
- std::string astring = aout.str();
- std::string bstring = bout.str();
+ std::ostringstream aout, bout;
+ aout << LLSDNotationStreamer(a);
+ bout << LLSDNotationStreamer(b);
+ std::string astring = aout.str();
+ std::string bstring = bout.str();
- return astring < bstring;
+ return astring < bstring;
}
// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field.
LLSD summarize_by_buckets(std::vector<LLSD> in_records,
- std::vector<std::string> by_fields,
- std::string val_field)
-{
- LLSD result = LLSD::emptyArray();
- std::map<LLSD,LLViewerStats::StatsAccumulator> accum;
- for (std::vector<LLSD>::iterator in_record_iter = in_records.begin();
- in_record_iter != in_records.end(); ++in_record_iter)
- {
- LLSD& record = *in_record_iter;
- LLSD key;
- for (std::vector<std::string>::iterator field_iter = by_fields.begin();
- field_iter != by_fields.end(); ++field_iter)
- {
- const std::string& field = *field_iter;
- key[field] = record[field];
- }
- LLViewerStats::StatsAccumulator& stats = accum[key];
- F32 value = record[val_field].asReal();
- stats.push(value);
- }
- for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin();
- accum_it != accum.end(); ++accum_it)
- {
- LLSD out_record = accum_it->first;
- out_record["stats"] = accum_it->second.asLLSD();
- result.append(out_record);
- }
- return result;
+ std::vector<std::string> by_fields,
+ std::string val_field)
+{
+ LLSD result = LLSD::emptyArray();
+ std::map<LLSD,LLViewerStats::StatsAccumulator> accum;
+ for (std::vector<LLSD>::iterator in_record_iter = in_records.begin();
+ in_record_iter != in_records.end(); ++in_record_iter)
+ {
+ LLSD& record = *in_record_iter;
+ LLSD key;
+ for (std::vector<std::string>::iterator field_iter = by_fields.begin();
+ field_iter != by_fields.end(); ++field_iter)
+ {
+ const std::string& field = *field_iter;
+ key[field] = record[field];
+ }
+ LLViewerStats::StatsAccumulator& stats = accum[key];
+ F32 value = record[val_field].asReal();
+ stats.push(value);
+ }
+ for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin();
+ accum_it != accum.end(); ++accum_it)
+ {
+ LLSD out_record = accum_it->first;
+ out_record["stats"] = accum_it->second.asLLSD();
+ result.append(out_record);
+ }
+ return result;
}
void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
{
- std::string caps_url;
- if (getRegion())
- {
- // runway - change here to activate.
- caps_url = getRegion()->getCapability("ViewerMetrics");
- }
- if (!caps_url.empty())
- {
+ std::string caps_url;
+ if (getRegion())
+ {
+ // runway - change here to activate.
+ caps_url = getRegion()->getCapability("ViewerMetrics");
+ }
+ if (!caps_url.empty())
+ {
LLCoros::instance().launch("LLVOAvatarSelf::appearanceChangeMetricsCoro",
boost::bind(&LLVOAvatarSelf::appearanceChangeMetricsCoro, this, caps_url));
- mTimeSinceLastRezMessage.reset();
- }
+ mTimeSinceLastRezMessage.reset();
+ }
}
const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
{
- if (canGrabBakedTexture(baked_index))
- {
- ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
- if (tex_index == TEX_NUM_INDICES)
- {
- return LLUUID::null;
- }
- return getTEImage( tex_index )->getID();
- }
- return LLUUID::null;
+ if (canGrabBakedTexture(baked_index))
+ {
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
+ if (tex_index == TEX_NUM_INDICES)
+ {
+ return LLUUID::null;
+ }
+ return getTEImage( tex_index )->getID();
+ }
+ return LLUUID::null;
}
BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
{
- ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
- if (tex_index == TEX_NUM_INDICES)
- {
- return FALSE;
- }
- // Check if the texture hasn't been baked yet.
- if (!isTextureDefined(tex_index, 0))
- {
- LL_DEBUGS() << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << LL_ENDL;
- return FALSE;
- }
-
- if (gAgent.isGodlikeWithoutAdminMenuFakery())
- return TRUE;
-
- // Check permissions of textures that show up in the
- // baked texture. We don't want people copying people's
- // work via baked textures.
-
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index);
- for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
- iter != baked_dict->mLocalTextures.end();
- ++iter)
- {
- const ETextureIndex t_index = (*iter);
- LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index);
- U32 count = gAgentWearables.getWearableCount(wearable_type);
- LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL;
-
- for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
- {
- LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);
- if (wearable)
- {
- const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
- const LLUUID& texture_id = texture->getID();
- if (texture_id != IMG_DEFAULT_AVATAR)
- {
- // Search inventory for this texture.
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLAssetIDMatches asset_id_matches(texture_id);
- gInventory.collectDescendentsIf(LLUUID::null,
- cats,
- items,
- LLInventoryModel::INCLUDE_TRASH,
- asset_id_matches);
-
- BOOL can_grab = FALSE;
- LL_DEBUGS() << "item count for asset " << texture_id << ": " << items.size() << LL_ENDL;
- if (items.size())
- {
- // search for full permissions version
- for (S32 i = 0; i < items.size(); i++)
- {
- LLViewerInventoryItem* itemp = items[i];
- if (itemp->getIsFullPerm())
- {
- can_grab = TRUE;
- break;
- }
- }
- }
- if (!can_grab) return FALSE;
- }
- }
- }
- }
-
- return TRUE;
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
+ if (tex_index == TEX_NUM_INDICES)
+ {
+ return FALSE;
+ }
+ // Check if the texture hasn't been baked yet.
+ if (!isTextureDefined(tex_index, 0))
+ {
+ LL_DEBUGS() << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << LL_ENDL;
+ return FALSE;
+ }
+
+ if (gAgent.isGodlikeWithoutAdminMenuFakery())
+ return TRUE;
+
+ // Check permissions of textures that show up in the
+ // baked texture. We don't want people copying people's
+ // work via baked textures.
+
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index);
+ for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
+ iter != baked_dict->mLocalTextures.end();
+ ++iter)
+ {
+ const ETextureIndex t_index = (*iter);
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index);
+ U32 count = gAgentWearables.getWearableCount(wearable_type);
+ LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL;
+
+ for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
+ {
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);
+ if (wearable)
+ {
+ const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
+ const LLUUID& texture_id = texture->getID();
+ if (texture_id != IMG_DEFAULT_AVATAR)
+ {
+ // Search inventory for this texture.
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(texture_id);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ BOOL can_grab = FALSE;
+ LL_DEBUGS() << "item count for asset " << texture_id << ": " << items.size() << LL_ENDL;
+ if (items.size())
+ {
+ // search for full permissions version
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp->getIsFullPerm())
+ {
+ can_grab = TRUE;
+ break;
+ }
+ }
+ }
+ if (!can_grab) return FALSE;
+ }
+ }
+ }
+ }
+
+ return TRUE;
}
void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep,
- F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
-{
- if (!isIndexLocalTexture(type)) return;
-
- // Sunshine - ignoring covered_by_baked will force local textures
- // to always load. Fix for SH-4001 and many related issues. Do
- // not restore this without some more targetted fix for the local
- // textures failing to load issue.
- //if (!covered_by_baked)
- {
- if (imagep->getID() != IMG_DEFAULT_AVATAR)
- {
- imagep->setNoDelete();
- if (imagep->getDiscardLevel() != 0)
- {
- F32 desired_pixels;
- desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
-
- imagep->setBoostLevel(getAvatarBoostLevel());
- imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
- imagep->addTextureStats( desired_pixels / texel_area_ratio );
- imagep->forceUpdateBindStats() ;
- if (imagep->getDiscardLevel() < 0)
- {
- mHasGrey = TRUE; // for statistics gathering
- }
- }
- }
- else
- {
- // texture asset is missing
- mHasGrey = TRUE; // for statistics gathering
- }
- }
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
+{
+ if (!isIndexLocalTexture(type)) return;
+
+ // Sunshine - ignoring covered_by_baked will force local textures
+ // to always load. Fix for SH-4001 and many related issues. Do
+ // not restore this without some more targetted fix for the local
+ // textures failing to load issue.
+ //if (!covered_by_baked)
+ {
+ if (imagep->getID() != IMG_DEFAULT_AVATAR)
+ {
+ imagep->setNoDelete();
+ if (imagep->getDiscardLevel() != 0)
+ {
+ F32 desired_pixels;
+ desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+
+ imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->resetTextureStats();
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
+ imagep->addTextureStats( desired_pixels / texel_area_ratio );
+ imagep->forceUpdateBindStats() ;
+ if (imagep->getDiscardLevel() < 0)
+ {
+ mHasGrey = TRUE; // for statistics gathering
+ }
+ }
+ }
+ else
+ {
+ // texture asset is missing
+ mHasGrey = TRUE; // for statistics gathering
+ }
+ }
}
LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
{
- LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
- LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
- if (wearable)
- {
- return wearable->getLocalTextureObject(i);
- }
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
+ if (wearable)
+ {
+ return wearable->getLocalTextureObject(i);
+ }
- return NULL;
+ return NULL;
}
//-----------------------------------------------------------------------------
@@ -2515,119 +2515,119 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDe
//-----------------------------------------------------------------------------
ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const
{
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- if (layerset == mBakedTextureDatas[i].mTexLayerSet )
- {
- return mBakedTextureDatas[i].mTextureIndex;
- }
- }
- llassert(0);
- return TEX_HEAD_BAKED;
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (layerset == mBakedTextureDatas[i].mTexLayerSet )
+ {
+ return mBakedTextureDatas[i].mTextureIndex;
+ }
+ }
+ llassert(0);
+ return TEX_HEAD_BAKED;
}
// FIXME: This is not called consistently. Something may be broken.
void LLVOAvatarSelf::outputRezDiagnostics() const
{
- if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
- {
- return ;
- }
-
- const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32();
- LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << LL_ENDL;
- LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << LL_ENDL;
- LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << LL_ENDL;
- LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << LL_ENDL;
- LL_DEBUGS("Avatar") << "\t Load time for each texture: " << LL_ENDL;
- for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
- {
- std::stringstream out;
- out << "\t\t (" << i << ") ";
- U32 j=0;
- for (j=0; j <= MAX_DISCARD_LEVEL; j++)
- {
- out << "\t";
- S32 load_time = (S32)mDebugTextureLoadTimes[i][j];
- if (load_time == -1)
- {
- out << "*";
- if (j == 0)
- break;
- }
- else
- {
- out << load_time;
- }
- }
-
- // Don't print out non-existent textures.
- if (j != 0)
- {
- LL_DEBUGS("Avatar") << out.str() << LL_ENDL;
- }
- }
- LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << LL_ENDL;
- for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
- {
- LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL;
- }
-
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
- baked_iter != sAvatarDictionary->getBakedTextures().end();
- ++baked_iter)
- {
- const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
- const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
- if (!layerset) continue;
- const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
- if (!layerset_buffer) continue;
- LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << LL_ENDL;
- }
-
- dumpAllTextures();
+ if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
+ {
+ return ;
+ }
+
+ const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32();
+ LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << LL_ENDL;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << LL_ENDL;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << LL_ENDL;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << LL_ENDL;
+ LL_DEBUGS("Avatar") << "\t Load time for each texture: " << LL_ENDL;
+ for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
+ {
+ std::stringstream out;
+ out << "\t\t (" << i << ") ";
+ U32 j=0;
+ for (j=0; j <= MAX_DISCARD_LEVEL; j++)
+ {
+ out << "\t";
+ S32 load_time = (S32)mDebugTextureLoadTimes[i][j];
+ if (load_time == -1)
+ {
+ out << "*";
+ if (j == 0)
+ break;
+ }
+ else
+ {
+ out << load_time;
+ }
+ }
+
+ // Don't print out non-existent textures.
+ if (j != 0)
+ {
+ LL_DEBUGS("Avatar") << out.str() << LL_ENDL;
+ }
+ }
+ LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << LL_ENDL;
+ for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
+ {
+ LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL;
+ }
+
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+ const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
+ if (!layerset) continue;
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
+ if (!layerset_buffer) continue;
+ LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << LL_ENDL;
+ }
+
+ dumpAllTextures();
}
void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
{
- LL_DEBUGS("Avatar")
- << avString()
- << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
- << LL_ENDL;
+ LL_DEBUGS("Avatar")
+ << avString()
+ << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
+ << LL_ENDL;
}
void LLVOAvatarSelf::reportAvatarRezTime() const
{
- // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow.
+ // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow.
}
// SUNSHINE CLEANUP - not clear we need any of this, may be sufficient to request server appearance in llviewermenu.cpp:handle_rebake_textures()
void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
{
- LL_INFOS() << "TAT: forced full rebake. " << LL_ENDL;
+ LL_INFOS() << "TAT: forced full rebake. " << LL_ENDL;
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
- LLViewerTexLayerSet* layer_set = getLayerSet(baked_index);
- if (layer_set)
- {
- if (slam_for_debug)
- {
- layer_set->setUpdatesEnabled(TRUE);
- }
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
+ LLViewerTexLayerSet* layer_set = getLayerSet(baked_index);
+ if (layer_set)
+ {
+ if (slam_for_debug)
+ {
+ layer_set->setUpdatesEnabled(TRUE);
+ }
- invalidateComposite(layer_set);
- add(LLStatViewer::TEX_REBAKES, 1);
- }
- else
- {
- LL_WARNS() << "TAT: NO LAYER SET FOR " << (S32)baked_index << LL_ENDL;
- }
- }
+ invalidateComposite(layer_set);
+ add(LLStatViewer::TEX_REBAKES, 1);
+ }
+ else
+ {
+ LL_WARNS() << "TAT: NO LAYER SET FOR " << (S32)baked_index << LL_ENDL;
+ }
+ }
- // Don't know if this is needed
- updateMeshTextures();
+ // Don't know if this is needed
+ updateMeshTextures();
}
//-----------------------------------------------------------------------------
@@ -2635,21 +2635,21 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
{
- /* switch(index)
- case LOCTEX_UPPER_BODYPAINT:
- case LOCTEX_UPPER_SHIRT:
- if( mUpperBodyLayerSet )
- mUpperBodyLayerSet->requestUpdate(); */
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
- if (!texture_dict)
- return;
- if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
- return;
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- if (mBakedTextureDatas[baked_index].mTexLayerSet)
- {
- mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate();
- }
+ /* switch(index)
+ case LOCTEX_UPPER_BODYPAINT:
+ case LOCTEX_UPPER_SHIRT:
+ if( mUpperBodyLayerSet )
+ mUpperBodyLayerSet->requestUpdate(); */
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
+ if (!texture_dict)
+ return;
+ if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
+ return;
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ if (mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate();
+ }
}
LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
@@ -2675,7 +2675,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index)
return mHeadLayerSet; */
if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
{
- return getTexLayerSet(baked_index);
+ return getTexLayerSet(baked_index);
}
return NULL;
}
@@ -2686,54 +2686,54 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index)
// static
void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
{
- if (isAgentAvatarValid())
- {
- LLUIUsage::instance().logCommand("Avatar.CustomizeStart");
- if (!gAgentAvatarp->mEndCustomizeCallback.get())
- {
- gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy;
- }
-
- gAgentAvatarp->mIsEditingAppearance = true;
- gAgentAvatarp->mUseLocalAppearance = true;
-
- if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
- {
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
-
- gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
- gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
- gAgentAvatarp->updateTextures(); // call updateTextureStats
- }
+ if (isAgentAvatarValid())
+ {
+ LLUIUsage::instance().logCommand("Avatar.CustomizeStart");
+ if (!gAgentAvatarp->mEndCustomizeCallback.get())
+ {
+ gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy;
+ }
+
+ gAgentAvatarp->mIsEditingAppearance = true;
+ gAgentAvatarp->mUseLocalAppearance = true;
+
+ if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+ {
+ gAgentCamera.changeCameraToCustomizeAvatar();
+ }
+
+ gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
+ gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
+ gAgentAvatarp->updateTextures(); // call updateTextureStats
+ }
}
// static
void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch)
{
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->mIsEditingAppearance = false;
- gAgentAvatarp->invalidateAll();
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->mIsEditingAppearance = false;
+ gAgentAvatarp->invalidateAll();
- if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
- {
- gAgentCamera.changeCameraToDefault();
- gAgentCamera.resetView();
- }
+ if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+ {
+ gAgentCamera.changeCameraToDefault();
+ gAgentCamera.resetView();
+ }
- // Dereferencing the previous callback will cause
- // updateAppearanceFromCOF to be called, whenever all refs
- // have resolved.
- gAgentAvatarp->mEndCustomizeCallback = NULL;
- }
+ // Dereferencing the previous callback will cause
+ // updateAppearanceFromCOF to be called, whenever all refs
+ // have resolved.
+ gAgentAvatarp->mEndCustomizeCallback = NULL;
+ }
}
// virtual
bool LLVOAvatarSelf::shouldRenderRigged() const
{
- return gAgent.needsRenderAvatar();
+ return gAgent.needsRenderAvatar();
}
// HACK: this will null out the avatar's local texture IDs before the TE message is sent
@@ -2743,39 +2743,39 @@ bool LLVOAvatarSelf::shouldRenderRigged() const
// This will involve further refactoring that is too risky for the initial release of 2.0.
bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
{
- LLUUID texture_id[TEX_NUM_INDICES];
- // pack away current TEs to make sure we don't send them out
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
- iter != sAvatarDictionary->getTextures().end();
- ++iter)
- {
- const ETextureIndex index = iter->first;
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- if (!texture_dict->mIsBakedTexture)
- {
- LLTextureEntry* entry = getTE((U8) index);
- texture_id[index] = entry->getID();
- entry->setID(IMG_DEFAULT_AVATAR);
- }
- }
-
- bool success = packTEMessage(mesgsys);
-
- // unpack TEs to make sure we don't re-trigger a bake
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
- iter != sAvatarDictionary->getTextures().end();
- ++iter)
- {
- const ETextureIndex index = iter->first;
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- if (!texture_dict->mIsBakedTexture)
- {
- LLTextureEntry* entry = getTE((U8) index);
- entry->setID(texture_id[index]);
- }
- }
-
- return success;
+ LLUUID texture_id[TEX_NUM_INDICES];
+ // pack away current TEs to make sure we don't send them out
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
+ ++iter)
+ {
+ const ETextureIndex index = iter->first;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (!texture_dict->mIsBakedTexture)
+ {
+ LLTextureEntry* entry = getTE((U8) index);
+ texture_id[index] = entry->getID();
+ entry->setID(IMG_DEFAULT_AVATAR);
+ }
+ }
+
+ bool success = packTEMessage(mesgsys);
+
+ // unpack TEs to make sure we don't re-trigger a bake
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
+ ++iter)
+ {
+ const ETextureIndex index = iter->first;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (!texture_dict->mIsBakedTexture)
+ {
+ LLTextureEntry* entry = getTE((U8) index);
+ entry->setID(texture_id[index]);
+ }
+ }
+
+ return success;
}
//------------------------------------------------------------------------
@@ -2783,37 +2783,37 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
//------------------------------------------------------------------------
void LLVOAvatarSelf::sendHoverHeight() const
{
- std::string url = gAgent.getRegionCapability("AgentPreferences");
+ std::string url = gAgent.getRegionCapability("AgentPreferences");
- if (!url.empty())
- {
- LLSD update = LLSD::emptyMap();
- const LLVector3& hover_offset = getHoverOffset();
- update["hover_height"] = hover_offset[2];
+ if (!url.empty())
+ {
+ LLSD update = LLSD::emptyMap();
+ const LLVector3& hover_offset = getHoverOffset();
+ update["hover_height"] = hover_offset[2];
- LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL;
+ LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL;
// *TODO: - this class doesn't really do anything, could just use a base
- // class responder if nothing else gets added.
+ // class responder if nothing else gets added.
// (comment from removed Responder)
- LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update,
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update,
"Hover height sent to sim", "Hover height not sent to sim");
- mLastHoverOffsetSent = hover_offset;
- }
+ mLastHoverOffsetSent = hover_offset;
+ }
}
void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_update)
{
- if (getHoverOffset() != hover_offset)
- {
- LL_INFOS("Avatar") << avString() << " setting hover due to change " << hover_offset[2] << LL_ENDL;
- LLVOAvatar::setHoverOffset(hover_offset, send_update);
- }
- if (send_update && (hover_offset != mLastHoverOffsetSent))
- {
- LL_INFOS("Avatar") << avString() << " sending hover due to change " << hover_offset[2] << LL_ENDL;
- sendHoverHeight();
- }
+ if (getHoverOffset() != hover_offset)
+ {
+ LL_INFOS("Avatar") << avString() << " setting hover due to change " << hover_offset[2] << LL_ENDL;
+ LLVOAvatar::setHoverOffset(hover_offset, send_update);
+ }
+ if (send_update && (hover_offset != mLastHoverOffsetSent))
+ {
+ LL_INFOS("Avatar") << avString() << " sending hover due to change " << hover_offset[2] << LL_ENDL;
+ sendHoverHeight();
+ }
}
//------------------------------------------------------------------------
@@ -2821,9 +2821,9 @@ void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_upd
//------------------------------------------------------------------------
BOOL LLVOAvatarSelf::needsRenderBeam()
{
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
- BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
+ BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
LLViewerObject* objp = LLToolGrab::getInstance()->getEditingObject();
if (objp // might need to be "!objp ||" instead of "objp &&".
&& (objp->isAttachment() || objp->isAvatar()))
@@ -2832,65 +2832,65 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
// attachments or avatars
is_touching_or_grabbing = FALSE;
}
- return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
+ return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
}
// static
void LLVOAvatarSelf::deleteScratchTextures()
{
- for(std::map< LLGLenum, LLGLuint*>::iterator it = sScratchTexNames.begin(), end_it = sScratchTexNames.end();
- it != end_it;
- ++it)
- {
- LLImageGL::deleteTextures(1, (U32 *)it->second );
- stop_glerror();
- }
+ for(std::map< LLGLenum, LLGLuint*>::iterator it = sScratchTexNames.begin(), end_it = sScratchTexNames.end();
+ it != end_it;
+ ++it)
+ {
+ LLImageGL::deleteTextures(1, (U32 *)it->second );
+ stop_glerror();
+ }
- if( sScratchTexBytes.value() )
- {
- LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL;
+ if( sScratchTexBytes.value() )
+ {
+ LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL;
- delete_and_clear(sScratchTexNames);
- sScratchTexBytes = S32Bytes(0);
- }
+ delete_and_clear(sScratchTexNames);
+ sScratchTexBytes = S32Bytes(0);
+ }
}
-// static
+// static
void LLVOAvatarSelf::dumpScratchTextureByteCount()
{
- LL_INFOS() << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << LL_ENDL;
+ LL_INFOS() << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << LL_ENDL;
}
void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)
{
- apr_file_t* file = outfile.getFileHandle();
- if (!file)
- {
- return;
- }
+ apr_file_t* file = outfile.getFileHandle();
+ if (!file)
+ {
+ return;
+ }
+
+ apr_file_printf( file, "\n<wearable_info>\n" );
- apr_file_printf( file, "\n<wearable_info>\n" );
-
- LLWearableData *wd = getWearableData();
+ LLWearableData *wd = getWearableData();
LLWearableType *wr_inst = LLWearableType::getInstance();
- for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)
- {
- const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type);
- for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)
- {
- LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j);
- apr_file_printf( file, "\n\t <wearable type=\"%s\" name=\"%s\"/>\n",
- type_name.c_str(), wearable->getName().c_str() );
- LLWearable::visual_param_vec_t v_params;
- wearable->getVisualParams(v_params);
- for (LLWearable::visual_param_vec_t::iterator it = v_params.begin();
- it != v_params.end(); ++it)
- {
- LLVisualParam *param = *it;
- dump_visual_param(file, param, param->getWeight());
- }
- }
- }
- apr_file_printf( file, "\n</wearable_info>\n" );
+ for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)
+ {
+ const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type);
+ for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)
+ {
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j);
+ apr_file_printf( file, "\n\t <wearable type=\"%s\" name=\"%s\"/>\n",
+ type_name.c_str(), wearable->getName().c_str() );
+ LLWearable::visual_param_vec_t v_params;
+ wearable->getVisualParams(v_params);
+ for (LLWearable::visual_param_vec_t::iterator it = v_params.begin();
+ it != v_params.end(); ++it)
+ {
+ LLVisualParam *param = *it;
+ dump_visual_param(file, param, param->getWeight());
+ }
+ }
+ }
+ apr_file_printf( file, "\n</wearable_info>\n" );
}
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index e5633f665f..8dad833eaa 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvocache.cpp
* @brief Cache of objects on the viewer.
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -33,7 +33,7 @@
#include "llviewerregion.h"
#include "llagentcamera.h"
#include "llsdserialize.h"
-
+#include "llworld.h" // For LLWorld::getInstance()
//static variables
U32 LLVOCacheEntry::sMinFrameRange = 0;
F32 LLVOCacheEntry::sNearRadius = 1.0f;
@@ -45,20 +45,24 @@ BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE;
const S32 ENTRY_HEADER_SIZE = 6 * sizeof(S32);
const S32 MAX_ENTRY_BODY_SIZE = 10000;
-BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
+BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
- return apr_file->read(src, n_bytes) == n_bytes ;
+ return apr_file->read(src, n_bytes) == n_bytes ;
}
-BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
+BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
- return apr_file->write(src, n_bytes) == n_bytes ;
+ return apr_file->write(src, n_bytes) == n_bytes ;
}
+// Material Override Cache needs a version label, so we can upgrade this later.
+const std::string LLGLTFOverrideCacheEntry::VERSION_LABEL = {"GLTFCacheVer"};
+const int LLGLTFOverrideCacheEntry::VERSION = 1;
+
bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
-
+
llassert(data.has("local_id"));
llassert(data.has("object_id"));
llassert(data.has("region_handle_x") && data.has("region_handle_y"));
@@ -152,57 +156,57 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const
//---------------------------------------------------------------------------
LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp)
-: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
- mLocalID(local_id),
- mCRC(crc),
- mUpdateFlags(-1),
- mHitCount(0),
- mDupeCount(0),
- mCRCChangeCount(0),
- mState(INACTIVE),
- mSceneContrib(0.f),
- mValid(TRUE),
- mParentID(0),
- mBSphereRadius(-1.0f)
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+ mLocalID(local_id),
+ mCRC(crc),
+ mUpdateFlags(-1),
+ mHitCount(0),
+ mDupeCount(0),
+ mCRCChangeCount(0),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mValid(TRUE),
+ mParentID(0),
+ mBSphereRadius(-1.0f)
{
- mBuffer = new U8[dp.getBufferSize()];
- mDP.assignBuffer(mBuffer, dp.getBufferSize());
- mDP = dp;
+ mBuffer = new U8[dp.getBufferSize()];
+ mDP.assignBuffer(mBuffer, dp.getBufferSize());
+ mDP = dp;
}
LLVOCacheEntry::LLVOCacheEntry()
-: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
- mLocalID(0),
- mCRC(0),
- mUpdateFlags(-1),
- mHitCount(0),
- mDupeCount(0),
- mCRCChangeCount(0),
- mBuffer(NULL),
- mState(INACTIVE),
- mSceneContrib(0.f),
- mValid(TRUE),
- mParentID(0),
- mBSphereRadius(-1.0f)
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+ mLocalID(0),
+ mCRC(0),
+ mUpdateFlags(-1),
+ mHitCount(0),
+ mDupeCount(0),
+ mCRCChangeCount(0),
+ mBuffer(NULL),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mValid(TRUE),
+ mParentID(0),
+ mBSphereRadius(-1.0f)
{
- mDP.assignBuffer(mBuffer, 0);
+ mDP.assignBuffer(mBuffer, 0);
}
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
-: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
- mBuffer(NULL),
- mUpdateFlags(-1),
- mState(INACTIVE),
- mSceneContrib(0.f),
- mValid(FALSE),
- mParentID(0),
- mBSphereRadius(-1.0f)
+: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+ mBuffer(NULL),
+ mUpdateFlags(-1),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mValid(FALSE),
+ mParentID(0),
+ mBSphereRadius(-1.0f)
{
- S32 size = -1;
- BOOL success;
+ S32 size = -1;
+ BOOL success;
static U8 data_buffer[ENTRY_HEADER_SIZE];
- mDP.assignBuffer(mBuffer, 0);
+ mDP.assignBuffer(mBuffer, 0);
success = check_read(apr_file, (void *)data_buffer, ENTRY_HEADER_SIZE);
if (success)
@@ -214,214 +218,216 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
memcpy(&mCRCChangeCount, data_buffer + (4 * sizeof(U32)), sizeof(S32));
memcpy(&size, data_buffer + (5 * sizeof(U32)), sizeof(S32));
- // Corruption in the cache entries
- if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1))
- {
- // We've got a bogus size, skip reading it.
- // We won't bother seeking, because the rest of this file
- // is likely bogus, and will be tossed anyway.
- LL_WARNS() << "Bogus cache entry, size " << size << ", aborting!" << LL_ENDL;
- success = FALSE;
- }
- }
- if(success && size > 0)
- {
- mBuffer = new U8[size];
- success = check_read(apr_file, mBuffer, size);
-
- if(success)
- {
- mDP.assignBuffer(mBuffer, size);
- }
- else
- {
- delete[] mBuffer ;
- mBuffer = NULL ;
- }
- }
-
- if(!success)
- {
- mLocalID = 0;
- mCRC = 0;
- mHitCount = 0;
- mDupeCount = 0;
- mCRCChangeCount = 0;
- mBuffer = NULL;
- mEntry = NULL;
- mState = INACTIVE;
- }
+ // Corruption in the cache entries
+ if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1))
+ {
+ // We've got a bogus size, skip reading it.
+ // We won't bother seeking, because the rest of this file
+ // is likely bogus, and will be tossed anyway.
+ LL_WARNS() << "Bogus cache entry, size " << size << ", aborting!" << LL_ENDL;
+ success = FALSE;
+ }
+ }
+ if(success && size > 0)
+ {
+ mBuffer = new U8[size];
+ success = check_read(apr_file, mBuffer, size);
+
+ if(success)
+ {
+ mDP.assignBuffer(mBuffer, size);
+ }
+ else
+ {
+ // Improve logging around vocache
+ LL_WARNS() << "Error loading cache entry for " << mLocalID << ", size " << size << " aborting!" << LL_ENDL;
+ delete[] mBuffer ;
+ mBuffer = NULL ;
+ }
+ }
+
+ if(!success)
+ {
+ mLocalID = 0;
+ mCRC = 0;
+ mHitCount = 0;
+ mDupeCount = 0;
+ mCRCChangeCount = 0;
+ mBuffer = NULL;
+ mEntry = NULL;
+ mState = INACTIVE;
+ }
}
LLVOCacheEntry::~LLVOCacheEntry()
{
- mDP.freeBuffer();
+ mDP.freeBuffer();
}
void LLVOCacheEntry::updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp)
-{
- if(mCRC != crc)
- {
- mCRC = crc;
- mCRCChangeCount++;
- }
-
- mDP.freeBuffer();
-
- llassert_always(dp.getBufferSize() > 0);
- mBuffer = new U8[dp.getBufferSize()];
- mDP.assignBuffer(mBuffer, dp.getBufferSize());
- mDP = dp;
+{
+ if(mCRC != crc)
+ {
+ mCRC = crc;
+ mCRCChangeCount++;
+ }
+
+ mDP.freeBuffer();
+
+ llassert_always(dp.getBufferSize() > 0);
+ mBuffer = new U8[dp.getBufferSize()];
+ mDP.assignBuffer(mBuffer, dp.getBufferSize());
+ mDP = dp;
}
-void LLVOCacheEntry::setParentID(U32 id)
+void LLVOCacheEntry::setParentID(U32 id)
{
- if(mParentID != id)
- {
- removeAllChildren();
- mParentID = id;
- }
+ if(mParentID != id)
+ {
+ removeAllChildren();
+ mParentID = id;
+ }
}
void LLVOCacheEntry::removeAllChildren()
{
- if(mChildrenList.empty())
- {
- return;
- }
-
- for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter)
- {
- (*iter)->setParentID(0);
- }
- mChildrenList.clear();
-
- return;
+ if(mChildrenList.empty())
+ {
+ return;
+ }
+
+ for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter)
+ {
+ (*iter)->setParentID(0);
+ }
+ mChildrenList.clear();
+
+ return;
}
-//virtual
+//virtual
void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry)
{
- if(!entry && mDP.getBufferSize() > 0)
- {
- LLUUID fullid;
- LLViewerObject::unpackUUID(&mDP, fullid, "ID");
-
- LLViewerObject* obj = gObjectList.findObject(fullid);
- if(obj && obj->mDrawable)
- {
- entry = obj->mDrawable->getEntry();
- }
- }
-
- LLViewerOctreeEntryData::setOctreeEntry(entry);
+ if(!entry && mDP.getBufferSize() > 0)
+ {
+ LLUUID fullid;
+ LLViewerObject::unpackUUID(&mDP, fullid, "ID");
+
+ LLViewerObject* obj = gObjectList.findObject(fullid);
+ if(obj && obj->mDrawable)
+ {
+ entry = obj->mDrawable->getEntry();
+ }
+ }
+
+ LLViewerOctreeEntryData::setOctreeEntry(entry);
}
void LLVOCacheEntry::setState(U32 state)
{
- if(state > LOW_BITS) //special states
- {
- mState |= (HIGH_BITS & state);
- return;
- }
-
- //
- //otherwise LOW_BITS states
- //
- clearState(LOW_BITS);
- mState |= (LOW_BITS & state);
-
- if(getState() == ACTIVE)
- {
- const S32 MIN_INTERVAL = 64 + sMinFrameRange;
- U32 last_visible = getVisible();
-
- setVisible();
-
- U32 cur_visible = getVisible();
- if(cur_visible - last_visible > MIN_INTERVAL ||
- cur_visible < MIN_INTERVAL)
- {
- mLastCameraUpdated = 0; //reset
- }
- else
- {
- mLastCameraUpdated = LLViewerRegion::sLastCameraUpdated;
- }
- }
+ if(state > LOW_BITS) //special states
+ {
+ mState |= (HIGH_BITS & state);
+ return;
+ }
+
+ //
+ //otherwise LOW_BITS states
+ //
+ clearState(LOW_BITS);
+ mState |= (LOW_BITS & state);
+
+ if(getState() == ACTIVE)
+ {
+ const S32 MIN_INTERVAL = 64 + sMinFrameRange;
+ U32 last_visible = getVisible();
+
+ setVisible();
+
+ U32 cur_visible = getVisible();
+ if(cur_visible - last_visible > MIN_INTERVAL ||
+ cur_visible < MIN_INTERVAL)
+ {
+ mLastCameraUpdated = 0; //reset
+ }
+ else
+ {
+ mLastCameraUpdated = LLViewerRegion::sLastCameraUpdated;
+ }
+ }
}
void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
{
- llassert(entry != NULL);
- llassert(entry->getParentID() == mLocalID);
- llassert(entry->getEntry() != NULL);
-
- if(!entry || !entry->getEntry() || entry->getParentID() != mLocalID)
- {
- return;
- }
-
- mChildrenList.insert(entry);
-
- //update parent bbox
- if(getEntry() != NULL && isState(INACTIVE))
- {
- updateParentBoundingInfo(entry);
- resetVisible();
- }
+ llassert(entry != NULL);
+ llassert(entry->getParentID() == mLocalID);
+ llassert(entry->getEntry() != NULL);
+
+ if(!entry || !entry->getEntry() || entry->getParentID() != mLocalID)
+ {
+ return;
+ }
+
+ mChildrenList.insert(entry);
+
+ //update parent bbox
+ if(getEntry() != NULL && isState(INACTIVE))
+ {
+ updateParentBoundingInfo(entry);
+ resetVisible();
+ }
}
-
+
void LLVOCacheEntry::removeChild(LLVOCacheEntry* entry)
{
- entry->setParentID(0);
+ entry->setParentID(0);
- vocache_entry_set_t::iterator iter = mChildrenList.find(entry);
- if(iter != mChildrenList.end())
- {
- mChildrenList.erase(iter);
- }
+ vocache_entry_set_t::iterator iter = mChildrenList.find(entry);
+ if(iter != mChildrenList.end())
+ {
+ mChildrenList.erase(iter);
+ }
}
//remove the first child, and return it.
LLVOCacheEntry* LLVOCacheEntry::getChild()
{
- LLVOCacheEntry* child = NULL;
- vocache_entry_set_t::iterator iter = mChildrenList.begin();
- if(iter != mChildrenList.end())
- {
- child = *iter;
- mChildrenList.erase(iter);
- }
-
- return child;
+ LLVOCacheEntry* child = NULL;
+ vocache_entry_set_t::iterator iter = mChildrenList.begin();
+ if(iter != mChildrenList.end())
+ {
+ child = *iter;
+ mChildrenList.erase(iter);
+ }
+
+ return child;
}
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP()
{
- if (mDP.getBufferSize() == 0)
- {
- //LL_INFOS() << "Not getting cache entry, invalid!" << LL_ENDL;
- return NULL;
- }
-
- return &mDP;
+ if (mDP.getBufferSize() == 0)
+ {
+ //LL_INFOS() << "Not getting cache entry, invalid!" << LL_ENDL;
+ return NULL;
+ }
+
+ return &mDP;
}
void LLVOCacheEntry::recordHit()
{
- mHitCount++;
+ mHitCount++;
}
void LLVOCacheEntry::dump() const
{
- LL_INFOS() << "local " << mLocalID
- << " crc " << mCRC
- << " hits " << mHitCount
- << " dupes " << mDupeCount
- << " change " << mCRCChangeCount
- << LL_ENDL;
+ LL_INFOS() << "local " << mLocalID
+ << " crc " << mCRC
+ << " hits " << mHitCount
+ << " dupes " << mDupeCount
+ << " change " << mCRCChangeCount
+ << LL_ENDL;
}
S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
@@ -446,34 +452,34 @@ S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
}
#ifndef LL_TEST
-//static
+//static
void LLVOCacheEntry::updateDebugSettings()
{
- static LLFrameTimer timer;
- if(timer.getElapsedTimeF32() < 1.0f) //update frequency once per second.
- {
- return;
- }
- timer.reset();
-
- //objects within the view frustum whose visible area is greater than this threshold will be loaded
- static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
- sFrontPixelThreshold = front_pixel_threshold;
-
- //objects out of the view frustum whose visible area is greater than this threshold will remain loaded
- static LLCachedControl<F32> rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold");
- sRearPixelThreshold = rear_pixel_threshold;
- sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
-
- //make parameters adaptive to memory usage
- //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
- static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
- static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
-
- LLMemory::updateMemoryInfo() ;
- U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
+ static LLFrameTimer timer;
+ if(timer.getElapsedTimeF32() < 1.0f) //update frequency once per second.
+ {
+ return;
+ }
+ timer.reset();
+
+ //objects within the view frustum whose visible area is greater than this threshold will be loaded
+ static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
+ sFrontPixelThreshold = front_pixel_threshold;
+
+ //objects out of the view frustum whose visible area is greater than this threshold will remain loaded
+ static LLCachedControl<F32> rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold");
+ sRearPixelThreshold = rear_pixel_threshold;
+ sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
+
+ //make parameters adaptive to memory usage
+ //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
+ static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
+ static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
+
+ LLMemory::updateMemoryInfo() ;
+ U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
static const F32 KB_to_MB = 1.f / 1024.f;
- U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
+ U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB;
const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1]
@@ -500,613 +506,613 @@ void LLVOCacheEntry::updateDebugSettings()
}
#endif // LL_TEST
-//static
+//static
F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front)
{
- F32 threshold;
- if(is_front)
- {
- threshold = sFrontPixelThreshold;
- }
- else
- {
- threshold = sRearPixelThreshold;
- }
-
- //object projected area threshold
- F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
- F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f;
- projection_threshold *= projection_threshold;
-
- return projection_threshold;
+ F32 threshold;
+ if(is_front)
+ {
+ threshold = sFrontPixelThreshold;
+ }
+ else
+ {
+ threshold = sRearPixelThreshold;
+ }
+
+ //object projected area threshold
+ F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
+ F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f;
+ projection_threshold *= projection_threshold;
+
+ return projection_threshold;
}
bool LLVOCacheEntry::isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold)
{
- LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)getGroup();
- if(!group)
- {
- return false;
- }
-
- //any visible
- bool vis = group->isAnyRecentlyVisible();
-
- //not ready to remove
- if(!vis)
- {
- S32 cur_vis = llmax(group->getAnyVisible(), (S32)getVisible());
- vis = (cur_vis + sMinFrameRange > LLViewerOctreeEntryData::getCurrentFrame());
- }
-
- //within the back sphere
- if(!vis && !mParentID && !group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
- {
- LLVector4a lookAt;
-
- if(mBSphereRadius > 0.f)
- {
- lookAt.setSub(mBSphereCenter, local_camera_origin);
- dist_threshold += mBSphereRadius;
- }
- else
- {
- lookAt.setSub(getPositionGroup(), camera_origin);
- dist_threshold += getBinRadius();
- }
-
- vis = (lookAt.dot3(lookAt).getF32() < dist_threshold * dist_threshold);
- }
-
- return vis;
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)getGroup();
+ if(!group)
+ {
+ return false;
+ }
+
+ //any visible
+ bool vis = group->isAnyRecentlyVisible();
+
+ //not ready to remove
+ if(!vis)
+ {
+ S32 cur_vis = llmax(group->getAnyVisible(), (S32)getVisible());
+ vis = (cur_vis + sMinFrameRange > LLViewerOctreeEntryData::getCurrentFrame());
+ }
+
+ //within the back sphere
+ if(!vis && !mParentID && !group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
+ {
+ LLVector4a lookAt;
+
+ if(mBSphereRadius > 0.f)
+ {
+ lookAt.setSub(mBSphereCenter, local_camera_origin);
+ dist_threshold += mBSphereRadius;
+ }
+ else
+ {
+ lookAt.setSub(getPositionGroup(), camera_origin);
+ dist_threshold += getBinRadius();
+ }
+
+ vis = (lookAt.dot3(lookAt).getF32() < dist_threshold * dist_threshold);
+ }
+
+ return vis;
}
void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 max_dist)
{
- if(!needs_update && getVisible() >= last_update)
- {
- return; //no need to update
- }
-
- LLVector4a lookAt;
- lookAt.setSub(getPositionGroup(), camera_origin);
- F32 distance = lookAt.getLength3().getF32();
- distance -= sNearRadius;
-
- if(distance <= 0.f)
- {
- //nearby objects, set a large number
- const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
- mSceneContrib = LARGE_SCENE_CONTRIBUTION;
- }
- else
- {
- F32 rad = getBinRadius();
- max_dist += rad;
-
- if(distance + sNearRadius < max_dist)
- {
- mSceneContrib = (rad * rad) / distance;
- }
- else
- {
- mSceneContrib = 0.f; //out of draw distance, not to load
- }
- }
-
- setVisible();
+ if(!needs_update && getVisible() >= last_update)
+ {
+ return; //no need to update
+ }
+
+ LLVector4a lookAt;
+ lookAt.setSub(getPositionGroup(), camera_origin);
+ F32 distance = lookAt.getLength3().getF32();
+ distance -= sNearRadius;
+
+ if(distance <= 0.f)
+ {
+ //nearby objects, set a large number
+ const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object.
+ mSceneContrib = LARGE_SCENE_CONTRIBUTION;
+ }
+ else
+ {
+ F32 rad = getBinRadius();
+ max_dist += rad;
+
+ if(distance + sNearRadius < max_dist)
+ {
+ mSceneContrib = (rad * rad) / distance;
+ }
+ else
+ {
+ mSceneContrib = 0.f; //out of draw distance, not to load
+ }
+ }
+
+ setVisible();
}
void LLVOCacheEntry::saveBoundingSphere()
{
- mBSphereCenter = getPositionGroup();
- mBSphereRadius = getBinRadius();
+ mBSphereCenter = getPositionGroup();
+ mBSphereRadius = getBinRadius();
}
void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale)
{
- LLVector4a center, newMin, newMax;
- center.load3(pos.mV);
- LLVector4a size;
- size.load3(scale.mV);
- newMin.setSub(center, size);
- newMax.setAdd(center, size);
-
- setPositionGroup(center);
- setSpatialExtents(newMin, newMax);
-
- if(getNumOfChildren() > 0) //has children
- {
- updateParentBoundingInfo();
- }
- else
- {
- setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
- }
+ LLVector4a center, newMin, newMax;
+ center.load3(pos.mV);
+ LLVector4a size;
+ size.load3(scale.mV);
+ newMin.setSub(center, size);
+ newMax.setAdd(center, size);
+
+ setPositionGroup(center);
+ setSpatialExtents(newMin, newMax);
+
+ if(getNumOfChildren() > 0) //has children
+ {
+ updateParentBoundingInfo();
+ }
+ else
+ {
+ setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
+ }
}
//make the parent bounding box to include all children
void LLVOCacheEntry::updateParentBoundingInfo()
{
- if(mChildrenList.empty())
- {
- return;
- }
-
- for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter)
- {
- updateParentBoundingInfo(*iter);
- }
- resetVisible();
+ if(mChildrenList.empty())
+ {
+ return;
+ }
+
+ for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter)
+ {
+ updateParentBoundingInfo(*iter);
+ }
+ resetVisible();
}
//make the parent bounding box to include this child
void LLVOCacheEntry::updateParentBoundingInfo(const LLVOCacheEntry* child)
{
- const LLVector4a* child_exts = child->getSpatialExtents();
- LLVector4a newMin, newMax;
- newMin = child_exts[0];
- newMax = child_exts[1];
-
- //move to regional space.
- {
- const LLVector4a& parent_pos = getPositionGroup();
- newMin.add(parent_pos);
- newMax.add(parent_pos);
- }
-
- //update parent's bbox(min, max)
- const LLVector4a* parent_exts = getSpatialExtents();
- update_min_max(newMin, newMax, parent_exts[0]);
- update_min_max(newMin, newMax, parent_exts[1]);
- for(S32 i = 0; i < 4; i++)
- {
- llclamp(newMin[i], 0.f, 256.f);
- llclamp(newMax[i], 0.f, 256.f);
- }
- setSpatialExtents(newMin, newMax);
-
- //update parent's bbox center
- LLVector4a center;
- center.setAdd(newMin, newMax);
- center.mul(0.5f);
- setPositionGroup(center);
-
- //update parent's bbox size vector
- LLVector4a size;
- size.setSub(newMax, newMin);
- size.mul(0.5f);
- setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
+ const LLVector4a* child_exts = child->getSpatialExtents();
+ LLVector4a newMin, newMax;
+ newMin = child_exts[0];
+ newMax = child_exts[1];
+
+ //move to regional space.
+ {
+ const LLVector4a& parent_pos = getPositionGroup();
+ newMin.add(parent_pos);
+ newMax.add(parent_pos);
+ }
+
+ //update parent's bbox(min, max)
+ const LLVector4a* parent_exts = getSpatialExtents();
+ update_min_max(newMin, newMax, parent_exts[0]);
+ update_min_max(newMin, newMax, parent_exts[1]);
+ for(S32 i = 0; i < 4; i++)
+ {
+ llclamp(newMin[i], 0.f, 256.f);
+ llclamp(newMax[i], 0.f, 256.f);
+ }
+ setSpatialExtents(newMin, newMax);
+
+ //update parent's bbox center
+ LLVector4a center;
+ center.setAdd(newMin, newMax);
+ center.mul(0.5f);
+ setPositionGroup(center);
+
+ //update parent's bbox size vector
+ LLVector4a size;
+ size.setSub(newMax, newMin);
+ size.mul(0.5f);
+ setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
}
//-------------------------------------------------------------------
//LLVOCachePartition
//-------------------------------------------------------------------
LLVOCacheGroup::~LLVOCacheGroup()
{
- if(mOcclusionState[LLViewerCamera::CAMERA_WORLD] & ACTIVE_OCCLUSION)
- {
- ((LLVOCachePartition*)mSpatialPartition)->removeOccluder(this);
- }
+ if(mOcclusionState[LLViewerCamera::CAMERA_WORLD] & ACTIVE_OCCLUSION)
+ {
+ ((LLVOCachePartition*)mSpatialPartition)->removeOccluder(this);
+ }
}
//virtual
void LLVOCacheGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
- if (child->getListenerCount() == 0)
- {
- new LLVOCacheGroup(child, mSpatialPartition);
- }
- else
- {
- OCT_ERRS << "LLVOCacheGroup redundancy detected." << LL_ENDL;
- }
-
- unbound();
-
- ((LLViewerOctreeGroup*)child->getListener(0))->unbound();
+ if (child->getListenerCount() == 0)
+ {
+ new LLVOCacheGroup(child, mSpatialPartition);
+ }
+ else
+ {
+ OCT_ERRS << "LLVOCacheGroup redundancy detected." << LL_ENDL;
+ }
+
+ unbound();
+
+ ((LLViewerOctreeGroup*)child->getListener(0))->unbound();
}
LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
{
- mLODPeriod = 16;
- mRegionp = regionp;
- mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
- mBackSlectionEnabled = -1;
- mIdleHash = 0;
-
- for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mCulledTime[i] = 0;
- }
- mCullHistory = -1;
-
- new LLVOCacheGroup(mOctree, this);
+ mLODPeriod = 16;
+ mRegionp = regionp;
+ mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
+ mBackSlectionEnabled = -1;
+ mIdleHash = 0;
+
+ for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mCulledTime[i] = 0;
+ }
+ mCullHistory = -1;
+
+ new LLVOCacheGroup(mOctree, this);
}
LLVOCachePartition::~LLVOCachePartition()
{
// SL-17276 make sure to do base class cleanup while this instance
- // can still be treated as an LLVOCachePartition
+ // can still be treated as an LLVOCachePartition
cleanup();
}
bool LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
{
- llassert(entry->hasVOCacheEntry());
+ llassert(entry->hasVOCacheEntry());
- if(!llfinite(entry->getBinRadius()) || !entry->getPositionGroup().isFinite3())
- {
- return false; //data corrupted
- }
+ if(!llfinite(entry->getBinRadius()) || !entry->getPositionGroup().isFinite3())
+ {
+ return false; //data corrupted
+ }
- mOctree->insert(entry);
+ mOctree->insert(entry);
- return true;
+ return true;
}
-
+
void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
{
- entry->getVOCacheEntry()->setGroup(NULL);
+ entry->getVOCacheEntry()->setGroup(NULL);
- llassert(!entry->getGroup());
+ llassert(!entry->getGroup());
}
-
+
class LLVOCacheOctreeCull : public LLViewerOctreeCull
{
public:
- LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp,
- const LLVector3& shift, bool use_object_cache_occlusion, F32 pixel_threshold, LLVOCachePartition* part)
- : LLViewerOctreeCull(camera),
- mRegionp(regionp),
- mPartition(part),
- mPixelThreshold(pixel_threshold)
- {
- mLocalShift = shift;
- mUseObjectCacheOcclusion = use_object_cache_occlusion;
- mNearRadius = LLVOCacheEntry::sNearRadius;
- }
-
- virtual bool earlyFail(LLViewerOctreeGroup* base_group)
- {
- if( mUseObjectCacheOcclusion &&
- base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
- {
- LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
- if(group->needsUpdate())
- {
- //needs to issue new occlusion culling check, perform view culling check first.
- return false;
- }
-
- group->checkOcclusion();
-
- if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
- {
- return true;
- }
- }
-
- return false;
- }
-
- virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
- {
+ LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp,
+ const LLVector3& shift, bool use_object_cache_occlusion, F32 pixel_threshold, LLVOCachePartition* part)
+ : LLViewerOctreeCull(camera),
+ mRegionp(regionp),
+ mPartition(part),
+ mPixelThreshold(pixel_threshold)
+ {
+ mLocalShift = shift;
+ mUseObjectCacheOcclusion = use_object_cache_occlusion;
+ mNearRadius = LLVOCacheEntry::sNearRadius;
+ }
+
+ virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+ {
+ if( mUseObjectCacheOcclusion &&
+ base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+ if(group->needsUpdate())
+ {
+ //needs to issue new occlusion culling check, perform view culling check first.
+ return false;
+ }
+
+ group->checkOcclusion();
+
+ if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
+ {
#if 0
- S32 res = AABBInRegionFrustumGroupBounds(group);
-#else
- S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group);
- if (res != 0)
- {
- res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift));
- }
+ S32 res = AABBInRegionFrustumGroupBounds(group);
+#else
+ S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift));
+ }
#endif
- return res;
- }
+ return res;
+ }
- virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
- {
+ virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
+ {
#if 0
- S32 res = AABBInRegionFrustumObjectBounds(group);
+ S32 res = AABBInRegionFrustumObjectBounds(group);
#else
- S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group);
- if (res != 0)
- {
- res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift));
- }
+ S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group);
+ if (res != 0)
+ {
+ res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift));
+ }
#endif
- if(res != 0)
- {
- //check if the objects projection large enough
- const LLVector4a* exts = group->getObjectExtents();
- res = checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mNearRadius);
- }
-
- return res;
- }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- if( !mUseObjectCacheOcclusion ||
- !base_group->getOctreeNode()->getParent())
- {
- //no occlusion check
- if(mRegionp->addVisibleGroup(base_group))
- {
- base_group->setVisible();
- }
- return;
- }
-
- LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
- if(group->needsUpdate() || !group->isRecentlyVisible())//needs to issue new occlusion culling check.
- {
- mPartition->addOccluders(group);
- group->setVisible();
- return ; //wait for occlusion culling result
- }
-
- if(group->isOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING) ||
- group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
- {
- //keep waiting
- group->setVisible();
- }
- else
- {
- if(mRegionp->addVisibleGroup(base_group))
- {
- base_group->setVisible();
- }
- }
- }
+ if(res != 0)
+ {
+ //check if the objects projection large enough
+ const LLVector4a* exts = group->getObjectExtents();
+ res = checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mNearRadius);
+ }
+
+ return res;
+ }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ if( !mUseObjectCacheOcclusion ||
+ !base_group->getOctreeNode()->getParent())
+ {
+ //no occlusion check
+ if(mRegionp->addVisibleGroup(base_group))
+ {
+ base_group->setVisible();
+ }
+ return;
+ }
+
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+ if(group->needsUpdate() || !group->isRecentlyVisible())//needs to issue new occlusion culling check.
+ {
+ mPartition->addOccluders(group);
+ group->setVisible();
+ return ; //wait for occlusion culling result
+ }
+
+ if(group->isOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING) ||
+ group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
+ {
+ //keep waiting
+ group->setVisible();
+ }
+ else
+ {
+ if(mRegionp->addVisibleGroup(base_group))
+ {
+ base_group->setVisible();
+ }
+ }
+ }
private:
- LLVOCachePartition* mPartition;
- LLViewerRegion* mRegionp;
- LLVector3 mLocalShift; //shift vector from agent space to local region space.
- F32 mPixelThreshold;
- F32 mNearRadius;
- bool mUseObjectCacheOcclusion;
+ LLVOCachePartition* mPartition;
+ LLViewerRegion* mRegionp;
+ LLVector3 mLocalShift; //shift vector from agent space to local region space.
+ F32 mPixelThreshold;
+ F32 mNearRadius;
+ bool mUseObjectCacheOcclusion;
};
//select objects behind camera
class LLVOCacheOctreeBackCull : public LLViewerOctreeCull
{
public:
- LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold, bool use_occlusion)
- : LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold), mUseObjectCacheOcclusion(use_occlusion)
- {
- mLocalShift = shift;
- mSphereRadius = LLVOCacheEntry::sRearFarRadius;
- }
-
- virtual bool earlyFail(LLViewerOctreeGroup* base_group)
- {
- if( mUseObjectCacheOcclusion &&
- base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
- {
- LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
-
- if (group->getOcclusionState() > 0) //occlusion state is not clear.
- {
- return true;
- }
- }
-
- return false;
- }
-
- virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
- {
- const LLVector4a* exts = group->getExtents();
- return backSphereCheck(exts[0], exts[1]);
- }
-
- virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
- {
- const LLVector4a* exts = group->getObjectExtents();
- if(backSphereCheck(exts[0], exts[1]))
- {
- //check if the objects projection large enough
- const LLVector4a* exts = group->getObjectExtents();
- return checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSphereRadius);
- }
- return false;
- }
-
- virtual void processGroup(LLViewerOctreeGroup* base_group)
- {
- mRegionp->addVisibleGroup(base_group);
- return;
- }
+ LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold, bool use_occlusion)
+ : LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold), mUseObjectCacheOcclusion(use_occlusion)
+ {
+ mLocalShift = shift;
+ mSphereRadius = LLVOCacheEntry::sRearFarRadius;
+ }
+
+ virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+ {
+ if( mUseObjectCacheOcclusion &&
+ base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+
+ if (group->getOcclusionState() > 0) //occlusion state is not clear.
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
+ {
+ const LLVector4a* exts = group->getExtents();
+ return backSphereCheck(exts[0], exts[1]);
+ }
+
+ virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
+ {
+ const LLVector4a* exts = group->getObjectExtents();
+ if(backSphereCheck(exts[0], exts[1]))
+ {
+ //check if the objects projection large enough
+ const LLVector4a* exts = group->getObjectExtents();
+ return checkProjectionArea(exts[0], exts[1], mLocalShift, mPixelThreshold, mSphereRadius);
+ }
+ return false;
+ }
+
+ virtual void processGroup(LLViewerOctreeGroup* base_group)
+ {
+ mRegionp->addVisibleGroup(base_group);
+ return;
+ }
private:
- //a sphere around the camera origin, including objects behind camera.
- S32 backSphereCheck(const LLVector4a& min, const LLVector4a& max)
- {
- return AABBSphereIntersect(min, max, mCamera->getOrigin() - mLocalShift, mSphereRadius);
- }
+ //a sphere around the camera origin, including objects behind camera.
+ S32 backSphereCheck(const LLVector4a& min, const LLVector4a& max)
+ {
+ return AABBSphereIntersect(min, max, mCamera->getOrigin() - mLocalShift, mSphereRadius);
+ }
private:
- F32 mSphereRadius;
- LLViewerRegion* mRegionp;
- LLVector3 mLocalShift; //shift vector from agent space to local region space.
- F32 mPixelThreshold;
- bool mUseObjectCacheOcclusion;
+ F32 mSphereRadius;
+ LLViewerRegion* mRegionp;
+ LLVector3 mLocalShift; //shift vector from agent space to local region space.
+ F32 mPixelThreshold;
+ bool mUseObjectCacheOcclusion;
};
void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold, bool use_occlusion)
{
- if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
- {
- return;
- }
-
- if(mBackSlectionEnabled < 0)
- {
- mBackSlectionEnabled = LLVOCacheEntry::sMinFrameRange - 1;
- mBackSlectionEnabled = llmax(mBackSlectionEnabled, (S32)1);
- }
-
- if(!mBackSlectionEnabled)
- {
- return;
- }
-
- //localize the camera
- LLVector3 region_agent = mRegionp->getOriginAgent();
-
- LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold, use_occlusion);
- culler.traverse(mOctree);
-
- mBackSlectionEnabled--;
- if(!mRegionp->getNumOfVisibleGroups())
- {
- mBackSlectionEnabled = 0;
- }
-
- return;
+ if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
+ {
+ return;
+ }
+
+ if(mBackSlectionEnabled < 0)
+ {
+ mBackSlectionEnabled = LLVOCacheEntry::sMinFrameRange - 1;
+ mBackSlectionEnabled = llmax(mBackSlectionEnabled, (S32)1);
+ }
+
+ if(!mBackSlectionEnabled)
+ {
+ return;
+ }
+
+ //localize the camera
+ LLVector3 region_agent = mRegionp->getOriginAgent();
+
+ LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold, use_occlusion);
+ culler.traverse(mOctree);
+
+ mBackSlectionEnabled--;
+ if(!mRegionp->getNumOfVisibleGroups())
+ {
+ mBackSlectionEnabled = 0;
+ }
+
+ return;
}
#ifndef LL_TEST
S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
- static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
-
- if(!LLViewerRegion::sVOCacheCullingEnabled)
- {
- return 0;
- }
- if(mRegionp->isPaused())
- {
- return 0;
- }
-
- ((LLViewerOctreeGroup*)mOctree->getListener(0))->rebound();
-
- if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
- {
- return 0; //no need for those cameras.
- }
-
- if(mCulledTime[LLViewerCamera::sCurCameraID] == LLViewerOctreeEntryData::getCurrentFrame())
- {
- return 0; //already culled
- }
- mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
-
- if(!mCullHistory && LLViewerRegion::isViewerCameraStatic())
- {
- U32 seed = llmax(mLODPeriod >> 1, (U32)4);
- if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
- {
- if(!(LLViewerOctreeEntryData::getCurrentFrame() % seed))
- {
- mIdleHash = (mIdleHash + 1) % seed;
- }
- }
- if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash)
- {
- mFrontCull = FALSE;
-
- //process back objects selection
- selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull),
- do_occlusion && use_object_cache_occlusion);
- return 0; //nothing changed, reduce frequency of culling
- }
- }
- else
- {
- mBackSlectionEnabled = -1; //reset it.
- }
-
- //localize the camera
- LLVector3 region_agent = mRegionp->getOriginAgent();
- camera.calcRegionFrustumPlanes(region_agent, gAgentCamera.mDrawDistance);
-
- mFrontCull = TRUE;
- LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion,
- LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), this);
- culler.traverse(mOctree);
-
- if(!sNeedsOcclusionCheck)
- {
- sNeedsOcclusionCheck = !mOccludedGroups.empty();
- }
- return 1;
+ static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
+
+ if(!LLViewerRegion::sVOCacheCullingEnabled)
+ {
+ return 0;
+ }
+ if(mRegionp->isPaused())
+ {
+ return 0;
+ }
+
+ ((LLViewerOctreeGroup*)mOctree->getListener(0))->rebound();
+
+ if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
+ {
+ return 0; //no need for those cameras.
+ }
+
+ if(mCulledTime[LLViewerCamera::sCurCameraID] == LLViewerOctreeEntryData::getCurrentFrame())
+ {
+ return 0; //already culled
+ }
+ mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
+
+ if(!mCullHistory && LLViewerRegion::isViewerCameraStatic())
+ {
+ U32 seed = llmax(mLODPeriod >> 1, (U32)4);
+ if(LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ {
+ if(!(LLViewerOctreeEntryData::getCurrentFrame() % seed))
+ {
+ mIdleHash = (mIdleHash + 1) % seed;
+ }
+ }
+ if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash)
+ {
+ mFrontCull = FALSE;
+
+ //process back objects selection
+ selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull),
+ do_occlusion && use_object_cache_occlusion);
+ return 0; //nothing changed, reduce frequency of culling
+ }
+ }
+ else
+ {
+ mBackSlectionEnabled = -1; //reset it.
+ }
+
+ //localize the camera
+ LLVector3 region_agent = mRegionp->getOriginAgent();
+ camera.calcRegionFrustumPlanes(region_agent, gAgentCamera.mDrawDistance);
+
+ mFrontCull = TRUE;
+ LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion,
+ LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), this);
+ culler.traverse(mOctree);
+
+ if(!sNeedsOcclusionCheck)
+ {
+ sNeedsOcclusionCheck = !mOccludedGroups.empty();
+ }
+ return 1;
}
#endif // LL_TEST
void LLVOCachePartition::setCullHistory(BOOL has_new_object)
{
- mCullHistory <<= 1;
- mCullHistory |= has_new_object;
+ mCullHistory <<= 1;
+ mCullHistory |= has_new_object;
}
void LLVOCachePartition::addOccluders(LLViewerOctreeGroup* gp)
{
- LLVOCacheGroup* group = (LLVOCacheGroup*)gp;
+ LLVOCacheGroup* group = (LLVOCacheGroup*)gp;
- if(!group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
- {
- group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
- mOccludedGroups.insert(group);
- }
+ if(!group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
+ {
+ group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
+ mOccludedGroups.insert(group);
+ }
}
void LLVOCachePartition::processOccluders(LLCamera* camera)
{
- if(mOccludedGroups.empty())
- {
- return;
- }
- if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
- {
- return; //no need for those cameras.
- }
-
- LLVector3 region_agent = mRegionp->getOriginAgent();
- LLVector4a shift(region_agent[0], region_agent[1], region_agent[2]);
- for(std::set<LLVOCacheGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
- {
- LLVOCacheGroup* group = *iter;
- if(group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
- {
- group->doOcclusion(camera, &shift);
- group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
- }
- }
-
- //safe to clear mOccludedGroups here because only the world camera accesses it.
- mOccludedGroups.clear();
- sNeedsOcclusionCheck = FALSE;
+ if(mOccludedGroups.empty())
+ {
+ return;
+ }
+ if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
+ {
+ return; //no need for those cameras.
+ }
+
+ LLVector3 region_agent = mRegionp->getOriginAgent();
+ LLVector4a shift(region_agent[0], region_agent[1], region_agent[2]);
+ for(std::set<LLVOCacheGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
+ {
+ LLVOCacheGroup* group = *iter;
+ if(group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
+ {
+ group->doOcclusion(camera, &shift);
+ group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
+ }
+ }
+
+ //safe to clear mOccludedGroups here because only the world camera accesses it.
+ mOccludedGroups.clear();
+ sNeedsOcclusionCheck = FALSE;
}
void LLVOCachePartition::resetOccluders()
{
- if(mOccludedGroups.empty())
- {
- return;
- }
-
- for(std::set<LLVOCacheGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
- {
- LLVOCacheGroup* group = *iter;
- group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
- }
- mOccludedGroups.clear();
- sNeedsOcclusionCheck = FALSE;
+ if(mOccludedGroups.empty())
+ {
+ return;
+ }
+
+ for(std::set<LLVOCacheGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
+ {
+ LLVOCacheGroup* group = *iter;
+ group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
+ }
+ mOccludedGroups.clear();
+ sNeedsOcclusionCheck = FALSE;
}
void LLVOCachePartition::removeOccluder(LLVOCacheGroup* group)
{
- if(mOccludedGroups.empty())
- {
- return;
- }
- mOccludedGroups.erase(group);
+ if(mOccludedGroups.empty())
+ {
+ return;
+ }
+ mOccludedGroups.erase(group);
}
//-------------------------------------------------------------------
//LLVOCache
@@ -1123,192 +1129,203 @@ const char* header_filename = "object.cache";
LLVOCache::LLVOCache(bool read_only) :
- mInitialized(false),
- mReadOnly(read_only),
- mNumEntries(0),
- mCacheSize(1),
+ mInitialized(false),
+ mReadOnly(read_only),
+ mNumEntries(0),
+ mCacheSize(1),
mEnabled(true)
{
#ifndef LL_TEST
- mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
+ mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
#endif
- mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
+ mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
}
LLVOCache::~LLVOCache()
{
- if(mEnabled)
- {
- writeCacheHeader();
- clearCacheInMemory();
- }
- delete mLocalAPRFilePoolp;
+ if(mEnabled)
+ {
+ writeCacheHeader();
+ clearCacheInMemory();
+ }
+ delete mLocalAPRFilePoolp;
}
void LLVOCache::setDirNames(ELLPath location)
{
- mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename);
- mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+ mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename);
+ mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
}
void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
{
- if(!mEnabled)
- {
- LL_WARNS() << "Not initializing cache: Cache is currently disabled." << LL_ENDL;
- return ;
- }
-
- if(mInitialized)
- {
- LL_WARNS() << "Cache already initialized." << LL_ENDL;
- return ;
- }
- mInitialized = true;
-
- setDirNames(location);
- if (!mReadOnly)
- {
- LLFile::mkdir(mObjectCacheDirName);
- }
- mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES);
- mMetaInfo.mVersion = cache_version;
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not initializing cache: Cache is currently disabled." << LL_ENDL;
+ return ;
+ }
+
+ if(mInitialized)
+ {
+ LL_WARNS() << "Cache already initialized." << LL_ENDL;
+ return ;
+ }
+ mInitialized = true;
+
+ setDirNames(location);
+ if (!mReadOnly)
+ {
+ LLFile::mkdir(mObjectCacheDirName);
+ }
+ mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES);
+ mMetaInfo.mVersion = cache_version;
#if defined(ADDRESS_SIZE)
- U32 expected_address = ADDRESS_SIZE;
+ U32 expected_address = ADDRESS_SIZE;
#else
- U32 expected_address = 32;
+ U32 expected_address = 32;
#endif
- mMetaInfo.mAddressSize = expected_address;
-
- readCacheHeader();
-
- LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL;
-
- if( mMetaInfo.mVersion != cache_version
- || mMetaInfo.mAddressSize != expected_address)
- {
- mMetaInfo.mVersion = cache_version ;
- mMetaInfo.mAddressSize = expected_address;
- if(mReadOnly) //disable cache
- {
- clearCacheInMemory();
- }
- else //delete the current cache if the format does not match.
- {
- LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL;
- removeCache();
- }
- }
+ mMetaInfo.mAddressSize = expected_address;
+
+ readCacheHeader();
+
+ LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL;
+
+ if( mMetaInfo.mVersion != cache_version
+ || mMetaInfo.mAddressSize != expected_address)
+ {
+ mMetaInfo.mVersion = cache_version ;
+ mMetaInfo.mAddressSize = expected_address;
+ if(mReadOnly) //disable cache
+ {
+ clearCacheInMemory();
+ }
+ else //delete the current cache if the format does not match.
+ {
+ LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL;
+ removeCache();
+ }
+ }
}
-
-void LLVOCache::removeCache(ELLPath location, bool started)
+
+void LLVOCache::removeCache(ELLPath location, bool started)
{
- if(started)
- {
- removeCache();
- return;
- }
-
- if(mReadOnly)
- {
- LL_WARNS() << "Not removing cache at " << location << ": Cache is currently in read-only mode." << LL_ENDL;
- return ;
- }
-
- LL_INFOS() << "about to remove the object cache due to settings." << LL_ENDL ;
-
- std::string mask = "*";
- std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
- LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
- gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
- LLFile::rmdir(cache_dir);
-
- clearCacheInMemory();
- mInitialized = false;
+ if(started)
+ {
+ removeCache();
+ return;
+ }
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not removing cache at " << location << ": Cache is currently in read-only mode." << LL_ENDL;
+ return ;
+ }
+
+ LL_INFOS() << "about to remove the object cache due to settings." << LL_ENDL ;
+
+ std::string mask = "*";
+ std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+ LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
+ gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
+ LLFile::rmdir(cache_dir);
+
+ clearCacheInMemory();
+ mInitialized = false;
}
-void LLVOCache::removeCache()
+void LLVOCache::removeCache()
{
- if(!mInitialized)
- {
- //OK to remove cache even it is not initialized.
- LL_WARNS() << "Object cache is not initialized yet." << LL_ENDL;
- }
-
- if(mReadOnly)
- {
- LL_WARNS() << "Not clearing object cache: Cache is currently in read-only mode." << LL_ENDL;
- return ;
- }
-
- std::string mask = "*";
- LL_INFOS() << "Removing object cache at " << mObjectCacheDirName << LL_ENDL;
- gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);
-
- clearCacheInMemory() ;
- writeCacheHeader();
+ if(!mInitialized)
+ {
+ //OK to remove cache even it is not initialized.
+ LL_WARNS() << "Object cache is not initialized yet." << LL_ENDL;
+ }
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not clearing object cache: Cache is currently in read-only mode." << LL_ENDL;
+ return ;
+ }
+
+ std::string mask = "*";
+ LL_INFOS() << "Removing object cache at " << mObjectCacheDirName << LL_ENDL;
+ gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);
+
+ clearCacheInMemory() ;
+ writeCacheHeader();
}
-void LLVOCache::removeEntry(HeaderEntryInfo* entry)
+void LLVOCache::removeEntry(HeaderEntryInfo* entry)
{
- llassert_always(mInitialized);
- if(mReadOnly)
- {
- return;
- }
- if(!entry)
- {
- return;
- }
-
- header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry);
- if(iter != mHeaderEntryQueue.end())
- {
- mHandleEntryMap.erase(entry->mHandle);
- mHeaderEntryQueue.erase(iter);
- removeFromCache(entry);
- delete entry;
-
- mNumEntries = mHandleEntryMap.size() ;
- }
+ llassert_always(mInitialized);
+ if(mReadOnly)
+ {
+ return;
+ }
+ if(!entry)
+ {
+ return;
+ }
+ // Bit more tracking of cache creation/destruction.
+ std::string filename;
+ getObjectCacheFilename(entry->mHandle, filename);
+ LL_INFOS() << "Removing entry for region with filename" << filename << LL_ENDL;
+
+ // make sure corresponding LLViewerRegion also clears its in-memory cache
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromHandle(entry->mHandle);
+ if (regionp)
+ {
+ regionp->clearVOCacheFromMemory();
+ }
+
+ header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry);
+ if(iter != mHeaderEntryQueue.end())
+ {
+ mHandleEntryMap.erase(entry->mHandle);
+ mHeaderEntryQueue.erase(iter);
+ removeFromCache(entry);
+ delete entry;
+
+ mNumEntries = mHandleEntryMap.size() ;
+ }
}
-void LLVOCache::removeEntry(U64 handle)
+void LLVOCache::removeEntry(U64 handle)
{
- handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
- if(iter == mHandleEntryMap.end()) //no cache
- {
- return ;
- }
- HeaderEntryInfo* entry = iter->second ;
- removeEntry(entry) ;
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ return ;
+ }
+ HeaderEntryInfo* entry = iter->second ;
+ removeEntry(entry) ;
}
void LLVOCache::clearCacheInMemory()
{
- if(!mHeaderEntryQueue.empty())
- {
- for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter)
- {
- delete *iter ;
- }
- mHeaderEntryQueue.clear();
- mHandleEntryMap.clear();
- mNumEntries = 0 ;
- }
+ if(!mHeaderEntryQueue.empty())
+ {
+ for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter)
+ {
+ delete *iter ;
+ }
+ mHeaderEntryQueue.clear();
+ mHandleEntryMap.clear();
+ mNumEntries = 0 ;
+ }
}
-void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
+void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
{
- U32 region_x, region_y;
+ U32 region_x, region_y;
- grid_from_region_handle(handle, &region_x, &region_y);
- filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
- llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
+ grid_from_region_handle(handle, &region_x, &region_y);
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+ llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
- return ;
+ return ;
}
std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle)
@@ -1322,231 +1339,247 @@ std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle)
void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
{
- if(mReadOnly)
- {
- LL_WARNS() << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << LL_ENDL;
- return ;
- }
-
- std::string filename;
- getObjectCacheFilename(entry->mHandle, filename);
- LLAPRFile::remove(filename, mLocalAPRFilePoolp);
- entry->mTime = INVALID_TIME ;
- updateEntry(entry) ; //update the head file.
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << LL_ENDL;
+ return ;
+ }
+
+ std::string filename;
+ getObjectCacheFilename(entry->mHandle, filename);
+ LL_WARNS("GLTF", "VOCache") << "Removing object cache for handle " << entry->mHandle << "Filename: " << filename << LL_ENDL;
+ LLAPRFile::remove(filename, mLocalAPRFilePoolp);
+
+ // Note: `removeFromCache` should take responsibility for cleaning up all cache artefacts specfic to the handle/entry.
+ // as such this now includes the generic extras
+ filename = getObjectCacheExtrasFilename(entry->mHandle);
+ LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << entry->mHandle << "Filename: " << filename << LL_ENDL;
+ LLFile::remove(filename);
+
+ entry->mTime = INVALID_TIME ;
+ updateEntry(entry) ; //update the head file.
}
void LLVOCache::readCacheHeader()
{
- if(!mEnabled)
- {
- LL_WARNS() << "Not reading cache header: Cache is currently disabled." << LL_ENDL;
- return;
- }
-
- //clear stale info.
- clearCacheInMemory();
-
- bool success = true ;
- if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
- {
- LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
-
- //read the meta element
- success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
-
- if(success)
- {
- HeaderEntryInfo* entry = NULL ;
- mNumEntries = 0 ;
- U32 num_read = 0 ;
- while(num_read++ < MAX_NUM_OBJECT_ENTRIES)
- {
- if(!entry)
- {
- entry = new HeaderEntryInfo() ;
- }
- success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
-
- if(!success) //failed
- {
- LL_WARNS() << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << LL_ENDL;
- delete entry ;
- entry = NULL ;
- break ;
- }
- else if(entry->mTime == INVALID_TIME)
- {
- continue ; //an empty entry
- }
-
- entry->mIndex = mNumEntries++ ;
- mHeaderEntryQueue.insert(entry) ;
- mHandleEntryMap[entry->mHandle] = entry ;
- entry = NULL ;
- }
- if(entry)
- {
- delete entry ;
- }
- }
-
- //---------
- //debug code
- //----------
- //std::string name ;
- //for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
- //{
- // getObjectCacheFilename((*iter)->mHandle, name) ;
- // LL_INFOS() << name << LL_ENDL ;
- //}
- //-----------
- }
- else
- {
- writeCacheHeader() ;
- }
-
- if(!success)
- {
- removeCache() ; //failed to read header, clear the cache
- }
- else if(mNumEntries >= mCacheSize)
- {
- purgeEntries(mCacheSize) ;
- }
-
- return ;
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not reading cache header: Cache is currently disabled." << LL_ENDL;
+ return;
+ }
+
+ //clear stale info.
+ clearCacheInMemory();
+
+ bool success = true ;
+ if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+ {
+ LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+
+ //read the meta element
+ success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
+
+ if(success)
+ {
+ HeaderEntryInfo* entry = NULL ;
+ mNumEntries = 0 ;
+ U32 num_read = 0 ;
+ while(num_read++ < MAX_NUM_OBJECT_ENTRIES)
+ {
+ if(!entry)
+ {
+ entry = new HeaderEntryInfo() ;
+ }
+ success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
+
+ if(!success) //failed
+ {
+ LL_WARNS() << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << LL_ENDL;
+ delete entry ;
+ entry = NULL ;
+ break ;
+ }
+ else if(entry->mTime == INVALID_TIME)
+ {
+ continue ; //an empty entry
+ }
+
+ entry->mIndex = mNumEntries++ ;
+ mHeaderEntryQueue.insert(entry) ;
+ mHandleEntryMap[entry->mHandle] = entry ;
+ entry = NULL ;
+ }
+ if(entry)
+ {
+ delete entry ;
+ }
+ }
+
+ //---------
+ //debug code
+ //----------
+ //std::string name ;
+ //for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
+ //{
+ // getObjectCacheFilename((*iter)->mHandle, name) ;
+ // LL_INFOS() << name << LL_ENDL ;
+ //}
+ //-----------
+ }
+ else
+ {
+ writeCacheHeader() ;
+ }
+
+ if(!success)
+ {
+ removeCache() ; //failed to read header, clear the cache
+ }
+ else if(mNumEntries >= mCacheSize)
+ {
+ purgeEntries(mCacheSize) ;
+ }
+
+ return ;
}
void LLVOCache::writeCacheHeader()
{
- if (!mEnabled)
- {
- LL_WARNS() << "Not writing cache header: Cache is currently disabled." << LL_ENDL;
- return;
- }
-
- if(mReadOnly)
- {
- LL_WARNS() << "Not writing cache header: Cache is currently in read-only mode." << LL_ENDL;
- return;
- }
-
- bool success = true ;
- {
- LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
-
- //write the meta element
- success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
-
-
- mNumEntries = 0 ;
- for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
- {
- (*iter)->mIndex = mNumEntries++ ;
- success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
- }
-
- mNumEntries = mHeaderEntryQueue.size() ;
- if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES)
- {
- HeaderEntryInfo* entry = new HeaderEntryInfo() ;
- entry->mTime = INVALID_TIME ;
- for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
- {
- //fill the cache with the default entry.
- success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
-
- }
- delete entry ;
- }
- }
-
- if(!success)
- {
- clearCacheInMemory() ;
- mReadOnly = TRUE ; //disable the cache.
- }
- return ;
+ if (!mEnabled)
+ {
+ LL_WARNS() << "Not writing cache header: Cache is currently disabled." << LL_ENDL;
+ return;
+ }
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not writing cache header: Cache is currently in read-only mode." << LL_ENDL;
+ return;
+ }
+
+ bool success = true ;
+ {
+ LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+
+ //write the meta element
+ success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
+
+
+ mNumEntries = 0 ;
+ for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
+ {
+ (*iter)->mIndex = mNumEntries++ ;
+ success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
+ }
+
+ mNumEntries = mHeaderEntryQueue.size() ;
+ if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES)
+ {
+ HeaderEntryInfo* entry = new HeaderEntryInfo() ;
+ entry->mTime = INVALID_TIME ;
+ for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
+ {
+ //fill the cache with the default entry.
+ success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
+
+ }
+ delete entry ;
+ }
+ }
+
+ if(!success)
+ {
+ clearCacheInMemory() ;
+ mReadOnly = TRUE ; //disable the cache.
+ }
+ return ;
}
BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
{
- LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
- apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
+ LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
- return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
+ return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
}
-void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
+// we now return bool to trigger dirty cache
+// this in turn forces a rewrite after a partial read due to corruption.
+bool LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
{
- if(!mEnabled)
- {
- LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
- return ;
- }
- llassert_always(mInitialized);
-
- handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
- if(iter == mHandleEntryMap.end()) //no cache
- {
- LL_WARNS() << "No handle map entry for " << handle << LL_ENDL;
- return ;
- }
-
- bool success = true ;
- {
- std::string filename;
- LLUUID cache_id;
- getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
-
- success = check_read(&apr_file, cache_id.mData, UUID_BYTES);
-
- if(success)
- {
- if(cache_id != id)
- {
- LL_INFOS() << "Cache ID doesn't match for this region, discarding"<< LL_ENDL;
- success = false ;
- }
-
- if(success)
- {
- S32 num_entries; // if removal was enabled during write num_entries might be wrong
- success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
-
- if(success)
- {
- for (S32 i = 0; i < num_entries && apr_file.eof() != APR_EOF; i++)
- {
- LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file);
- if (!entry->getLocalID())
- {
- LL_WARNS() << "Aborting cache file load for " << filename << ", cache file corruption!" << LL_ENDL;
- success = false ;
- break ;
- }
- cache_entry_map[entry->getLocalID()] = entry;
- }
- }
- }
- }
- }
-
- if(!success)
- {
- if(cache_entry_map.empty())
- {
- removeEntry(iter->second) ;
- }
- }
-
- return ;
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return true; // no problem we're just read only
+ }
+ llassert_always(mInitialized);
+
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ LL_WARNS() << "No handle map entry for " << handle << LL_ENDL;
+ return false; // arguably no a problem, but we'll mark this as dirty anyway.
+ }
+
+ bool success = true ;
+ S32 num_entries = 0 ; // lifted out of inner loop.
+ std::string filename; // lifted out of loop
+ {
+ LLUUID cache_id;
+ getObjectCacheFilename(handle, filename);
+ LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+
+ success = check_read(&apr_file, cache_id.mData, UUID_BYTES);
+
+ if(success)
+ {
+ if(cache_id != id)
+ {
+ LL_INFOS() << "Cache ID doesn't match for this region, discarding"<< LL_ENDL;
+ success = false ;
+ }
+
+ if(success)
+ {
+ success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
+
+ if(success)
+ {
+ for (S32 i = 0; i < num_entries && apr_file.eof() != APR_EOF; i++)
+ {
+ LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file);
+ if (!entry->getLocalID())
+ {
+ LL_WARNS() << "Aborting cache file load for " << filename << ", cache file corruption!" << LL_ENDL;
+ success = false ;
+ break ;
+ }
+ cache_entry_map[entry->getLocalID()] = entry;
+ }
+ }
+ }
+ }
+ }
+
+ if(!success)
+ {
+ if(cache_entry_map.empty())
+ {
+ removeEntry(iter->second) ;
+ }
+ }
+
+ LL_DEBUGS("GLTF", "VOCache") << "Read " << cache_entry_map.size() << " entries from object cache " << filename << ", expected " << num_entries << ", success=" << (success?"True":"False") << LL_ENDL;
+ return success;
}
-void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map)
+// We now pass in the cache entry map, so that we can remove entries from extras that are no longer in the primary cache.
+void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
{
+ int loaded= 0;
+ int discarded = 0;
+ // get ViewerRegion pointer from handle
+ LLViewerRegion* pRegion = LLWorld::getInstance()->getRegionFromHandle(handle);
if(!mEnabled)
{
LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
@@ -1566,40 +1599,73 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac
std::string line;
std::getline(in, line);
- if(!in.good()) {
+ if(!in.good())
+ {
LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
+ return;
+ }
+ // file formats need versions, let's add one. legacy cache files will be considered version 0
+ // This will make it easier to upgrade/revise later.
+ int versionNumber=0;
+ if (line.compare(0, LLGLTFOverrideCacheEntry::VERSION_LABEL.length(), LLGLTFOverrideCacheEntry::VERSION_LABEL) == 0)
+ {
+ std::string versionStr = line.substr(LLGLTFOverrideCacheEntry::VERSION_LABEL.length()+1); // skip the version label and ':'
+ versionNumber = std::stol(versionStr);
+ }
+ // For future versions we may call a legacy handler here, but realistically we'll just consider this cache out of date.
+ // The important thing is to make sure it gets removed.
+ if(versionNumber != LLGLTFOverrideCacheEntry::VERSION)
+ {
+ LL_WARNS() << "Unexpected version number " << versionNumber << " for extras cache for handle " << handle << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
return;
}
+ LL_DEBUGS("VOCache") << "Reading extras cache for handle " << handle << ", version " << versionNumber << LL_ENDL;
+ std::getline(in, line);
if(!LLUUID::validate(line))
{
LL_WARNS() << "Failed reading extras cache for handle" << handle << ". invalid uuid line: '" << line << "'" << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
return;
}
LLUUID cache_id(line);
if(cache_id != id)
{
- LL_INFOS() << "Cache ID doesn't match for this region, discarding" << LL_ENDL;
+ // if the cache id doesn't match the expected region we should just kill the file.
+ LL_WARNS() << "Cache ID doesn't match for this region, deleting it" << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
return;
}
U32 num_entries; // if removal was enabled during write num_entries might be wrong
std::getline(in, line);
- if(!in.good()) {
+ if(!in.good())
+ {
LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
return;
}
- try {
+ try
+ {
num_entries = std::stol(line);
}
catch(std::logic_error&) // either invalid_argument or out_of_range
{
LL_WARNS() << "Failed reading extras cache for handle " << handle << ". unreadable num_entries" << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
return;
}
- LL_DEBUGS("GLTF") << "Beginning reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+ LL_DEBUGS("GLTF") << "Beginning reading extras cache for handle " << handle << " from " << getObjectCacheExtrasFilename(handle) << LL_ENDL;
LLSD entry_llsd;
for (U32 i = 0; i < num_entries && !in.eof(); i++)
@@ -1607,104 +1673,123 @@ void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCac
static const U32 max_size = 4096;
bool success = LLSDSerialize::deserialize(entry_llsd, in, max_size);
// check bool(in) this time since eof is not a failure condition here
- if(!success || !in) {
- LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << LL_ENDL;
- return;
+ if(!success || !in)
+ {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << " cache patrtial load only." << LL_ENDL;
+ in.close();
+ removeGenericExtrasForHandle(handle);
+ break;
}
LLGLTFOverrideCacheEntry entry;
entry.fromLLSD(entry_llsd);
U32 local_id = entry_llsd["local_id"].asInteger();
- cache_extras_entry_map[local_id] = entry;
+ // only add entries that exist in the primary cache
+ // this is a self-healing test that avoids us polluting the cache with entries that are no longer valid based on the main cache.
+ if(cache_entry_map.find(local_id)!= cache_entry_map.end())
+ {
+ // attempt to backfill a null objectId, though these shouldn't be in the persisted cache really
+ if(entry.mObjectId.isNull() && pRegion)
+ {
+ gObjectList.getUUIDFromLocal( entry.mObjectId, local_id, pRegion->getHost().getAddress(), pRegion->getHost().getPort() );
+ }
+ cache_extras_entry_map[local_id] = entry;
+ loaded++;
+ }
+ else
+ {
+ discarded++;
+ }
}
-
- LL_DEBUGS("GLTF") << "Completed reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+ LL_DEBUGS("GLTF") << "Completed reading extras cache for handle " << handle << ", " << loaded << " loaded, " << discarded << " discarded" << LL_ENDL;
}
void LLVOCache::purgeEntries(U32 size)
{
- while(mHeaderEntryQueue.size() > size)
- {
- header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ;
- HeaderEntryInfo* entry = *iter ;
- mHandleEntryMap.erase(entry->mHandle);
- mHeaderEntryQueue.erase(iter) ;
- removeFromCache(entry) ;
- delete entry;
- // TODO also delete extras
- }
- mNumEntries = mHandleEntryMap.size() ;
+ LL_DEBUGS("VOCache","GLTF") << "Purging " << size << " entries from cache" << LL_ENDL;
+ while(mHeaderEntryQueue.size() > size)
+ {
+ header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ;
+ HeaderEntryInfo* entry = *iter ;
+ mHandleEntryMap.erase(entry->mHandle) ;
+ mHeaderEntryQueue.erase(iter) ;
+ removeFromCache(entry) ; // This now handles removing extras cache where appropriate.
+ delete entry;
+ }
+ mNumEntries = mHandleEntryMap.size() ;
}
-void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled)
+void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled)
{
- if(!mEnabled)
- {
- LL_WARNS() << "Not writing cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
- return ;
- }
- llassert_always(mInitialized);
-
- if(mReadOnly)
- {
- LL_WARNS() << "Not writing cache for handle " << handle << "): Cache is currently in read-only mode." << LL_ENDL;
- return ;
- }
-
- HeaderEntryInfo* entry;
- handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
- if(iter == mHandleEntryMap.end()) //new entry
- {
- if(mNumEntries >= mCacheSize - 1)
- {
- purgeEntries(mCacheSize - 1) ;
- }
-
- entry = new HeaderEntryInfo();
- entry->mHandle = handle ;
- entry->mTime = time(NULL) ;
- entry->mIndex = mNumEntries++;
- mHeaderEntryQueue.insert(entry) ;
- mHandleEntryMap[handle] = entry ;
- }
- else
- {
- // Update access time.
- entry = iter->second ;
-
- //resort
- mHeaderEntryQueue.erase(entry) ;
-
- entry->mTime = time(NULL) ;
- mHeaderEntryQueue.insert(entry) ;
- }
-
- //update cache header
- if(!updateEntry(entry))
- {
- LL_WARNS() << "Failed to update cache header index " << entry->mIndex << ". handle = " << handle << LL_ENDL;
- return ; //update failed.
- }
-
- if(!dirty_cache)
- {
- LL_WARNS() << "Skipping write to cache for handle " << handle << ": cache not dirty" << LL_ENDL;
- return ; //nothing changed, no need to update.
- }
-
- //write to cache file
- bool success = true ;
- {
- std::string filename;
- getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp);
-
- success = check_write(&apr_file, (void*)id.mData, UUID_BYTES);
-
- if(success)
- {
- S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong
- success = check_write(&apr_file, &num_entries, sizeof(S32));
+ std::string filename;
+ getObjectCacheFilename(handle, filename);
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently disabled." << LL_ENDL;
+ return ;
+ }
+ llassert_always(mInitialized);
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not writing cache for " << filename << " (handle:" << handle << "): Cache is currently in read-only mode." << LL_ENDL;
+ return ;
+ }
+
+ HeaderEntryInfo* entry;
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //new entry
+ {
+ if(mNumEntries >= mCacheSize - 1)
+ {
+ purgeEntries(mCacheSize - 1) ;
+ }
+
+ entry = new HeaderEntryInfo();
+ entry->mHandle = handle ;
+ entry->mTime = time(NULL) ;
+ entry->mIndex = mNumEntries++;
+ mHeaderEntryQueue.insert(entry) ;
+ mHandleEntryMap[handle] = entry ;
+ }
+ else
+ {
+ // Update access time.
+ entry = iter->second ;
+
+ //resort
+ mHeaderEntryQueue.erase(entry) ;
+
+ entry->mTime = time(NULL) ;
+ mHeaderEntryQueue.insert(entry) ;
+ }
+
+ //update cache header
+ if(!updateEntry(entry))
+ {
+ LL_WARNS() << "Failed to update cache header index " << entry->mIndex << ". " << filename << " handle = " << handle << LL_ENDL;
+ return ; //update failed.
+ }
+
+ if(!dirty_cache)
+ {
+ LL_WARNS() << "Skipping write to cache for " << filename << " (handle:" << handle << "): cache not dirty" << LL_ENDL;
+ return ; //nothing changed, no need to update.
+ }
+
+ //write to cache file
+ bool success = true ;
+ {
+ std::string filename;
+ getObjectCacheFilename(handle, filename);
+ LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp);
+
+ success = check_write(&apr_file, (void*)id.mData, UUID_BYTES);
+
+ if(success)
+ {
+ S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong
+ success = check_write(&apr_file, &num_entries, sizeof(S32));
if (success)
{
const S32 buffer_size = 32768; //should be large enough for couple MAX_ENTRY_BODY_SIZE
@@ -1724,6 +1809,7 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
}
else
{
+ LL_WARNS() << "Failed to write cache entry to buffer for " << filename << ", entry number " << iter->second->getLocalID() << LL_ENDL;
success = false;
break;
}
@@ -1735,6 +1821,7 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
size_in_buffer = 0;
if (!success)
{
+ LL_WARNS() << "Failed to write cache to disk " << filename << LL_ENDL;
break;
}
}
@@ -1745,18 +1832,45 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
{
// final write
success = check_write(&apr_file, (void*)data_buffer, size_in_buffer);
+ if(!success)
+ {
+ LL_WARNS() << "Failed to write cache entry to disk " << filename << LL_ENDL;
+ }
size_in_buffer = 0;
}
+ LL_DEBUGS("VOCache") << "Wrote " << num_entries << " entries to the primary VOCache file " << filename << ". success = " << (success ? "True":"False") << LL_ENDL;
}
- }
- }
+ }
+ }
- if(!success)
+ if(!success)
+ {
+ removeEntry(entry) ;
+ }
+
+ return ;
+}
+
+void LLVOCache::removeGenericExtrasForHandle(U64 handle)
+{
+ if(mReadOnly)
{
- removeEntry(entry) ;
+ LL_WARNS() << "Not removing cache for handle " << handle << ": Cache is currently in read-only mode." << LL_ENDL;
+ return ;
+ }
+
+ // NOTE: when removing the extras, we must also remove the objects so the simulator will send us a full upddate with the valid overrides
+ auto* entry = mHandleEntryMap[handle];
+ if (entry)
+ {
+ removeEntry(entry);
+ }
+ else
+ {
+ //shouldn't happen, but if it does, we should remove the extras file since it's orphaned
+ LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << entry->mHandle << "Filename: " << getObjectCacheExtrasFilename(handle) << LL_ENDL;
+ LLFile::remove(getObjectCacheExtrasFilename(entry->mHandle));
}
-
- return ;
}
void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled)
@@ -1774,46 +1888,86 @@ void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LL
return;
}
- std::string filename(getObjectCacheExtrasFilename(handle));
+ // <FS:Beq> FIRE-33808 - Material Override Cache causes long delays
+ std::string filename = getObjectCacheExtrasFilename(handle);
+ // </FS:Beq>
llofstream out(filename, std::ios::out | std::ios::binary);
if(!out.good())
{
LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ removeGenericExtrasForHandle(handle);
return;
- // TODO - clean up broken cache file
}
+ // It is good practice to version file formats so let's add one.
+ // legacy versions will be treated as version 0.
+ out << LLGLTFOverrideCacheEntry::VERSION_LABEL << ":" << LLGLTFOverrideCacheEntry::VERSION << '\n';
out << id << '\n';
if(!out.good())
{
LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ removeGenericExtrasForHandle(handle);
return;
- // TODO - clean up broken cache file
}
-
- U32 num_entries = cache_extras_entry_map.size();
- out << num_entries << '\n';
+ // Because we don't write out all the entries we need to record a placeholder and rewrite this later
+ auto num_entries_placeholder = out.tellp();
+ out << std::setw(10) << std::setfill('0') << 0 << '\n';
if(!out.good())
{
LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ removeGenericExtrasForHandle(handle);
return;
- // TODO - clean up broken cache file
}
- for (auto const & entry : cache_extras_entry_map)
+ // get ViewerRegion pointer from handle
+ LLViewerRegion* pRegion = LLWorld::getInstance()->getRegionFromHandle(handle);
+
+ U32 num_entries = 0;
+ U32 inmem_entries = 0;
+ U32 skipped = 0;
+ inmem_entries = cache_extras_entry_map.size();
+ for (auto [local_id, entry] : cache_extras_entry_map)
{
- S32 local_id = entry.first;
- LLSD entry_llsd = entry.second.toLLSD();
- entry_llsd["local_id"] = local_id;
- LLSDSerialize::serialize(entry_llsd, out, LLSDSerialize::LLSD_XML);
- out << '\n';
- if(!out.good())
+ // Only write out GLTFOverrides that we can actually apply again on import.
+ // worst case we have an extra cache miss.
+ // Note: A null mObjectId is valid when in memory as we might have a data race between GLTF of the object itself.
+ // This remains a valid state to persist as it is consistent with the localid checks on import with the main cache.
+ // the mObjectId will be updated if/when the local object is updated from the gObject list (due to full update)
+ if(entry.mObjectId.isNull() && pRegion)
{
- LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
- return;
- // TODO - clean up broken cache file
+ gObjectList.getUUIDFromLocal( entry.mObjectId, local_id, pRegion->getHost().getAddress(), pRegion->getHost().getPort() );
}
- }
- LL_DEBUGS("GLTF") << "Completed writing extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+ if( entry.mSides.size() > 0 &&
+ entry.mSides.size() == entry.mGLTFMaterial.size()
+ )
+ {
+ LLSD entry_llsd = entry.toLLSD();
+ entry_llsd["local_id"] = (S32)local_id;
+ LLSDSerialize::serialize(entry_llsd, out, LLSDSerialize::LLSD_XML);
+ out << '\n';
+ if(!out.good())
+ {
+ // We're not in a good place when this happens so we might as well nuke the file.
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << ". Corrupted cache file " << filename << " removed." << LL_ENDL;
+ removeGenericExtrasForHandle(handle);
+ return;
+ }
+ num_entries++;
+ }
+ else
+ {
+ skipped++;
+ }
+ }
+ // Rewrite the placeholder
+ out.seekp(num_entries_placeholder);
+ out << std::setw(10) << std::setfill('0') << num_entries << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ removeGenericExtrasForHandle(handle);
+ return;
+ }
+ LL_DEBUGS("GLTF") << "Completed writing extras cache for handle " << handle << ", " << num_entries << " entries. Total in RAM: " << inmem_entries << " skipped (no persist): " << skipped << LL_ENDL;
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 22c97573be..d94e79ce1b 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvocache.h
* @brief Cache of objects on the viewer.
*
* $LicenseInfo:firstyear=2003&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$
*/
@@ -43,6 +43,8 @@ class LLCamera;
class LLGLTFOverrideCacheEntry
{
public:
+ static const std::string VERSION_LABEL;
+ static const int VERSION;
bool fromLLSD(const LLSD& data);
LLSD toLLSD() const;
@@ -53,195 +55,189 @@ public:
U64 mRegionHandle = 0;
};
-class LLVOCacheEntry
-: public LLViewerOctreeEntryData
+class LLVOCacheEntry
+: public LLViewerOctreeEntryData
{
LL_ALIGN_NEW
public:
- enum
- {
- //low 16-bit state
- INACTIVE = 0x00000000, //not visible
- IN_QUEUE = 0x00000001, //in visible queue, object to be created
- WAITING = 0x00000002, //object creation request sent
- ACTIVE = 0x00000004, //object created, and in rendering pipeline.
-
- //high 16-bit state
- IN_VO_TREE = 0x00010000, //the entry is in the object cache tree.
-
- LOW_BITS = 0x0000ffff,
- HIGH_BITS = 0xffff0000
- };
-
- struct CompareVOCacheEntry
- {
- bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) const
- {
- F32 lpa = lhs->getSceneContribution();
- F32 rpa = rhs->getSceneContribution();
-
- //larger pixel area first
- if(lpa > rpa)
- {
- return true;
- }
- else if(lpa < rpa)
- {
- return false;
- }
- else
- {
- return lhs < rhs;
- }
- }
- };
-
- struct ExtrasEntry
- {
- LLSD extras;
- std::string extras_raw;
- };
+ enum
+ {
+ //low 16-bit state
+ INACTIVE = 0x00000000, //not visible
+ IN_QUEUE = 0x00000001, //in visible queue, object to be created
+ WAITING = 0x00000002, //object creation request sent
+ ACTIVE = 0x00000004, //object created, and in rendering pipeline.
+
+ //high 16-bit state
+ IN_VO_TREE = 0x00010000, //the entry is in the object cache tree.
+
+ LOW_BITS = 0x0000ffff,
+ HIGH_BITS = 0xffff0000
+ };
+
+ struct CompareVOCacheEntry
+ {
+ bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) const
+ {
+ F32 lpa = lhs->getSceneContribution();
+ F32 rpa = rhs->getSceneContribution();
+
+ //larger pixel area first
+ if(lpa > rpa)
+ {
+ return true;
+ }
+ else if(lpa < rpa)
+ {
+ return false;
+ }
+ else
+ {
+ return lhs < rhs;
+ }
+ }
+ };
protected:
- ~LLVOCacheEntry();
+ ~LLVOCacheEntry();
public:
- LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
- LLVOCacheEntry(LLAPRFile* apr_file);
- LLVOCacheEntry();
-
- void updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp);
-
- void clearState(U32 state) {mState &= ~state;}
- bool hasState(U32 state) {return mState & state;}
- void setState(U32 state);
- bool isState(U32 state) {return (mState & LOW_BITS) == state;}
- U32 getState() const {return mState & LOW_BITS;}
-
- bool isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold);
-
- U32 getLocalID() const { return mLocalID; }
- U32 getCRC() const { return mCRC; }
- S32 getHitCount() const { return mHitCount; }
- S32 getCRCChangeCount() const { return mCRCChangeCount; }
-
- void calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 dist_threshold);
- void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;}
- F32 getSceneContribution() const { return mSceneContrib;}
-
- void dump() const;
- S32 writeToBuffer(U8 *data_buffer) const;
- LLDataPackerBinaryBuffer *getDP();
- void recordHit();
- void recordDupe() { mDupeCount++; }
-
- /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry);
-
- void setParentID(U32 id);
- U32 getParentID() const {return mParentID;}
- bool isChild() const {return mParentID > 0;}
-
- void addChild(LLVOCacheEntry* entry);
- void removeChild(LLVOCacheEntry* entry);
- void removeAllChildren();
- LLVOCacheEntry* getChild(); //remove the first child, and return it.
- S32 getNumOfChildren() const {return mChildrenList.size();}
-
- void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); //called from processing object update message
- void updateParentBoundingInfo();
- void saveBoundingSphere();
-
- void setValid(BOOL valid = TRUE) {mValid = valid;}
- BOOL isValid() const {return mValid;}
-
- void setUpdateFlags(U32 flags) {mUpdateFlags = flags;}
- U32 getUpdateFlags() const {return mUpdateFlags;}
-
- static void updateDebugSettings();
- static F32 getSquaredPixelThreshold(bool is_front);
+ LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
+ LLVOCacheEntry(LLAPRFile* apr_file);
+ LLVOCacheEntry();
+
+ void updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp);
+
+ void clearState(U32 state) {mState &= ~state;}
+ bool hasState(U32 state) {return mState & state;}
+ void setState(U32 state);
+ bool isState(U32 state) {return (mState & LOW_BITS) == state;}
+ U32 getState() const {return mState & LOW_BITS;}
+
+ bool isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold);
+
+ U32 getLocalID() const { return mLocalID; }
+ U32 getCRC() const { return mCRC; }
+ S32 getHitCount() const { return mHitCount; }
+ S32 getCRCChangeCount() const { return mCRCChangeCount; }
+
+ void calcSceneContribution(const LLVector4a& camera_origin, bool needs_update, U32 last_update, F32 dist_threshold);
+ void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;}
+ F32 getSceneContribution() const { return mSceneContrib;}
+
+ void dump() const;
+ S32 writeToBuffer(U8 *data_buffer) const;
+ LLDataPackerBinaryBuffer *getDP();
+ void recordHit();
+ void recordDupe() { mDupeCount++; }
+
+ /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry);
+
+ void setParentID(U32 id);
+ U32 getParentID() const {return mParentID;}
+ bool isChild() const {return mParentID > 0;}
+
+ void addChild(LLVOCacheEntry* entry);
+ void removeChild(LLVOCacheEntry* entry);
+ void removeAllChildren();
+ LLVOCacheEntry* getChild(); //remove the first child, and return it.
+ S32 getNumOfChildren() const {return mChildrenList.size();}
+
+ void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); //called from processing object update message
+ void updateParentBoundingInfo();
+ void saveBoundingSphere();
+
+ void setValid(BOOL valid = TRUE) {mValid = valid;}
+ BOOL isValid() const {return mValid;}
+
+ void setUpdateFlags(U32 flags) {mUpdateFlags = flags;}
+ U32 getUpdateFlags() const {return mUpdateFlags;}
+
+ static void updateDebugSettings();
+ static F32 getSquaredPixelThreshold(bool is_front);
private:
- void updateParentBoundingInfo(const LLVOCacheEntry* child);
+ void updateParentBoundingInfo(const LLVOCacheEntry* child);
public:
- typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
- typedef std::set<LLVOCacheEntry*> vocache_entry_set_t;
- typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
+ typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
+ typedef std::set<LLVOCacheEntry*> vocache_entry_set_t;
+ typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
typedef std::unordered_map<U32, LLGLTFOverrideCacheEntry> vocache_gltf_overrides_map_t;
- S32 mLastCameraUpdated;
+ S32 mLastCameraUpdated;
protected:
- U32 mLocalID;
- U32 mParentID;
- U32 mCRC;
- U32 mUpdateFlags; //receive from sim
- S32 mHitCount;
- S32 mDupeCount;
- S32 mCRCChangeCount;
- LLDataPackerBinaryBuffer mDP;
- U8 *mBuffer;
+ U32 mLocalID;
+ U32 mParentID;
+ U32 mCRC;
+ U32 mUpdateFlags; //receive from sim
+ S32 mHitCount;
+ S32 mDupeCount;
+ S32 mCRCChangeCount;
+ LLDataPackerBinaryBuffer mDP;
+ U8 *mBuffer;
- F32 mSceneContrib; //projected scene contributuion of this object.
- U32 mState; //high 16 bits reserved for special use.
- vocache_entry_set_t mChildrenList; //children entries in a linked set.
+ F32 mSceneContrib; //projected scene contributuion of this object.
+ U32 mState; //high 16 bits reserved for special use.
+ vocache_entry_set_t mChildrenList; //children entries in a linked set.
- BOOL mValid; //if set, this entry is valid, otherwise it is invalid and will be removed.
+ BOOL mValid; //if set, this entry is valid, otherwise it is invalid and will be removed.
- LLVector4a mBSphereCenter; //bounding sphere center
- F32 mBSphereRadius; //bounding sphere radius
+ LLVector4a mBSphereCenter; //bounding sphere center
+ F32 mBSphereRadius; //bounding sphere radius
public:
- static U32 sMinFrameRange;
- static F32 sNearRadius;
- static F32 sRearFarRadius;
- static F32 sFrontPixelThreshold;
- static F32 sRearPixelThreshold;
+ static U32 sMinFrameRange;
+ static F32 sNearRadius;
+ static F32 sRearFarRadius;
+ static F32 sFrontPixelThreshold;
+ static F32 sRearPixelThreshold;
};
class LLVOCacheGroup : public LLOcclusionCullingGroup
{
public:
- LLVOCacheGroup(OctreeNode* node, LLViewerOctreePartition* part) : LLOcclusionCullingGroup(node, part){}
+ LLVOCacheGroup(OctreeNode* node, LLViewerOctreePartition* part) : LLOcclusionCullingGroup(node, part){}
- //virtual
- void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
+ //virtual
+ void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
protected:
- virtual ~LLVOCacheGroup();
+ virtual ~LLVOCacheGroup();
};
class LLVOCachePartition : public LLViewerOctreePartition
{
public:
- LLVOCachePartition(LLViewerRegion* regionp);
+ LLVOCachePartition(LLViewerRegion* regionp);
virtual ~LLVOCachePartition();
- bool addEntry(LLViewerOctreeEntry* entry);
- void removeEntry(LLViewerOctreeEntry* entry);
- /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion);
- void addOccluders(LLViewerOctreeGroup* gp);
- void resetOccluders();
- void processOccluders(LLCamera* camera);
- void removeOccluder(LLVOCacheGroup* group);
+ bool addEntry(LLViewerOctreeEntry* entry);
+ void removeEntry(LLViewerOctreeEntry* entry);
+ /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion);
+ void addOccluders(LLViewerOctreeGroup* gp);
+ void resetOccluders();
+ void processOccluders(LLCamera* camera);
+ void removeOccluder(LLVOCacheGroup* group);
- void setCullHistory(BOOL has_new_object);
+ void setCullHistory(BOOL has_new_object);
- bool isFrontCull() const {return mFrontCull;}
+ bool isFrontCull() const {return mFrontCull;}
private:
- void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff, bool use_occlusion); //select objects behind camera.
+ void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff, bool use_occlusion); //select objects behind camera.
public:
- static BOOL sNeedsOcclusionCheck;
+ static BOOL sNeedsOcclusionCheck;
private:
- BOOL mFrontCull; //the view frustum cull if set, otherwise is back sphere cull.
- U32 mCullHistory;
- U32 mCulledTime[LLViewerCamera::NUM_CAMERAS];
- std::set<LLVOCacheGroup*> mOccludedGroups;
+ BOOL mFrontCull; //the view frustum cull if set, otherwise is back sphere cull.
+ U32 mCullHistory;
+ U32 mCulledTime[LLViewerCamera::NUM_CAMERAS];
+ std::set<LLVOCacheGroup*> mOccludedGroups;
- S32 mBackSlectionEnabled; //enable to select back objects if > 0.
- U32 mIdleHash;
+ S32 mBackSlectionEnabled; //enable to select back objects if > 0.
+ U32 mIdleHash;
};
//
@@ -249,82 +245,83 @@ private:
//
class LLVOCache : public LLParamSingleton<LLVOCache>
{
- LLSINGLETON(LLVOCache, bool read_only);
- ~LLVOCache() ;
+ LLSINGLETON(LLVOCache, bool read_only);
+ ~LLVOCache() ;
private:
- struct HeaderEntryInfo
- {
- HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {}
- S32 mIndex;
- U64 mHandle ;
- U32 mTime ;
- };
-
- struct HeaderMetaInfo
- {
- HeaderMetaInfo() : mVersion(0), mAddressSize(0) {}
-
- U32 mVersion;
- U32 mAddressSize;
- };
-
- struct header_entry_less
- {
- bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const
- {
- if(lhs->mTime == rhs->mTime)
- {
- return lhs < rhs ;
- }
-
- return lhs->mTime < rhs->mTime ; // older entry in front of queue (set)
- }
- };
- typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
- typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
+ struct HeaderEntryInfo
+ {
+ HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {}
+ S32 mIndex;
+ U64 mHandle ;
+ U32 mTime ;
+ };
+
+ struct HeaderMetaInfo
+ {
+ HeaderMetaInfo() : mVersion(0), mAddressSize(0) {}
+
+ U32 mVersion;
+ U32 mAddressSize;
+ };
+
+ struct header_entry_less
+ {
+ bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const
+ {
+ if(lhs->mTime == rhs->mTime)
+ {
+ return lhs < rhs ;
+ }
+
+ return lhs->mTime < rhs->mTime ; // older entry in front of queue (set)
+ }
+ };
+ typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
+ typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
public:
- // We need this init to be separate from constructor, since we might construct cache, purge it, then init.
- void initCache(ELLPath location, U32 size, U32 cache_version);
- void removeCache(ELLPath location, bool started = false) ;
+ // We need this init to be separate from constructor, since we might construct cache, purge it, then init.
+ void initCache(ELLPath location, U32 size, U32 cache_version);
+ void removeCache(ELLPath location, bool started = false) ;
- void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
- void readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map);
+ bool readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
+ void readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map);
- void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled);
+ void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled);
void writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled);
- void removeEntry(U64 handle) ;
+ void removeEntry(U64 handle) ;
+ void removeGenericExtrasForHandle(U64 handle);
- U32 getCacheEntries() { return mNumEntries; }
- U32 getCacheEntriesMax() { return mCacheSize; }
+ U32 getCacheEntries() { return mNumEntries; }
+ U32 getCacheEntriesMax() { return mCacheSize; }
private:
- void setDirNames(ELLPath location);
- // determine the cache filename for the region from the region handle
- void getObjectCacheFilename(U64 handle, std::string& filename);
+ void setDirNames(ELLPath location);
+ // determine the cache filename for the region from the region handle
+ void getObjectCacheFilename(U64 handle, std::string& filename);
std::string getObjectCacheExtrasFilename(U64 handle);
- void removeFromCache(HeaderEntryInfo* entry);
- void readCacheHeader();
- void writeCacheHeader();
- void clearCacheInMemory();
- void removeCache() ;
- void removeEntry(HeaderEntryInfo* entry) ;
- void purgeEntries(U32 size);
- BOOL updateEntry(const HeaderEntryInfo* entry);
-
+ void removeFromCache(HeaderEntryInfo* entry);
+ void readCacheHeader();
+ void writeCacheHeader();
+ void clearCacheInMemory();
+ void removeCache() ;
+ void removeEntry(HeaderEntryInfo* entry) ;
+ void purgeEntries(U32 size);
+ BOOL updateEntry(const HeaderEntryInfo* entry);
+
private:
- bool mEnabled;
- bool mInitialized ;
- bool mReadOnly ;
- HeaderMetaInfo mMetaInfo;
- U32 mCacheSize;
- U32 mNumEntries;
- std::string mHeaderFileName ;
- std::string mObjectCacheDirName;
- LLVolatileAPRPool* mLocalAPRFilePoolp ;
- header_entry_queue_t mHeaderEntryQueue;
- handle_entry_map_t mHandleEntryMap;
+ bool mEnabled;
+ bool mInitialized ;
+ bool mReadOnly ;
+ HeaderMetaInfo mMetaInfo;
+ U32 mCacheSize;
+ U32 mNumEntries;
+ std::string mHeaderFileName ;
+ std::string mObjectCacheDirName;
+ LLVolatileAPRPool* mLocalAPRFilePoolp ;
+ header_entry_queue_t mHeaderEntryQueue;
+ handle_entry_map_t mHandleEntryMap;
};
#endif
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index b7d623b725..69b9476d38 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvosurfacepatch.cpp
* @brief Viewer-object derived "surface patch", which is a piece of terrain
*
* $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$
*/
@@ -39,6 +39,7 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llvlcomposition.h"
+#include "llvolume.h"
#include "llvovolume.h"
#include "pipeline.h"
#include "llspatialpartition.h"
@@ -46,51 +47,51 @@
F32 LLVOSurfacePatch::sLODFactor = 1.f;
LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
- : LLStaticViewerObject(id, pcode, regionp),
- mDirtiedPatch(FALSE),
- mPool(NULL),
- mBaseComp(0),
- mPatchp(NULL),
- mDirtyTexture(FALSE),
- mDirtyTerrain(FALSE),
- mLastNorthStride(0),
- mLastEastStride(0),
- mLastStride(0),
- mLastLength(0)
+ : LLStaticViewerObject(id, pcode, regionp),
+ mDirtiedPatch(FALSE),
+ mPool(NULL),
+ mBaseComp(0),
+ mPatchp(NULL),
+ mDirtyTexture(FALSE),
+ mDirtyTerrain(FALSE),
+ mLastNorthStride(0),
+ mLastEastStride(0),
+ mLastStride(0),
+ mLastLength(0)
{
- // Terrain must draw during selection passes so it can block objects behind it.
- mbCanSelect = TRUE;
- setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility.
+ // Terrain must draw during selection passes so it can block objects behind it.
+ mbCanSelect = TRUE;
+ setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility.
}
LLVOSurfacePatch::~LLVOSurfacePatch()
{
- mPatchp = NULL;
+ mPatchp = NULL;
}
void LLVOSurfacePatch::markDead()
{
- if (mPatchp)
- {
- mPatchp->clearVObj();
- mPatchp = NULL;
- }
- LLViewerObject::markDead();
+ if (mPatchp)
+ {
+ mPatchp->clearVObj();
+ mPatchp = NULL;
+ }
+ LLViewerObject::markDead();
}
BOOL LLVOSurfacePatch::isActive() const
{
- return FALSE;
+ return FALSE;
}
void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent)
{
- mAppAngle = 50;
- mPixelArea = 500*500;
+ mAppAngle = 50;
+ mPixelArea = 500*500;
}
@@ -101,179 +102,182 @@ void LLVOSurfacePatch::updateTextures()
LLFacePool *LLVOSurfacePatch::getPool()
{
- mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture());
+ mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture());
- return mPool;
+ return mPool;
}
LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
{
- pipeline->allocDrawable(this);
-
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN);
-
- mBaseComp = llfloor(mPatchp->getMinComposition());
- S32 min_comp, max_comp, range;
- min_comp = llfloor(mPatchp->getMinComposition());
- max_comp = llceil(mPatchp->getMaxComposition());
- range = (max_comp - min_comp);
- range++;
- if (range > 3)
- {
- if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
- {
- // The top side runs over more
- mBaseComp++;
- }
- range = 3;
- }
-
- LLFacePool *poolp = getPool();
-
- mDrawable->addFace(poolp, NULL);
-
- return mDrawable;
+ pipeline->allocDrawable(this);
+
+ mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN);
+
+ mBaseComp = llfloor(mPatchp->getMinComposition());
+ S32 min_comp, max_comp, range;
+ min_comp = llfloor(mPatchp->getMinComposition());
+ max_comp = llceil(mPatchp->getMaxComposition());
+ range = (max_comp - min_comp);
+ range++;
+ if (range > 3)
+ {
+ if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
+ {
+ // The top side runs over more
+ mBaseComp++;
+ }
+ range = 3;
+ }
+
+ LLFacePool *poolp = getPool();
+
+ mDrawable->addFace(poolp, NULL);
+
+ return mDrawable;
}
void LLVOSurfacePatch::updateGL()
{
- if (mPatchp)
- {
- LL_PROFILE_ZONE_SCOPED
- mPatchp->updateGL();
- }
+ if (mPatchp)
+ {
+ LL_PROFILE_ZONE_SCOPED
+ mPatchp->updateGL();
+ }
}
BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
{
LL_PROFILE_ZONE_SCOPED;
- dirtySpatialGroup();
-
- S32 min_comp, max_comp, range;
- min_comp = lltrunc(mPatchp->getMinComposition());
- max_comp = lltrunc(ceil(mPatchp->getMaxComposition()));
- range = (max_comp - min_comp);
- range++;
- S32 new_base_comp = lltrunc(mPatchp->getMinComposition());
- if (range > 3)
- {
- if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
- {
- // The top side runs over more
- new_base_comp++;
- }
- range = 3;
- }
-
- // Pick the two closest detail textures for this patch...
- // Then create the draw pool for it.
- // Actually, should get the average composition instead of the center.
- mBaseComp = new_base_comp;
-
- //////////////////////////
- //
- // Figure out the strides
- //
- //
-
- U32 patch_width, render_stride, north_stride, east_stride, length;
- render_stride = mPatchp->getRenderStride();
- patch_width = mPatchp->getSurface()->getGridsPerPatchEdge();
-
- length = patch_width / render_stride;
-
- if (mPatchp->getNeighborPatch(NORTH))
- {
- north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride();
- }
- else
- {
- north_stride = render_stride;
- }
-
- if (mPatchp->getNeighborPatch(EAST))
- {
- east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride();
- }
- else
- {
- east_stride = render_stride;
- }
-
- mLastLength = length;
- mLastStride = render_stride;
- mLastNorthStride = north_stride;
- mLastEastStride = east_stride;
-
- return TRUE;
+ dirtySpatialGroup();
+
+ S32 min_comp, max_comp, range;
+ min_comp = lltrunc(mPatchp->getMinComposition());
+ max_comp = lltrunc(ceil(mPatchp->getMaxComposition()));
+ range = (max_comp - min_comp);
+ range++;
+ S32 new_base_comp = lltrunc(mPatchp->getMinComposition());
+ if (range > 3)
+ {
+ if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
+ {
+ // The top side runs over more
+ new_base_comp++;
+ }
+ range = 3;
+ }
+
+ // Pick the two closest detail textures for this patch...
+ // Then create the draw pool for it.
+ // Actually, should get the average composition instead of the center.
+ mBaseComp = new_base_comp;
+
+ //////////////////////////
+ //
+ // Figure out the strides
+ //
+ //
+
+ U32 patch_width, render_stride, north_stride, east_stride, length;
+ render_stride = mPatchp->getRenderStride();
+ patch_width = mPatchp->getSurface()->getGridsPerPatchEdge();
+
+ length = patch_width / render_stride;
+
+ if (mPatchp->getNeighborPatch(NORTH))
+ {
+ north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride();
+ }
+ else
+ {
+ north_stride = render_stride;
+ }
+
+ if (mPatchp->getNeighborPatch(EAST))
+ {
+ east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride();
+ }
+ else
+ {
+ east_stride = render_stride;
+ }
+
+ mLastLength = length;
+ mLastStride = render_stride;
+ mLastNorthStride = north_stride;
+ mLastEastStride = east_stride;
+
+ return TRUE;
}
void LLVOSurfacePatch::updateFaceSize(S32 idx)
{
- if (idx != 0)
- {
- LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL;
- return;
- }
-
- LLFace* facep = mDrawable->getFace(idx);
- if (facep)
- {
- S32 num_vertices = 0;
- S32 num_indices = 0;
-
- if (mLastStride)
- {
- getGeomSizesMain(mLastStride, num_vertices, num_indices);
- getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
- getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
- }
-
- facep->setSize(num_vertices, num_indices);
- }
+ LL_PROFILE_ZONE_SCOPED;
+ if (idx != 0)
+ {
+ LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL;
+ return;
+ }
+
+ LLFace* facep = mDrawable->getFace(idx);
+ if (facep)
+ {
+ S32 num_vertices = 0;
+ S32 num_indices = 0;
+
+ if (mLastStride)
+ {
+ getGeomSizesMain(mLastStride, num_vertices, num_indices);
+ getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
+ getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
+ }
+
+ facep->setSize(num_vertices, num_indices);
+ }
}
BOOL LLVOSurfacePatch::updateLOD()
{
- return TRUE;
+ return TRUE;
}
-void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
- LLStrider<LLVector3> &normalsp,
- LLStrider<LLVector2> &texCoords0p,
- LLStrider<LLVector2> &texCoords1p,
- LLStrider<U16> &indicesp)
+void LLVOSurfacePatch::getTerrainGeometry(LLStrider<LLVector3> &verticesp,
+ LLStrider<LLVector3> &normalsp,
+ LLStrider<LLVector2> &texCoords0p,
+ LLStrider<LLVector2> &texCoords1p,
+ LLStrider<U16> &indicesp)
{
- LLFace* facep = mDrawable->getFace(0);
- if (facep)
+ LLFace* facep = mDrawable->getFace(0);
+ if (!facep)
{
- U32 index_offset = facep->getGeomIndex();
+ return;
+ }
+
+ U32 index_offset = facep->getGeomIndex();
- updateMainGeometry(facep,
+ updateMainGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ updateNorthGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ updateEastGeometry(facep,
verticesp,
normalsp,
texCoords0p,
texCoords1p,
indicesp,
index_offset);
- updateNorthGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- updateEastGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- }
}
void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
@@ -284,99 +288,99 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
LLStrider<U16> &indicesp,
U32 &index_offset)
{
- S32 i, j, x, y;
-
- U32 patch_size, render_stride;
- S32 num_vertices, num_indices;
- U32 index;
-
- llassert(mLastStride > 0);
-
- render_stride = mLastStride;
- patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
- S32 vert_size = patch_size / render_stride;
-
- ///////////////////////////
- //
- // Render the main patch
- //
- //
-
- num_vertices = 0;
- num_indices = 0;
- // First, figure out how many vertices we need...
- getGeomSizesMain(render_stride, num_vertices, num_indices);
-
- if (num_vertices > 0)
- {
- facep->mCenterAgent = mPatchp->getPointAgent(8, 8);
-
- // Generate patch points first
- for (j = 0; j < vert_size; j++)
- {
- for (i = 0; i < vert_size; i++)
- {
- x = i * render_stride;
- y = j * render_stride;
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
- }
-
- for (j = 0; j < (vert_size - 1); j++)
- {
- if (j % 2)
- {
- for (i = (vert_size - 1); i > 0; i--)
- {
- index = (i - 1)+ j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = i + (j+1)*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = (i - 1) + (j+1)*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = (i - 1) + j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = i + j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = i + (j+1)*vert_size;
- *(indicesp++) = index_offset + index;
- }
- }
- else
- {
- for (i = 0; i < (vert_size - 1); i++)
- {
- index = i + j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = (i + 1) + (j+1)*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = i + (j+1)*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = i + j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = (i + 1) + j*vert_size;
- *(indicesp++) = index_offset + index;
-
- index = (i + 1) + (j + 1)*vert_size;
- *(indicesp++) = index_offset + index;
- }
- }
- }
- }
- index_offset += num_vertices;
+ S32 i, j, x, y;
+
+ U32 patch_size, render_stride;
+ S32 num_vertices, num_indices;
+ U32 index;
+
+ llassert(mLastStride > 0);
+
+ render_stride = mLastStride;
+ patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+ S32 vert_size = patch_size / render_stride;
+
+ ///////////////////////////
+ //
+ // Render the main patch
+ //
+ //
+
+ num_vertices = 0;
+ num_indices = 0;
+ // First, figure out how many vertices we need...
+ getGeomSizesMain(render_stride, num_vertices, num_indices);
+
+ if (num_vertices > 0)
+ {
+ facep->mCenterAgent = mPatchp->getPointAgent(8, 8);
+
+ // Generate patch points first
+ for (j = 0; j < vert_size; j++)
+ {
+ for (i = 0; i < vert_size; i++)
+ {
+ x = i * render_stride;
+ y = j * render_stride;
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+ }
+
+ for (j = 0; j < (vert_size - 1); j++)
+ {
+ if (j % 2)
+ {
+ for (i = (vert_size - 1); i > 0; i--)
+ {
+ index = (i - 1)+ j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = i + (j+1)*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = (i - 1) + (j+1)*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = (i - 1) + j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = i + j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = i + (j+1)*vert_size;
+ *(indicesp++) = index_offset + index;
+ }
+ }
+ else
+ {
+ for (i = 0; i < (vert_size - 1); i++)
+ {
+ index = i + j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = (i + 1) + (j+1)*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = i + (j+1)*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = i + j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = (i + 1) + j*vert_size;
+ *(indicesp++) = index_offset + index;
+
+ index = (i + 1) + (j + 1)*vert_size;
+ *(indicesp++) = index_offset + index;
+ }
+ }
+ }
+ }
+ index_offset += num_vertices;
}
@@ -388,186 +392,186 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
LLStrider<U16> &indicesp,
U32 &index_offset)
{
- S32 i, x, y;
-
- S32 num_vertices;
-
- U32 render_stride = mLastStride;
- S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
- S32 length = patch_size / render_stride;
- S32 half_length = length / 2;
- U32 north_stride = mLastNorthStride;
-
- ///////////////////////////
- //
- // Render the north strip
- //
- //
-
- // Stride lengths are the same
- if (north_stride == render_stride)
- {
- num_vertices = 2 * length + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
-
- // Main patch
- for (i = 0; i < length; i++)
- {
- x = i * render_stride;
- y = 16 - render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- // North patch
- for (i = 0; i <= length; i++)
- {
- x = i * render_stride;
- y = 16;
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
-
- for (i = 0; i < length; i++)
- {
- // Generate indices
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + length + i + 1;
- *(indicesp++) = index_offset + length + i;
-
- if (i != length - 1)
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + i + 1;
- *(indicesp++) = index_offset + length + i + 1;
- }
- }
- }
- else if (north_stride > render_stride)
- {
- // North stride is longer (has less vertices)
- num_vertices = length + length/2 + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
-
- // Iterate through this patch's points
- for (i = 0; i < length; i++)
- {
- x = i * render_stride;
- y = 16 - render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- // Iterate through the north patch's points
- for (i = 0; i <= length; i+=2)
- {
- x = i * render_stride;
- y = 16;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
-
- for (i = 0; i < length; i++)
- {
- if (!(i % 2))
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + i + 1;
- *(indicesp++) = index_offset + length + (i/2);
-
- *(indicesp++) = index_offset + i + 1;
- *(indicesp++) = index_offset + length + (i/2) + 1;
- *(indicesp++) = index_offset + length + (i/2);
- }
- else if (i < (length - 1))
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + i + 1;
- *(indicesp++) = index_offset + length + (i/2) + 1;
- }
- }
- }
- else
- {
- // North stride is shorter (more vertices)
- length = patch_size / north_stride;
- half_length = length / 2;
- num_vertices = length + half_length + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
-
- // Iterate through this patch's points
- for (i = 0; i < length; i+=2)
- {
- x = i * north_stride;
- y = 16 - render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- // Iterate through the north patch's points
- for (i = 0; i <= length; i++)
- {
- x = i * north_stride;
- y = 16;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- for (i = 0; i < length; i++)
- {
- if (!(i%2))
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + i/2;
- *(indicesp++) = index_offset + half_length + i + 1;
- }
- else if (i < (length - 2))
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + i/2;
- *(indicesp++) = index_offset + i/2 + 1;
-
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + i/2 + 1;
- *(indicesp++) = index_offset + half_length + i + 1;
- }
- else
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + i/2;
- *(indicesp++) = index_offset + half_length + i + 1;
- }
- }
- }
- index_offset += num_vertices;
+ S32 i, x, y;
+
+ S32 num_vertices;
+
+ U32 render_stride = mLastStride;
+ S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+ S32 length = patch_size / render_stride;
+ S32 half_length = length / 2;
+ U32 north_stride = mLastNorthStride;
+
+ ///////////////////////////
+ //
+ // Render the north strip
+ //
+ //
+
+ // Stride lengths are the same
+ if (north_stride == render_stride)
+ {
+ num_vertices = 2 * length + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
+
+ // Main patch
+ for (i = 0; i < length; i++)
+ {
+ x = i * render_stride;
+ y = 16 - render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ // North patch
+ for (i = 0; i <= length; i++)
+ {
+ x = i * render_stride;
+ y = 16;
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+
+ for (i = 0; i < length; i++)
+ {
+ // Generate indices
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + length + i + 1;
+ *(indicesp++) = index_offset + length + i;
+
+ if (i != length - 1)
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + i + 1;
+ *(indicesp++) = index_offset + length + i + 1;
+ }
+ }
+ }
+ else if (north_stride > render_stride)
+ {
+ // North stride is longer (has less vertices)
+ num_vertices = length + length/2 + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
+
+ // Iterate through this patch's points
+ for (i = 0; i < length; i++)
+ {
+ x = i * render_stride;
+ y = 16 - render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ // Iterate through the north patch's points
+ for (i = 0; i <= length; i+=2)
+ {
+ x = i * render_stride;
+ y = 16;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+
+ for (i = 0; i < length; i++)
+ {
+ if (!(i % 2))
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + i + 1;
+ *(indicesp++) = index_offset + length + (i/2);
+
+ *(indicesp++) = index_offset + i + 1;
+ *(indicesp++) = index_offset + length + (i/2) + 1;
+ *(indicesp++) = index_offset + length + (i/2);
+ }
+ else if (i < (length - 1))
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + i + 1;
+ *(indicesp++) = index_offset + length + (i/2) + 1;
+ }
+ }
+ }
+ else
+ {
+ // North stride is shorter (more vertices)
+ length = patch_size / north_stride;
+ half_length = length / 2;
+ num_vertices = length + half_length + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
+
+ // Iterate through this patch's points
+ for (i = 0; i < length; i+=2)
+ {
+ x = i * north_stride;
+ y = 16 - render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ // Iterate through the north patch's points
+ for (i = 0; i <= length; i++)
+ {
+ x = i * north_stride;
+ y = 16;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ if (!(i%2))
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + i/2;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ }
+ else if (i < (length - 2))
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + i/2;
+ *(indicesp++) = index_offset + i/2 + 1;
+
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + i/2 + 1;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ }
+ else
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + i/2;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ }
+ }
+ }
+ index_offset += num_vertices;
}
void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
@@ -578,448 +582,513 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
LLStrider<U16> &indicesp,
U32 &index_offset)
{
- S32 i, x, y;
-
- S32 num_vertices;
-
- U32 render_stride = mLastStride;
- S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
- S32 length = patch_size / render_stride;
- S32 half_length = length / 2;
-
- U32 east_stride = mLastEastStride;
-
- // Stride lengths are the same
- if (east_stride == render_stride)
- {
- num_vertices = 2 * length + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
-
- // Main patch
- for (i = 0; i < length; i++)
- {
- x = 16 - render_stride;
- y = i * render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- // East patch
- for (i = 0; i <= length; i++)
- {
- x = 16;
- y = i * render_stride;
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
-
- for (i = 0; i < length; i++)
- {
- // Generate indices
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + length + i;
- *(indicesp++) = index_offset + length + i + 1;
-
- if (i != length - 1)
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + length + i + 1;
- *(indicesp++) = index_offset + i + 1;
- }
- }
- }
- else if (east_stride > render_stride)
- {
- // East stride is longer (has less vertices)
- num_vertices = length + half_length + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
-
- // Iterate through this patch's points
- for (i = 0; i < length; i++)
- {
- x = 16 - render_stride;
- y = i * render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
- // Iterate through the east patch's points
- for (i = 0; i <= length; i+=2)
- {
- x = 16;
- y = i * render_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- for (i = 0; i < length; i++)
- {
- if (!(i % 2))
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + length + (i/2);
- *(indicesp++) = index_offset + i + 1;
-
- *(indicesp++) = index_offset + i + 1;
- *(indicesp++) = index_offset + length + (i/2);
- *(indicesp++) = index_offset + length + (i/2) + 1;
- }
- else if (i < (length - 1))
- {
- *(indicesp++) = index_offset + i;
- *(indicesp++) = index_offset + length + (i/2) + 1;
- *(indicesp++) = index_offset + i + 1;
- }
- }
- }
- else
- {
- // East stride is shorter (more vertices)
- length = patch_size / east_stride;
- half_length = length / 2;
- num_vertices = length + length/2 + 1;
-
- facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
-
- // Iterate through this patch's points
- for (i = 0; i < length; i+=2)
- {
- x = 16 - render_stride;
- y = i * east_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
- // Iterate through the east patch's points
- for (i = 0; i <= length; i++)
- {
- x = 16;
- y = i * east_stride;
-
- mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
- verticesp++;
- normalsp++;
- texCoords0p++;
- texCoords1p++;
- }
-
- for (i = 0; i < length; i++)
- {
- if (!(i%2))
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + half_length + i + 1;
- *(indicesp++) = index_offset + i/2;
- }
- else if (i < (length - 2))
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + i/2 + 1;
- *(indicesp++) = index_offset + i/2;
-
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + half_length + i + 1;
- *(indicesp++) = index_offset + i/2 + 1;
- }
- else
- {
- *(indicesp++) = index_offset + half_length + i;
- *(indicesp++) = index_offset + half_length + i + 1;
- *(indicesp++) = index_offset + i/2;
- }
- }
- }
- index_offset += num_vertices;
+ S32 i, x, y;
+
+ S32 num_vertices;
+
+ U32 render_stride = mLastStride;
+ S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+ S32 length = patch_size / render_stride;
+ S32 half_length = length / 2;
+
+ U32 east_stride = mLastEastStride;
+
+ // Stride lengths are the same
+ if (east_stride == render_stride)
+ {
+ num_vertices = 2 * length + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
+
+ // Main patch
+ for (i = 0; i < length; i++)
+ {
+ x = 16 - render_stride;
+ y = i * render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ // East patch
+ for (i = 0; i <= length; i++)
+ {
+ x = 16;
+ y = i * render_stride;
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+
+ for (i = 0; i < length; i++)
+ {
+ // Generate indices
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + length + i;
+ *(indicesp++) = index_offset + length + i + 1;
+
+ if (i != length - 1)
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + length + i + 1;
+ *(indicesp++) = index_offset + i + 1;
+ }
+ }
+ }
+ else if (east_stride > render_stride)
+ {
+ // East stride is longer (has less vertices)
+ num_vertices = length + half_length + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
+
+ // Iterate through this patch's points
+ for (i = 0; i < length; i++)
+ {
+ x = 16 - render_stride;
+ y = i * render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+ // Iterate through the east patch's points
+ for (i = 0; i <= length; i+=2)
+ {
+ x = 16;
+ y = i * render_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ if (!(i % 2))
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + length + (i/2);
+ *(indicesp++) = index_offset + i + 1;
+
+ *(indicesp++) = index_offset + i + 1;
+ *(indicesp++) = index_offset + length + (i/2);
+ *(indicesp++) = index_offset + length + (i/2) + 1;
+ }
+ else if (i < (length - 1))
+ {
+ *(indicesp++) = index_offset + i;
+ *(indicesp++) = index_offset + length + (i/2) + 1;
+ *(indicesp++) = index_offset + i + 1;
+ }
+ }
+ }
+ else
+ {
+ // East stride is shorter (more vertices)
+ length = patch_size / east_stride;
+ half_length = length / 2;
+ num_vertices = length + length/2 + 1;
+
+ facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
+
+ // Iterate through this patch's points
+ for (i = 0; i < length; i+=2)
+ {
+ x = 16 - render_stride;
+ y = i * east_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+ // Iterate through the east patch's points
+ for (i = 0; i <= length; i++)
+ {
+ x = 16;
+ y = i * east_stride;
+
+ mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
+ verticesp++;
+ normalsp++;
+ texCoords0p++;
+ texCoords1p++;
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ if (!(i%2))
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ *(indicesp++) = index_offset + i/2;
+ }
+ else if (i < (length - 2))
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + i/2 + 1;
+ *(indicesp++) = index_offset + i/2;
+
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ *(indicesp++) = index_offset + i/2 + 1;
+ }
+ else
+ {
+ *(indicesp++) = index_offset + half_length + i;
+ *(indicesp++) = index_offset + half_length + i + 1;
+ *(indicesp++) = index_offset + i/2;
+ }
+ }
+ }
+ index_offset += num_vertices;
}
void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp)
{
- mPatchp = patchp;
+ mPatchp = patchp;
- dirtyPatch();
+ dirtyPatch();
};
void LLVOSurfacePatch::dirtyPatch()
{
- mDirtiedPatch = TRUE;
- dirtyGeom();
- mDirtyTerrain = TRUE;
- LLVector3 center = mPatchp->getCenterRegion();
- LLSurface *surfacep = mPatchp->getSurface();
+ mDirtiedPatch = TRUE;
+ dirtyGeom();
+ mDirtyTerrain = TRUE;
+ LLVector3 center = mPatchp->getCenterRegion();
+ LLSurface *surfacep = mPatchp->getSurface();
- setPositionRegion(center);
+ setPositionRegion(center);
- F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid();
- setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ()));
+ F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid();
+ setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ()));
}
void LLVOSurfacePatch::dirtyGeom()
{
- if (mDrawable)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
- LLFace* facep = mDrawable->getFace(0);
- if (facep)
- {
- facep->setVertexBuffer(NULL);
- }
- mDrawable->movePartition();
- }
+ if (mDrawable)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep->setVertexBuffer(NULL);
+ }
+ mDrawable->movePartition();
+ }
}
void LLVOSurfacePatch::getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices)
{
- S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
-
- // First, figure out how many vertices we need...
- S32 vert_size = patch_size / stride;
- if (vert_size >= 2)
- {
- num_vertices += vert_size * vert_size;
- num_indices += 6 * (vert_size - 1)*(vert_size - 1);
- }
+ S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+
+ // First, figure out how many vertices we need...
+ S32 vert_size = patch_size / stride;
+ if (vert_size >= 2)
+ {
+ num_vertices += vert_size * vert_size;
+ num_indices += 6 * (vert_size - 1)*(vert_size - 1);
+ }
}
void LLVOSurfacePatch::getGeomSizesNorth(const S32 stride, const S32 north_stride,
- S32 &num_vertices, S32 &num_indices)
+ S32 &num_vertices, S32 &num_indices)
{
- S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
- S32 length = patch_size / stride;
- // Stride lengths are the same
- if (north_stride == stride)
- {
- num_vertices += 2 * length + 1;
- num_indices += length * 6 - 3;
- }
- else if (north_stride > stride)
- {
- // North stride is longer (has less vertices)
- num_vertices += length + (length/2) + 1;
- num_indices += (length/2)*9 - 3;
- }
- else
- {
- // North stride is shorter (more vertices)
- length = patch_size / north_stride;
- num_vertices += length + (length/2) + 1;
- num_indices += 9*(length/2) - 3;
- }
+ S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+ S32 length = patch_size / stride;
+ // Stride lengths are the same
+ if (north_stride == stride)
+ {
+ num_vertices += 2 * length + 1;
+ num_indices += length * 6 - 3;
+ }
+ else if (north_stride > stride)
+ {
+ // North stride is longer (has less vertices)
+ num_vertices += length + (length/2) + 1;
+ num_indices += (length/2)*9 - 3;
+ }
+ else
+ {
+ // North stride is shorter (more vertices)
+ length = patch_size / north_stride;
+ num_vertices += length + (length/2) + 1;
+ num_indices += 9*(length/2) - 3;
+ }
}
void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
- S32 &num_vertices, S32 &num_indices)
+ S32 &num_vertices, S32 &num_indices)
{
- S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
- S32 length = patch_size / stride;
- // Stride lengths are the same
- if (east_stride == stride)
- {
- num_vertices += 2 * length + 1;
- num_indices += length * 6 - 3;
- }
- else if (east_stride > stride)
- {
- // East stride is longer (has less vertices)
- num_vertices += length + (length/2) + 1;
- num_indices += (length/2)*9 - 3;
- }
- else
- {
- // East stride is shorter (more vertices)
- length = patch_size / east_stride;
- num_vertices += length + (length/2) + 1;
- num_indices += 9*(length/2) - 3;
- }
+ S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
+ S32 length = patch_size / stride;
+ // Stride lengths are the same
+ if (east_stride == stride)
+ {
+ num_vertices += 2 * length + 1;
+ num_indices += length * 6 - 3;
+ }
+ else if (east_stride > stride)
+ {
+ // East stride is longer (has less vertices)
+ num_vertices += length + (length/2) + 1;
+ num_indices += (length/2)*9 - 3;
+ }
+ else
+ {
+ // East stride is shorter (more vertices)
+ length = patch_size / east_stride;
+ num_vertices += length + (length/2) + 1;
+ num_indices += 9*(length/2) - 3;
+ }
}
BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
- LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
-
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
+
{
- if (!lineSegmentBoundingBox(start, end))
- {
- return FALSE;
- }
-
- LLVector4a da;
- da.setSub(end, start);
- LLVector3 delta(da.getF32ptr());
+ if (!lineSegmentBoundingBox(start, end))
+ {
+ return FALSE;
+ }
+
+ LLVector4a da;
+ da.setSub(end, start);
+ LLVector3 delta(da.getF32ptr());
+
+ LLVector3 pdelta = delta;
+ pdelta.mV[2] = 0;
+
+ F32 plength = pdelta.length();
+
+ F32 tdelta = 1.f/plength;
+
+ LLVector3 v_start(start.getF32ptr());
+
+ LLVector3 origin = v_start - mRegionp->getOriginAgent();
+
+ if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
+ {
+ //origin is under ground, treat as no intersection
+ return FALSE;
+ }
+
+ //step one meter at a time until intersection point found
+
+ //VECTORIZE THIS
+ const LLVector4a* exta = mDrawable->getSpatialExtents();
+
+ LLVector3 ext[2];
+ ext[0].set(exta[0].getF32ptr());
+ ext[1].set(exta[1].getF32ptr());
+
+ F32 rad = (delta*tdelta).magVecSquared();
+
+ F32 t = 0.f;
+ while ( t <= 1.f)
+ {
+ LLVector3 sample = origin + delta*t;
+
+ if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad))
+ {
+ F32 height = mRegionp->getLandHeightRegion(sample);
+ if (height > sample.mV[2])
+ { //ray went below ground, positive intersection
+ //quick and dirty binary search to get impact point
+ tdelta = -tdelta*0.5f;
+ F32 err_dist = 0.001f;
+ F32 dist = fabsf(sample.mV[2] - height);
+
+ while (dist > err_dist && tdelta*tdelta > 0.0f)
+ {
+ t += tdelta;
+ sample = origin+delta*t;
+ height = mRegionp->getLandHeightRegion(sample);
+ if ((tdelta < 0 && height < sample.mV[2]) ||
+ (height > sample.mV[2] && tdelta > 0))
+ { //jumped over intersection point, go back
+ tdelta = -tdelta;
+ }
+ tdelta *= 0.5f;
+ dist = fabsf(sample.mV[2] - height);
+ }
+
+ if (intersection)
+ {
+ F32 height = mRegionp->getLandHeightRegion(sample);
+ if (fabsf(sample.mV[2]-height) < delta.length()*tdelta)
+ {
+ sample.mV[2] = mRegionp->getLandHeightRegion(sample);
+ }
+ intersection->load3((sample + mRegionp->getOriginAgent()).mV);
+ }
+
+ if (normal)
+ {
+ normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
+ }
+
+ return TRUE;
+ }
+ }
+
+ t += tdelta;
+ if (t > 1 && t < 1.f+tdelta*0.99f)
+ { //make sure end point is checked (saves vertical lines coming up negative)
+ t = 1.f;
+ }
+ }
+
+
+ return FALSE;
+}
- LLVector3 pdelta = delta;
- pdelta.mV[2] = 0;
+void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
+{
+ LLVector3 posAgent = getPositionAgent();
+ LLVector3 scale = getScale();
+ //make z-axis scale at least 1 to avoid shadow artifacts on totally flat land
+ scale.mV[VZ] = llmax(scale.mV[VZ], 1.f);
+ newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong
+ newMax.load3( (posAgent+scale*0.5f).mV);
+ LLVector4a pos;
+ pos.setAdd(newMin,newMax);
+ pos.mul(0.5f);
+ mDrawable->setPositionGroup(pos);
+}
- F32 plength = pdelta.length();
+U32 LLVOSurfacePatch::getPartitionType() const
+{
+ return LLViewerRegion::PARTITION_TERRAIN;
+}
- F32 tdelta = 1.f/plength;
+LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
+: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, regionp)
+{
+ mOcclusionEnabled = FALSE;
+ mInfiniteFarClip = TRUE;
+ mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN;
+ mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
+}
- LLVector3 v_start(start.getF32ptr());
+// Do not add vertices; honor strict vertex count specified by strider_vertex_count
+void gen_terrain_tangents(U16 strider_vertex_count,
+ U32 strider_index_count,
+ LLStrider<LLVector3> &verticesp,
+ LLStrider<LLVector3> &normalsp,
+ LLStrider<LLVector4a> &tangentsp,
+ LLStrider<LLVector2> &texCoords0p,
+ LLStrider<U16> &indicesp)
+{
+ LL_PROFILE_ZONE_SCOPED
- LLVector3 origin = v_start - mRegionp->getOriginAgent();
+ LLVector4a *vertices = new LLVector4a[strider_vertex_count];
+ LLVector4a *normals = new LLVector4a[strider_vertex_count];
+ LLVector4a *tangents = new LLVector4a[strider_vertex_count];
+ std::vector<LLVector2> texcoords(strider_vertex_count);
+ std::vector<U16> indices(strider_index_count);
- if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
+ for (U16 v = 0; v < strider_vertex_count; ++v)
{
- //origin is under ground, treat as no intersection
- return FALSE;
+ F32 *vert = verticesp[v].mV;
+ vertices[v] = LLVector4a(vert[0], vert[1], vert[2], 1.f);
+ F32 *n = normalsp[v].mV;
+ normals[v] = LLVector4a(n[0], n[1], n[2], 1.f);
+ tangents[v] = tangentsp[v];
+ texcoords[v] = texCoords0p[v];
}
-
- //step one meter at a time until intersection point found
-
- //VECTORIZE THIS
- const LLVector4a* exta = mDrawable->getSpatialExtents();
-
- LLVector3 ext[2];
- ext[0].set(exta[0].getF32ptr());
- ext[1].set(exta[1].getF32ptr());
-
- F32 rad = (delta*tdelta).magVecSquared();
-
- F32 t = 0.f;
- while ( t <= 1.f)
+ for (U32 i = 0; i < strider_index_count; ++i)
{
- LLVector3 sample = origin + delta*t;
-
- if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad))
- {
- F32 height = mRegionp->getLandHeightRegion(sample);
- if (height > sample.mV[2])
- { //ray went below ground, positive intersection
- //quick and dirty binary search to get impact point
- tdelta = -tdelta*0.5f;
- F32 err_dist = 0.001f;
- F32 dist = fabsf(sample.mV[2] - height);
-
- while (dist > err_dist && tdelta*tdelta > 0.0f)
- {
- t += tdelta;
- sample = origin+delta*t;
- height = mRegionp->getLandHeightRegion(sample);
- if ((tdelta < 0 && height < sample.mV[2]) ||
- (height > sample.mV[2] && tdelta > 0))
- { //jumped over intersection point, go back
- tdelta = -tdelta;
- }
- tdelta *= 0.5f;
- dist = fabsf(sample.mV[2] - height);
- }
-
- if (intersection)
- {
- F32 height = mRegionp->getLandHeightRegion(sample);
- if (fabsf(sample.mV[2]-height) < delta.length()*tdelta)
- {
- sample.mV[2] = mRegionp->getLandHeightRegion(sample);
- }
- intersection->load3((sample + mRegionp->getOriginAgent()).mV);
- }
-
- if (normal)
- {
- normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
- }
-
- return TRUE;
- }
- }
-
- t += tdelta;
- if (t > 1 && t < 1.f+tdelta*0.99f)
- { //make sure end point is checked (saves vertical lines coming up negative)
- t = 1.f;
- }
+ indices[i] = indicesp[i];
}
+ LLCalculateTangentArray(strider_vertex_count, vertices, normals, texcoords.data(), strider_index_count / 3, indices.data(), tangents);
- return FALSE;
-}
-
-void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
-{
- LLVector3 posAgent = getPositionAgent();
- LLVector3 scale = getScale();
- //make z-axis scale at least 1 to avoid shadow artifacts on totally flat land
- scale.mV[VZ] = llmax(scale.mV[VZ], 1.f);
- newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong
- newMax.load3( (posAgent+scale*0.5f).mV);
- LLVector4a pos;
- pos.setAdd(newMin,newMax);
- pos.mul(0.5f);
- mDrawable->setPositionGroup(pos);
-}
-
-U32 LLVOSurfacePatch::getPartitionType() const
-{
- return LLViewerRegion::PARTITION_TERRAIN;
-}
+ for (U16 v = 0; v < strider_vertex_count; ++v)
+ {
+ tangentsp[v] = tangents[v];
+ }
-LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, regionp)
-{
- mOcclusionEnabled = FALSE;
- mInfiniteFarClip = TRUE;
- mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN;
- mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
+ delete[] vertices;
+ delete[] normals;
+ delete[] tangents;
}
void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED;
- LLVertexBuffer* buffer = group->mVertexBuffer;
+ LLVertexBuffer* buffer = group->mVertexBuffer;
- //get vertex buffer striders
- LLStrider<LLVector3> vertices;
- LLStrider<LLVector3> normals;
- LLStrider<LLVector2> texcoords2;
- LLStrider<LLVector2> texcoords;
- LLStrider<U16> indices;
+ //get vertex buffer striders
+ LLStrider<LLVector3> vertices_start;
+ LLStrider<LLVector3> normals_start;
+ LLStrider<LLVector4a> tangents_start;
+ LLStrider<LLVector2> texcoords_start;
+ LLStrider<LLVector2> texcoords2_start;
+ LLStrider<U16> indices_start;
- llassert_always(buffer->getVertexStrider(vertices));
- llassert_always(buffer->getNormalStrider(normals));
- llassert_always(buffer->getTexCoord0Strider(texcoords));
- llassert_always(buffer->getTexCoord1Strider(texcoords2));
- llassert_always(buffer->getIndexStrider(indices));
+ llassert_always(buffer->getVertexStrider(vertices_start));
+ llassert_always(buffer->getNormalStrider(normals_start));
+ llassert_always(buffer->getTangentStrider(tangents_start));
+ llassert_always(buffer->getTexCoord0Strider(texcoords_start));
+ llassert_always(buffer->getTexCoord1Strider(texcoords2_start));
+ llassert_always(buffer->getIndexStrider(indices_start));
U32 indices_index = 0;
U32 index_offset = 0;
- for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
{
- LLFace* facep = *i;
+ LLStrider<LLVector3> vertices = vertices_start;
+ LLStrider<LLVector3> normals = normals_start;
+ LLStrider<LLVector2> texcoords = texcoords_start;
+ LLStrider<LLVector2> texcoords2 = texcoords2_start;
+ LLStrider<U16> indices = indices_start;
- facep->setIndicesIndex(indices_index);
- facep->setGeomIndex(index_offset);
- facep->setVertexBuffer(buffer);
+ for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
+ {
+ LLFace* facep = *i;
- LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject();
- patchp->getGeometry(vertices, normals, texcoords, texcoords2, indices);
+ facep->setIndicesIndex(indices_index);
+ facep->setGeomIndex(index_offset);
+ facep->setVertexBuffer(buffer);
+
+ LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject();
+ patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices);
+
+ indices_index += facep->getIndicesCount();
+ index_offset += facep->getGeomCount();
+ }
+ }
+
+ const bool has_tangents = tangents_start.get() != nullptr;
+ if (has_tangents)
+ {
+ LLStrider<LLVector3> vertices = vertices_start;
+ LLStrider<LLVector3> normals = normals_start;
+ LLStrider<LLVector4a> tangents = tangents_start;
+ LLStrider<LLVector2> texcoords = texcoords_start;
+ LLStrider<U16> indices = indices_start;
- indices_index += facep->getIndicesCount();
- index_offset += facep->getGeomCount();
+ gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, texcoords, indices);
}
- buffer->unmapBuffer();
- mFaceList.clear();
+ buffer->unmapBuffer();
+ mFaceList.clear();
}
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 5de70e176a..a3dcb945d1 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvosurfacepatch.h
* @brief Description of LLVOSurfacePatch class
*
* $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$
*/
@@ -39,103 +39,103 @@ class LLFace;
class LLVOSurfacePatch : public LLStaticViewerObject
{
public:
- static F32 sLODFactor;
+ static F32 sLODFactor;
- enum
- {
- VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
- (1 << LLVertexBuffer::TYPE_NORMAL) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD1)
- };
+ enum
+ {
+ VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
+ (1 << LLVertexBuffer::TYPE_NORMAL) |
+ (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
+ (1 << LLVertexBuffer::TYPE_TEXCOORD1)
+ };
- LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void markDead();
+ /*virtual*/ void markDead();
- // Initialize data that's only inited once per class.
- static void initClass();
+ // Initialize data that's only inited once per class.
+ static void initClass();
- virtual U32 getPartitionType() const;
+ virtual U32 getPartitionType() const;
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
- /*virtual*/ void updateGL();
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- /*virtual*/ BOOL updateLOD();
- /*virtual*/ void updateFaceSize(S32 idx);
- void getGeometry(LLStrider<LLVector3> &verticesp,
+ /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
+ /*virtual*/ void updateGL();
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
+ /*virtual*/ BOOL updateLOD();
+ /*virtual*/ void updateFaceSize(S32 idx);
+ void getTerrainGeometry(LLStrider<LLVector3> &verticesp,
LLStrider<LLVector3> &normalsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
LLStrider<U16> &indicesp);
- /*virtual*/ void updateTextures();
- /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
+ /*virtual*/ void updateTextures();
+ /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
- /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
- /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
+ /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
+ /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- void setPatch(LLSurfacePatch *patchp);
- LLSurfacePatch *getPatch() const { return mPatchp; }
+ void setPatch(LLSurfacePatch *patchp);
+ LLSurfacePatch *getPatch() const { return mPatchp; }
- void dirtyPatch();
- void dirtyGeom();
+ void dirtyPatch();
+ void dirtyGeom();
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = -1, // which face to check, -1 = ALL_SIDES
- BOOL pick_transparent = FALSE,
- BOOL pick_rigged = FALSE,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face = -1, // which face to check, -1 = ALL_SIDES
+ BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
BOOL pick_unselectable = TRUE,
- S32* face_hit = NULL, // which face was hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
-
- BOOL mDirtiedPatch;
+ S32* face_hit = NULL, // which face was hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+ BOOL mDirtiedPatch;
protected:
- ~LLVOSurfacePatch();
-
- LLFacePool *mPool;
- LLFacePool *getPool();
- S32 mBaseComp;
- LLSurfacePatch *mPatchp;
- BOOL mDirtyTexture;
- BOOL mDirtyTerrain;
-
- S32 mLastNorthStride;
- S32 mLastEastStride;
- S32 mLastStride;
- S32 mLastLength;
-
- void getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices);
- void getGeomSizesNorth(const S32 stride, const S32 north_stride,
- S32 &num_vertices, S32 &num_indices);
- void getGeomSizesEast(const S32 stride, const S32 east_stride,
- S32 &num_vertices, S32 &num_indices);
-
- void updateMainGeometry(LLFace *facep,
- LLStrider<LLVector3> &verticesp,
- LLStrider<LLVector3> &normalsp,
- LLStrider<LLVector2> &texCoords0p,
- LLStrider<LLVector2> &texCoords1p,
- LLStrider<U16> &indicesp,
- U32 &index_offset);
- void updateNorthGeometry(LLFace *facep,
- LLStrider<LLVector3> &verticesp,
- LLStrider<LLVector3> &normalsp,
- LLStrider<LLVector2> &texCoords0p,
- LLStrider<LLVector2> &texCoords1p,
- LLStrider<U16> &indicesp,
- U32 &index_offset);
- void updateEastGeometry(LLFace *facep,
- LLStrider<LLVector3> &verticesp,
- LLStrider<LLVector3> &normalsp,
- LLStrider<LLVector2> &texCoords0p,
- LLStrider<LLVector2> &texCoords1p,
- LLStrider<U16> &indicesp,
- U32 &index_offset);
+ ~LLVOSurfacePatch();
+
+ LLFacePool *mPool;
+ LLFacePool *getPool();
+ S32 mBaseComp;
+ LLSurfacePatch *mPatchp;
+ BOOL mDirtyTexture;
+ BOOL mDirtyTerrain;
+
+ S32 mLastNorthStride;
+ S32 mLastEastStride;
+ S32 mLastStride;
+ S32 mLastLength;
+
+ void getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices);
+ void getGeomSizesNorth(const S32 stride, const S32 north_stride,
+ S32 &num_vertices, S32 &num_indices);
+ void getGeomSizesEast(const S32 stride, const S32 east_stride,
+ S32 &num_vertices, S32 &num_indices);
+
+ void updateMainGeometry(LLFace *facep,
+ LLStrider<LLVector3> &verticesp,
+ LLStrider<LLVector3> &normalsp,
+ LLStrider<LLVector2> &texCoords0p,
+ LLStrider<LLVector2> &texCoords1p,
+ LLStrider<U16> &indicesp,
+ U32 &index_offset);
+ void updateNorthGeometry(LLFace *facep,
+ LLStrider<LLVector3> &verticesp,
+ LLStrider<LLVector3> &normalsp,
+ LLStrider<LLVector2> &texCoords0p,
+ LLStrider<LLVector2> &texCoords1p,
+ LLStrider<U16> &indicesp,
+ U32 &index_offset);
+ void updateEastGeometry(LLFace *facep,
+ LLStrider<LLVector3> &verticesp,
+ LLStrider<LLVector3> &normalsp,
+ LLStrider<LLVector2> &texCoords0p,
+ LLStrider<LLVector2> &texCoords1p,
+ LLStrider<U16> &indicesp,
+ U32 &index_offset);
};
#endif // LL_VOSURFACEPATCH_H
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index ea6fb2e55b..a956814147 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvovolume.cpp
* @brief LLVOVolume 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$
*/
@@ -97,7 +97,7 @@ U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1;
BOOL gAnimateTextures = TRUE;
F32 LLVOVolume::sLODFactor = 1.f;
-F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
+F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
F32 LLVOVolume::sDistanceFactor = 1.0f;
S32 LLVOVolume::sNumLODChanges = 0;
S32 LLVOVolume::mRenderComplexity_last = 0;
@@ -111,213 +111,218 @@ extern BOOL gCubeSnapshot;
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
public:
- LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew)
- {
- mObject->addMDCImpl();
- }
- ~LLMediaDataClientObjectImpl()
- {
- mObject->removeMDCImpl();
- }
-
- virtual U8 getMediaDataCount() const
- { return mObject->getNumTEs(); }
-
- virtual LLSD getMediaDataLLSD(U8 index) const
- {
- LLSD result;
- LLTextureEntry *te = mObject->getTE(index);
- if (NULL != te)
- {
- llassert((te->getMediaData() != NULL) == te->hasMedia());
- if (te->getMediaData() != NULL)
- {
- result = te->getMediaData()->asLLSD();
- // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
- // See DEV-41949
- if (!result.has(LLMediaEntry::WHITELIST_KEY))
- {
- result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
- }
- }
- }
- return result;
- }
- virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const
- {
- LLTextureEntry *te = mObject->getTE(index);
- if (te)
- {
- if (te->getMediaData())
- {
- return (te->getMediaData()->getCurrentURL() == url);
- }
- }
- return url.empty();
- }
-
- virtual LLUUID getID() const
- { return mObject->getID(); }
-
- virtual void mediaNavigateBounceBack(U8 index)
- { mObject->mediaNavigateBounceBack(index); }
-
- virtual bool hasMedia() const
- { return mObject->hasMedia(); }
-
- virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string)
- { mObject->updateObjectMediaData(data, version_string); }
-
- virtual F64 getMediaInterest() const
- {
- F64 interest = mObject->getTotalMediaInterest();
- if (interest < (F64)0.0)
- {
- // media interest not valid yet, try pixel area
- interest = mObject->getPixelArea();
- // HACK: force recalculation of pixel area if interest is the "magic default" of 1024.
- if (interest == 1024.f)
- {
- const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent);
- interest = mObject->getPixelArea();
- }
- }
- return interest;
- }
-
- virtual bool isInterestingEnough() const
- {
- return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest());
- }
-
- virtual std::string getCapabilityUrl(const std::string &name) const
- { return mObject->getRegion()->getCapability(name); }
-
- virtual bool isDead() const
- { return mObject->isDead(); }
-
- virtual U32 getMediaVersion() const
- { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); }
-
- virtual bool isNew() const
- { return mNew; }
+ LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew)
+ {
+ mObject->addMDCImpl();
+ }
+ ~LLMediaDataClientObjectImpl()
+ {
+ mObject->removeMDCImpl();
+ }
+
+ virtual U8 getMediaDataCount() const
+ { return mObject->getNumTEs(); }
+
+ virtual LLSD getMediaDataLLSD(U8 index) const
+ {
+ LLSD result;
+ LLTextureEntry *te = mObject->getTE(index);
+ if (NULL != te)
+ {
+ llassert((te->getMediaData() != NULL) == te->hasMedia());
+ if (te->getMediaData() != NULL)
+ {
+ result = te->getMediaData()->asLLSD();
+ // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
+ // See DEV-41949
+ if (!result.has(LLMediaEntry::WHITELIST_KEY))
+ {
+ result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
+ }
+ }
+ }
+ return result;
+ }
+ virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const
+ {
+ LLTextureEntry *te = mObject->getTE(index);
+ if (te)
+ {
+ if (te->getMediaData())
+ {
+ return (te->getMediaData()->getCurrentURL() == url);
+ }
+ }
+ return url.empty();
+ }
+
+ virtual LLUUID getID() const
+ { return mObject->getID(); }
+
+ virtual void mediaNavigateBounceBack(U8 index)
+ { mObject->mediaNavigateBounceBack(index); }
+
+ virtual bool hasMedia() const
+ { return mObject->hasMedia(); }
+
+ virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string)
+ { mObject->updateObjectMediaData(data, version_string); }
+
+ virtual F64 getMediaInterest() const
+ {
+ F64 interest = mObject->getTotalMediaInterest();
+ if (interest < (F64)0.0)
+ {
+ // media interest not valid yet, try pixel area
+ interest = mObject->getPixelArea();
+ // HACK: force recalculation of pixel area if interest is the "magic default" of 1024.
+ if (interest == 1024.f)
+ {
+ const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent);
+ interest = mObject->getPixelArea();
+ }
+ }
+ return interest;
+ }
+
+ virtual bool isInterestingEnough() const
+ {
+ return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest());
+ }
+
+ virtual std::string getCapabilityUrl(const std::string &name) const
+ { return mObject->getRegion()->getCapability(name); }
+
+ virtual bool isDead() const
+ { return mObject->isDead(); }
+
+ virtual U32 getMediaVersion() const
+ { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); }
+
+ virtual bool isNew() const
+ { return mNew; }
private:
- LLPointer<LLVOVolume> mObject;
- bool mNew;
+ LLPointer<LLVOVolume> mObject;
+ bool mNew;
};
LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
- : LLViewerObject(id, pcode, regionp),
- mVolumeImpl(NULL)
+ : LLViewerObject(id, pcode, regionp),
+ mVolumeImpl(NULL)
{
- mTexAnimMode = 0;
- mRelativeXform.setIdentity();
- mRelativeXformInvTrans.setIdentity();
+ mTexAnimMode = 0;
+ mRelativeXform.setIdentity();
+ mRelativeXformInvTrans.setIdentity();
- mFaceMappingChanged = FALSE;
- mLOD = MIN_LOD;
+ mFaceMappingChanged = FALSE;
+ mLOD = MIN_LOD;
mLODDistance = 0.0f;
mLODAdjustedDistance = 0.0f;
mLODRadius = 0.0f;
- mTextureAnimp = NULL;
- mVolumeChanged = FALSE;
- mVObjRadius = LLVector3(1,1,0.5f).length();
- mNumFaces = 0;
- mLODChanged = FALSE;
- mSculptChanged = FALSE;
+ mTextureAnimp = NULL;
+ mVolumeChanged = FALSE;
+ mVObjRadius = LLVector3(1,1,0.5f).length();
+ mNumFaces = 0;
+ mLODChanged = FALSE;
+ mSculptChanged = FALSE;
mColorChanged = FALSE;
- mSpotLightPriority = 0.f;
+ mSpotLightPriority = 0.f;
mSkinInfoUnavaliable = false;
- mSkinInfo = NULL;
+ mSkinInfo = NULL;
- mMediaImplList.resize(getNumTEs());
- mLastFetchedMediaVersion = -1;
+ mMediaImplList.resize(getNumTEs());
+ mLastFetchedMediaVersion = -1;
mServerDrawableUpdateCount = 0;
- memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
- mMDCImplCount = 0;
- mLastRiggingInfoLOD = -1;
- mResetDebugText = false;
+ memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
+ mMDCImplCount = 0;
+ mLastRiggingInfoLOD = -1;
+ mResetDebugText = false;
}
LLVOVolume::~LLVOVolume()
{
LL_PROFILE_ZONE_SCOPED;
- delete mTextureAnimp;
- mTextureAnimp = NULL;
- delete mVolumeImpl;
- mVolumeImpl = NULL;
+ delete mTextureAnimp;
+ mTextureAnimp = NULL;
+ delete mVolumeImpl;
+ mVolumeImpl = NULL;
- gMeshRepo.unregisterMesh(this);
+ gMeshRepo.unregisterMesh(this);
- if(!mMediaImplList.empty())
- {
- for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
- {
- if(mMediaImplList[i].notNull())
- {
- mMediaImplList[i]->removeObject(this) ;
- }
- }
- }
+ if(!mMediaImplList.empty())
+ {
+ for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
+ {
+ if(mMediaImplList[i].notNull())
+ {
+ mMediaImplList[i]->removeObject(this) ;
+ }
+ }
+ }
}
void LLVOVolume::markDead()
{
- if (!mDead)
- {
+ if (!mDead)
+ {
LL_PROFILE_ZONE_SCOPED;
if (getVolume())
{
LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
}
- if(getMDCImplCount() > 0)
- {
- LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
- if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj);
- if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj);
- }
-
- // Detach all media impls from this object
- for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
- {
- removeMediaImpl(i);
- }
+ if(getMDCImplCount() > 0)
+ {
+ LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
+ if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj);
+ if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj);
+ }
+
+ // Detach all media impls from this object
+ for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
+ {
+ removeMediaImpl(i);
+ }
- if (mSculptTexture.notNull())
- {
- mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this);
- }
+ if (mSculptTexture.notNull())
+ {
+ mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this);
+ }
- if (mLightTexture.notNull())
+ if (mLightTexture.notNull())
+ {
+ mLightTexture->removeVolume(LLRender::LIGHT_TEX, this);
+ }
+
+ if (mIsHeroProbe)
{
- mLightTexture->removeVolume(LLRender::LIGHT_TEX, this);
+ gPipeline.mHeroProbeManager.unregisterViewerObject(this);
}
- }
-
- LLViewerObject::markDead();
+ }
+
+ LLViewerObject::markDead();
}
// static
void LLVOVolume::initClass()
{
- // gSavedSettings better be around
- if (gSavedSettings.getBOOL("PrimMediaMasterEnabled"))
- {
- const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay");
- const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay");
- const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries");
- const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize");
- const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize");
- sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries,
- max_sorted_queue_size, max_round_robin_queue_size);
- sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay,
- max_retries, max_sorted_queue_size, max_round_robin_queue_size);
- }
+ // gSavedSettings better be around
+ if (gSavedSettings.getBOOL("PrimMediaMasterEnabled"))
+ {
+ const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay");
+ const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay");
+ const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries");
+ const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize");
+ const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize");
+ sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries,
+ max_sorted_queue_size, max_round_robin_queue_size);
+ sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay,
+ max_retries, max_sorted_queue_size, max_round_robin_queue_size);
+ }
}
// static
@@ -328,65 +333,65 @@ void LLVOVolume::cleanupClass()
}
U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num, EObjectUpdateType update_type,
- LLDataPacker *dp)
+ void **user_data,
+ U32 block_num, EObjectUpdateType update_type,
+ LLDataPacker *dp)
{
-
- LLColor4U color;
- const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
+
+ LLColor4U color;
+ const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
const bool previously_volume_changed = mVolumeChanged;
const bool previously_face_mapping_changed = mFaceMappingChanged;
const bool previously_color_changed = mColorChanged;
- // Do base class updates...
- U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
+ // Do base class updates...
+ U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
- LLUUID sculpt_id;
- U8 sculpt_type = 0;
- if (isSculpted())
- {
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- sculpt_id = sculpt_params->getSculptTexture();
- sculpt_type = sculpt_params->getSculptType();
+ LLUUID sculpt_id;
+ U8 sculpt_type = 0;
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ sculpt_id = sculpt_params->getSculptTexture();
+ sculpt_type = sculpt_params->getSculptType();
LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL;
dumpStack("ObjectUpdateStack");
- }
-
- if (!dp)
- {
- if (update_type == OUT_FULL)
- {
- ////////////////////////////////
- //
- // Unpack texture animation data
- //
- //
-
- if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim))
- {
- if (!mTextureAnimp)
- {
- mTextureAnimp = new LLViewerTextureAnim(this);
- }
- else
- {
- if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
- {
- mTextureAnimp->reset();
- }
- }
- mTexAnimMode = 0;
-
- mTextureAnimp->unpackTAMessage(mesgsys, block_num);
- }
- else
- {
- if (mTextureAnimp)
- {
- delete mTextureAnimp;
- mTextureAnimp = NULL;
+ }
+
+ if (!dp)
+ {
+ if (update_type == OUT_FULL)
+ {
+ ////////////////////////////////
+ //
+ // Unpack texture animation data
+ //
+ //
+
+ if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim))
+ {
+ if (!mTextureAnimp)
+ {
+ mTextureAnimp = new LLViewerTextureAnim(this);
+ }
+ else
+ {
+ if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
+ {
+ mTextureAnimp->reset();
+ }
+ }
+ mTexAnimMode = 0;
+
+ mTextureAnimp->unpackTAMessage(mesgsys, block_num);
+ }
+ else
+ {
+ if (mTextureAnimp)
+ {
+ delete mTextureAnimp;
+ mTextureAnimp = NULL;
for (S32 i = 0; i < getNumTEs(); i++)
{
@@ -399,98 +404,98 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- mTexAnimMode = 0;
- }
- }
-
- // Unpack volume data
- LLVolumeParams volume_params;
- LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num);
- volume_params.setSculptID(sculpt_id, sculpt_type);
-
- if (setVolume(volume_params, 0))
- {
- markForUpdate();
- }
- }
-
- // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens...
- ////////////////////////////
- //
- // Unpack texture entry data
- //
-
- S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
-
- if (result & TEM_CHANGE_MEDIA)
- {
- retval |= MEDIA_FLAGS_CHANGED;
- }
- }
- else
- {
- if (update_type != OUT_TERSE_IMPROVED)
- {
- LLVolumeParams volume_params;
- BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp);
- if (!res)
- {
- LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL;
- LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL;
- }
-
- volume_params.setSculptID(sculpt_id, sculpt_type);
-
- if (setVolume(volume_params, 0))
- {
- markForUpdate();
- }
- S32 res2 = unpackTEMessage(*dp);
- if (TEM_INVALID == res2)
- {
- // There's something bogus in the data that we're unpacking.
- dp->dumpBufferToLog();
- LL_WARNS() << "Flushing cache files" << LL_ENDL;
-
- if(LLVOCache::instanceExists() && getRegion())
- {
- LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;
- }
-
- LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL;
- }
- else
- {
- if (res2 & TEM_CHANGE_MEDIA)
- {
- retval |= MEDIA_FLAGS_CHANGED;
- }
- }
-
- U32 value = dp->getPassFlags();
-
- if (value & 0x40)
- {
- if (!mTextureAnimp)
- {
- mTextureAnimp = new LLViewerTextureAnim(this);
- }
- else
- {
- if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
- {
- mTextureAnimp->reset();
- }
- }
- mTexAnimMode = 0;
- mTextureAnimp->unpackTAMessage(*dp);
- }
- else if (mTextureAnimp)
- {
- delete mTextureAnimp;
- mTextureAnimp = NULL;
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ mTexAnimMode = 0;
+ }
+ }
+
+ // Unpack volume data
+ LLVolumeParams volume_params;
+ LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num);
+ volume_params.setSculptID(sculpt_id, sculpt_type);
+
+ if (setVolume(volume_params, 0))
+ {
+ markForUpdate();
+ }
+ }
+
+ // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens...
+ ////////////////////////////
+ //
+ // Unpack texture entry data
+ //
+
+ S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
+
+ if (result & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
+ }
+ else
+ {
+ if (update_type != OUT_TERSE_IMPROVED)
+ {
+ LLVolumeParams volume_params;
+ BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp);
+ if (!res)
+ {
+ LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL;
+ LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL;
+ }
+
+ volume_params.setSculptID(sculpt_id, sculpt_type);
+
+ if (setVolume(volume_params, 0))
+ {
+ markForUpdate();
+ }
+ S32 res2 = unpackTEMessage(*dp);
+ if (TEM_INVALID == res2)
+ {
+ // There's something bogus in the data that we're unpacking.
+ dp->dumpBufferToLog();
+ LL_WARNS() << "Flushing cache files" << LL_ENDL;
+
+ if(LLVOCache::instanceExists() && getRegion())
+ {
+ LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;
+ }
+
+ LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL;
+ }
+ else
+ {
+ if (res2 & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
+ }
+
+ U32 value = dp->getPassFlags();
+
+ if (value & 0x40)
+ {
+ if (!mTextureAnimp)
+ {
+ mTextureAnimp = new LLViewerTextureAnim(this);
+ }
+ else
+ {
+ if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
+ {
+ mTextureAnimp->reset();
+ }
+ }
+ mTexAnimMode = 0;
+ mTextureAnimp->unpackTAMessage(*dp);
+ }
+ else if (mTextureAnimp)
+ {
+ delete mTextureAnimp;
+ mTextureAnimp = NULL;
for (S32 i = 0; i < getNumTEs(); i++)
{
@@ -503,59 +508,59 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- mTexAnimMode = 0;
- }
-
- if (value & 0x400)
- { //particle system (new)
- unpackParticleSource(*dp, mOwnerID, false);
- }
- }
- else
- {
- S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry);
- if (texture_length)
- {
- U8 tdpbuffer[1024];
- LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024);
- S32 result = unpackTEMessage(tdp);
- if (result & teDirtyBits)
- {
- if (mDrawable)
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ mTexAnimMode = 0;
+ }
+
+ if (value & 0x400)
+ { //particle system (new)
+ unpackParticleSource(*dp, mOwnerID, false);
+ }
+ }
+ else
+ {
+ S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry);
+ if (texture_length)
+ {
+ U8 tdpbuffer[1024];
+ LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024);
+ S32 result = unpackTEMessage(tdp);
+ if (result & teDirtyBits)
+ {
+ if (mDrawable)
{ //on the fly TE updates break batches, isolate in octree
shrinkWrap();
}
- }
- if (result & TEM_CHANGE_MEDIA)
- {
- retval |= MEDIA_FLAGS_CHANGED;
- }
- }
- }
- }
- if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED))
- {
- // If only the media URL changed, and it isn't a media version URL,
- // ignore it
- if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) &&
- mMedia && ! mMedia->mMediaURL.empty() &&
- ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) )
- {
- // If the media changed at all, request new media data
- LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " <<
+ }
+ if (result & TEM_CHANGE_MEDIA)
+ {
+ retval |= MEDIA_FLAGS_CHANGED;
+ }
+ }
+ }
+ }
+ if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED))
+ {
+ // If only the media URL changed, and it isn't a media version URL,
+ // ignore it
+ if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) &&
+ mMedia && ! mMedia->mMediaURL.empty() &&
+ ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) )
+ {
+ // If the media changed at all, request new media data
+ LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " <<
((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL;
- requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED);
- }
+ requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED);
+ }
else {
LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " <<
((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL;
}
- }
- // ...and clean up any media impls
- cleanUpMediaImpls();
+ }
+ // ...and clean up any media impls
+ cleanUpMediaImpls();
if ((
(mVolumeChanged && !previously_volume_changed) ||
@@ -566,7 +571,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
onDrawableUpdateFromServer();
}
- return retval;
+ return retval;
}
// Called when a volume, material, etc is updated by the server, possibly by a
@@ -585,117 +590,117 @@ void LLVOVolume::onDrawableUpdateFromServer()
void LLVOVolume::animateTextures()
{
- if (!mDead)
- {
+ if (!mDead)
+ {
shrinkWrap();
- F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
- S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
-
- if (result)
- {
- if (!mTexAnimMode)
- {
- mFaceMappingChanged = TRUE;
- gPipeline.markTextured(mDrawable);
- }
- mTexAnimMode = result | mTextureAnimp->mMode;
-
- S32 start=0, end=mDrawable->getNumFaces()-1;
- if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
- {
- start = end = mTextureAnimp->mFace;
- }
-
- for (S32 i = start; i <= end; i++)
- {
- LLFace* facep = mDrawable->getFace(i);
- if (!facep) continue;
- if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
-
- const LLTextureEntry* te = facep->getTextureEntry();
-
- if (!te)
- {
- continue;
- }
-
- if (!(result & LLViewerTextureAnim::ROTATE))
- {
- te->getRotation(&rot);
- }
- if (!(result & LLViewerTextureAnim::TRANSLATE))
- {
- te->getOffset(&off_s,&off_t);
- }
- if (!(result & LLViewerTextureAnim::SCALE))
- {
- te->getScale(&scale_s, &scale_t);
- }
-
- if (!facep->mTextureMatrix)
- {
- facep->mTextureMatrix = new LLMatrix4();
- }
-
- LLMatrix4& tex_mat = *facep->mTextureMatrix;
- tex_mat.setIdentity();
- LLVector3 trans ;
-
- trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
- tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
-
- LLVector3 scale(scale_s, scale_t, 1.f);
- LLQuaternion quat;
- quat.setQuat(rot, 0, 0, -1.f);
-
- tex_mat.rotate(quat);
-
- LLMatrix4 mat;
- mat.initAll(scale, LLQuaternion(), LLVector3());
- tex_mat *= mat;
-
- tex_mat.translate(trans);
- }
- }
- else
- {
- if (mTexAnimMode && mTextureAnimp->mRate == 0)
- {
- U8 start, count;
-
- if (mTextureAnimp->mFace == -1)
- {
- start = 0;
- count = getNumTEs();
- }
- else
- {
- start = (U8) mTextureAnimp->mFace;
- count = 1;
- }
-
- for (S32 i = start; i < start + count; i++)
- {
- if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
- {
- setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
- }
- if (mTexAnimMode & LLViewerTextureAnim::SCALE)
- {
- setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
- }
- if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
- {
- setTERotation(i, mTextureAnimp->mRot);
- }
- }
-
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- mTexAnimMode = 0;
- }
- }
- }
+ F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
+ S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
+
+ if (result)
+ {
+ if (!mTexAnimMode)
+ {
+ mFaceMappingChanged = TRUE;
+ gPipeline.markTextured(mDrawable);
+ }
+ mTexAnimMode = result | mTextureAnimp->mMode;
+
+ S32 start=0, end=mDrawable->getNumFaces()-1;
+ if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
+ {
+ start = end = mTextureAnimp->mFace;
+ }
+
+ for (S32 i = start; i <= end; i++)
+ {
+ LLFace* facep = mDrawable->getFace(i);
+ if (!facep) continue;
+ if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
+
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ if (!te)
+ {
+ continue;
+ }
+
+ if (!(result & LLViewerTextureAnim::ROTATE))
+ {
+ te->getRotation(&rot);
+ }
+ if (!(result & LLViewerTextureAnim::TRANSLATE))
+ {
+ te->getOffset(&off_s,&off_t);
+ }
+ if (!(result & LLViewerTextureAnim::SCALE))
+ {
+ te->getScale(&scale_s, &scale_t);
+ }
+
+ if (!facep->mTextureMatrix)
+ {
+ facep->mTextureMatrix = new LLMatrix4();
+ }
+
+ LLMatrix4& tex_mat = *facep->mTextureMatrix;
+ tex_mat.setIdentity();
+ LLVector3 trans ;
+
+ trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
+ tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
+
+ LLVector3 scale(scale_s, scale_t, 1.f);
+ LLQuaternion quat;
+ quat.setQuat(rot, 0, 0, -1.f);
+
+ tex_mat.rotate(quat);
+
+ LLMatrix4 mat;
+ mat.initAll(scale, LLQuaternion(), LLVector3());
+ tex_mat *= mat;
+
+ tex_mat.translate(trans);
+ }
+ }
+ else
+ {
+ if (mTexAnimMode && mTextureAnimp->mRate == 0)
+ {
+ U8 start, count;
+
+ if (mTextureAnimp->mFace == -1)
+ {
+ start = 0;
+ count = getNumTEs();
+ }
+ else
+ {
+ start = (U8) mTextureAnimp->mFace;
+ count = 1;
+ }
+
+ for (S32 i = start; i < start + count; i++)
+ {
+ if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
+ {
+ setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
+ }
+ if (mTexAnimMode & LLViewerTextureAnim::SCALE)
+ {
+ setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
+ }
+ if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
+ {
+ setTERotation(i, mTextureAnimp->mRot);
+ }
+ }
+
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ mTexAnimMode = 0;
+ }
+ }
+ }
}
void LLVOVolume::updateTextures()
@@ -704,403 +709,403 @@ void LLVOVolume::updateTextures()
updateTextureVirtualSize();
}
-BOOL LLVOVolume::isVisible() const
+BOOL LLVOVolume::isVisible() const
{
- if(mDrawable.notNull() && mDrawable->isVisible())
- {
- return TRUE ;
- }
+ if(mDrawable.notNull() && mDrawable->isVisible())
+ {
+ return TRUE ;
+ }
- if(isAttachment())
- {
- LLViewerObject* objp = (LLViewerObject*)getParent() ;
- while(objp && !objp->isAvatar())
- {
- objp = (LLViewerObject*)objp->getParent() ;
- }
+ if(isAttachment())
+ {
+ LLViewerObject* objp = (LLViewerObject*)getParent() ;
+ while(objp && !objp->isAvatar())
+ {
+ objp = (LLViewerObject*)objp->getParent() ;
+ }
- return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ;
- }
+ return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ;
+ }
- return FALSE ;
+ return FALSE ;
}
void LLVOVolume::updateTextureVirtualSize(bool forced)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- // Update the pixel area of all faces
+ // Update the pixel area of all faces
if (mDrawable.isNull() || gCubeSnapshot)
{
return;
}
- if(!forced)
- {
- if(!isVisible())
- { //don't load textures for non-visible faces
- const S32 num_faces = mDrawable->getNumFaces();
- for (S32 i = 0; i < num_faces; i++)
- {
- LLFace* face = mDrawable->getFace(i);
- if (face)
- {
- face->setPixelArea(0.f);
- face->setVirtualSize(0.f);
- }
- }
-
- return ;
- }
-
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE))
- {
- return;
- }
- }
-
- static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false);
-
- if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible())
- {
- return;
- }
-
- mTextureUpdateTimer.reset();
-
- F32 old_area = mPixelArea;
- mPixelArea = 0.f;
-
- const S32 num_faces = mDrawable->getNumFaces();
- F32 min_vsize=999999999.f, max_vsize=0.f;
- LLViewerCamera* camera = LLViewerCamera::getInstance();
+ if(!forced)
+ {
+ if(!isVisible())
+ { //don't load textures for non-visible faces
+ const S32 num_faces = mDrawable->getNumFaces();
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (face)
+ {
+ face->setPixelArea(0.f);
+ face->setVirtualSize(0.f);
+ }
+ }
+
+ return ;
+ }
+
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE))
+ {
+ return;
+ }
+ }
+
+ static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false);
+
+ if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible())
+ {
+ return;
+ }
+
+ mTextureUpdateTimer.reset();
+
+ F32 old_area = mPixelArea;
+ mPixelArea = 0.f;
+
+ const S32 num_faces = mDrawable->getNumFaces();
+ F32 min_vsize=999999999.f, max_vsize=0.f;
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
std::stringstream debug_text;
- for (S32 i = 0; i < num_faces; i++)
- {
- LLFace* face = mDrawable->getFace(i);
- if (!face) continue;
- const LLTextureEntry *te = face->getTextureEntry();
- LLViewerTexture *imagep = face->getTexture();
- if (!imagep || !te ||
- face->mExtents[0].equals3(face->mExtents[1]))
- {
- continue;
- }
-
- F32 vsize;
- F32 old_size = face->getVirtualSize();
-
- if (isHUDAttachment())
- {
- F32 area = (F32) camera->getScreenPixelArea();
- vsize = area;
- imagep->setBoostLevel(LLGLTexture::BOOST_HUD);
- face->setPixelArea(area); // treat as full screen
- face->setVirtualSize(vsize);
- }
- else
- {
- vsize = face->getTextureVirtualSize();
- }
-
- mPixelArea = llmax(mPixelArea, face->getPixelArea());
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
+ const LLTextureEntry *te = face->getTextureEntry();
+ LLViewerTexture *imagep = face->getTexture();
+ if (!imagep || !te ||
+ face->mExtents[0].equals3(face->mExtents[1]))
+ {
+ continue;
+ }
+
+ F32 vsize;
+ F32 old_size = face->getVirtualSize();
+
+ if (isHUDAttachment())
+ {
+ F32 area = (F32) camera->getScreenPixelArea();
+ vsize = area;
+ imagep->setBoostLevel(LLGLTexture::BOOST_HUD);
+ face->setPixelArea(area); // treat as full screen
+ face->setVirtualSize(vsize);
+ }
+ else
+ {
+ vsize = face->getTextureVirtualSize();
+ }
+
+ mPixelArea = llmax(mPixelArea, face->getPixelArea());
// if the face has gotten small enough to turn off texture animation and texture
// animation is running, rebuild the render batch for this face to turn off
// texture animation
- if (face->mTextureMatrix != NULL)
- {
- if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
- (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE))
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- }
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
- {
- LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
- if(img)
- {
+ if (face->mTextureMatrix != NULL)
+ {
+ if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
+ (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE))
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ }
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ {
+ LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
+ if(img)
+ {
debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n";
- /*F32 pri = img->getDecodePriority();
- pri = llmax(pri, 0.0f);
- if (pri < min_vsize) min_vsize = pri;
- if (pri > max_vsize) max_vsize = pri;*/
- }
- }
- else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
- {
- F32 pri = mPixelArea;
- if (pri < min_vsize) min_vsize = pri;
- if (pri > max_vsize) max_vsize = pri;
- }
- }
-
- if (isSculpted())
- {
+ /*F32 pri = img->getDecodePriority();
+ pri = llmax(pri, 0.0f);
+ if (pri < min_vsize) min_vsize = pri;
+ if (pri > max_vsize) max_vsize = pri;*/
+ }
+ }
+ else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
+ {
+ F32 pri = mPixelArea;
+ if (pri < min_vsize) min_vsize = pri;
+ if (pri > max_vsize) max_vsize = pri;
+ }
+ }
+
+ if (isSculpted())
+ {
updateSculptTexture();
-
-
-
- if (mSculptTexture.notNull())
- {
- mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
- (S32)LLGLTexture::BOOST_SCULPTED));
- mSculptTexture->setForSculpt() ;
-
- if(!mSculptTexture->isCachedRawImageReady())
- {
- S32 lod = llmin(mLOD, 3);
- F32 lodf = ((F32)(lod + 1.0f)/4.f);
- F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
- mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
- }
-
- S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
- S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
-
- if (texture_discard >= 0 && //texture has some data available
- (texture_discard < current_discard || //texture has more data than last rebuild
- current_discard < 0)) //no previous rebuild
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- mSculptChanged = TRUE;
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED))
- {
- setDebugText(llformat("T%d C%d V%d\n%dx%d",
- texture_discard, current_discard, getVolume()->getSculptLevel(),
- mSculptTexture->getHeight(), mSculptTexture->getWidth()));
- }
- }
-
- }
-
- if (getLightTextureID().notNull())
- {
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- LLUUID id = params->getLightTexture();
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
- if (mLightTexture.notNull())
- {
- F32 rad = getLightRadius();
- mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(),
- LLVector3(rad,rad,rad),
- *camera));
- }
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
- {
- setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
- }
- else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
- {
- //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+
+
+
+ if (mSculptTexture.notNull())
+ {
+ mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
+ (S32)LLGLTexture::BOOST_SCULPTED));
+ mSculptTexture->setForSculpt() ;
+
+ if(!mSculptTexture->isCachedRawImageReady())
+ {
+ S32 lod = llmin(mLOD, 3);
+ F32 lodf = ((F32)(lod + 1.0f)/4.f);
+ F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
+ mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
+ }
+
+ S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
+ S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
+
+ if (texture_discard >= 0 && //texture has some data available
+ (texture_discard < current_discard || //texture has more data than last rebuild
+ current_discard < 0)) //no previous rebuild
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+ mSculptChanged = TRUE;
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED))
+ {
+ setDebugText(llformat("T%d C%d V%d\n%dx%d",
+ texture_discard, current_discard, getVolume()->getSculptLevel(),
+ mSculptTexture->getHeight(), mSculptTexture->getWidth()));
+ }
+ }
+
+ }
+
+ if (getLightTextureID().notNull())
+ {
+ LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLUUID id = params->getLightTexture();
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
+ if (mLightTexture.notNull())
+ {
+ F32 rad = getLightRadius();
+ mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(),
+ LLVector3(rad,rad,rad),
+ *camera));
+ }
+ }
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
+ {
+ setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+ }
+ else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ {
+ //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
setDebugText(debug_text.str());
- }
- else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
- {
- setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
- }
+ }
+ else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
+ {
+ setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+ }
- if (mPixelArea == 0)
- { //flexi phasing issues make this happen
- mPixelArea = old_area;
- }
+ if (mPixelArea == 0)
+ { //flexi phasing issues make this happen
+ mPixelArea = old_area;
+ }
}
BOOL LLVOVolume::isActive() const
{
- return !mStatic;
+ return !mStatic;
}
BOOL LLVOVolume::setMaterial(const U8 material)
{
- BOOL res = LLViewerObject::setMaterial(material);
-
- return res;
+ BOOL res = LLViewerObject::setMaterial(material);
+
+ return res;
}
void LLVOVolume::setTexture(const S32 face)
{
- llassert(face < getNumTEs());
- gGL.getTexUnit(0)->bind(getTEImage(face));
+ llassert(face < getNumTEs());
+ gGL.getTexUnit(0)->bind(getTEImage(face));
}
void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped)
{
- if (scale != getScale())
- {
- // store local radius
- LLViewerObject::setScale(scale);
+ if (scale != getScale())
+ {
+ // store local radius
+ LLViewerObject::setScale(scale);
- if (mVolumeImpl)
- {
- mVolumeImpl->onSetScale(scale, damped);
- }
-
- updateRadius();
+ if (mVolumeImpl)
+ {
+ mVolumeImpl->onSetScale(scale, damped);
+ }
+
+ updateRadius();
- //since drawable transforms do not include scale, changing volume scale
- //requires an immediate rebuild of volume verts.
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
+ //since drawable transforms do not include scale, changing volume scale
+ //requires an immediate rebuild of volume verts.
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
if (mDrawable)
{
shrinkWrap();
}
- }
+ }
}
LLFace* LLVOVolume::addFace(S32 f)
{
- const LLTextureEntry* te = getTE(f);
- LLViewerTexture* imagep = getTEImage(f);
- if (te->getMaterialParams().notNull())
- {
- LLViewerTexture* normalp = getTENormalMap(f);
- LLViewerTexture* specularp = getTESpecularMap(f);
- return mDrawable->addFace(te, imagep, normalp, specularp);
- }
- return mDrawable->addFace(te, imagep);
+ const LLTextureEntry* te = getTE(f);
+ LLViewerTexture* imagep = getTEImage(f);
+ if (te->getMaterialParams().notNull())
+ {
+ LLViewerTexture* normalp = getTENormalMap(f);
+ LLViewerTexture* specularp = getTESpecularMap(f);
+ return mDrawable->addFace(te, imagep, normalp, specularp);
+ }
+ return mDrawable->addFace(te, imagep);
}
LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
{
- pipeline->allocDrawable(this);
+ pipeline->allocDrawable(this);
+
+ mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME);
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME);
+ S32 max_tes_to_set = getNumTEs();
+ for (S32 i = 0; i < max_tes_to_set; i++)
+ {
+ addFace(i);
+ }
+ mNumFaces = max_tes_to_set;
- S32 max_tes_to_set = getNumTEs();
- for (S32 i = 0; i < max_tes_to_set; i++)
- {
- addFace(i);
- }
- mNumFaces = max_tes_to_set;
+ if (isAttachment())
+ {
+ mDrawable->makeActive();
+ }
- if (isAttachment())
- {
- mDrawable->makeActive();
- }
-
- if (getIsLight())
- {
- // Add it to the pipeline mLightSet
- gPipeline.setLight(mDrawable, TRUE);
- }
+ if (getIsLight())
+ {
+ // Add it to the pipeline mLightSet
+ gPipeline.setLight(mDrawable, TRUE);
+ }
if (isReflectionProbe())
{
updateReflectionProbePtr();
}
+
+ updateRadius();
+ bool force_update = true; // avoid non-alpha mDistance update being optimized away
+ mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
- updateRadius();
- bool force_update = true; // avoid non-alpha mDistance update being optimized away
- mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
-
- return mDrawable;
+ return mDrawable;
}
BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bool unique_volume)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- LLVolumeParams volume_params = params_in;
-
- S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1;
- S32 lod = mLOD;
-
- BOOL is404 = FALSE;
-
- if (isSculpted())
- {
- // if it's a mesh
- if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
- { //meshes might not have all LODs, get the force detail to best existing LOD
- if (NO_LOD != lod)
- {
- lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
- if (lod == -1)
- {
- is404 = TRUE;
- lod = 0;
- }
- }
- }
- }
-
- // Check if we need to change implementations
- bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE);
- if (is_flexible)
- {
- setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false);
- if (!mVolumeImpl)
- {
- LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
- mVolumeImpl = new LLVolumeImplFlexible(this, data);
- }
- }
- else
- {
- // Mark the parameter not in use
- setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false);
- if (mVolumeImpl)
- {
- delete mVolumeImpl;
- mVolumeImpl = NULL;
- if (mDrawable.notNull())
- {
- // Undo the damage we did to this matrix
- mDrawable->updateXform(FALSE);
- }
- }
- }
-
- if (is404)
- {
- setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
- //render prim proxy when mesh loading attempts give up
- volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE);
-
- }
-
- if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
- {
- mFaceMappingChanged = TRUE;
-
- if (mVolumeImpl)
- {
- mVolumeImpl->onSetVolume(volume_params, mLOD);
- }
-
- updateSculptTexture();
-
- if (isSculpted())
- {
- updateSculptTexture();
- // if it's a mesh
- if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
- {
- if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
- {
- mSkinInfo = NULL;
- mSkinInfoUnavaliable = false;
- }
-
- if (!getVolume()->isMeshAssetLoaded())
- {
- //load request not yet issued, request pipeline load this mesh
- S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod);
- if (available_lod != lod)
- {
- LLPrimitive::setVolume(volume_params, available_lod);
- }
- }
-
- if (!mSkinInfo && !mSkinInfoUnavaliable)
- {
+ LLVolumeParams volume_params = params_in;
+
+ S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1;
+ S32 lod = mLOD;
+
+ BOOL is404 = FALSE;
+
+ if (isSculpted())
+ {
+ // if it's a mesh
+ if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ { //meshes might not have all LODs, get the force detail to best existing LOD
+ if (NO_LOD != lod)
+ {
+ lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
+ if (lod == -1)
+ {
+ is404 = TRUE;
+ lod = 0;
+ }
+ }
+ }
+ }
+
+ // Check if we need to change implementations
+ bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE);
+ if (is_flexible)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false);
+ if (!mVolumeImpl)
+ {
+ LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ mVolumeImpl = new LLVolumeImplFlexible(this, data);
+ }
+ }
+ else
+ {
+ // Mark the parameter not in use
+ setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false);
+ if (mVolumeImpl)
+ {
+ delete mVolumeImpl;
+ mVolumeImpl = NULL;
+ if (mDrawable.notNull())
+ {
+ // Undo the damage we did to this matrix
+ mDrawable->updateXform(FALSE);
+ }
+ }
+ }
+
+ if (is404)
+ {
+ setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
+ //render prim proxy when mesh loading attempts give up
+ volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE);
+
+ }
+
+ if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
+ {
+ mFaceMappingChanged = TRUE;
+
+ if (mVolumeImpl)
+ {
+ mVolumeImpl->onSetVolume(volume_params, mLOD);
+ }
+
+ updateSculptTexture();
+
+ if (isSculpted())
+ {
+ updateSculptTexture();
+ // if it's a mesh
+ if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ {
+ if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
+ {
+ mSkinInfo = NULL;
+ mSkinInfoUnavaliable = false;
+ }
+
+ if (!getVolume()->isMeshAssetLoaded())
+ {
+ //load request not yet issued, request pipeline load this mesh
+ S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod);
+ if (available_lod != lod)
+ {
+ LLPrimitive::setVolume(volume_params, available_lod);
+ }
+ }
+
+ if (!mSkinInfo && !mSkinInfoUnavaliable)
+ {
LLUUID mesh_id = volume_params.getSculptID();
if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id))
{
@@ -1117,60 +1122,60 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
notifySkinInfoLoaded(skin_info);
}
}
- }
- }
- else // otherwise is sculptie
- {
- if (mSculptTexture.notNull())
- {
- sculpt();
- }
- }
- }
+ }
+ }
+ else // otherwise is sculptie
+ {
+ if (mSculptTexture.notNull())
+ {
+ sculpt();
+ }
+ }
+ }
return TRUE;
- }
- else if (NO_LOD == lod)
- {
- LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID());
- }
+ }
+ else if (NO_LOD == lod)
+ {
+ LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID());
+ }
- return FALSE;
+ return FALSE;
}
void LLVOVolume::updateSculptTexture()
{
- LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture;
+ LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture;
- if (isSculpted() && !isMesh())
- {
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID id = sculpt_params->getSculptTexture();
- if (id.notNull())
- {
- mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- }
+ if (isSculpted() && !isMesh())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLUUID id = sculpt_params->getSculptTexture();
+ if (id.notNull())
+ {
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
mSkinInfoUnavaliable = false;
- mSkinInfo = NULL;
- }
- else
- {
- mSculptTexture = NULL;
- }
-
- if (mSculptTexture != old_sculpt)
- {
- if (old_sculpt.notNull())
- {
- old_sculpt->removeVolume(LLRender::SCULPT_TEX, this);
- }
- if (mSculptTexture.notNull())
- {
- mSculptTexture->addVolume(LLRender::SCULPT_TEX, this);
- }
- }
-
+ mSkinInfo = NULL;
+ }
+ else
+ {
+ mSculptTexture = NULL;
+ }
+
+ if (mSculptTexture != old_sculpt)
+ {
+ if (old_sculpt.notNull())
+ {
+ old_sculpt->removeVolume(LLRender::SCULPT_TEX, this);
+ }
+ if (mSculptTexture.notNull())
+ {
+ mSculptTexture->addVolume(LLRender::SCULPT_TEX, this);
+ }
+ }
+
}
void LLVOVolume::updateVisualComplexity()
@@ -1188,9 +1193,9 @@ void LLVOVolume::updateVisualComplexity()
}
void LLVOVolume::notifyMeshLoaded()
-{
- mSculptChanged = TRUE;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+{
+ mSculptChanged = TRUE;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
if (!mSkinInfo && !mSkinInfoUnavaliable)
{
@@ -1220,137 +1225,137 @@ void LLVOVolume::notifyMeshLoaded()
void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
{
mSkinInfoUnavaliable = false;
- mSkinInfo = skin;
+ mSkinInfo = skin;
- notifyMeshLoaded();
+ notifyMeshLoaded();
}
void LLVOVolume::notifySkinInfoUnavailable()
{
- mSkinInfoUnavaliable = true;
- mSkinInfo = nullptr;
+ mSkinInfoUnavaliable = true;
+ mSkinInfo = nullptr;
}
// sculpt replaces generate() for sculpted surfaces
void LLVOVolume::sculpt()
-{
- if (mSculptTexture.notNull())
- {
- U16 sculpt_height = 0;
- U16 sculpt_width = 0;
- S8 sculpt_components = 0;
- const U8* sculpt_data = NULL;
-
- S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;
- LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
-
- S32 max_discard = mSculptTexture->getMaxDiscardLevel();
- if (discard_level > max_discard)
- {
- discard_level = max_discard; // clamp to the best we can do
- }
- if(discard_level > MAX_DISCARD_LEVEL)
- {
- return; //we think data is not ready yet.
- }
-
- S32 current_discard = getVolume()->getSculptLevel() ;
- if(current_discard < -2)
- {
- static S32 low_sculpty_discard_warning_count = 1;
- S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) ));
- S32 interval = pow(10.0, exponent);
- if ( low_sculpty_discard_warning_count < 10 ||
- (low_sculpty_discard_warning_count % interval) == 0)
- { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
- LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
- << " at " << current_discard
- << " is less than -2."
- << " Hit this " << low_sculpty_discard_warning_count << " times"
- << LL_ENDL;
- }
- low_sculpty_discard_warning_count++;
-
- // corrupted volume... don't update the sculpty
- return;
- }
- else if (current_discard > MAX_DISCARD_LEVEL)
- {
- static S32 high_sculpty_discard_warning_count = 1;
- S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) ));
- S32 interval = pow(10.0, exponent);
- if ( high_sculpty_discard_warning_count < 10 ||
- (high_sculpty_discard_warning_count % interval) == 0)
- { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
- LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
- << " at " << current_discard
- << " is more than than allowed max of " << MAX_DISCARD_LEVEL
- << ". Hit this " << high_sculpty_discard_warning_count << " times"
- << LL_ENDL;
- }
- high_sculpty_discard_warning_count++;
-
- // corrupted volume... don't update the sculpty
- return;
- }
-
- if (current_discard == discard_level) // no work to do here
- return;
-
- if(!raw_image)
- {
- llassert(discard_level < 0) ;
-
- sculpt_width = 0;
- sculpt_height = 0;
- sculpt_data = NULL ;
-
- if(LLViewerTextureManager::sTesterp)
- {
- LLViewerTextureManager::sTesterp->updateGrayTextureBinding();
- }
- }
- else
- {
- sculpt_height = raw_image->getHeight();
- sculpt_width = raw_image->getWidth();
- sculpt_components = raw_image->getComponents();
-
- sculpt_data = raw_image->getData();
-
- if(LLViewerTextureManager::sTesterp)
- {
- mSculptTexture->updateBindStatsForTester() ;
- }
- }
- getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());
-
- //notify rebuild any other VOVolumes that reference this sculpty volume
- for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i)
- {
- LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i];
- if (volume != this && volume->getVolume() == getVolume())
- {
- gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY);
- }
- }
- }
-}
-
-S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
-{
- S32 cur_detail;
- if (LLPipeline::sDynamicLOD)
- {
- // We've got LOD in the profile, and in the twist. Use radius.
- F32 tan_angle = (lod_factor*radius)/distance;
- cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
- }
- else
- {
- cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3);
- }
- return cur_detail;
+{
+ if (mSculptTexture.notNull())
+ {
+ U16 sculpt_height = 0;
+ U16 sculpt_width = 0;
+ S8 sculpt_components = 0;
+ const U8* sculpt_data = NULL;
+
+ S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;
+ LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
+
+ S32 max_discard = mSculptTexture->getMaxDiscardLevel();
+ if (discard_level > max_discard)
+ {
+ discard_level = max_discard; // clamp to the best we can do
+ }
+ if(discard_level > MAX_DISCARD_LEVEL)
+ {
+ return; //we think data is not ready yet.
+ }
+
+ S32 current_discard = getVolume()->getSculptLevel() ;
+ if(current_discard < -2)
+ {
+ static S32 low_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( low_sculpty_discard_warning_count < 10 ||
+ (low_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
+ LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
+ << " at " << current_discard
+ << " is less than -2."
+ << " Hit this " << low_sculpty_discard_warning_count << " times"
+ << LL_ENDL;
+ }
+ low_sculpty_discard_warning_count++;
+
+ // corrupted volume... don't update the sculpty
+ return;
+ }
+ else if (current_discard > MAX_DISCARD_LEVEL)
+ {
+ static S32 high_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( high_sculpty_discard_warning_count < 10 ||
+ (high_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
+ LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
+ << " at " << current_discard
+ << " is more than than allowed max of " << MAX_DISCARD_LEVEL
+ << ". Hit this " << high_sculpty_discard_warning_count << " times"
+ << LL_ENDL;
+ }
+ high_sculpty_discard_warning_count++;
+
+ // corrupted volume... don't update the sculpty
+ return;
+ }
+
+ if (current_discard == discard_level) // no work to do here
+ return;
+
+ if(!raw_image)
+ {
+ llassert(discard_level < 0) ;
+
+ sculpt_width = 0;
+ sculpt_height = 0;
+ sculpt_data = NULL ;
+
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->updateGrayTextureBinding();
+ }
+ }
+ else
+ {
+ sculpt_height = raw_image->getHeight();
+ sculpt_width = raw_image->getWidth();
+ sculpt_components = raw_image->getComponents();
+
+ sculpt_data = raw_image->getData();
+
+ if(LLViewerTextureManager::sTesterp)
+ {
+ mSculptTexture->updateBindStatsForTester() ;
+ }
+ }
+ getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());
+
+ //notify rebuild any other VOVolumes that reference this sculpty volume
+ for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i)
+ {
+ LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i];
+ if (volume != this && volume->getVolume() == getVolume())
+ {
+ gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ }
+ }
+ }
+}
+
+S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
+{
+ S32 cur_detail;
+ if (LLPipeline::sDynamicLOD)
+ {
+ // We've got LOD in the profile, and in the twist. Use radius.
+ F32 tan_angle = (lod_factor*radius)/distance;
+ cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
+ }
+ else
+ {
+ cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3);
+ }
+ return cur_detail;
}
std::string get_debug_object_lod_text(LLVOVolume *rootp)
@@ -1395,28 +1400,28 @@ std::string get_debug_object_lod_text(LLVOVolume *rootp)
BOOL LLVOVolume::calcLOD()
{
- if (mDrawable.isNull())
- {
- return FALSE;
- }
+ if (mDrawable.isNull())
+ {
+ return FALSE;
+ }
- S32 cur_detail = 0;
-
- F32 radius;
- F32 distance;
- F32 lod_factor = LLVOVolume::sLODFactor;
+ S32 cur_detail = 0;
+
+ F32 radius;
+ F32 distance;
+ F32 lod_factor = LLVOVolume::sLODFactor;
- if (mDrawable->isState(LLDrawable::RIGGED))
- {
- LLVOAvatar* avatar = getAvatar();
-
- // Not sure how this can really happen, but alas it does. Better exit here than crashing.
- if( !avatar || !avatar->mDrawable )
- {
- return FALSE;
- }
+ if (mDrawable->isState(LLDrawable::RIGGED))
+ {
+ LLVOAvatar* avatar = getAvatar();
+
+ // Not sure how this can really happen, but alas it does. Better exit here than crashing.
+ if( !avatar || !avatar->mDrawable )
+ {
+ return FALSE;
+ }
- distance = avatar->mDrawable->mDistanceWRTCamera;
+ distance = avatar->mDrawable->mDistanceWRTCamera;
if (avatar->isControlAvatar())
@@ -1443,20 +1448,20 @@ BOOL LLVOVolume::calcLOD()
LL_DEBUGS("DynamicBox","CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL;
return FALSE;
}
- }
- else
- {
- distance = mDrawable->mDistanceWRTCamera;
- radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
+ }
+ else
+ {
+ distance = mDrawable->mDistanceWRTCamera;
+ radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
if (distance <= 0.f || radius <= 0.f)
{
LL_DEBUGS("DynamicBox","CalcLOD") << "non-avatar distance/radius uninitialized, skipping" << LL_ENDL;
return FALSE;
}
- }
-
- //hold onto unmodified distance for debugging
- //F32 debug_distance = distance;
+ }
+
+ //hold onto unmodified distance for debugging
+ //F32 debug_distance = distance;
mLODDistance = distance;
mLODRadius = radius;
@@ -1482,24 +1487,24 @@ BOOL LLVOVolume::calcLOD()
distance *= sDistanceFactor;
- F32 rampDist = LLVOVolume::sLODFactor * 2;
-
- if (distance < rampDist)
- {
- // Boost LOD when you're REALLY close
- distance *= 1.0f/rampDist;
- distance *= distance;
- distance *= rampDist;
- }
-
-
- distance *= F_PI/3.f;
-
- static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs");
- if(!ignore_fov_zoom)
- {
- lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV();
- }
+ F32 rampDist = LLVOVolume::sLODFactor * 2;
+
+ if (distance < rampDist)
+ {
+ // Boost LOD when you're REALLY close
+ distance *= 1.0f/rampDist;
+ distance *= distance;
+ distance *= rampDist;
+ }
+
+
+ distance *= F_PI/3.f;
+
+ static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs");
+ if(!ignore_fov_zoom)
+ {
+ lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV();
+ }
mLODAdjustedDistance = distance;
@@ -1522,189 +1527,189 @@ BOOL LLVOVolume::calcLOD()
setDebugText(llformat("TRIS SHOWN %d EST %d", total_tris, est_max_tris));
}
}
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
- mDrawable->getFace(0))
- {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
+ mDrawable->getFace(0))
+ {
// This is a debug display for LODs. Please don't put the texture index here.
setDebugText(llformat("%d", cur_detail));
- }
+ }
- if (cur_detail != mLOD)
- {
- LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD
+ if (cur_detail != mLOD)
+ {
+ LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD
<< " distance " << distance << " radius " << radius << " rampDist " << rampDist
<< " drawable rigged? " << (mDrawable ? (S32) mDrawable->isState(LLDrawable::RIGGED) : (S32) -1)
- << " mRiggedVolume " << (void*)getRiggedVolume()
+ << " mRiggedVolume " << (void*)getRiggedVolume()
<< " distanceWRTCamera " << (mDrawable ? mDrawable->mDistanceWRTCamera : -1.f)
<< LL_ENDL;
-
- mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
- mLOD = cur_detail;
+
+ mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
+ mLOD = cur_detail;
return TRUE;
- }
+ }
- return FALSE;
+ return FALSE;
}
BOOL LLVOVolume::updateLOD()
{
- if (mDrawable.isNull())
- {
- return FALSE;
- }
+ if (mDrawable.isNull())
+ {
+ return FALSE;
+ }
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- BOOL lod_changed = FALSE;
-
- if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
- {
- lod_changed = calcLOD();
- }
- else
- {
- return FALSE;
- }
-
- if (lod_changed)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- mLODChanged = TRUE;
- }
- else
- {
- F32 new_radius = getBinRadius();
- F32 old_radius = mDrawable->getBinRadius();
- if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f)
- {
- gPipeline.markPartitionMove(mDrawable);
- }
- }
-
- lod_changed = lod_changed || LLViewerObject::updateLOD();
-
- return lod_changed;
+ BOOL lod_changed = FALSE;
+
+ if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
+ {
+ lod_changed = calcLOD();
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (lod_changed)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+ mLODChanged = TRUE;
+ }
+ else
+ {
+ F32 new_radius = getBinRadius();
+ F32 old_radius = mDrawable->getBinRadius();
+ if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f)
+ {
+ gPipeline.markPartitionMove(mDrawable);
+ }
+ }
+
+ lod_changed = lod_changed || LLViewerObject::updateLOD();
+
+ return lod_changed;
}
BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp)
{
- if (!LLViewerObject::setDrawableParent(parentp))
- {
- // no change in drawable parent
- return FALSE;
- }
-
- if (!mDrawable->isRoot())
- {
- // rebuild vertices in parent relative space
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
-
- if (mDrawable->isActive() && !parentp->isActive())
- {
- parentp->makeActive();
- }
- else if (mDrawable->isStatic() && parentp->isActive())
- {
- mDrawable->makeActive();
- }
- }
-
- return TRUE;
+ if (!LLViewerObject::setDrawableParent(parentp))
+ {
+ // no change in drawable parent
+ return FALSE;
+ }
+
+ if (!mDrawable->isRoot())
+ {
+ // rebuild vertices in parent relative space
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+
+ if (mDrawable->isActive() && !parentp->isActive())
+ {
+ parentp->makeActive();
+ }
+ else if (mDrawable->isStatic() && parentp->isActive())
+ {
+ mDrawable->makeActive();
+ }
+ }
+
+ return TRUE;
}
void LLVOVolume::updateFaceFlags()
{
- // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
- for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++)
- {
- LLFace *face = mDrawable->getFace(i);
- if (face)
- {
- BOOL fullbright = getTE(i)->getFullbright();
- face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
-
- if (fullbright || (mMaterial == LL_MCODE_LIGHT))
- {
- face->setState(LLFace::FULLBRIGHT);
- }
- if (mDrawable->isLight())
- {
- face->setState(LLFace::LIGHT);
- }
- if (isHUDAttachment())
- {
- face->setState(LLFace::HUD_RENDER);
- }
- }
- }
+ // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
+ for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++)
+ {
+ LLFace *face = mDrawable->getFace(i);
+ if (face)
+ {
+ BOOL fullbright = getTE(i)->getFullbright();
+ face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
+
+ if (fullbright || (mMaterial == LL_MCODE_LIGHT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+ if (mDrawable->isLight())
+ {
+ face->setState(LLFace::LIGHT);
+ }
+ if (isHUDAttachment())
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
+ }
+ }
}
BOOL LLVOVolume::setParent(LLViewerObject* parent)
{
- BOOL ret = FALSE ;
+ BOOL ret = FALSE ;
LLViewerObject *old_parent = (LLViewerObject*) getParent();
- if (parent != old_parent)
- {
- ret = LLViewerObject::setParent(parent);
- if (ret && mDrawable)
- {
- gPipeline.markMoved(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- }
+ if (parent != old_parent)
+ {
+ ret = LLViewerObject::setParent(parent);
+ if (ret && mDrawable)
+ {
+ gPipeline.markMoved(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+ }
onReparent(old_parent, parent);
- }
+ }
- return ret ;
+ return ret ;
}
// NOTE: regenFaces() MUST be followed by genTriangles()!
void LLVOVolume::regenFaces()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- // remove existing faces
- BOOL count_changed = mNumFaces != getNumTEs();
-
- if (count_changed)
- {
- deleteFaces();
- // add new faces
- mNumFaces = getNumTEs();
- }
-
- for (S32 i = 0; i < mNumFaces; i++)
- {
- LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
- if (!facep) continue;
-
- facep->setTEOffset(i);
- facep->setTexture(getTEImage(i));
- if (facep->getTextureEntry()->getMaterialParams().notNull())
- {
- facep->setNormalMap(getTENormalMap(i));
- facep->setSpecularMap(getTESpecularMap(i));
- }
- facep->setViewerObject(this);
-
- // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face.
- // Re-establish the link.
- if((int)mMediaImplList.size() > i)
- {
- if(mMediaImplList[i])
- {
- LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ;
- if(media_tex)
- {
- media_tex->addMediaToFace(facep) ;
- }
- }
- }
- }
-
- if (!count_changed)
- {
- updateFaceFlags();
- }
+ // remove existing faces
+ BOOL count_changed = mNumFaces != getNumTEs();
+
+ if (count_changed)
+ {
+ deleteFaces();
+ // add new faces
+ mNumFaces = getNumTEs();
+ }
+
+ for (S32 i = 0; i < mNumFaces; i++)
+ {
+ LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
+ if (!facep) continue;
+
+ facep->setTEOffset(i);
+ facep->setTexture(getTEImage(i));
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ {
+ facep->setNormalMap(getTENormalMap(i));
+ facep->setSpecularMap(getTESpecularMap(i));
+ }
+ facep->setViewerObject(this);
+
+ // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face.
+ // Re-establish the link.
+ if((int)mMediaImplList.size() > i)
+ {
+ if(mMediaImplList[i])
+ {
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ;
+ if(media_tex)
+ {
+ media_tex->addMediaToFace(facep) ;
+ }
+ }
+ }
+ }
+
+ if (!count_changed)
+ {
+ updateFaceFlags();
+ }
}
BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
@@ -1822,7 +1827,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
mDrawable->setPositionGroup(min);
}
}
-
+
updateRadius();
mDrawable->movePartition();
}
@@ -1836,581 +1841,581 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
void LLVOVolume::preRebuild()
{
- if (mVolumeImpl != NULL)
- {
- mVolumeImpl->preRebuild();
- }
+ if (mVolumeImpl != NULL)
+ {
+ mVolumeImpl->preRebuild();
+ }
}
void LLVOVolume::updateRelativeXform(bool force_identity)
{
- if (mVolumeImpl)
- {
- mVolumeImpl->updateRelativeXform(force_identity);
- return;
- }
-
- LLDrawable* drawable = mDrawable;
-
- if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull())
- { //rigged volume (which is in agent space) is used for generating bounding boxes etc
- //inverse of render matrix should go to partition space
- mRelativeXform = getRenderMatrix();
-
- F32* dst = (F32*) mRelativeXformInvTrans.mMatrix;
- F32* src = (F32*) mRelativeXform.mMatrix;
- dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
- dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6];
- dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10];
-
- mRelativeXform.invert();
- mRelativeXformInvTrans.transpose();
- }
- else if (drawable->isActive() || force_identity)
- {
- // setup relative transforms
- LLQuaternion delta_rot;
- LLVector3 delta_pos, delta_scale;
-
- //matrix from local space to parent relative/global space
- bool use_identity = force_identity || drawable->isSpatialRoot();
- delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
- delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
- delta_scale = mDrawable->getScale();
-
- // Vertex transform (4x4)
- LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot;
- LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot;
- LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot;
-
- mRelativeXform.initRows(LLVector4(x_axis, 0.f),
- LLVector4(y_axis, 0.f),
- LLVector4(z_axis, 0.f),
- LLVector4(delta_pos, 1.f));
-
-
- // compute inverse transpose for normals
- // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
- // mRelativeXformInvTrans.invert();
- // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
- // grumble - invert is NOT a matrix invert, so we do it by hand:
-
- LLMatrix3 rot_inverse = LLMatrix3(~delta_rot);
-
- LLMatrix3 scale_inverse;
- scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX],
- LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY],
- LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]);
-
-
- mRelativeXformInvTrans = rot_inverse * scale_inverse;
-
- mRelativeXformInvTrans.transpose();
- }
- else
- {
- LLVector3 pos = getPosition();
- LLVector3 scale = getScale();
- LLQuaternion rot = getRotation();
-
- if (mParent)
- {
- pos *= mParent->getRotation();
- pos += mParent->getPosition();
- rot *= mParent->getRotation();
- }
-
- //LLViewerRegion* region = getRegion();
- //pos += region->getOriginAgent();
-
- LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot;
- LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot;
- LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot;
-
- mRelativeXform.initRows(LLVector4(x_axis, 0.f),
- LLVector4(y_axis, 0.f),
- LLVector4(z_axis, 0.f),
- LLVector4(pos, 1.f));
-
- // compute inverse transpose for normals
- LLMatrix3 rot_inverse = LLMatrix3(~rot);
-
- LLMatrix3 scale_inverse;
- scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX],
- LLVector3(0.0, 1.0, 0.0) / scale.mV[VY],
- LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]);
-
-
- mRelativeXformInvTrans = rot_inverse * scale_inverse;
-
- mRelativeXformInvTrans.transpose();
- }
+ if (mVolumeImpl)
+ {
+ mVolumeImpl->updateRelativeXform(force_identity);
+ return;
+ }
+
+ LLDrawable* drawable = mDrawable;
+
+ if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull())
+ { //rigged volume (which is in agent space) is used for generating bounding boxes etc
+ //inverse of render matrix should go to partition space
+ mRelativeXform = getRenderMatrix();
+
+ F32* dst = (F32*) mRelativeXformInvTrans.mMatrix;
+ F32* src = (F32*) mRelativeXform.mMatrix;
+ dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
+ dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6];
+ dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10];
+
+ mRelativeXform.invert();
+ mRelativeXformInvTrans.transpose();
+ }
+ else if (drawable->isActive() || force_identity)
+ {
+ // setup relative transforms
+ LLQuaternion delta_rot;
+ LLVector3 delta_pos, delta_scale;
+
+ //matrix from local space to parent relative/global space
+ bool use_identity = force_identity || drawable->isSpatialRoot();
+ delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
+ delta_scale = mDrawable->getScale();
+
+ // Vertex transform (4x4)
+ LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot;
+ LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot;
+ LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot;
+
+ mRelativeXform.initRows(LLVector4(x_axis, 0.f),
+ LLVector4(y_axis, 0.f),
+ LLVector4(z_axis, 0.f),
+ LLVector4(delta_pos, 1.f));
+
+
+ // compute inverse transpose for normals
+ // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
+ // mRelativeXformInvTrans.invert();
+ // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
+ // grumble - invert is NOT a matrix invert, so we do it by hand:
+
+ LLMatrix3 rot_inverse = LLMatrix3(~delta_rot);
+
+ LLMatrix3 scale_inverse;
+ scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX],
+ LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY],
+ LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]);
+
+
+ mRelativeXformInvTrans = rot_inverse * scale_inverse;
+
+ mRelativeXformInvTrans.transpose();
+ }
+ else
+ {
+ LLVector3 pos = getPosition();
+ LLVector3 scale = getScale();
+ LLQuaternion rot = getRotation();
+
+ if (mParent)
+ {
+ pos *= mParent->getRotation();
+ pos += mParent->getPosition();
+ rot *= mParent->getRotation();
+ }
+
+ //LLViewerRegion* region = getRegion();
+ //pos += region->getOriginAgent();
+
+ LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot;
+ LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot;
+ LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot;
+
+ mRelativeXform.initRows(LLVector4(x_axis, 0.f),
+ LLVector4(y_axis, 0.f),
+ LLVector4(z_axis, 0.f),
+ LLVector4(pos, 1.f));
+
+ // compute inverse transpose for normals
+ LLMatrix3 rot_inverse = LLMatrix3(~rot);
+
+ LLMatrix3 scale_inverse;
+ scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX],
+ LLVector3(0.0, 1.0, 0.0) / scale.mV[VY],
+ LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]);
+
+
+ mRelativeXformInvTrans = rot_inverse * scale_inverse;
+
+ mRelativeXformInvTrans.transpose();
+ }
}
bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- bool regen_faces = false;
+ bool regen_faces = false;
- LLVolume *old_volumep, *new_volumep;
- F32 old_lod, new_lod;
- S32 old_num_faces, new_num_faces;
+ LLVolume *old_volumep, *new_volumep;
+ F32 old_lod, new_lod;
+ S32 old_num_faces, new_num_faces;
- old_volumep = getVolume();
- old_lod = old_volumep->getDetail();
- old_num_faces = old_volumep->getNumFaces();
- old_volumep = NULL;
+ old_volumep = getVolume();
+ old_lod = old_volumep->getDetail();
+ old_num_faces = old_volumep->getNumFaces();
+ old_volumep = NULL;
- {
- const LLVolumeParams &volume_params = getVolume()->getParams();
- setVolume(volume_params, 0);
- }
+ {
+ const LLVolumeParams &volume_params = getVolume()->getParams();
+ setVolume(volume_params, 0);
+ }
- new_volumep = getVolume();
- new_lod = new_volumep->getDetail();
- new_num_faces = new_volumep->getNumFaces();
- new_volumep = NULL;
+ new_volumep = getVolume();
+ new_lod = new_volumep->getDetail();
+ new_num_faces = new_volumep->getNumFaces();
+ new_volumep = NULL;
- if ((new_lod != old_lod) || mSculptChanged)
- {
+ if ((new_lod != old_lod) || mSculptChanged)
+ {
if (mDrawable->isState(LLDrawable::RIGGED))
{
updateVisualComplexity();
}
- compiled = TRUE;
+ compiled = TRUE;
// new_lod > old_lod breaks a feedback loop between LOD updates and
// bounding box updates.
should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod;
- sNumLODChanges += new_num_faces;
-
- if ((S32)getNumTEs() != getVolume()->getNumFaces())
- {
- setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces.
- }
-
- drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
-
- {
- regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs();
- if (regen_faces)
- {
- regenFaces();
- }
-
- if (mSculptChanged)
- { //changes in sculpt maps can thrash an object bounding box without
- //triggering a spatial group bounding box update -- force spatial group
- //to update bounding boxes
- LLSpatialGroup* group = mDrawable->getSpatialGroup();
- if (group)
- {
- group->unbound();
- }
- }
- }
- }
-
- return regen_faces;
+ sNumLODChanges += new_num_faces;
+
+ if ((S32)getNumTEs() != getVolume()->getNumFaces())
+ {
+ setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces.
+ }
+
+ drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
+
+ {
+ regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs();
+ if (regen_faces)
+ {
+ regenFaces();
+ }
+
+ if (mSculptChanged)
+ { //changes in sculpt maps can thrash an object bounding box without
+ //triggering a spatial group bounding box update -- force spatial group
+ //to update bounding boxes
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->unbound();
+ }
+ }
+ }
+ }
+
+ return regen_faces;
}
BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
-
- if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
- {
+
+ if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
+ {
updateRiggedVolume(false);
- genBBoxes(FALSE);
- mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
- }
-
- if (mVolumeImpl != NULL)
- {
- BOOL res;
- {
- res = mVolumeImpl->doUpdateGeometry(drawable);
- }
- updateFaceFlags();
- return res;
- }
-
- LLSpatialGroup* group = drawable->getSpatialGroup();
- if (group)
- {
+ genBBoxes(FALSE);
+ mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
+ }
+
+ if (mVolumeImpl != NULL)
+ {
+ BOOL res;
+ {
+ res = mVolumeImpl->doUpdateGeometry(drawable);
+ }
+ updateFaceFlags();
+ return res;
+ }
+
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ if (group)
+ {
group->dirtyMesh();
- }
+ }
- updateRelativeXform();
-
- if (mDrawable.isNull()) // Not sure why this is happening, but it is...
- {
- return TRUE; // No update to complete
- }
+ updateRelativeXform();
+
+ if (mDrawable.isNull()) // Not sure why this is happening, but it is...
+ {
+ return TRUE; // No update to complete
+ }
- BOOL compiled = FALSE;
+ BOOL compiled = FALSE;
// This should be true in most cases, unless we're sure no octree update is
// needed.
BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3();
- if (mVolumeChanged || mFaceMappingChanged)
- {
- dirtySpatialGroup();
+ if (mVolumeChanged || mFaceMappingChanged)
+ {
+ dirtySpatialGroup();
- bool was_regen_faces = false;
+ bool was_regen_faces = false;
should_update_octree_bounds = true;
- if (mVolumeChanged)
- {
+ if (mVolumeChanged)
+ {
was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
- drawable->setState(LLDrawable::REBUILD_VOLUME);
- }
- else if (mSculptChanged || mLODChanged || mColorChanged)
- {
- compiled = TRUE;
+ drawable->setState(LLDrawable::REBUILD_VOLUME);
+ }
+ else if (mSculptChanged || mLODChanged || mColorChanged)
+ {
+ compiled = TRUE;
was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
- }
-
- if (!was_regen_faces) {
- regenFaces();
- }
- }
- else if (mLODChanged || mSculptChanged || mColorChanged)
- {
- dirtySpatialGroup();
- compiled = TRUE;
+ }
+
+ if (!was_regen_faces) {
+ regenFaces();
+ }
+ }
+ else if (mLODChanged || mSculptChanged || mColorChanged)
+ {
+ dirtySpatialGroup();
+ compiled = TRUE;
lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
-
- if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
- {
- updateRiggedVolume(false);
- }
- }
- // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
- else
- {
- compiled = TRUE;
- // All it did was move or we changed the texture coordinate offset
- }
+
+ if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
+ {
+ updateRiggedVolume(false);
+ }
+ }
+ // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
+ else
+ {
+ compiled = TRUE;
+ // All it did was move or we changed the texture coordinate offset
+ }
// Generate bounding boxes if needed, and update the object's size in the
// octree
genBBoxes(FALSE, should_update_octree_bounds);
- // Update face flags
- updateFaceFlags();
-
- if(compiled)
- {
- LLPipeline::sCompiles++;
- }
-
- mVolumeChanged = FALSE;
- mLODChanged = FALSE;
- mSculptChanged = FALSE;
- mFaceMappingChanged = FALSE;
+ // Update face flags
+ updateFaceFlags();
+
+ if(compiled)
+ {
+ LLPipeline::sCompiles++;
+ }
+
+ mVolumeChanged = FALSE;
+ mLODChanged = FALSE;
+ mSculptChanged = FALSE;
+ mFaceMappingChanged = FALSE;
mColorChanged = FALSE;
-
- return LLViewerObject::updateGeometry(drawable);
+
+ return LLViewerObject::updateGeometry(drawable);
}
void LLVOVolume::updateFaceSize(S32 idx)
{
- if( mDrawable->getNumFaces() <= idx )
- {
- return;
- }
-
- LLFace* facep = mDrawable->getFace(idx);
- if (facep)
- {
- if (idx >= getVolume()->getNumVolumeFaces())
- {
- facep->setSize(0,0, true);
- }
- else
- {
- const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
- facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
- true); // <--- volume faces should be padded for 16-byte alignment
-
- }
- }
+ if( mDrawable->getNumFaces() <= idx )
+ {
+ return;
+ }
+
+ LLFace* facep = mDrawable->getFace(idx);
+ if (facep)
+ {
+ if (idx >= getVolume()->getNumVolumeFaces())
+ {
+ facep->setSize(0,0, true);
+ }
+ else
+ {
+ const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+ facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
+ true); // <--- volume faces should be padded for 16-byte alignment
+
+ }
+ }
}
BOOL LLVOVolume::isRootEdit() const
{
- if (mParent && !((LLViewerObject*)mParent)->isAvatar())
- {
- return FALSE;
- }
- return TRUE;
+ if (mParent && !((LLViewerObject*)mParent)->isAvatar())
+ {
+ return FALSE;
+ }
+ return TRUE;
}
//virtual
void LLVOVolume::setNumTEs(const U8 num_tes)
{
- const U8 old_num_tes = getNumTEs() ;
-
- if(old_num_tes && old_num_tes < num_tes) //new faces added
- {
- LLViewerObject::setNumTEs(num_tes) ;
-
- if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
- {
- mMediaImplList.resize(num_tes) ;
- const LLTextureEntry* te = getTE(old_num_tes - 1) ;
- for(U8 i = old_num_tes; i < num_tes ; i++)
- {
- setTE(i, *te) ;
- mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
- }
- mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
- }
- }
- else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
- {
- U8 end = (U8)(mMediaImplList.size()) ;
- for(U8 i = num_tes; i < end ; i++)
- {
- removeMediaImpl(i) ;
- }
- mMediaImplList.resize(num_tes) ;
-
- LLViewerObject::setNumTEs(num_tes) ;
- }
- else
- {
- LLViewerObject::setNumTEs(num_tes) ;
- }
-
- return ;
+ const U8 old_num_tes = getNumTEs() ;
+
+ if(old_num_tes && old_num_tes < num_tes) //new faces added
+ {
+ LLViewerObject::setNumTEs(num_tes) ;
+
+ if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
+ {
+ mMediaImplList.resize(num_tes) ;
+ const LLTextureEntry* te = getTE(old_num_tes - 1) ;
+ for(U8 i = old_num_tes; i < num_tes ; i++)
+ {
+ setTE(i, *te) ;
+ mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
+ }
+ mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
+ }
+ }
+ else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
+ {
+ U8 end = (U8)(mMediaImplList.size()) ;
+ for(U8 i = num_tes; i < end ; i++)
+ {
+ removeMediaImpl(i) ;
+ }
+ mMediaImplList.resize(num_tes) ;
+
+ LLViewerObject::setNumTEs(num_tes) ;
+ }
+ else
+ {
+ LLViewerObject::setNumTEs(num_tes) ;
+ }
+
+ return ;
}
//virtual
void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
{
- BOOL changed = (mTEImages[index] != imagep);
- LLViewerObject::changeTEImage(index, imagep);
- if (changed)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
+ BOOL changed = (mTEImages[index] != imagep);
+ LLViewerObject::changeTEImage(index, imagep);
+ if (changed)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
}
void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
{
- BOOL changed = (mTEImages[te] != imagep);
- LLViewerObject::setTEImage(te, imagep);
- if (changed)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
+ BOOL changed = (mTEImages[te] != imagep);
+ LLViewerObject::setTEImage(te, imagep);
+ if (changed)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
}
S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid)
{
- S32 res = LLViewerObject::setTETexture(te, uuid);
- if (res)
- {
+ S32 res = LLViewerObject::setTETexture(te, uuid);
+ if (res)
+ {
if (mDrawable)
{
// dynamic texture changes break batches, isolate in octree
shrinkWrap();
gPipeline.markTextured(mDrawable);
}
- mFaceMappingChanged = TRUE;
- }
- return res;
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color)
{
- return setTEColor(te, LLColor4(color));
+ return setTEColor(te, LLColor4(color));
}
S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
{
- S32 retval = 0;
- const LLTextureEntry *tep = getTE(te);
- if (!tep)
- {
- LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
- }
- else if (color != tep->getColor())
- {
- F32 old_alpha = tep->getColor().mV[3];
- if (color.mV[3] != old_alpha)
- {
- gPipeline.markTextured(mDrawable);
- //treat this alpha change as an LoD update since render batches may need to get rebuilt
- mLODChanged = TRUE;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- }
- retval = LLPrimitive::setTEColor(te, color);
- if (mDrawable.notNull() && retval)
- {
- // These should only happen on updates which are not the initial update.
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ }
+ else if (color != tep->getColor())
+ {
+ F32 old_alpha = tep->getColor().mV[3];
+ if (color.mV[3] != old_alpha)
+ {
+ gPipeline.markTextured(mDrawable);
+ //treat this alpha change as an LoD update since render batches may need to get rebuilt
+ mLODChanged = TRUE;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
+ }
+ retval = LLPrimitive::setTEColor(te, color);
+ if (mDrawable.notNull() && retval)
+ {
+ // These should only happen on updates which are not the initial update.
mColorChanged = TRUE;
- mDrawable->setState(LLDrawable::REBUILD_COLOR);
+ mDrawable->setState(LLDrawable::REBUILD_COLOR);
shrinkWrap();
- dirtyMesh();
- }
- }
+ dirtyMesh();
+ }
+ }
- return retval;
+ return retval;
}
S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap)
{
- S32 res = LLViewerObject::setTEBumpmap(te, bumpmap);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEBumpmap(te, bumpmap);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTETexGen(const U8 te, const U8 texgen)
{
- S32 res = LLViewerObject::setTETexGen(te, texgen);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTETexGen(te, texgen);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEMediaTexGen(const U8 te, const U8 media)
{
- S32 res = LLViewerObject::setTEMediaTexGen(te, media);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEMediaTexGen(te, media);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny)
{
- S32 res = LLViewerObject::setTEShiny(te, shiny);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEShiny(te, shiny);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright)
{
- S32 res = LLViewerObject::setTEFullbright(te, fullbright);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEFullbright(te, fullbright);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump)
{
- S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags)
{
- S32 res = LLViewerObject::setTEMediaFlags(te, media_flags);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEMediaFlags(te, media_flags);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
{
- S32 res = LLViewerObject::setTEGlow(te, glow);
- if (res)
- {
+ S32 res = LLViewerObject::setTEGlow(te, glow);
+ if (res)
+ {
if (mDrawable)
{
gPipeline.markTextured(mDrawable);
shrinkWrap();
}
- mFaceMappingChanged = TRUE;
- }
- return res;
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te)
{
- LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID);
- if (pVol)
- {
- LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
- if (te >= pVol->getNumTEs())
- return;
+ LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID);
+ if (pVol)
+ {
+ LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
+ if (te >= pVol->getNumTEs())
+ return;
- LLTextureEntry* texture_entry = pVol->getTE(te);
- if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
- {
- pVol->setTEMaterialParams(te, pMaterialParams);
- }
- }
+ LLTextureEntry* texture_entry = pVol->getTE(te);
+ if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
+ {
+ pVol->setTEMaterialParams(te, pMaterialParams);
+ }
+ }
}
S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
{
- S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
- LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
- << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
- << LL_ENDL;
-
- LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
- if (res)
- {
- LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
-
- setChanged(ALL_CHANGED);
- if (!mDrawable.isNull())
- {
- gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
- }
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
+ LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+
+ LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
+ if (res)
+ {
+ LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
+
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
- S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
+ S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
- LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
- << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
- << LL_ENDL;
- setChanged(ALL_CHANGED);
- if (!mDrawable.isNull())
- {
- gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
- }
- mFaceMappingChanged = TRUE;
- return TEM_CHANGE_TEXTURE;
+ LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ return TEM_CHANGE_TEXTURE;
}
S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat)
@@ -2433,230 +2438,230 @@ S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat)
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
- S32 res = LLViewerObject::setTEScale(te, s, t);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEScale(te, s, t);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEScaleS(const U8 te, const F32 s)
{
- S32 res = LLViewerObject::setTEScaleS(te, s);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEScaleS(te, s);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
{
- S32 res = LLViewerObject::setTEScaleT(te, t);
- if (res)
- {
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- return res;
+ S32 res = LLViewerObject::setTEScaleT(te, t);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
}
bool LLVOVolume::hasMedia() const
{
- bool result = false;
- const U8 numTEs = getNumTEs();
- for (U8 i = 0; i < numTEs; i++)
- {
- const LLTextureEntry* te = getTE(i);
- if(te->hasMedia())
- {
- result = true;
- break;
- }
- }
- return result;
+ bool result = false;
+ const U8 numTEs = getNumTEs();
+ for (U8 i = 0; i < numTEs; i++)
+ {
+ const LLTextureEntry* te = getTE(i);
+ if(te->hasMedia())
+ {
+ result = true;
+ break;
+ }
+ }
+ return result;
}
LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id)
{
- LLVolume* volume = getVolume();
- LLVector4a result;
- result.clear();
-
- LLVector3 ret;
+ LLVolume* volume = getVolume();
+ LLVector4a result;
+ result.clear();
- if (volume && face_id < volume->getNumVolumeFaces())
- {
- const LLVolumeFace& face = volume->getVolumeFace(face_id);
- for (S32 i = 0; i < (S32)face.mNumVertices; ++i)
- {
- result.add(face.mNormals[i]);
- }
+ LLVector3 ret;
- LLVector3 ret(result.getF32ptr());
- ret = volumeDirectionToAgent(ret);
- ret.normVec();
- }
+ if (volume && face_id < volume->getNumVolumeFaces())
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(face_id);
+ for (S32 i = 0; i < (S32)face.mNumVertices; ++i)
+ {
+ result.add(face.mNormals[i]);
+ }
- return ret;
+ LLVector3 ret(result.getF32ptr());
+ ret = volumeDirectionToAgent(ret);
+ ret.normVec();
+ }
+
+ return ret;
}
void LLVOVolume::requestMediaDataUpdate(bool isNew)
{
if (sObjectMediaClient)
- sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew));
+ sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew));
}
bool LLVOVolume::isMediaDataBeingFetched() const
{
- // I know what I'm doing by const_casting this away: this is just
- // a wrapper class that is only going to do a lookup.
- return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false)) : false;
+ // I know what I'm doing by const_casting this away: this is just
+ // a wrapper class that is only going to do a lookup.
+ return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false)) : false;
}
void LLVOVolume::cleanUpMediaImpls()
{
- // Iterate through our TEs and remove any Impls that are no longer used
- const U8 numTEs = getNumTEs();
- for (U8 i = 0; i < numTEs; i++)
- {
- const LLTextureEntry* te = getTE(i);
- if( ! te->hasMedia())
- {
- // Delete the media IMPL!
- removeMediaImpl(i) ;
- }
- }
+ // Iterate through our TEs and remove any Impls that are no longer used
+ const U8 numTEs = getNumTEs();
+ for (U8 i = 0; i < numTEs; i++)
+ {
+ const LLTextureEntry* te = getTE(i);
+ if( ! te->hasMedia())
+ {
+ // Delete the media IMPL!
+ removeMediaImpl(i) ;
+ }
+ }
}
void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version)
{
- // media_data_array is an array of media entry maps
- // media_version is the version string in the response.
- U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version);
-
- // Only update it if it is newer!
- if ( (S32)fetched_version > mLastFetchedMediaVersion)
- {
- mLastFetchedMediaVersion = fetched_version;
- //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL;
-
- LLSD::array_const_iterator iter = media_data_array.beginArray();
- LLSD::array_const_iterator end = media_data_array.endArray();
- U8 texture_index = 0;
- for (; iter != end; ++iter, ++texture_index)
- {
- syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
- }
- }
+ // media_data_array is an array of media entry maps
+ // media_version is the version string in the response.
+ U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version);
+
+ // Only update it if it is newer!
+ if ( (S32)fetched_version > mLastFetchedMediaVersion)
+ {
+ mLastFetchedMediaVersion = fetched_version;
+ //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL;
+
+ LLSD::array_const_iterator iter = media_data_array.beginArray();
+ LLSD::array_const_iterator end = media_data_array.endArray();
+ U8 texture_index = 0;
+ for (; iter != end; ++iter, ++texture_index)
+ {
+ syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
+ }
+ }
}
void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
{
- if(mDead)
- {
- // If the object has been marked dead, don't process media updates.
- return;
- }
-
- LLTextureEntry *te = getTE(texture_index);
- if(!te)
- {
- return ;
- }
-
- LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index
- << " hasMedia = " << te->hasMedia() << " : "
- << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL;
-
- std::string previous_url;
- LLMediaEntry* mep = te->getMediaData();
- if(mep)
- {
- // Save the "current url" from before the update so we can tell if
- // it changes.
- previous_url = mep->getCurrentURL();
- }
-
- if (merge)
- {
- te->mergeIntoMediaData(media_data);
- }
- else {
- // XXX Question: what if the media data is undefined LLSD, but the
- // update we got above said that we have media flags?? Here we clobber
- // that, assuming the data from the service is more up-to-date.
- te->updateMediaData(media_data);
- }
-
- mep = te->getMediaData();
- if(mep)
- {
- bool update_from_self = false;
- if (!ignore_agent)
- {
- LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
- update_from_self = (updating_agent == gAgent.getID());
- }
- viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self);
-
- addMediaImpl(media_impl, texture_index) ;
- }
- else
- {
- removeMediaImpl(texture_index);
- }
-
- LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index
- << " hasMedia = " << te->hasMedia() << " : "
- << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL;
+ if(mDead)
+ {
+ // If the object has been marked dead, don't process media updates.
+ return;
+ }
+
+ LLTextureEntry *te = getTE(texture_index);
+ if(!te)
+ {
+ return ;
+ }
+
+ LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index
+ << " hasMedia = " << te->hasMedia() << " : "
+ << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL;
+
+ std::string previous_url;
+ LLMediaEntry* mep = te->getMediaData();
+ if(mep)
+ {
+ // Save the "current url" from before the update so we can tell if
+ // it changes.
+ previous_url = mep->getCurrentURL();
+ }
+
+ if (merge)
+ {
+ te->mergeIntoMediaData(media_data);
+ }
+ else {
+ // XXX Question: what if the media data is undefined LLSD, but the
+ // update we got above said that we have media flags?? Here we clobber
+ // that, assuming the data from the service is more up-to-date.
+ te->updateMediaData(media_data);
+ }
+
+ mep = te->getMediaData();
+ if(mep)
+ {
+ bool update_from_self = false;
+ if (!ignore_agent)
+ {
+ LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
+ update_from_self = (updating_agent == gAgent.getID());
+ }
+ viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self);
+
+ addMediaImpl(media_impl, texture_index) ;
+ }
+ else
+ {
+ removeMediaImpl(texture_index);
+ }
+
+ LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index
+ << " hasMedia = " << te->hasMedia() << " : "
+ << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL;
}
void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)
{
- // Find the media entry for this navigate
- const LLMediaEntry* mep = NULL;
- viewer_media_t impl = getMediaImpl(texture_index);
- LLTextureEntry *te = getTE(texture_index);
- if(te)
- {
- mep = te->getMediaData();
- }
-
- if (mep && impl)
- {
+ // Find the media entry for this navigate
+ const LLMediaEntry* mep = NULL;
+ viewer_media_t impl = getMediaImpl(texture_index);
+ LLTextureEntry *te = getTE(texture_index);
+ if(te)
+ {
+ mep = te->getMediaData();
+ }
+
+ if (mep && impl)
+ {
std::string url = mep->getCurrentURL();
- // Look for a ":", if not there, assume "http://"
- if (!url.empty() && std::string::npos == url.find(':'))
- {
- url = "http://" + url;
- }
- // If the url we're trying to "bounce back" to is either empty or not
- // allowed by the whitelist, try the home url. If *that* doesn't work,
- // set the media as failed and unload it
+ // Look for a ":", if not there, assume "http://"
+ if (!url.empty() && std::string::npos == url.find(':'))
+ {
+ url = "http://" + url;
+ }
+ // If the url we're trying to "bounce back" to is either empty or not
+ // allowed by the whitelist, try the home url. If *that* doesn't work,
+ // set the media as failed and unload it
if (url.empty() || !mep->checkCandidateUrl(url))
{
url = mep->getHomeURL();
- // Look for a ":", if not there, assume "http://"
- if (!url.empty() && std::string::npos == url.find(':'))
- {
- url = "http://" + url;
- }
+ // Look for a ":", if not there, assume "http://"
+ if (!url.empty() && std::string::npos == url.find(':'))
+ {
+ url = "http://" + url;
+ }
}
if (url.empty() || !mep->checkCandidateUrl(url))
- {
- // The url to navigate back to is not good, and we have nowhere else
- // to go.
- LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL;
- impl->setMediaFailed(true);
- }
- // Make sure we are not bouncing to url we came from
- else if (impl->getCurrentMediaURL() != url)
- {
- // Okay, navigate now
+ {
+ // The url to navigate back to is not good, and we have nowhere else
+ // to go.
+ LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL;
+ impl->setMediaFailed(true);
+ }
+ // Make sure we are not bouncing to url we came from
+ else if (impl->getCurrentMediaURL() != url)
+ {
+ // Okay, navigate now
LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL;
impl->navigateTo(url, "", false, true);
}
@@ -2667,153 +2672,153 @@ bool LLVOVolume::hasMediaPermission(const LLMediaEntry* media_entry, MediaPermTy
{
// NOTE: This logic ALMOST duplicates the logic in the server (in particular, in llmediaservice.cpp).
if (NULL == media_entry ) return false; // XXX should we assert here?
-
+
// The agent has permissions if:
// - world permissions are on, or
// - group permissions are on, and agent_id is in the group, or
// - agent permissions are on, and agent_id is the owner
-
- // *NOTE: We *used* to check for modify permissions here (i.e. permissions were
- // granted if permModify() was true). However, this doesn't make sense in the
- // viewer: we don't want to show controls or allow interaction if the author
- // has deemed it so. See DEV-42115.
-
+
+ // *NOTE: We *used* to check for modify permissions here (i.e. permissions were
+ // granted if permModify() was true). However, this doesn't make sense in the
+ // viewer: we don't want to show controls or allow interaction if the author
+ // has deemed it so. See DEV-42115.
+
U8 media_perms = (perm_type == MEDIA_PERM_INTERACT) ? media_entry->getPermsInteract() : media_entry->getPermsControl();
-
+
// World permissions
- if (0 != (media_perms & LLMediaEntry::PERM_ANYONE))
+ if (0 != (media_perms & LLMediaEntry::PERM_ANYONE))
{
return true;
}
-
+
// Group permissions
else if (0 != (media_perms & LLMediaEntry::PERM_GROUP))
{
- LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
- if (obj_perm && gAgent.isInGroup(obj_perm->getGroup()))
- {
- return true;
- }
+ LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
+ if (obj_perm && gAgent.isInGroup(obj_perm->getGroup()))
+ {
+ return true;
+ }
}
-
+
// Owner permissions
- else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner())
+ else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner())
{
return true;
}
-
+
return false;
-
+
}
void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location)
{
- bool block_navigation = false;
- // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
- // to deal with multiple face indices.
- int face_index = getFaceIndexWithMediaImpl(impl, -1);
-
- // Find the media entry for this navigate
- LLMediaEntry* mep = NULL;
- LLTextureEntry *te = getTE(face_index);
- if(te)
- {
- mep = te->getMediaData();
- }
-
- if(mep)
- {
- if(!mep->checkCandidateUrl(new_location))
- {
- block_navigation = true;
- }
- if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT))
- {
- block_navigation = true;
- }
- }
- else
- {
- LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL;
- }
-
- if(block_navigation)
- {
- LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL;
-
- // "bounce back" to the current URL from the media entry
- mediaNavigateBounceBack(face_index);
- }
- else if (sObjectMediaNavigateClient)
- {
-
- LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL;
-
- sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location);
- }
+ bool block_navigation = false;
+ // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
+ // to deal with multiple face indices.
+ int face_index = getFaceIndexWithMediaImpl(impl, -1);
+
+ // Find the media entry for this navigate
+ LLMediaEntry* mep = NULL;
+ LLTextureEntry *te = getTE(face_index);
+ if(te)
+ {
+ mep = te->getMediaData();
+ }
+
+ if(mep)
+ {
+ if(!mep->checkCandidateUrl(new_location))
+ {
+ block_navigation = true;
+ }
+ if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT))
+ {
+ block_navigation = true;
+ }
+ }
+ else
+ {
+ LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL;
+ }
+
+ if(block_navigation)
+ {
+ LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL;
+
+ // "bounce back" to the current URL from the media entry
+ mediaNavigateBounceBack(face_index);
+ }
+ else if (sObjectMediaNavigateClient)
+ {
+
+ LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL;
+
+ sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location);
+ }
}
void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
{
- switch(event)
- {
-
- case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
- {
- switch(impl->getNavState())
- {
- case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
- {
- // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back.
- mediaNavigated(impl, plugin, plugin->getLocation());
- }
- break;
-
- case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS:
- // This navigate didn't change the current URL.
- LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL;
- break;
-
- case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
- // This is the first location changed event after the start of a server-directed nav. Don't broadcast it.
- LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL;
- break;
-
- default:
- // This is a subsequent location-changed due to a redirect. Don't broadcast.
- LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL;
- break;
- }
- }
- break;
-
- case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
- {
- switch(impl->getNavState())
- {
- case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED:
- {
- // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back.
- mediaNavigated(impl, plugin, plugin->getNavigateURI());
- }
- break;
-
- case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS:
- // This navigate didn't change the current URL.
- LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL;
- break;
-
- case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED:
- // This is the the navigate complete event from a server-directed nav. Don't broadcast it.
- LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL;
- break;
-
- default:
- // For all other states, the navigate should have been handled by LOCATION_CHANGED events already.
- break;
- }
- }
- break;
+ switch(event)
+ {
+
+ case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ switch(impl->getNavState())
+ {
+ case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
+ {
+ // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back.
+ mediaNavigated(impl, plugin, plugin->getLocation());
+ }
+ break;
+
+ case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS:
+ // This navigate didn't change the current URL.
+ LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL;
+ break;
+
+ case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
+ // This is the first location changed event after the start of a server-directed nav. Don't broadcast it.
+ LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL;
+ break;
+
+ default:
+ // This is a subsequent location-changed due to a redirect. Don't broadcast.
+ LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL;
+ break;
+ }
+ }
+ break;
+
+ case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ switch(impl->getNavState())
+ {
+ case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED:
+ {
+ // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back.
+ mediaNavigated(impl, plugin, plugin->getNavigateURI());
+ }
+ break;
+
+ case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS:
+ // This navigate didn't change the current URL.
+ LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL;
+ break;
+
+ case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED:
+ // This is the the navigate complete event from a server-directed nav. Don't broadcast it.
+ LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL;
+ break;
+
+ default:
+ // For all other states, the navigate should have been handled by LOCATION_CHANGED events already.
+ break;
+ }
+ }
+ break;
case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
{
@@ -2825,233 +2830,233 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,
LLNotificationsUtil::add("MediaFileDownloadUnsupported");
}
break;
-
- default:
- break;
- }
+
+ default:
+ break;
+ }
}
void LLVOVolume::sendMediaDataUpdate()
{
if (sObjectMediaClient)
- sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false));
+ sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false));
}
void LLVOVolume::removeMediaImpl(S32 texture_index)
{
- if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
- {
- return ;
- }
-
- //make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
- if(mDrawable && texture_index < mDrawable->getNumFaces())
- {
- LLFace* facep = mDrawable->getFace(texture_index) ;
- if(facep)
- {
- LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
- if(media_tex)
- {
- media_tex->removeMediaFromFace(facep) ;
- }
- }
- }
-
- //check if some other face(s) of this object reference(s)to this media impl.
- S32 i ;
- S32 end = (S32)mMediaImplList.size() ;
- for(i = 0; i < end ; i++)
- {
- if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
- {
- break ;
- }
- }
-
- if(i == end) //this object does not need this media impl.
- {
- mMediaImplList[texture_index]->removeObject(this) ;
- }
-
- mMediaImplList[texture_index] = NULL ;
- return ;
+ if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
+ {
+ return ;
+ }
+
+ //make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
+ if(mDrawable && texture_index < mDrawable->getNumFaces())
+ {
+ LLFace* facep = mDrawable->getFace(texture_index) ;
+ if(facep)
+ {
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+ if(media_tex)
+ {
+ media_tex->removeMediaFromFace(facep) ;
+ }
+ }
+ }
+
+ //check if some other face(s) of this object reference(s)to this media impl.
+ S32 i ;
+ S32 end = (S32)mMediaImplList.size() ;
+ for(i = 0; i < end ; i++)
+ {
+ if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
+ {
+ break ;
+ }
+ }
+
+ if(i == end) //this object does not need this media impl.
+ {
+ mMediaImplList[texture_index]->removeObject(this) ;
+ }
+
+ mMediaImplList[texture_index] = NULL ;
+ return ;
}
void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
{
- if((S32)mMediaImplList.size() < texture_index + 1)
- {
- mMediaImplList.resize(texture_index + 1) ;
- }
-
- if(mMediaImplList[texture_index].notNull())
- {
- if(mMediaImplList[texture_index] == media_impl)
- {
- return ;
- }
-
- removeMediaImpl(texture_index) ;
- }
-
- mMediaImplList[texture_index] = media_impl;
- media_impl->addObject(this) ;
-
- //add the face to show the media if it is in playing
- if(mDrawable)
- {
- LLFace* facep(NULL);
- if( texture_index < mDrawable->getNumFaces() )
- {
- facep = mDrawable->getFace(texture_index) ;
- }
-
- if(facep)
- {
- LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
- if(media_tex)
- {
- media_tex->addMediaToFace(facep) ;
- }
- }
- else //the face is not available now, start media on this face later.
- {
- media_impl->setUpdated(TRUE) ;
- }
- }
- return ;
+ if((S32)mMediaImplList.size() < texture_index + 1)
+ {
+ mMediaImplList.resize(texture_index + 1) ;
+ }
+
+ if(mMediaImplList[texture_index].notNull())
+ {
+ if(mMediaImplList[texture_index] == media_impl)
+ {
+ return ;
+ }
+
+ removeMediaImpl(texture_index) ;
+ }
+
+ mMediaImplList[texture_index] = media_impl;
+ media_impl->addObject(this) ;
+
+ //add the face to show the media if it is in playing
+ if(mDrawable)
+ {
+ LLFace* facep(NULL);
+ if( texture_index < mDrawable->getNumFaces() )
+ {
+ facep = mDrawable->getFace(texture_index) ;
+ }
+
+ if(facep)
+ {
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
+ if(media_tex)
+ {
+ media_tex->addMediaToFace(facep) ;
+ }
+ }
+ else //the face is not available now, start media on this face later.
+ {
+ media_impl->setUpdated(TRUE) ;
+ }
+ }
+ return ;
}
viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
{
- if(mMediaImplList.size() > face_id)
- {
- return mMediaImplList[face_id];
- }
- return NULL;
+ if(mMediaImplList.size() > face_id)
+ {
+ return mMediaImplList[face_id];
+ }
+ return NULL;
}
F64 LLVOVolume::getTotalMediaInterest() const
{
- // If this object is currently focused, this object has "high" interest
- if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID())
- return F64_MAX;
-
- F64 interest = (F64)-1.0; // means not interested;
-
- // If this object is selected, this object has "high" interest, but since
- // there can be more than one, we still add in calculated impl interest
- // XXX Sadly, 'contains()' doesn't take a const :(
- if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this)))
- interest = F64_MAX / 2.0;
-
- int i = 0;
- const int end = getNumTEs();
- for ( ; i < end; ++i)
- {
- const viewer_media_t &impl = getMediaImpl(i);
- if (!impl.isNull())
- {
- if (interest == (F64)-1.0) interest = (F64)0.0;
- interest += impl->getInterest();
- }
- }
- return interest;
+ // If this object is currently focused, this object has "high" interest
+ if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID())
+ return F64_MAX;
+
+ F64 interest = (F64)-1.0; // means not interested;
+
+ // If this object is selected, this object has "high" interest, but since
+ // there can be more than one, we still add in calculated impl interest
+ // XXX Sadly, 'contains()' doesn't take a const :(
+ if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this)))
+ interest = F64_MAX / 2.0;
+
+ int i = 0;
+ const int end = getNumTEs();
+ for ( ; i < end; ++i)
+ {
+ const viewer_media_t &impl = getMediaImpl(i);
+ if (!impl.isNull())
+ {
+ if (interest == (F64)-1.0) interest = (F64)0.0;
+ interest += impl->getInterest();
+ }
+ }
+ return interest;
}
S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)
{
- S32 end = (S32)mMediaImplList.size() ;
- for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
- {
- if(mMediaImplList[face_id] == media_impl)
- {
- return face_id ;
- }
- }
- return -1 ;
+ S32 end = (S32)mMediaImplList.size() ;
+ for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
+ {
+ if(mMediaImplList[face_id] == media_impl)
+ {
+ return face_id ;
+ }
+ }
+ return -1 ;
}
//----------------------------------------------------------------------------
void LLVOVolume::setLightTextureID(LLUUID id)
{
- LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary
- if (id.notNull())
- {
- if (!hasLightTexture())
- {
- setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true);
- }
- else if (old_texturep)
- {
- old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
- }
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block && param_block->getLightTexture() != id)
- {
- param_block->setLightTexture(id);
- parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
- }
- LLViewerTexture* tex = getLightTexture();
- if (tex)
- {
- tex->addVolume(LLRender::LIGHT_TEX, this); // new texture
- }
- else
- {
- LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL;
- }
- }
- else if (hasLightTexture())
- {
- if (old_texturep)
- {
- old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
- }
- setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
- parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
- mLightTexture = NULL;
- }
+ LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary
+ if (id.notNull())
+ {
+ if (!hasLightTexture())
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true);
+ }
+ else if (old_texturep)
+ {
+ old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
+ }
+ LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (param_block && param_block->getLightTexture() != id)
+ {
+ param_block->setLightTexture(id);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
+ }
+ LLViewerTexture* tex = getLightTexture();
+ if (tex)
+ {
+ tex->addVolume(LLRender::LIGHT_TEX, this); // new texture
+ }
+ else
+ {
+ LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL;
+ }
+ }
+ else if (hasLightTexture())
+ {
+ if (old_texturep)
+ {
+ old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
+ }
+ setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
+ mLightTexture = NULL;
+ }
}
void LLVOVolume::setSpotLightParams(LLVector3 params)
{
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block && param_block->getParams() != params)
- {
- param_block->setParams(params);
- parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
- }
+ LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (param_block && param_block->getParams() != params)
+ {
+ param_block->setParams(params);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
+ }
}
-
+
void LLVOVolume::setIsLight(BOOL is_light)
{
- BOOL was_light = getIsLight();
- if (is_light != was_light)
- {
- if (is_light)
- {
- setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true);
- }
- else
- {
- setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true);
- }
-
- if (is_light)
- {
- // Add it to the pipeline mLightSet
- gPipeline.setLight(mDrawable, TRUE);
- }
- else
- {
- // Not a light. Remove it from the pipeline's light set.
- gPipeline.setLight(mDrawable, FALSE);
- }
- }
+ BOOL was_light = getIsLight();
+ if (is_light != was_light)
+ {
+ if (is_light)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true);
+ }
+
+ if (is_light)
+ {
+ // Add it to the pipeline mLightSet
+ gPipeline.setLight(mDrawable, TRUE);
+ }
+ else
+ {
+ // Not a light. Remove it from the pipeline's light set.
+ gPipeline.setLight(mDrawable, FALSE);
+ }
+ }
}
void LLVOVolume::setLightSRGBColor(const LLColor3& color)
@@ -3061,69 +3066,69 @@ void LLVOVolume::setLightSRGBColor(const LLColor3& color)
void LLVOVolume::setLightLinearColor(const LLColor3& color)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- if (param_block->getLinearColor() != color)
- {
- param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3]));
- parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- }
- }
+ LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ if (param_block->getLinearColor() != color)
+ {
+ param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3]));
+ parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ }
}
void LLVOVolume::setLightIntensity(F32 intensity)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- if (param_block->getLinearColor().mV[3] != intensity)
- {
- param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity));
- parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
- }
- }
+ LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ if (param_block->getLinearColor().mV[3] != intensity)
+ {
+ param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity));
+ parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
+ }
+ }
}
void LLVOVolume::setLightRadius(F32 radius)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- if (param_block->getRadius() != radius)
- {
- param_block->setRadius(radius);
- parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
- }
- }
+ LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ if (param_block->getRadius() != radius)
+ {
+ param_block->setRadius(radius);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
+ }
+ }
}
void LLVOVolume::setLightFalloff(F32 falloff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- if (param_block->getFalloff() != falloff)
- {
- param_block->setFalloff(falloff);
- parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
- }
- }
+ LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ if (param_block->getFalloff() != falloff)
+ {
+ param_block->setFalloff(falloff);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
+ }
+ }
}
void LLVOVolume::setLightCutoff(F32 cutoff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- if (param_block->getCutoff() != cutoff)
- {
- param_block->setCutoff(cutoff);
- parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
- }
- }
+ LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ if (param_block->getCutoff() != cutoff)
+ {
+ param_block->setCutoff(cutoff);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -3146,15 +3151,15 @@ LLColor3 LLVOVolume::getLightSRGBBaseColor() const
LLColor3 LLVOVolume::getLightLinearBaseColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return LLColor3(param_block->getLinearColor());
- }
- else
- {
- return LLColor3(1,1,1);
- }
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return LLColor3(param_block->getLinearColor());
+ }
+ else
+ {
+ return LLColor3(1,1,1);
+ }
}
LLColor3 LLVOVolume::getLightLinearColor() const
@@ -3179,36 +3184,36 @@ LLColor3 LLVOVolume::getLightSRGBColor() const
LLUUID LLVOVolume::getLightTextureID() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
- {
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getLightTexture();
- }
- }
-
- return LLUUID::null;
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ {
+ const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (param_block)
+ {
+ return param_block->getLightTexture();
+ }
+ }
+
+ return LLUUID::null;
}
LLVector3 LLVOVolume::getSpotLightParams() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
- {
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getParams();
- }
- }
-
- return LLVector3();
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ {
+ const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (param_block)
+ {
+ return param_block->getParams();
+ }
+ }
+
+ return LLVector3();
}
F32 LLVOVolume::getSpotLightPriority() const
{
- return mSpotLightPriority;
+ return mSpotLightPriority;
}
void LLVOVolume::updateSpotLightPriority()
@@ -3219,104 +3224,104 @@ void LLVOVolume::updateSpotLightPriority()
}
F32 r = getLightRadius();
- LLVector3 pos = mDrawable->getPositionAgent();
+ LLVector3 pos = mDrawable->getPositionAgent();
- LLVector3 at(0,0,-1);
- at *= getRenderRotation();
- pos += at * r;
+ LLVector3 at(0,0,-1);
+ at *= getRenderRotation();
+ pos += at * r;
- at = LLViewerCamera::getInstance()->getAtAxis();
- pos -= at * r;
+ at = LLViewerCamera::getInstance()->getAtAxis();
+ pos -= at * r;
- mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance());
+ mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance());
- if (mLightTexture.notNull())
- {
- mLightTexture->addTextureStats(mSpotLightPriority);
- }
+ if (mLightTexture.notNull())
+ {
+ mLightTexture->addTextureStats(mSpotLightPriority);
+ }
}
bool LLVOVolume::isLightSpotlight() const
{
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
- {
- return params->isLightSpotlight();
- }
- return false;
+ LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ {
+ return params->isLightSpotlight();
+ }
+ return false;
}
LLViewerTexture* LLVOVolume::getLightTexture()
{
- LLUUID id = getLightTextureID();
+ LLUUID id = getLightTextureID();
- if (id.notNull())
- {
- if (mLightTexture.isNull() || id != mLightTexture->getID())
- {
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
- }
- }
- else
- {
- mLightTexture = NULL;
- }
+ if (id.notNull())
+ {
+ if (mLightTexture.isNull() || id != mLightTexture->getID())
+ {
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
+ }
+ }
+ else
+ {
+ mLightTexture = NULL;
+ }
- return mLightTexture;
+ return mLightTexture;
}
F32 LLVOVolume::getLightIntensity() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return param_block->getLinearColor().mV[3];
- }
- else
- {
- return 1.f;
- }
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return param_block->getLinearColor().mV[3];
+ }
+ else
+ {
+ return 1.f;
+ }
}
F32 LLVOVolume::getLightRadius() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return param_block->getRadius();
- }
- else
- {
- return 0.f;
- }
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return param_block->getRadius();
+ }
+ else
+ {
+ return 0.f;
+ }
}
F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return param_block->getFalloff() * fudge_factor;
- }
- else
- {
- return 0.f;
- }
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return param_block->getFalloff() * fudge_factor;
+ }
+ else
+ {
+ return 0.f;
+ }
}
F32 LLVOVolume::getLightCutoff() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return param_block->getCutoff();
- }
- else
- {
- return 0.f;
- }
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return param_block->getCutoff();
+ }
+ else
+ {
+ return 0.f;
+ }
}
BOOL LLVOVolume::isReflectionProbe() const
@@ -3408,6 +3413,29 @@ bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
return false;
}
+bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
+{
+ LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsMirror() != is_mirror)
+ {
+ LL_INFOS() << "Setting reflection probe mirror to " << is_mirror << LL_ENDL;
+ param_block->setIsMirror(is_mirror);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+
+ if (!is_mirror)
+ gPipeline.mHeroProbeManager.unregisterViewerObject(this);
+ else
+ gPipeline.mHeroProbeManager.registerViewerObject(this);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
F32 LLVOVolume::getReflectionProbeAmbiance() const
{
const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
@@ -3441,7 +3469,7 @@ bool LLVOVolume::getReflectionProbeIsBox() const
{
return param_block->getIsBox();
}
-
+
return false;
}
@@ -3456,70 +3484,82 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const
return false;
}
-U32 LLVOVolume::getVolumeInterfaceID() const
+bool LLVOVolume::getReflectionProbeIsMirror() const
{
- if (mVolumeImpl)
+ const LLReflectionProbeParams *param_block =
+ (const LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
{
- return mVolumeImpl->getID();
+ return param_block->getIsMirror();
}
- return 0;
+ return false;
+}
+
+U32 LLVOVolume::getVolumeInterfaceID() const
+{
+ if (mVolumeImpl)
+ {
+ return mVolumeImpl->getID();
+ }
+
+ return 0;
}
BOOL LLVOVolume::isFlexible() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
- {
- LLVolume* volume = getVolume();
- if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
- {
- LLVolumeParams volume_params = getVolume()->getParams();
- U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
- volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
- }
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
+ {
+ LLVolume* volume = getVolume();
+ if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
+ {
+ LLVolumeParams volume_params = getVolume()->getParams();
+ U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
+ volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
BOOL LLVOVolume::isSculpted() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
- {
- return TRUE;
- }
-
- return FALSE;
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
}
BOOL LLVOVolume::isMesh() const
{
- if (isSculpted())
- {
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- U8 sculpt_type = sculpt_params->getSculptType();
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ U8 sculpt_type = sculpt_params->getSculptType();
- if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
- // mesh is a mesh
- {
- return TRUE;
- }
- }
+ if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ // mesh is a mesh
+ {
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
BOOL LLVOVolume::hasLightTexture() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
- {
- return TRUE;
- }
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ {
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
bool LLVOVolume::isFlexibleFast() const
@@ -3549,67 +3589,67 @@ bool LLVOVolume::isAnimatedObjectFast() const
BOOL LLVOVolume::isVolumeGlobal() const
{
- if (mVolumeImpl)
- {
- return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE;
- }
- else if (mRiggedVolume.notNull())
- {
- return TRUE;
- }
+ if (mVolumeImpl)
+ {
+ return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE;
+ }
+ else if (mRiggedVolume.notNull())
+ {
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
BOOL LLVOVolume::canBeFlexible() const
{
- U8 path = getVolume()->getParams().getPathParams().getCurveType();
- return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE);
+ U8 path = getVolume()->getParams().getPathParams().getCurveType();
+ return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE);
}
BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
{
- BOOL res = FALSE;
- BOOL was_flexible = isFlexible();
- LLVolumeParams volume_params;
- if (is_flexible)
- {
- if (!was_flexible)
- {
- volume_params = getVolume()->getParams();
- U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
- volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
- res = TRUE;
- setFlags(FLAGS_USE_PHYSICS, FALSE);
- setFlags(FLAGS_PHANTOM, TRUE);
- setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true);
- if (mDrawable)
- {
- mDrawable->makeActive();
- }
- }
- }
- else
- {
- if (was_flexible)
- {
- volume_params = getVolume()->getParams();
- U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
- volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE);
- res = TRUE;
- setFlags(FLAGS_PHANTOM, FALSE);
- setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true);
- }
- }
- if (res)
- {
- res = setVolume(volume_params, 1);
- if (res)
- {
- markForUpdate();
- }
- }
- return res;
+ BOOL res = FALSE;
+ BOOL was_flexible = isFlexible();
+ LLVolumeParams volume_params;
+ if (is_flexible)
+ {
+ if (!was_flexible)
+ {
+ volume_params = getVolume()->getParams();
+ U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
+ volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
+ res = TRUE;
+ setFlags(FLAGS_USE_PHYSICS, FALSE);
+ setFlags(FLAGS_PHANTOM, TRUE);
+ setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true);
+ if (mDrawable)
+ {
+ mDrawable->makeActive();
+ }
+ }
+ }
+ else
+ {
+ if (was_flexible)
+ {
+ volume_params = getVolume()->getParams();
+ U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
+ volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE);
+ res = TRUE;
+ setFlags(FLAGS_PHANTOM, FALSE);
+ setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true);
+ }
+ }
+ if (res)
+ {
+ res = setVolume(volume_params, 1);
+ if (res)
+ {
+ markForUpdate();
+ }
+ }
+ return res;
}
const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
@@ -3633,16 +3673,16 @@ BOOL LLVOVolume::isRiggedMesh() const
//----------------------------------------------------------------------------
U32 LLVOVolume::getExtendedMeshFlags() const
{
- const LLExtendedMeshParams *param_block =
+ const LLExtendedMeshParams *param_block =
(const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
- if (param_block)
- {
- return param_block->getFlags();
- }
- else
- {
- return 0;
- }
+ if (param_block)
+ {
+ return param_block->getFlags();
+ }
+ else
+ {
+ return 0;
+ }
}
void LLVOVolume::onSetExtendedMeshFlags(U32 flags)
@@ -3651,7 +3691,7 @@ void LLVOVolume::onSetExtendedMeshFlags(U32 flags)
// The isAnySelected() check was needed at one point to prevent
// graphics problems. These are now believed to be fixed so the
// check has been disabled.
- if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull())
+ if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull())
{
// Need to trigger rebuildGeom(), which is where control avatars get created/removed
getRootEdit()->recursiveMarkForUpdate();
@@ -3679,7 +3719,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags)
{
bool in_use = true;
setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true);
- LLExtendedMeshParams *param_block =
+ LLExtendedMeshParams *param_block =
(LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
if (param_block)
{
@@ -3749,13 +3789,13 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare
void LLVOVolume::afterReparent()
{
{
- LL_DEBUGS("AnimatedObjects") << "new child added for parent "
+ LL_DEBUGS("AnimatedObjects") << "new child added for parent "
<< ((LLViewerObject*)getParent())->getID() << LL_ENDL;
}
-
+
if (isAnimatedObject() && getControlAvatar())
{
- LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object "
+ LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object "
<< ((LLViewerObject*)getParent())->getID() << LL_ENDL;
// MAINT-8239 - doing a full rebuild whenever parent is set
@@ -3763,15 +3803,15 @@ void LLVOVolume::afterReparent()
// addAttachmentOverrides should be sufficient, but in
// practice doing a full rebuild helps compensate for
// notifyMeshLoaded() not being called reliably enough.
-
+
// was: getControlAvatar()->addAttachmentOverridesForObject(this);
//getControlAvatar()->rebuildAttachmentOverrides();
getControlAvatar()->updateAnimations();
}
else
{
- LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: "
- << ((LLViewerObject*)getParent())->getID()
+ LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: "
+ << ((LLViewerObject*)getParent())->getID()
<< " isAnimated: " << isAnimatedObject() << " cav "
<< getControlAvatar() << LL_ENDL;
}
@@ -3804,8 +3844,8 @@ void LLVOVolume::updateRiggingInfo()
}
// Keep the highest LOD info available.
mLastRiggingInfoLOD = getLOD();
- LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume "
- << this << " lod " << mLastRiggingInfoLOD
+ LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume "
+ << this << " lod " << mLastRiggingInfoLOD
<< LL_ENDL;
}
}
@@ -3816,86 +3856,86 @@ void LLVOVolume::updateRiggingInfo()
void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
{
- LLVolume *volume = getVolume();
-
- if (volume)
- {
- LLVector3 view_vector;
- view_vector = view_point;
-
- //transform view vector into volume space
- view_vector -= getRenderPosition();
- //mDrawable->mDistanceWRTCamera = view_vector.length();
- LLQuaternion worldRot = getRenderRotation();
- view_vector = view_vector * ~worldRot;
- if (!isVolumeGlobal())
- {
- LLVector3 objScale = getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- view_vector.scaleVec(invObjScale);
- }
-
- updateRelativeXform();
- LLMatrix4 trans_mat = mRelativeXform;
- if (mDrawable->isStatic())
- {
- trans_mat.translate(getRegion()->getOriginAgent());
- }
-
- volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask());
-
- nodep->mSilhouetteExists = TRUE;
- }
+ LLVolume *volume = getVolume();
+
+ if (volume)
+ {
+ LLVector3 view_vector;
+ view_vector = view_point;
+
+ //transform view vector into volume space
+ view_vector -= getRenderPosition();
+ //mDrawable->mDistanceWRTCamera = view_vector.length();
+ LLQuaternion worldRot = getRenderRotation();
+ view_vector = view_vector * ~worldRot;
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ view_vector.scaleVec(invObjScale);
+ }
+
+ updateRelativeXform();
+ LLMatrix4 trans_mat = mRelativeXform;
+ if (mDrawable->isStatic())
+ {
+ trans_mat.translate(getRegion()->getOriginAgent());
+ }
+
+ volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask());
+
+ nodep->mSilhouetteExists = TRUE;
+ }
}
void LLVOVolume::deleteFaces()
{
- S32 face_count = mNumFaces;
- if (mDrawable.notNull())
- {
- mDrawable->deleteFaces(0, face_count);
- }
+ S32 face_count = mNumFaces;
+ if (mDrawable.notNull())
+ {
+ mDrawable->deleteFaces(0, face_count);
+ }
- mNumFaces = 0;
+ mNumFaces = 0;
}
void LLVOVolume::updateRadius()
{
- if (mDrawable.isNull())
- {
- return;
- }
-
- mVObjRadius = getScale().length();
- mDrawable->setRadius(mVObjRadius);
+ if (mDrawable.isNull())
+ {
+ return;
+ }
+
+ mVObjRadius = getScale().length();
+ mDrawable->setRadius(mVObjRadius);
}
BOOL LLVOVolume::isAttachment() const
{
- return mAttachmentState != 0 ;
+ return mAttachmentState != 0 ;
}
BOOL LLVOVolume::isHUDAttachment() const
{
- // *NOTE: we assume hud attachment points are in defined range
- // since this range is constant for backwards compatibility
- // reasons this is probably a reasonable assumption to make
- S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState);
- return ( attachment_id >= 31 && attachment_id <= 38 );
+ // *NOTE: we assume hud attachment points are in defined range
+ // since this range is constant for backwards compatibility
+ // reasons this is probably a reasonable assumption to make
+ S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState);
+ return ( attachment_id >= 31 && attachment_id <= 38 );
}
const LLMatrix4 LLVOVolume::getRenderMatrix() const
{
- if (mDrawable->isActive() && !mDrawable->isRoot())
- {
- return mDrawable->getParent()->getWorldMatrix();
- }
- return mDrawable->getWorldMatrix();
+ if (mDrawable->isActive() && !mDrawable->isRoot())
+ {
+ return mDrawable->getParent()->getWorldMatrix();
+ }
+ return mDrawable->getWorldMatrix();
}
-//static
+//static
S32 LLVOVolume::getTextureCost(const LLViewerTexture* img)
{
static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
@@ -3937,57 +3977,57 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
* the official viewer for consideration.
*****************************************************************/
- // Get access to params we'll need at various points.
- // Skip if this is object doesn't have a volume (e.g. is an avatar).
+ // Get access to params we'll need at various points.
+ // Skip if this is object doesn't have a volume (e.g. is an avatar).
if (getVolume() == NULL)
{
return 0;
}
- U32 num_triangles = 0;
+ U32 num_triangles = 0;
- // per-prim costs
- static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
- static const U32 ARC_PARTICLE_MAX = 2048; // default values
- static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
- static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
+ // per-prim costs
+ static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
+ static const U32 ARC_PARTICLE_MAX = 2048; // default values
+ static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
+ static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
- // per-prim multipliers
- static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance
- static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance
- static const F32 ARC_FLEXI_MULT = 5; // tested based on performance
- static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance
- static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance
- static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance
+ // per-prim multipliers
+ static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance
+ static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance
+ static const F32 ARC_FLEXI_MULT = 5; // tested based on performance
+ static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance
+ static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance
+ static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance
- static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact
- static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance
- static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance
+ static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact
+ static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance
+ static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance
- F32 shame = 0;
+ F32 shame = 0;
- U32 invisi = 0;
- U32 shiny = 0;
- U32 glow = 0;
- U32 alpha = 0;
- U32 flexi = 0;
- U32 animtex = 0;
- U32 particles = 0;
- U32 bump = 0;
- U32 planar = 0;
- U32 weighted_mesh = 0;
- U32 produces_light = 0;
- U32 media_faces = 0;
+ U32 invisi = 0;
+ U32 shiny = 0;
+ U32 glow = 0;
+ U32 alpha = 0;
+ U32 flexi = 0;
+ U32 animtex = 0;
+ U32 particles = 0;
+ U32 bump = 0;
+ U32 planar = 0;
+ U32 weighted_mesh = 0;
+ U32 produces_light = 0;
+ U32 media_faces = 0;
- const LLDrawable* drawablep = mDrawable;
- U32 num_faces = drawablep->getNumFaces();
+ const LLDrawable* drawablep = mDrawable;
+ U32 num_faces = drawablep->getNumFaces();
- const LLVolumeParams& volume_params = getVolume()->getParams();
+ const LLVolumeParams& volume_params = getVolume()->getParams();
LLMeshCostData costs;
- if (getCostData(costs))
- {
+ if (getCostData(costs))
+ {
if (isAnimatedObjectFast() && isRiggedMeshFast())
{
// Scaling here is to make animated object vs
@@ -4000,58 +4040,58 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
F32 radius = getScale().length()*0.5f;
num_triangles = costs.getRadiusWeightedTris(radius);
}
- }
-
-
- if (num_triangles <= 0)
- {
- num_triangles = 4;
- }
-
- if (isSculptedFast())
- {
- if (isMeshFast())
- {
- // base cost is dependent on mesh complexity
- // note that 3 is the highest LOD as of the time of this coding.
- S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());
- if ( size > 0)
- {
- if (isRiggedMeshFast())
- {
- // weighted attachment - 1 point for every 3 bytes
- weighted_mesh = 1;
- }
- }
- else
- {
- // something went wrong - user should know their content isn't render-free
- return 0;
- }
- }
- else
- {
+ }
+
+
+ if (num_triangles <= 0)
+ {
+ num_triangles = 4;
+ }
+
+ if (isSculptedFast())
+ {
+ if (isMeshFast())
+ {
+ // base cost is dependent on mesh complexity
+ // note that 3 is the highest LOD as of the time of this coding.
+ S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());
+ if ( size > 0)
+ {
+ if (isRiggedMeshFast())
+ {
+ // weighted attachment - 1 point for every 3 bytes
+ weighted_mesh = 1;
+ }
+ }
+ else
+ {
+ // something went wrong - user should know their content isn't render-free
+ return 0;
+ }
+ }
+ else
+ {
LLViewerFetchedTexture* texture = mSculptTexture;
- if (texture && textures.find(texture) == textures.end())
- {
+ if (texture && textures.find(texture) == textures.end())
+ {
textures.insert(texture);
- }
- }
- }
+ }
+ }
+ }
- if (isFlexibleFast())
- {
- flexi = 1;
- }
- if (isParticleSource())
- {
- particles = 1;
- }
+ if (isFlexibleFast())
+ {
+ flexi = 1;
+ }
+ if (isParticleSource())
+ {
+ particles = 1;
+ }
- if (getIsLightFast())
- {
- produces_light = 1;
- }
+ if (getIsLightFast())
+ {
+ produces_light = 1;
+ }
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list");
@@ -4109,79 +4149,79 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
}
- // shame currently has the "base" cost of 1 point per 15 triangles, min 2.
- shame = num_triangles * 5.f;
- shame = shame < 2.f ? 2.f : shame;
-
- // multiply by per-face modifiers
- if (planar)
- {
- shame *= planar * ARC_PLANAR_COST;
- }
-
- if (animtex)
- {
- shame *= animtex * ARC_ANIM_TEX_COST;
- }
-
- if (alpha)
- {
- shame *= alpha * ARC_ALPHA_COST;
- }
-
- if(invisi)
- {
- shame *= invisi * ARC_INVISI_COST;
- }
-
- if (glow)
- {
- shame *= glow * ARC_GLOW_MULT;
- }
-
- if (bump)
- {
- shame *= bump * ARC_BUMP_MULT;
- }
-
- if (shiny)
- {
- shame *= shiny * ARC_SHINY_MULT;
- }
-
-
- // multiply shame by multipliers
- if (weighted_mesh)
- {
- shame *= weighted_mesh * ARC_WEIGHTED_MESH;
- }
-
- if (flexi)
- {
- shame *= flexi * ARC_FLEXI_MULT;
- }
-
-
- // add additional costs
- if (particles)
- {
- const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData);
- const LLPartData *part_data = &(part_sys_data->mPartData);
- U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate));
- num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles;
- F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f;
- shame += num_particles * part_size * ARC_PARTICLE_COST;
- }
-
- if (produces_light)
- {
- shame += ARC_LIGHT_COST;
- }
-
- if (media_faces)
- {
- shame += media_faces * ARC_MEDIA_FACE_COST;
- }
+ // shame currently has the "base" cost of 1 point per 15 triangles, min 2.
+ shame = num_triangles * 5.f;
+ shame = shame < 2.f ? 2.f : shame;
+
+ // multiply by per-face modifiers
+ if (planar)
+ {
+ shame *= planar * ARC_PLANAR_COST;
+ }
+
+ if (animtex)
+ {
+ shame *= animtex * ARC_ANIM_TEX_COST;
+ }
+
+ if (alpha)
+ {
+ shame *= alpha * ARC_ALPHA_COST;
+ }
+
+ if(invisi)
+ {
+ shame *= invisi * ARC_INVISI_COST;
+ }
+
+ if (glow)
+ {
+ shame *= glow * ARC_GLOW_MULT;
+ }
+
+ if (bump)
+ {
+ shame *= bump * ARC_BUMP_MULT;
+ }
+
+ if (shiny)
+ {
+ shame *= shiny * ARC_SHINY_MULT;
+ }
+
+
+ // multiply shame by multipliers
+ if (weighted_mesh)
+ {
+ shame *= weighted_mesh * ARC_WEIGHTED_MESH;
+ }
+
+ if (flexi)
+ {
+ shame *= flexi * ARC_FLEXI_MULT;
+ }
+
+
+ // add additional costs
+ if (particles)
+ {
+ const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData);
+ const LLPartData *part_data = &(part_sys_data->mPartData);
+ U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate));
+ num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles;
+ F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f;
+ shame += num_particles * part_size * ARC_PARTICLE_COST;
+ }
+
+ if (produces_light)
+ {
+ shame += ARC_LIGHT_COST;
+ }
+
+ if (media_faces)
+ {
+ shame += media_faces * ARC_MEDIA_FACE_COST;
+ }
// Streaming cost for animated objects includes a fixed cost
// per linkset. Add a corresponding charge here translated into
@@ -4191,35 +4231,35 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f;
}
- if (shame > mRenderComplexity_current)
- {
- mRenderComplexity_current = (S32)shame;
- }
+ if (shame > mRenderComplexity_current)
+ {
+ mRenderComplexity_current = (S32)shame;
+ }
- return (U32)shame;
+ return (U32)shame;
}
F32 LLVOVolume::getEstTrianglesMax() const
{
- if (isMeshFast() && getVolume())
- {
- return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());
- }
+ if (isMeshFast() && getVolume())
+ {
+ return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());
+ }
return 0.f;
}
F32 LLVOVolume::getEstTrianglesStreamingCost() const
{
- if (isMeshFast() && getVolume())
- {
- return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());
- }
+ if (isMeshFast() && getVolume())
+ {
+ return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());
+ }
return 0.f;
}
F32 LLVOVolume::getStreamingCost() const
{
- F32 radius = getScale().length()*0.5f;
+ F32 radius = getScale().length()*0.5f;
F32 linkset_base_cost = 0.f;
LLMeshCostData costs;
@@ -4263,87 +4303,87 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const
}
else
{
- LLVolume* volume = getVolume();
- S32 counts[4];
- LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
+ LLVolume* volume = getVolume();
+ S32 counts[4];
+ LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
LLMeshHeader header;
- header.mLodSize[0] = counts[0] * 10;
- header.mLodSize[1] = counts[1] * 10;
- header.mLodSize[2] = counts[2] * 10;
- header.mLodSize[3] = counts[3] * 10;
+ header.mLodSize[0] = counts[0] * 10;
+ header.mLodSize[1] = counts[1] * 10;
+ header.mLodSize[2] = counts[2] * 10;
+ header.mLodSize[3] = counts[3] * 10;
- return gMeshRepo.getCostData(header, costs);
+ return gMeshRepo.getCostData(header, costs);
}
}
-//static
+//static
void LLVOVolume::updateRenderComplexity()
{
- mRenderComplexity_last = mRenderComplexity_current;
- mRenderComplexity_current = 0;
+ mRenderComplexity_last = mRenderComplexity_current;
+ mRenderComplexity_current = 0;
}
U32 LLVOVolume::getTriangleCount(S32* vcount) const
{
- U32 count = 0;
- LLVolume* volume = getVolume();
- if (volume)
- {
- count = volume->getNumTriangles(vcount);
- }
+ U32 count = 0;
+ LLVolume* volume = getVolume();
+ if (volume)
+ {
+ count = volume->getNumTriangles(vcount);
+ }
- return count;
+ return count;
}
U32 LLVOVolume::getHighLODTriangleCount()
{
- U32 ret = 0;
-
- LLVolume* volume = getVolume();
-
- if (!isSculpted())
- {
- LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
- ret = ref->getNumTriangles();
- LLPrimitive::getVolumeManager()->unrefVolume(ref);
- }
- else if (isMesh())
- {
- LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
- if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
- {
- gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
- }
- ret = ref->getNumTriangles();
- LLPrimitive::getVolumeManager()->unrefVolume(ref);
- }
- else
- { //default sculpts have a constant number of triangles
- ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch
- }
-
- return ret;
+ U32 ret = 0;
+
+ LLVolume* volume = getVolume();
+
+ if (!isSculpted())
+ {
+ LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
+ ret = ref->getNumTriangles();
+ LLPrimitive::getVolumeManager()->unrefVolume(ref);
+ }
+ else if (isMesh())
+ {
+ LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
+ if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
+ {
+ gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
+ }
+ ret = ref->getNumTriangles();
+ LLPrimitive::getVolumeManager()->unrefVolume(ref);
+ }
+ else
+ { //default sculpts have a constant number of triangles
+ ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch
+ }
+
+ return ret;
}
//static
void LLVOVolume::preUpdateGeom()
{
- sNumLODChanges = 0;
+ sNumLODChanges = 0;
}
void LLVOVolume::parameterChanged(U16 param_type, bool local_origin)
{
- LLViewerObject::parameterChanged(param_type, local_origin);
+ LLViewerObject::parameterChanged(param_type, local_origin);
}
void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
{
- LLViewerObject::parameterChanged(param_type, data, in_use, local_origin);
- if (mVolumeImpl)
- {
- mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin);
- }
+ LLViewerObject::parameterChanged(param_type, data, in_use, local_origin);
+ if (mVolumeImpl)
+ {
+ mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin);
+ }
if (!local_origin && param_type == LLNetworkData::PARAMS_EXTENDED_MESH)
{
U32 extended_mesh_flags = getExtendedMeshFlags();
@@ -4359,15 +4399,15 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
onSetExtendedMeshFlags(extended_mesh_flags);
}
}
- if (mDrawable.notNull())
- {
- BOOL is_light = getIsLight();
- if (is_light != mDrawable->isState(LLDrawable::LIGHT))
- {
- gPipeline.setLight(mDrawable, is_light);
- }
- }
-
+ if (mDrawable.notNull())
+ {
+ BOOL is_light = getIsLight();
+ if (is_light != mDrawable->isState(LLDrawable::LIGHT))
+ {
+ gPipeline.setLight(mDrawable, is_light);
+ }
+ }
+
updateReflectionProbePtr();
}
@@ -4375,20 +4415,36 @@ void LLVOVolume::updateReflectionProbePtr()
{
if (isReflectionProbe())
{
- if (mReflectionProbe.isNull())
+ if (mReflectionProbe.isNull() && !getReflectionProbeIsMirror())
{
mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
}
+ else if (mReflectionProbe.isNull() && getReflectionProbeIsMirror())
+ {
+ // Geenz: This is a special case - what we want here is a hero probe.
+ // What we want to do here is instantiate a hero probe from the hero probe manager.
+
+ if (!mIsHeroProbe)
+ mIsHeroProbe = gPipeline.mHeroProbeManager.registerViewerObject(this);
+ }
}
- else if (mReflectionProbe.notNull())
+ else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror())
{
- mReflectionProbe = nullptr;
+ if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe = nullptr;
+ }
+
+ if (getReflectionProbeIsMirror())
+ {
+ gPipeline.mHeroProbeManager.unregisterViewerObject(this);
+ }
}
}
void LLVOVolume::setSelected(BOOL sel)
{
- LLViewerObject::setSelected(sel);
+ LLViewerObject::setSelected(sel);
if (isAnimatedObject())
{
getRootEdit()->recursiveMarkForUpdate();
@@ -4403,7 +4459,7 @@ void LLVOVolume::setSelected(BOOL sel)
}
void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
-{
+{
}
F32 LLVOVolume::getBinRadius()
@@ -4468,104 +4524,104 @@ F32 LLVOVolume::getBinRadius()
const LLVector3 LLVOVolume::getPivotPositionAgent() const
{
- if (mVolumeImpl)
- {
- return mVolumeImpl->getPivotPosition();
- }
- return LLViewerObject::getPivotPositionAgent();
+ if (mVolumeImpl)
+ {
+ return mVolumeImpl->getPivotPosition();
+ }
+ return LLViewerObject::getPivotPositionAgent();
}
void LLVOVolume::onShift(const LLVector4a &shift_vector)
{
- if (mVolumeImpl)
- {
- mVolumeImpl->onShift(shift_vector);
- }
+ if (mVolumeImpl)
+ {
+ mVolumeImpl->onShift(shift_vector);
+ }
- updateRelativeXform();
+ updateRelativeXform();
}
const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const
{
- if (mVolumeImpl)
- {
- return mVolumeImpl->getWorldMatrix(xform);
- }
- return xform->getWorldMatrix();
+ if (mVolumeImpl)
+ {
+ return mVolumeImpl->getWorldMatrix(xform);
+ }
+ return xform->getWorldMatrix();
}
void LLVOVolume::markForUpdate()
-{
+{
if (mDrawable)
{
shrinkWrap();
}
- LLViewerObject::markForUpdate();
- mVolumeChanged = TRUE;
+ LLViewerObject::markForUpdate();
+ mVolumeChanged = TRUE;
}
LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
{
- LLVector3 ret = pos - getRenderPosition();
- ret = ret * ~getRenderRotation();
- if (!isVolumeGlobal())
- {
- LLVector3 objScale = getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- ret.scaleVec(invObjScale);
- }
-
- return ret;
+ LLVector3 ret = pos - getRenderPosition();
+ ret = ret * ~getRenderRotation();
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ ret.scaleVec(invObjScale);
+ }
+
+ return ret;
}
LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
{
- LLVector3 ret = dir * ~getRenderRotation();
-
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- ret.scaleVec(objScale);
+ LLVector3 ret = dir * ~getRenderRotation();
+
+ LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
+ ret.scaleVec(objScale);
- return ret;
+ return ret;
}
LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
{
- LLVector3 ret = dir;
- if (!isVolumeGlobal())
- {
- LLVector3 objScale = getScale();
- ret.scaleVec(objScale);
- }
+ LLVector3 ret = dir;
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ ret.scaleVec(objScale);
+ }
- ret = ret * getRenderRotation();
- ret += getRenderPosition();
-
- return ret;
+ ret = ret * getRenderRotation();
+ ret += getRenderPosition();
+
+ return ret;
}
LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
{
- LLVector3 ret = dir;
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- ret.scaleVec(invObjScale);
- ret = ret * getRenderRotation();
+ LLVector3 ret = dir;
+ LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ ret.scaleVec(invObjScale);
+ ret = ret * getRenderRotation();
- return ret;
+ return ret;
}
BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
- LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
-
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
+
{
- if (!mbCanSelect
- || mDrawable->isDead()
- || !gPipeline.hasRenderType(mDrawable->getRenderType()))
- {
- return FALSE;
- }
+ if (!mbCanSelect
+ || mDrawable->isDead()
+ || !gPipeline.hasRenderType(mDrawable->getRenderType()))
+ {
+ return FALSE;
+ }
if (!pick_unselectable)
{
@@ -4580,203 +4636,203 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
return FALSE;
}
- BOOL ret = FALSE;
+ BOOL ret = FALSE;
- LLVolume* volume = getVolume();
+ LLVolume* volume = getVolume();
- bool transform = true;
+ bool transform = true;
- if (mDrawable->isState(LLDrawable::RIGGED))
- {
- if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
- {
+ if (mDrawable->isState(LLDrawable::RIGGED))
+ {
+ if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
+ {
updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
- volume = mRiggedVolume;
- transform = false;
- }
- else
- { //cannot pick rigged attachments on other avatars or when not in build mode
- return FALSE;
- }
- }
-
- if (volume)
- {
- LLVector4a local_start = start;
- LLVector4a local_end = end;
-
- if (transform)
- {
- LLVector3 v_start(start.getF32ptr());
- LLVector3 v_end(end.getF32ptr());
-
- v_start = agentPositionToVolume(v_start);
- v_end = agentPositionToVolume(v_end);
-
- local_start.load3(v_start.mV);
- local_end.load3(v_end.mV);
- }
-
- LLVector4a p;
- LLVector4a n;
- LLVector2 tc;
- LLVector4a tn;
-
- if (intersection != NULL)
- {
- p = *intersection;
- }
-
- if (tex_coord != NULL)
- {
- tc = *tex_coord;
- }
-
- if (normal != NULL)
- {
- n = *normal;
- }
-
- if (tangent != NULL)
- {
- tn = *tangent;
- }
-
- S32 face_hit = -1;
-
- S32 start_face, end_face;
- if (face == -1)
- {
- start_face = 0;
- end_face = volume->getNumVolumeFaces();
- }
- else
- {
- start_face = face;
- end_face = face+1;
- }
- pick_transparent |= isHiglightedOrBeacon();
+ volume = mRiggedVolume;
+ transform = false;
+ }
+ else
+ { //cannot pick rigged attachments on other avatars or when not in build mode
+ return FALSE;
+ }
+ }
+
+ if (volume)
+ {
+ LLVector4a local_start = start;
+ LLVector4a local_end = end;
+
+ if (transform)
+ {
+ LLVector3 v_start(start.getF32ptr());
+ LLVector3 v_end(end.getF32ptr());
+
+ v_start = agentPositionToVolume(v_start);
+ v_end = agentPositionToVolume(v_end);
+
+ local_start.load3(v_start.mV);
+ local_end.load3(v_end.mV);
+ }
+
+ LLVector4a p;
+ LLVector4a n;
+ LLVector2 tc;
+ LLVector4a tn;
+
+ if (intersection != NULL)
+ {
+ p = *intersection;
+ }
+
+ if (tex_coord != NULL)
+ {
+ tc = *tex_coord;
+ }
+
+ if (normal != NULL)
+ {
+ n = *normal;
+ }
+
+ if (tangent != NULL)
+ {
+ tn = *tangent;
+ }
+
+ S32 face_hit = -1;
+
+ S32 start_face, end_face;
+ if (face == -1)
+ {
+ start_face = 0;
+ end_face = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ start_face = face;
+ end_face = face+1;
+ }
+ pick_transparent |= isHiglightedOrBeacon();
// we *probably* shouldn't care about special cursor at all, but we *definitely*
// don't care about special cursor for reflection probes -- makes alt-zoom
// go through reflection probes on vehicles
- bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor();
+ bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor();
- for (S32 i = start_face; i < end_face; ++i)
- {
- if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f)
- { //don't attempt to pick completely transparent faces unless
- //pick_transparent is true
- continue;
- }
+ for (S32 i = start_face; i < end_face; ++i)
+ {
+ if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f)
+ { //don't attempt to pick completely transparent faces unless
+ //pick_transparent is true
+ continue;
+ }
// This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree.
// rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking.
updateRiggedVolume(true, i, false);
- face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
- &p, &tc, &n, &tn);
-
- if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
- {
- LLFace* face = mDrawable->getFace(face_hit);
-
- bool ignore_alpha = false;
-
- const LLTextureEntry* te = face->getTextureEntry();
- if (te)
- {
- LLMaterial* mat = te->getMaterialParams();
- if (mat)
- {
- U8 mode = mat->getDiffuseAlphaMode();
-
- if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
- || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
- || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0))
- {
- ignore_alpha = true;
- }
- }
- }
+ face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
+ &p, &tc, &n, &tn);
+
+ if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
+ {
+ LLFace* face = mDrawable->getFace(face_hit);
+
+ bool ignore_alpha = false;
+
+ const LLTextureEntry* te = face->getTextureEntry();
+ if (te)
+ {
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
+ || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+ || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0))
+ {
+ ignore_alpha = true;
+ }
+ }
+ }
BOOL no_texture = !face->getTexture() || !face->getTexture()->hasGLTexture();
BOOL mask = no_texture ? FALSE : face->getTexture()->getMask(face->surfaceToTexture(tc, p, n));
- if (face &&
- (ignore_alpha || pick_transparent || no_texture || mask))
- {
- local_end = p;
- if (face_hitp != NULL)
- {
- *face_hitp = face_hit;
- }
-
- if (intersection != NULL)
- {
- if (transform)
- {
- LLVector3 v_p(p.getF32ptr());
-
- intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space
- }
- else
- {
- *intersection = p;
- }
- }
-
- if (normal != NULL)
- {
- if (transform)
- {
- LLVector3 v_n(n.getF32ptr());
- normal->load3(volumeDirectionToAgent(v_n).mV);
- }
- else
- {
- *normal = n;
- }
- (*normal).normalize3fast();
- }
-
- if (tangent != NULL)
- {
- if (transform)
- {
- LLVector3 v_tn(tn.getF32ptr());
-
- LLVector4a trans_tangent;
- trans_tangent.load3(volumeDirectionToAgent(v_tn).mV);
-
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<3>();
-
- tangent->setSelectWithMask(mask, tn, trans_tangent);
- }
- else
- {
- *tangent = tn;
- }
- (*tangent).normalize3fast();
- }
-
- if (tex_coord != NULL)
- {
- *tex_coord = tc;
- }
-
- ret = TRUE;
- }
- }
- }
- }
-
- return ret;
+ if (face &&
+ (ignore_alpha || pick_transparent || no_texture || mask))
+ {
+ local_end = p;
+ if (face_hitp != NULL)
+ {
+ *face_hitp = face_hit;
+ }
+
+ if (intersection != NULL)
+ {
+ if (transform)
+ {
+ LLVector3 v_p(p.getF32ptr());
+
+ intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space
+ }
+ else
+ {
+ *intersection = p;
+ }
+ }
+
+ if (normal != NULL)
+ {
+ if (transform)
+ {
+ LLVector3 v_n(n.getF32ptr());
+ normal->load3(volumeDirectionToAgent(v_n).mV);
+ }
+ else
+ {
+ *normal = n;
+ }
+ (*normal).normalize3fast();
+ }
+
+ if (tangent != NULL)
+ {
+ if (transform)
+ {
+ LLVector3 v_tn(tn.getF32ptr());
+
+ LLVector4a trans_tangent;
+ trans_tangent.load3(volumeDirectionToAgent(v_tn).mV);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ tangent->setSelectWithMask(mask, tn, trans_tangent);
+ }
+ else
+ {
+ *tangent = tn;
+ }
+ (*tangent).normalize3fast();
+ }
+
+ if (tex_coord != NULL)
+ {
+ *tex_coord = tc;
+ }
+
+ ret = TRUE;
+ }
+ }
+ }
+ }
+
+ return ret;
}
bool LLVOVolume::treatAsRigged()
{
- return isSelected() &&
+ return isSelected() &&
(isAttachment() || isAnimatedObject()) &&
mDrawable.notNull() &&
mDrawable->isState(LLDrawable::RIGGED);
@@ -4784,52 +4840,52 @@ bool LLVOVolume::treatAsRigged()
LLRiggedVolume* LLVOVolume::getRiggedVolume()
{
- return mRiggedVolume;
+ return mRiggedVolume;
}
void LLVOVolume::clearRiggedVolume()
{
- if (mRiggedVolume.notNull())
- {
- mRiggedVolume = NULL;
- updateRelativeXform();
- }
+ if (mRiggedVolume.notNull())
+ {
+ mRiggedVolume = NULL;
+ updateRelativeXform();
+ }
}
void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- //Update mRiggedVolume to match current animation frame of avatar.
- //Also update position/size in octree.
+ //Update mRiggedVolume to match current animation frame of avatar.
+ //Also update position/size in octree.
if ((!force_treat_as_rigged) && (!treatAsRigged()))
- {
- clearRiggedVolume();
-
- return;
- }
-
- LLVolume* volume = getVolume();
- const LLMeshSkinInfo* skin = getSkinInfo();
- if (!skin)
- {
- clearRiggedVolume();
- return;
- }
-
- LLVOAvatar* avatar = getAvatar();
- if (!avatar)
- {
- clearRiggedVolume();
- return;
- }
-
- if (!mRiggedVolume)
- {
- LLVolumeParams p;
- mRiggedVolume = new LLRiggedVolume(p);
- updateRelativeXform();
- }
+ {
+ clearRiggedVolume();
+
+ return;
+ }
+
+ LLVolume* volume = getVolume();
+ const LLMeshSkinInfo* skin = getSkinInfo();
+ if (!skin)
+ {
+ clearRiggedVolume();
+ return;
+ }
+
+ LLVOAvatar* avatar = getAvatar();
+ if (!avatar)
+ {
+ clearRiggedVolume();
+ return;
+ }
+
+ if (!mRiggedVolume)
+ {
+ LLVolumeParams p;
+ mRiggedVolume = new LLRiggedVolume(p);
+ updateRelativeXform();
+ }
mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
@@ -4842,47 +4898,47 @@ void LLRiggedVolume::update(
bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- bool copy = false;
- if (volume->getNumVolumeFaces() != getNumVolumeFaces())
- {
- copy = true;
- }
-
- for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i)
- {
- const LLVolumeFace& src_face = volume->getVolumeFace(i);
- const LLVolumeFace& dst_face = getVolumeFace(i);
-
- if (src_face.mNumIndices != dst_face.mNumIndices ||
- src_face.mNumVertices != dst_face.mNumVertices)
- {
- copy = true;
- }
- }
-
- if (copy)
- {
- copyVolumeFaces(volume);
- }
+ bool copy = false;
+ if (volume->getNumVolumeFaces() != getNumVolumeFaces())
+ {
+ copy = true;
+ }
+
+ for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i)
+ {
+ const LLVolumeFace& src_face = volume->getVolumeFace(i);
+ const LLVolumeFace& dst_face = getVolumeFace(i);
+
+ if (src_face.mNumIndices != dst_face.mNumIndices ||
+ src_face.mNumVertices != dst_face.mNumVertices)
+ {
+ copy = true;
+ }
+ }
+
+ if (copy)
+ {
+ copyVolumeFaces(volume);
+ }
else
{
bool is_paused = avatar && avatar->areAnimationsPaused();
- if (is_paused)
- {
+ if (is_paused)
+ {
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
if (frames_paused > 1)
{
return;
}
- }
+ }
}
- //build matrix palette
- static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT;
+ //build matrix palette
+ static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT;
- LLMatrix4a mat[kMaxJoints];
- U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
+ LLMatrix4a mat[kMaxJoints];
+ U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar);
const LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix;
@@ -4907,21 +4963,21 @@ void LLRiggedVolume::update(
face_end = face_begin + 1;
}
for (S32 i = face_begin; i < face_end; ++i)
- {
- const LLVolumeFace& vol_face = volume->getVolumeFace(i);
-
- LLVolumeFace& dst_face = mVolumeFaces[i];
-
- LLVector4a* weight = vol_face.mWeights;
-
- if ( weight )
- {
+ {
+ const LLVolumeFace& vol_face = volume->getVolumeFace(i);
+
+ LLVolumeFace& dst_face = mVolumeFaces[i];
+
+ LLVector4a* weight = vol_face.mWeights;
+
+ if ( weight )
+ {
LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin);
- LLVector4a* pos = dst_face.mPositions;
+ LLVector4a* pos = dst_face.mPositions;
- if (pos && dst_face.mExtents)
- {
+ if (pos && dst_face.mExtents)
+ {
U32 max_joints = LLSkinningUtil::getMaxJointCount();
rigged_vert_count += dst_face.mNumVertices;
rigged_face_count++;
@@ -4933,71 +4989,71 @@ void LLRiggedVolume::update(
U8* joint_indices_cursor = vol_face.mJointIndices;
LLVector4a* just_weights = vol_face.mJustWeights;
for (U32 j = 0; j < dst_face.mNumVertices; ++j)
- {
- LLMatrix4a final_mat;
+ {
+ LLMatrix4a final_mat;
F32* w = just_weights[j].getF32ptr();
LLSkinningUtil::getPerVertexSkinMatrixWithIndices(w, joint_indices_cursor, mat, final_mat, src);
joint_indices_cursor += 4;
- LLVector4a& v = vol_face.mPositions[j];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
- }
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+ }
}
else
#endif
{
- for (U32 j = 0; j < dst_face.mNumVertices; ++j)
- {
- LLMatrix4a final_mat;
+ for (U32 j = 0; j < dst_face.mNumVertices; ++j)
+ {
+ LLMatrix4a final_mat;
LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
-
- LLVector4a& v = vol_face.mPositions[j];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
- }
+
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+ }
}
- //update bounding box
- // VFExtents change
- LLVector4a& min = dst_face.mExtents[0];
- LLVector4a& max = dst_face.mExtents[1];
+ //update bounding box
+ // VFExtents change
+ LLVector4a& min = dst_face.mExtents[0];
+ LLVector4a& max = dst_face.mExtents[1];
- min = pos[0];
- max = pos[1];
+ min = pos[0];
+ max = pos[1];
if (i==0)
{
box_min = min;
box_max = max;
}
- for (U32 j = 1; j < dst_face.mNumVertices; ++j)
- {
- min.setMin(min, pos[j]);
- max.setMax(max, pos[j]);
- }
+ for (U32 j = 1; j < dst_face.mNumVertices; ++j)
+ {
+ min.setMin(min, pos[j]);
+ max.setMax(max, pos[j]);
+ }
box_min.setMin(min,box_min);
box_max.setMax(max,box_max);
- dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]);
- dst_face.mCenter->mul(0.5f);
+ dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]);
+ dst_face.mCenter->mul(0.5f);
- }
+ }
if (rebuild_face_octrees)
- {
+ {
dst_face.destroyOctree();
dst_face.createOctree();
- }
- }
- }
+ }
+ }
+ }
mExtraDebugText = llformat("rigged %d/%d - box (%f %f %f) (%f %f %f)",
rigged_face_count, rigged_vert_count,
box_min[0], box_min[1], box_min[2],
@@ -5006,111 +5062,111 @@ void LLRiggedVolume::update(
U32 LLVOVolume::getPartitionType() const
{
- if (isHUDAttachment())
- {
- return LLViewerRegion::PARTITION_HUD;
- }
- if (isAnimatedObject() && getControlAvatar())
- {
- return LLViewerRegion::PARTITION_CONTROL_AV;
- }
- if (isAttachment())
- {
- return LLViewerRegion::PARTITION_AVATAR;
- }
+ if (isHUDAttachment())
+ {
+ return LLViewerRegion::PARTITION_HUD;
+ }
+ if (isAnimatedObject() && getControlAvatar())
+ {
+ return LLViewerRegion::PARTITION_CONTROL_AV;
+ }
+ if (isAttachment())
+ {
+ return LLViewerRegion::PARTITION_AVATAR;
+ }
- return LLViewerRegion::PARTITION_VOLUME;
+ return LLViewerRegion::PARTITION_VOLUME;
}
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, regionp),
LLVolumeGeometryManager()
{
- mLODPeriod = 32;
- mDepthMask = FALSE;
- mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
- mPartitionType = LLViewerRegion::PARTITION_VOLUME;
- mSlopRatio = 0.25f;
+ mLODPeriod = 32;
+ mDepthMask = FALSE;
+ mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
+ mPartitionType = LLViewerRegion::PARTITION_VOLUME;
+ mSlopRatio = 0.25f;
}
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp),
LLVolumeGeometryManager()
{
- mDepthMask = FALSE;
- mLODPeriod = 32;
- mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
- mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
-
- mSlopRatio = 0.25f;
+ mDepthMask = FALSE;
+ mLODPeriod = 32;
+ mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
+ mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
+
+ mSlopRatio = 0.25f;
}
LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
- : LLVolumeBridge(drawablep, regionp)
+ : LLVolumeBridge(drawablep, regionp)
{
- mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
- mPartitionType = LLViewerRegion::PARTITION_AVATAR;
+ mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+ mPartitionType = LLViewerRegion::PARTITION_AVATAR;
}
LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
- : LLVolumeBridge(drawablep, regionp)
+ : LLVolumeBridge(drawablep, regionp)
{
- mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
- mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
+ mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
+ mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
}
void LLControlAVBridge::updateSpatialExtents()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
- LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0);
+ LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0);
- bool rootWasDirty = root->isDirty();
+ bool rootWasDirty = root->isDirty();
- super::updateSpatialExtents(); // root becomes non-dirty here
+ super::updateSpatialExtents(); // root becomes non-dirty here
- // SL-18251 "On-screen animesh characters using pelvis offset animations
- // disappear when root goes off-screen"
- //
- // Expand extents to include Control Avatar placed outside of the bounds
+ // SL-18251 "On-screen animesh characters using pelvis offset animations
+ // disappear when root goes off-screen"
+ //
+ // Expand extents to include Control Avatar placed outside of the bounds
LLControlAvatar* controlAvatar = getVObj() ? getVObj()->getControlAvatar() : NULL;
if (controlAvatar
&& controlAvatar->mDrawable
&& controlAvatar->mDrawable->getEntry()
&& (rootWasDirty || controlAvatar->mPlaying))
- {
- root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform());
- }
+ {
+ root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform());
+ }
}
bool can_batch_texture(LLFace* facep)
{
- if (facep->getTextureEntry()->getBumpmap())
- { //bump maps aren't worked into texture batching yet
- return false;
- }
-
- if (facep->getTextureEntry()->getMaterialParams().notNull())
- { //materials don't work with texture batching yet
- return false;
- }
-
- if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)
- { //can't batch invisiprims
- return false;
- }
-
- if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
- { //texture animation breaks batches
- return false;
- }
-
+ if (facep->getTextureEntry()->getBumpmap())
+ { //bump maps aren't worked into texture batching yet
+ return false;
+ }
+
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ { //materials don't work with texture batching yet
+ return false;
+ }
+
+ if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)
+ { //can't batch invisiprims
+ return false;
+ }
+
+ if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
+ { //texture animation breaks batches
+ return false;
+ }
+
if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr)
{ // PBR materials break indexed texture batching
return false;
}
- return true;
+ return true;
}
const static U32 MAX_FACE_COUNT = 4096U;
@@ -5125,27 +5181,27 @@ LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL };
LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };
LLVolumeGeometryManager::LLVolumeGeometryManager()
- : LLGeometryManager()
+ : LLGeometryManager()
{
- llassert(sInstanceCount >= 0);
- if (sInstanceCount == 0)
- {
- allocateFaces(MAX_FACE_COUNT);
- }
+ llassert(sInstanceCount >= 0);
+ if (sInstanceCount == 0)
+ {
+ allocateFaces(MAX_FACE_COUNT);
+ }
- ++sInstanceCount;
+ ++sInstanceCount;
}
LLVolumeGeometryManager::~LLVolumeGeometryManager()
{
- llassert(sInstanceCount > 0);
- --sInstanceCount;
+ llassert(sInstanceCount > 0);
+ --sInstanceCount;
- if (sInstanceCount <= 0)
- {
- freeFaces();
- sInstanceCount = 0;
- }
+ if (sInstanceCount <= 0)
+ {
+ freeFaces();
+ sInstanceCount = 0;
+ }
}
void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)
@@ -5190,22 +5246,22 @@ void LLVolumeGeometryManager::freeFaces()
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- if ( type == LLRenderPass::PASS_ALPHA
- && facep->getTextureEntry()->getMaterialParams().notNull()
- && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)
- && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1)
- {
- LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
- }
+ if ( type == LLRenderPass::PASS_ALPHA
+ && facep->getTextureEntry()->getMaterialParams().notNull()
+ && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)
+ && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1)
+ {
+ LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
+ }
- bool selected = facep->getViewerObject()->isSelected();
+ bool selected = facep->getViewerObject()->isSelected();
- if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)
- {
- return;
- }
+ if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)
+ {
+ return;
+ }
- LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type));
+ LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type));
U32 passType = type;
@@ -5217,66 +5273,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
// See LLRenderPass PASS_foo enum
passType += 1;
}
- //add face to drawmap
- LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType];
-
- S32 idx = draw_vec.size()-1;
+ //add face to drawmap
+ LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType];
- bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
- (type == LLRenderPass::PASS_INVISIBLE) ||
- (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
- (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
- (facep->getTextureEntry()->getFullbright());
+ S32 idx = draw_vec.size()-1;
- if (!fullbright &&
- type != LLRenderPass::PASS_GLOW &&
+ bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
+ (type == LLRenderPass::PASS_INVISIBLE) ||
+ (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
+ (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
+ (facep->getTextureEntry()->getFullbright());
+
+ if (!fullbright &&
+ type != LLRenderPass::PASS_GLOW &&
!facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
- {
+ {
llassert(false);
- LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL;
- return;
- }
+ LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL;
+ return;
+ }
- const LLMatrix4* tex_mat = NULL;
- if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
- {
- tex_mat = facep->mTextureMatrix;
- }
-
- const LLMatrix4* model_mat = NULL;
+ const LLMatrix4* tex_mat = NULL;
+ if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
+ {
+ tex_mat = facep->mTextureMatrix;
+ }
- LLDrawable* drawable = facep->getDrawable();
+ const LLMatrix4* model_mat = NULL;
+ LLDrawable* drawable = facep->getDrawable();
+
if (rigged)
{
// rigged meshes ignore their model matrix
model_mat = nullptr;
}
- else if (drawable->isState(LLDrawable::ANIMATED_CHILD))
- {
- model_mat = &drawable->getWorldMatrix();
- }
- else if (drawable->isActive())
- {
- model_mat = &drawable->getRenderMatrix();
- }
- else
- {
- model_mat = &(drawable->getRegion()->mRenderMatrix);
- }
-
- //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
+ else if (drawable->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ model_mat = &drawable->getWorldMatrix();
+ }
+ else if (drawable->isActive())
+ {
+ model_mat = &drawable->getRenderMatrix();
+ }
+ else
+ {
+ model_mat = &(drawable->getRegion()->mRenderMatrix);
+ }
+
+ //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
const LLTextureEntry* te = facep->getTextureEntry();
- U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0;
- U8 shiny = te->getShiny();
-
- LLViewerTexture* tex = facep->getTexture();
+ U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0;
+ U8 shiny = te->getShiny();
+
+ LLViewerTexture* tex = facep->getTexture();
- U8 index = facep->getTextureIndex();
+ U8 index = facep->getTextureIndex();
LLMaterial* mat = nullptr;
-
+
LLUUID mat_id;
auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
@@ -5298,110 +5354,110 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
- bool batchable = false;
-
- U32 shader_mask = 0xFFFFFFFF; //no shader
-
- if (mat)
- {
- BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE;
- if (type == LLRenderPass::PASS_ALPHA)
- {
- shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha);
- }
- else
- {
- shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha);
- }
- }
-
- if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
- {
- if (mat || gltf_mat || draw_vec[idx]->mMaterial)
- { //can't batch textures when materials are present (yet)
- batchable = false;
- }
- else if (index < draw_vec[idx]->mTextureList.size())
- {
- if (draw_vec[idx]->mTextureList[index].isNull())
- {
- batchable = true;
- draw_vec[idx]->mTextureList[index] = tex;
- }
- else if (draw_vec[idx]->mTextureList[index] == tex)
- { //this face's texture index can be used with this batch
- batchable = true;
- }
- }
- else
- { //texture list can be expanded to fit this texture index
- batchable = true;
- }
- }
+ bool batchable = false;
+
+ U32 shader_mask = 0xFFFFFFFF; //no shader
+
+ if (mat)
+ {
+ BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE;
+ if (type == LLRenderPass::PASS_ALPHA)
+ {
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha);
+ }
+ else
+ {
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha);
+ }
+ }
+
+ if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
+ {
+ if (mat || gltf_mat || draw_vec[idx]->mMaterial)
+ { //can't batch textures when materials are present (yet)
+ batchable = false;
+ }
+ else if (index < draw_vec[idx]->mTextureList.size())
+ {
+ if (draw_vec[idx]->mTextureList[index].isNull())
+ {
+ batchable = true;
+ draw_vec[idx]->mTextureList[index] = tex;
+ }
+ else if (draw_vec[idx]->mTextureList[index] == tex)
+ { //this face's texture index can be used with this batch
+ batchable = true;
+ }
+ }
+ else
+ { //texture list can be expanded to fit this texture index
+ batchable = true;
+ }
+ }
LLDrawInfo* info = idx >= 0 ? draw_vec[idx] : nullptr;
- if (info &&
- info->mVertexBuffer == facep->getVertexBuffer() &&
- info->mEnd == facep->getGeomIndex()-1 &&
- (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&
+ if (info &&
+ info->mVertexBuffer == facep->getVertexBuffer() &&
+ info->mEnd == facep->getGeomIndex()-1 &&
+ (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&
#if LL_DARWIN
- info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
- info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
+ info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
+ info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- info->mMaterialID == mat_id &&
- info->mFullbright == fullbright &&
- info->mBump == bump &&
- (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
- info->mTextureMatrix == tex_mat &&
- info->mModelMatrix == model_mat &&
- info->mShaderMask == shader_mask &&
+ info->mMaterialID == mat_id &&
+ info->mFullbright == fullbright &&
+ info->mBump == bump &&
+ (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
+ info->mTextureMatrix == tex_mat &&
+ info->mModelMatrix == model_mat &&
+ info->mShaderMask == shader_mask &&
info->mAvatar == facep->mAvatar &&
info->getSkinHash() == facep->getSkinHash())
- {
- info->mCount += facep->getIndicesCount();
- info->mEnd += facep->getGeomCount();
-
- if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size())
- {
- info->mTextureList.resize(index+1);
- info->mTextureList[index] = tex;
- }
- info->validate();
- }
- else
- {
- U32 start = facep->getGeomIndex();
- U32 end = start + facep->getGeomCount()-1;
- U32 offset = facep->getIndicesStart();
- U32 count = facep->getIndicesCount();
- LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ {
+ info->mCount += facep->getIndicesCount();
+ info->mEnd += facep->getGeomCount();
+
+ if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size())
+ {
+ info->mTextureList.resize(index+1);
+ info->mTextureList[index] = tex;
+ }
+ info->validate();
+ }
+ else
+ {
+ U32 start = facep->getGeomIndex();
+ U32 end = start + facep->getGeomCount()-1;
+ U32 offset = facep->getIndicesStart();
+ U32 count = facep->getIndicesCount();
+ LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
+ facep->getVertexBuffer(), fullbright, bump);
info = draw_info;
- draw_vec.push_back(draw_info);
- draw_info->mTextureMatrix = tex_mat;
- draw_info->mModelMatrix = model_mat;
-
- draw_info->mBump = bump;
- draw_info->mShiny = shiny;
-
- static const float alpha[4] =
- {
- 0.00f,
- 0.25f,
- 0.5f,
- 0.75f
- };
- float spec = alpha[shiny & TEM_SHINY_MASK];
- LLVector4 specColor(spec, spec, spec, spec);
- draw_info->mSpecColor = specColor;
- draw_info->mEnvIntensity = spec;
- draw_info->mSpecularMap = NULL;
- draw_info->mMaterial = mat;
+ draw_vec.push_back(draw_info);
+ draw_info->mTextureMatrix = tex_mat;
+ draw_info->mModelMatrix = model_mat;
+
+ draw_info->mBump = bump;
+ draw_info->mShiny = shiny;
+
+ static const float alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+ float spec = alpha[shiny & TEM_SHINY_MASK];
+ LLVector4 specColor(spec, spec, spec, spec);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = spec;
+ draw_info->mSpecularMap = NULL;
+ draw_info->mMaterial = mat;
draw_info->mGLTFMaterial = gltf_mat;
- draw_info->mShaderMask = shader_mask;
+ draw_info->mShaderMask = shader_mask;
draw_info->mAvatar = facep->mAvatar;
draw_info->mSkinInfo = facep->mSkinInfo;
@@ -5411,58 +5467,58 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mMaterialID = mat_id;
}
else if (mat)
- {
- draw_info->mMaterialID = mat_id;
-
- // We have a material. Update our draw info accordingly.
-
- if (!mat->getSpecularID().isNull())
- {
- LLVector4 specColor;
- specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
- specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
- specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
- specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
- draw_info->mSpecColor = specColor;
- draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
- draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
- }
-
- draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
- draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
- draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
- }
- else
- {
- if (type == LLRenderPass::PASS_GRASS)
- {
- draw_info->mAlphaMaskCutoff = 0.5f;
- }
- else
- {
- draw_info->mAlphaMaskCutoff = 0.33f;
- }
- }
-
- // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr
- { //for alpha sorting
- facep->setDrawInfo(draw_info);
- }
-
- if (index < FACE_DO_NOT_BATCH_TEXTURES)
- { //initialize texture list for texture batching
- draw_info->mTextureList.resize(index+1);
- draw_info->mTextureList[index] = tex;
- }
- draw_info->validate();
- }
+ {
+ draw_info->mMaterialID = mat_id;
+
+ // We have a material. Update our draw info accordingly.
+
+ if (!mat->getSpecularID().isNull())
+ {
+ LLVector4 specColor;
+ specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+ specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+ specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+ specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+ draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+ }
+
+ draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+ draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+ draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
+ }
+ else
+ {
+ if (type == LLRenderPass::PASS_GRASS)
+ {
+ draw_info->mAlphaMaskCutoff = 0.5f;
+ }
+ else
+ {
+ draw_info->mAlphaMaskCutoff = 0.33f;
+ }
+ }
+
+ // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr
+ { //for alpha sorting
+ facep->setDrawInfo(draw_info);
+ }
+
+ if (index < FACE_DO_NOT_BATCH_TEXTURES)
+ { //initialize texture list for texture batching
+ draw_info->mTextureList.resize(index+1);
+ draw_info->mTextureList[index] = tex;
+ }
+ draw_info->validate();
+ }
llassert(info->mGLTFMaterial == nullptr || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0);
llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR || info->mGLTFMaterial != nullptr);
llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED || info->mGLTFMaterial != nullptr);
llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK || info->mGLTFMaterial != nullptr);
llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED || info->mGLTFMaterial != nullptr);
-
+
llassert(type != LLRenderPass::PASS_BUMP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0);
llassert(type != LLRenderPass::PASS_NORMSPEC || info->mNormalMap.notNull());
llassert(type != LLRenderPass::PASS_SPECMAP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TEXCOORD2) != 0);
@@ -5505,93 +5561,93 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
return;
}
- if (group->changeLOD())
- {
- group->mLastUpdateDistance = group->mDistance;
- }
-
- group->mLastUpdateViewAngle = group->mViewAngle;
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ }
- if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
- {
- if (group->hasState(LLSpatialGroup::MESH_DIRTY))
- {
- rebuildMesh(group);
- }
- return;
- }
+ group->mLastUpdateViewAngle = group->mViewAngle;
- group->mBuilt = 1.f;
+ if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
+ {
+ if (group->hasState(LLSpatialGroup::MESH_DIRTY))
+ {
+ rebuildMesh(group);
+ }
+ return;
+ }
- LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
+ group->mBuilt = 1.f;
+
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
LLViewerObject *vobj = NULL;
LLVOVolume *vol_obj = NULL;
- if (bridge)
- {
+ if (bridge)
+ {
vobj = bridge->mDrawable->getVObj();
vol_obj = dynamic_cast<LLVOVolume*>(vobj);
- }
+ }
if (vol_obj)
{
vol_obj->updateVisualComplexity();
}
- group->mGeometryBytes = 0;
- group->mSurfaceArea = 0;
+ group->mGeometryBytes = 0;
+ group->mSurfaceArea = 0;
+
+ //cache object box size since it might be used for determining visibility
+ const LLVector4a* bounds = group->getObjectBounds();
+ group->mObjectBoxSize = bounds[1].getLength3().getF32();
- //cache object box size since it might be used for determining visibility
- const LLVector4a* bounds = group->getObjectBounds();
- group->mObjectBoxSize = bounds[1].getLength3().getF32();
-
- group->clearDrawMap();
+ group->clearDrawMap();
U32 fullbright_count[2] = { 0 };
- U32 bump_count[2] = { 0 };
- U32 simple_count[2] = { 0 };
- U32 alpha_count[2] = { 0 };
- U32 norm_count[2] = { 0 };
- U32 spec_count[2] = { 0 };
- U32 normspec_count[2] = { 0 };
- U32 pbr_count[2] = { 0 };
-
- static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
- static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
- U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
- U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
- max_vertices = llmin(max_vertices, (U32) 65535);
-
- U32 cur_total = 0;
-
- bool emissive = false;
-
- //Determine if we've received skininfo that contains an
- //alternate bind matrix - if it does then apply the translational component
- //to the joints of the avatar.
+ U32 bump_count[2] = { 0 };
+ U32 simple_count[2] = { 0 };
+ U32 alpha_count[2] = { 0 };
+ U32 norm_count[2] = { 0 };
+ U32 spec_count[2] = { 0 };
+ U32 normspec_count[2] = { 0 };
+ U32 pbr_count[2] = { 0 };
+
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
+ U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ max_vertices = llmin(max_vertices, (U32) 65535);
+
+ U32 cur_total = 0;
+
+ bool emissive = false;
+
+ //Determine if we've received skininfo that contains an
+ //alternate bind matrix - if it does then apply the translational component
+ //to the joints of the avatar.
#if 0
- bool pelvisGotSet = false;
+ bool pelvisGotSet = false;
#endif
- {
+ {
LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");
- //get all the faces into a list
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
+ //get all the faces into a list
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
-
- if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
- {
- continue;
- }
-
- LLVOVolume* vobj = drawablep->getVOVolume();
-
- if (!vobj || vobj->isDead())
- {
- continue;
- }
+ {
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+
+ if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ {
+ continue;
+ }
+
+ LLVOVolume* vobj = drawablep->getVOVolume();
+
+ if (!vobj || vobj->isDead())
+ {
+ continue;
+ }
// HACK -- brute force this check every time a drawable gets rebuilt
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
@@ -5621,24 +5677,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
- LLVolume* volume = vobj->getVolume();
- if (volume)
- {
- const LLVector3& scale = vobj->getScale();
- group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
- }
-
+ LLVolume* volume = vobj->getVolume();
+ if (volume)
+ {
+ const LLVector3& scale = vobj->getScale();
+ group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+ }
+
F32 est_tris = vobj->getEstTrianglesMax();
vobj->updateControlAvatar();
-
+
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment()
<< " is_mesh " << is_mesh
<< " est_tris " << est_tris
<< " is_animated " << vobj->isAnimatedObject()
- << " can_animate " << vobj->canBeAnimatedObject()
- << " cav " << vobj->getControlAvatar()
+ << " can_animate " << vobj->canBeAnimatedObject()
+ << " cav " << vobj->getControlAvatar()
<< " lod " << vobj->getLOD()
<< " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED))
<< " drawable state " << drawablep->getState()
@@ -5646,11 +5702,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
<< " frame " << LLFrameTimer::getFrameCount()
<< LL_ENDL;
- llassert_always(vobj);
- vobj->updateTextureVirtualSize(true);
- vobj->preRebuild();
+ llassert_always(vobj);
+ vobj->updateTextureVirtualSize(true);
+ vobj->preRebuild();
- drawablep->clearState(LLDrawable::HAS_ALPHA);
+ drawablep->clearState(LLDrawable::HAS_ALPHA);
LLVOAvatar* avatar = nullptr;
const LLMeshSkinInfo* skinInfo = nullptr;
@@ -5676,23 +5732,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
- // Standard rigged mesh attachments:
- bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
+ // Standard rigged mesh attachments:
+ bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
// exclude static objects in animated object linksets.
- rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
+ rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying);
- bool any_rigged_face = false;
+ bool any_rigged_face = false;
- //for each face
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i);
- if (!facep)
- {
- continue;
- }
+ //for each face
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace* facep = drawablep->getFace(i);
+ if (!facep)
+ {
+ continue;
+ }
#if 0
#if LL_RELEASE_WITH_DEBUG_INFO
const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
@@ -5706,12 +5762,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool is_pbr = gltf_mat != nullptr;
#endif
- //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
- // batch, it will recover its vertex buffer reference from the spatial group
- facep->setVertexBuffer(NULL);
-
- //sum up face verts and indices
- drawablep->updateFaceSize(i);
+ //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
+ // batch, it will recover its vertex buffer reference from the spatial group
+ facep->setVertexBuffer(NULL);
+
+ //sum up face verts and indices
+ drawablep->updateFaceSize(i);
if (rigged)
{
@@ -5728,7 +5784,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
if (facep->isState(LLFace::RIGGED))
- {
+ {
//face is not rigged but used to be, remove from rigged face pool
LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
if (pool)
@@ -5741,84 +5797,84 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
- if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
- {
- facep->clearVertexBuffer();
- continue;
- }
+ if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
+ {
+ facep->clearVertexBuffer();
+ continue;
+ }
- if (facep->hasGeometry() &&
+ if (facep->hasGeometry() &&
(rigged || // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects
facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces
- {
+ {
cur_total += facep->getGeomCount();
- const LLTextureEntry* te = facep->getTextureEntry();
- LLViewerTexture* tex = facep->getTexture();
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLViewerTexture* tex = facep->getTexture();
- if (te->getGlow() > 0.f)
- {
- emissive = true;
- }
+ if (te->getGlow() > 0.f)
+ {
+ emissive = true;
+ }
- if (facep->isState(LLFace::TEXTURE_ANIM))
- {
- if (!vobj->mTexAnimMode)
- {
- facep->clearState(LLFace::TEXTURE_ANIM);
- }
- }
+ if (facep->isState(LLFace::TEXTURE_ANIM))
+ {
+ if (!vobj->mTexAnimMode)
+ {
+ facep->clearState(LLFace::TEXTURE_ANIM);
+ }
+ }
- BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND)
{
type = LLDrawPool::POOL_GLTF_PBR;
}
else
- if (type != LLDrawPool::POOL_ALPHA && force_simple)
- {
- type = LLDrawPool::POOL_SIMPLE;
- }
- facep->setPoolType(type);
-
- if (vobj->isHUDAttachment() && !is_pbr)
- {
- facep->setState(LLFace::FULLBRIGHT);
- }
-
- if (vobj->mTextureAnimp && vobj->mTexAnimMode)
- {
- if (vobj->mTextureAnimp->mFace <= -1)
- {
- S32 face;
- for (face = 0; face < vobj->getNumTEs(); face++)
- {
- LLFace * facep = drawablep->getFace(face);
- if (facep)
- {
- facep->setState(LLFace::TEXTURE_ANIM);
- }
- }
- }
- else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
- {
- LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
- if (facep)
- {
- facep->setState(LLFace::TEXTURE_ANIM);
- }
- }
- }
-
- if (type == LLDrawPool::POOL_ALPHA)
- {
- if (facep->canRenderAsMask())
- { //can be treated as alpha mask
+ if (type != LLDrawPool::POOL_ALPHA && force_simple)
+ {
+ type = LLDrawPool::POOL_SIMPLE;
+ }
+ facep->setPoolType(type);
+
+ if (vobj->isHUDAttachment() && !is_pbr)
+ {
+ facep->setState(LLFace::FULLBRIGHT);
+ }
+
+ if (vobj->mTextureAnimp && vobj->mTexAnimMode)
+ {
+ if (vobj->mTextureAnimp->mFace <= -1)
+ {
+ S32 face;
+ for (face = 0; face < vobj->getNumTEs(); face++)
+ {
+ LLFace * facep = drawablep->getFace(face);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
+ }
+ else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+ {
+ LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
+ }
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ if (facep->canRenderAsMask())
+ { //can be treated as alpha mask
add_face(sSimpleFaces, simple_count, facep);
- }
- else
- {
+ }
+ else
+ {
F32 alpha;
if (is_pbr)
{
@@ -5829,33 +5885,33 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
alpha = te->getColor().mV[3];
}
if (alpha > 0.f || te->getGlow() > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- add_face(sAlphaFaces, alpha_count, facep);
- }
- else if (LLDrawPoolAlpha::sShowDebugAlpha ||
- (gPipeline.sRenderHighlight && !drawablep->getParent() &&
- //only root objects are highlighted with red color in this case
- drawablep->getVObj() && drawablep->getVObj()->flagScripted() &&
- (LLPipeline::getRenderScriptedBeacons() ||
- (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch()))))
- { //draw the transparent face for debugging purposes using a custom texture
- add_face(sAlphaFaces, alpha_count, facep);
- }
- }
- }
- else
- {
- if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
- {
- facep->mLastUpdateTime = gFrameTimeSeconds;
- }
-
- {
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
+ else if (LLDrawPoolAlpha::sShowDebugAlpha ||
+ (gPipeline.sRenderHighlight && !drawablep->getParent() &&
+ //only root objects are highlighted with red color in this case
+ drawablep->getVObj() && drawablep->getVObj()->flagScripted() &&
+ (LLPipeline::getRenderScriptedBeacons() ||
+ (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch()))))
+ { //draw the transparent face for debugging purposes using a custom texture
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
+ }
+ }
+ else
+ {
+ if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+ {
+ facep->mLastUpdateTime = gFrameTimeSeconds;
+ }
+
+ {
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
- if (gltf_mat != nullptr || (te->getMaterialParams().notNull()))
- {
+ if (gltf_mat != nullptr || (te->getMaterialParams().notNull()))
+ {
if (gltf_mat != nullptr)
{
add_face(sPbrFaces, pbr_count, facep);
@@ -5884,91 +5940,91 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
add_face(sSimpleFaces, simple_count, facep);
}
}
- }
- else if (te->getBumpmap())
- { //needs normal + tangent
+ }
+ else if (te->getBumpmap())
+ { //needs normal + tangent
add_face(sBumpFaces, bump_count, facep);
- }
- else if (te->getShiny() || !te->getFullbright())
- { //needs normal
+ }
+ else if (te->getShiny() || !te->getFullbright())
+ { //needs normal
add_face(sSimpleFaces, simple_count, facep);
- }
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
add_face(sFullbrightFaces, fullbright_count, facep);
- }
- }
- }
- }
- else
- { //face has no renderable geometry
- facep->clearVertexBuffer();
- }
- }
-
- if (any_rigged_face)
- {
- if (!drawablep->isState(LLDrawable::RIGGED))
- {
- drawablep->setState(LLDrawable::RIGGED);
+ }
+ }
+ }
+ }
+ else
+ { //face has no renderable geometry
+ facep->clearVertexBuffer();
+ }
+ }
+
+ if (any_rigged_face)
+ {
+ if (!drawablep->isState(LLDrawable::RIGGED))
+ {
+ drawablep->setState(LLDrawable::RIGGED);
LLDrawable* root = drawablep->getRoot();
if (root != drawablep)
{
root->setState(LLDrawable::RIGGED_CHILD);
}
- //first time this is drawable is being marked as rigged,
- // do another LoD update to use avatar bounding box
- vobj->updateLOD();
- }
- }
- else
- {
- drawablep->clearState(LLDrawable::RIGGED);
+ //first time this is drawable is being marked as rigged,
+ // do another LoD update to use avatar bounding box
+ vobj->updateLOD();
+ }
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::RIGGED);
vobj->updateRiggedVolume(false);
- }
- }
- }
-
- //PROCESS NON-ALPHA FACES
- U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
- U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
- U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
- U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
-
- U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
- U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
- U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
-
- U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT;
-
- if (emissive)
- { //emissive faces are present, include emissive byte to preserve batching
- simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
- alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;
- bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;
- fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE;
- norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
- normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
- spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
+ }
+ }
+ }
+
+ //PROCESS NON-ALPHA FACES
+ U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
+ U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
+ U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
+ U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
+
+ U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
+ U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
+ U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
+
+ U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT;
+
+ if (emissive)
+ { //emissive faces are present, include emissive byte to preserve batching
+ simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
+ alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;
+ bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;
+ fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE;
+ norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
+ normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
+ spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE;
- }
+ }
- BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
+ BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
// add extra vertex data for deferred rendering (not necessarily for batching textures)
- if (batch_textures)
- {
- bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;
- simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
- alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;
- fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
- }
+ if (batch_textures)
+ {
+ bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;
+ simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;
+ fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ }
- group->mGeometryBytes = 0;
+ group->mGeometryBytes = 0;
- U32 geometryBytes = 0;
+ U32 geometryBytes = 0;
// generate render batches for static geometry
U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX;
@@ -5990,70 +6046,70 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
rigged = TRUE;
}
- group->mGeometryBytes = geometryBytes;
+ group->mGeometryBytes = geometryBytes;
- {
- //drawables have been rebuilt, clear rebuild status
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if(drawablep)
- {
+ {
+ //drawables have been rebuilt, clear rebuild status
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
+ {
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+ if(drawablep)
+ {
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
}
- }
+ }
- group->mLastUpdateTime = gFrameTimeSeconds;
- group->mBuilt = 1.f;
- group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
+ group->mLastUpdateTime = gFrameTimeSeconds;
+ group->mBuilt = 1.f;
+ group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
}
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- llassert(group);
- if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
- {
- {
+ llassert(group);
+ if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ {
LL_PROFILE_ZONE_NAMED("rebuildMesh - gen draw info");
group->mBuilt = 1.f;
+
+ const U32 MAX_BUFFER_COUNT = 4096;
+ LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
- const U32 MAX_BUFFER_COUNT = 4096;
- LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
-
- U32 buffer_count = 0;
+ U32 buffer_count = 0;
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
-
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
- {
- LLVOVolume* vobj = drawablep->getVOVolume();
-
- if (!vobj) continue;
-
- if (vobj->isNoLOD()) continue;
-
- vobj->preRebuild();
-
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- {
- vobj->updateRelativeXform(true);
- }
-
- LLVolume* volume = vobj->getVolume();
- if (!volume) continue;
- for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
- {
- LLFace* face = drawablep->getFace(i);
- if (face)
- {
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
- {
+ {
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
+ {
+ LLVOVolume* vobj = drawablep->getVOVolume();
+
+ if (!vobj) continue;
+
+ if (vobj->isNoLOD()) continue;
+
+ vobj->preRebuild();
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
+ LLVolume* volume = vobj->getVolume();
+ if (!volume) continue;
+ for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ {
+ LLFace* face = drawablep->getFace(i);
+ if (face)
+ {
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff)
+ {
if (!face->getGeometryVolume(*volume, // volume
face->getTEOffset(), // face_index
vobj->getRelativeXform(), // mat_vert_in
@@ -6068,72 +6124,72 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
buff->unmapBuffer();
- }
- }
- }
+ }
+ }
+ }
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- {
- vobj->updateRelativeXform();
- }
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
- drawablep->clearState(LLDrawable::REBUILD_ALL);
- }
- }
+ drawablep->clearState(LLDrawable::REBUILD_ALL);
+ }
+ }
- {
+ {
LL_PROFILE_ZONE_NAMED("rebuildMesh - flush");
- for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
- {
- (*iter)->unmapBuffer();
- }
-
- // don't forget alpha
- if(group != NULL &&
- !group->mVertexBuffer.isNull())
- {
- group->mVertexBuffer->unmapBuffer();
- }
- }
-
- group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
- }
- }
+ for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
+ {
+ (*iter)->unmapBuffer();
+ }
+
+ // don't forget alpha
+ if(group != NULL &&
+ !group->mVertexBuffer.isNull())
+ {
+ group->mVertexBuffer->unmapBuffer();
+ }
+ }
+
+ group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ }
+ }
}
struct CompareBatchBreaker
{
- bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
- {
- const LLTextureEntry* lte = lhs->getTextureEntry();
- const LLTextureEntry* rte = rhs->getTextureEntry();
+ bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
+ {
+ const LLTextureEntry* lte = lhs->getTextureEntry();
+ const LLTextureEntry* rte = rhs->getTextureEntry();
if (lte->getBumpmap() != rte->getBumpmap())
- {
- return lte->getBumpmap() < rte->getBumpmap();
- }
- else if (lte->getFullbright() != rte->getFullbright())
- {
- return lte->getFullbright() < rte->getFullbright();
- }
+ {
+ return lte->getBumpmap() < rte->getBumpmap();
+ }
+ else if (lte->getFullbright() != rte->getFullbright())
+ {
+ return lte->getFullbright() < rte->getFullbright();
+ }
else if (lte->getMaterialID() != rte->getMaterialID())
{
return lte->getMaterialID() < rte->getMaterialID();
}
- else if (lte->getShiny() != rte->getShiny())
- {
- return lte->getShiny() < rte->getShiny();
- }
+ else if (lte->getShiny() != rte->getShiny())
+ {
+ return lte->getShiny() < rte->getShiny();
+ }
else if (lhs->getTexture() != rhs->getTexture())
- {
- return lhs->getTexture() < rhs->getTexture();
- }
- else
+ {
+ return lhs->getTexture() < rhs->getTexture();
+ }
+ else
{
// all else being equal, maintain consistent draw order
return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex();
}
- }
+ }
};
struct CompareBatchBreakerRigged
@@ -6161,16 +6217,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- U32 geometryBytes = 0;
+ U32 geometryBytes = 0;
+
+ //calculate maximum number of vertices to store in a single buffer
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ max_vertices = llmin(max_vertices, (U32) 65535);
- //calculate maximum number of vertices to store in a single buffer
- static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
- U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
- max_vertices = llmin(max_vertices, (U32) 65535);
-
- {
+ {
LL_PROFILE_ZONE_NAMED("genDrawInfo - sort");
-
+
if (rigged)
{
if (!distance_sort) // <--- alpha "sort" rigged faces by maintaining original draw order
@@ -6184,289 +6240,277 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//sort faces by things that break batches, not including avatar and mesh id
std::sort(faces, faces + face_count, CompareBatchBreaker());
}
- else
- {
- //sort faces by distance
- std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());
- }
- }
-
- bool hud_group = group->isHUDGroup() ;
- LLFace** face_iter = faces;
- LLFace** end_faces = faces+face_count;
-
- LLSpatialGroup::buffer_map_t buffer_map;
-
- LLViewerTexture* last_tex = NULL;
-
- S32 texture_index_channels = 1;
-
- if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
- {
- texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity;
- }
-
- if (distance_sort)
- {
- texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
- }
-
- texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
-
- bool flexi = false;
-
- while (face_iter != end_faces)
- {
- //pull off next face
- LLFace* facep = *face_iter;
- LLViewerTexture* tex = facep->getTexture();
+ else
+ {
+ //sort faces by distance
+ std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());
+ }
+ }
+
+ bool hud_group = group->isHUDGroup() ;
+ LLFace** face_iter = faces;
+ LLFace** end_faces = faces+face_count;
+
+ LLSpatialGroup::buffer_map_t buffer_map;
+
+ LLViewerTexture* last_tex = NULL;
+
+ S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
+
+ bool flexi = false;
+
+ while (face_iter != end_faces)
+ {
+ //pull off next face
+ LLFace* facep = *face_iter;
+ LLViewerTexture* tex = facep->getTexture();
const LLTextureEntry* te = facep->getTextureEntry();
- LLMaterialPtr mat = te->getMaterialParams();
+ LLMaterialPtr mat = te->getMaterialParams();
LLMaterialID matId = te->getMaterialID();
- if (distance_sort)
- {
- tex = NULL;
- }
-
- if (last_tex != tex)
- {
- last_tex = tex;
- }
-
- bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic();
+ if (distance_sort)
+ {
+ tex = NULL;
+ }
- U32 index_count = facep->getIndicesCount();
- U32 geom_count = facep->getGeomCount();
+ if (last_tex != tex)
+ {
+ last_tex = tex;
+ }
- flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+ bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic();
- //sum up vertices needed for this render batch
- LLFace** i = face_iter;
- ++i;
+ U32 index_count = facep->getIndicesCount();
+ U32 geom_count = facep->getGeomCount();
- const U32 MAX_TEXTURE_COUNT = 32;
- LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
- U32 texture_count = 0;
+ //sum up vertices needed for this render batch
+ LLFace** i = face_iter;
+ ++i;
+
+ const U32 MAX_TEXTURE_COUNT = 32;
+ LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
+
+ U32 texture_count = 0;
- {
+ {
LL_PROFILE_ZONE_NAMED("genDrawInfo - face size");
- if (batch_textures)
- {
- U8 cur_tex = 0;
- facep->setTextureIndex(cur_tex);
- if (texture_count < MAX_TEXTURE_COUNT)
- {
- texture_list[texture_count++] = tex;
- }
-
- if (can_batch_texture(facep))
- { //populate texture_list with any textures that can be batched
- //move i to the next unbatchable face
- while (i != end_faces)
- {
- facep = *i;
-
- if (!can_batch_texture(facep))
- { //face is bump mapped or has an animated texture matrix -- can't
- //batch more than 1 texture at a time
- facep->setTextureIndex(0);
- break;
- }
-
- if (facep->getTexture() != tex)
- {
- if (distance_sort)
- { //textures might be out of order, see if texture exists in current batch
- bool found = false;
- for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)
- {
- if (facep->getTexture() == texture_list[tex_idx])
- {
- cur_tex = tex_idx;
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- cur_tex = texture_count;
- }
- }
- else
- {
- cur_tex++;
- }
-
- if (cur_tex >= texture_index_channels)
- { //cut batches when index channels are depleted
- break;
- }
-
- tex = facep->getTexture();
-
- if (texture_count < MAX_TEXTURE_COUNT)
- {
- texture_list[texture_count++] = tex;
- }
- }
-
- if (geom_count + facep->getGeomCount() > max_vertices)
- { //cut batches on geom count too big
- break;
- }
-
- ++i;
-
- flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
-
- index_count += facep->getIndicesCount();
- geom_count += facep->getGeomCount();
-
- facep->setTextureIndex(cur_tex);
- }
- }
- else
- {
- facep->setTextureIndex(0);
- }
-
- tex = texture_list[0];
- }
- else
- {
- while (i != end_faces &&
- (LLPipeline::sTextureBindTest ||
- (distance_sort ||
- ((*i)->getTexture() == tex))))
- {
- facep = *i;
+ if (batch_textures)
+ {
+ U8 cur_tex = 0;
+ facep->setTextureIndex(cur_tex);
+ if (texture_count < MAX_TEXTURE_COUNT)
+ {
+ texture_list[texture_count++] = tex;
+ }
+
+ if (can_batch_texture(facep))
+ { //populate texture_list with any textures that can be batched
+ //move i to the next unbatchable face
+ while (i != end_faces)
+ {
+ facep = *i;
+
+ if (!can_batch_texture(facep))
+ { //face is bump mapped or has an animated texture matrix -- can't
+ //batch more than 1 texture at a time
+ facep->setTextureIndex(0);
+ break;
+ }
+
+ if (facep->getTexture() != tex)
+ {
+ if (distance_sort)
+ { //textures might be out of order, see if texture exists in current batch
+ bool found = false;
+ for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)
+ {
+ if (facep->getTexture() == texture_list[tex_idx])
+ {
+ cur_tex = tex_idx;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ cur_tex = texture_count;
+ }
+ }
+ else
+ {
+ cur_tex++;
+ }
+
+ if (cur_tex >= texture_index_channels)
+ { //cut batches when index channels are depleted
+ break;
+ }
+
+ tex = facep->getTexture();
+
+ if (texture_count < MAX_TEXTURE_COUNT)
+ {
+ texture_list[texture_count++] = tex;
+ }
+ }
+
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
+ break;
+ }
+
+ ++i;
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
+
+ facep->setTextureIndex(cur_tex);
+ }
+ }
+ else
+ {
+ facep->setTextureIndex(0);
+ }
+
+ tex = texture_list[0];
+ }
+ else
+ {
+ while (i != end_faces &&
+ (LLPipeline::sTextureBindTest ||
+ (distance_sort ||
+ ((*i)->getTexture() == tex))))
+ {
+ facep = *i;
const LLTextureEntry* nextTe = facep->getTextureEntry();
if (nextTe->getMaterialID() != matId)
{
break;
}
- //face has no texture index
- facep->mDrawInfo = NULL;
- facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
+ //face has no texture index
+ facep->mDrawInfo = NULL;
+ facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
- if (geom_count + facep->getGeomCount() > max_vertices)
- { //cut batches on geom count too big
- break;
- }
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
+ break;
+ }
- ++i;
- index_count += facep->getIndicesCount();
- geom_count += facep->getGeomCount();
+ ++i;
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
- flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
- }
- }
- }
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+ }
+ }
+ }
- //create vertex buffer
- LLPointer<LLVertexBuffer> buffer;
+ //create vertex buffer
+ LLPointer<LLVertexBuffer> buffer;
- {
+ {
LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate");
- buffer = new LLVertexBuffer(mask);
- if(!buffer->allocateBuffer(geom_count, index_count))
- {
- LL_WARNS() << "Failed to allocate group Vertex Buffer to "
- << geom_count << " vertices and "
- << index_count << " indices" << LL_ENDL;
- buffer = NULL;
- }
- }
-
- if (buffer)
- {
- geometryBytes += buffer->getSize() + buffer->getIndicesSize();
- buffer_map[mask][*face_iter].push_back(buffer);
- }
-
- //add face geometry
-
- U32 indices_index = 0;
- U16 index_offset = 0;
+ buffer = new LLVertexBuffer(mask);
+ if(!buffer->allocateBuffer(geom_count, index_count))
+ {
+ LL_WARNS() << "Failed to allocate group Vertex Buffer to "
+ << geom_count << " vertices and "
+ << index_count << " indices" << LL_ENDL;
+ buffer = NULL;
+ }
+ }
+
+ if (buffer)
+ {
+ geometryBytes += buffer->getSize() + buffer->getIndicesSize();
+ buffer_map[mask][*face_iter].push_back(buffer);
+ }
+
+ //add face geometry
+
+ U32 indices_index = 0;
+ U16 index_offset = 0;
while (face_iter < i)
- {
- //update face indices for new buffer
- facep = *face_iter;
-
- if (buffer.isNull())
- {
- // Bulk allocation failed
- facep->setVertexBuffer(buffer);
- facep->setSize(0, 0); // mark as no geometry
- ++face_iter;
- continue;
- }
- facep->setIndicesIndex(indices_index);
- facep->setGeomIndex(index_offset);
- facep->setVertexBuffer(buffer);
-
- if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES)
- {
- LL_ERRS() << "Invalid texture index." << LL_ENDL;
- }
-
- {
- //for debugging, set last time face was updated vs moved
- facep->updateRebuildFlags();
-
- { //copy face geometry into vertex buffer
- LLDrawable* drawablep = facep->getDrawable();
- LLVOVolume* vobj = drawablep->getVOVolume();
- LLVolume* volume = vobj->getVolume();
-
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- {
- vobj->updateRelativeXform(true);
- }
-
- U32 te_idx = facep->getTEOffset();
-
- if (!facep->getGeometryVolume(*volume, te_idx,
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
- {
- LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL;
- }
-
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- {
- vobj->updateRelativeXform(false);
- }
- }
- }
-
- index_offset += facep->getGeomCount();
- indices_index += facep->getIndicesCount();
-
- //append face to appropriate render batch
-
- BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
- BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
- if ((mask & LLVertexBuffer::MAP_NORMAL) == 0)
- { //paranoia check to make sure GL doesn't try to read non-existant normals
- fullbright = TRUE;
- }
+ {
+ //update face indices for new buffer
+ facep = *face_iter;
+
+ if (buffer.isNull())
+ {
+ // Bulk allocation failed
+ facep->setVertexBuffer(buffer);
+ facep->setSize(0, 0); // mark as no geometry
+ ++face_iter;
+ continue;
+ }
+ facep->setIndicesIndex(indices_index);
+ facep->setGeomIndex(index_offset);
+ facep->setVertexBuffer(buffer);
+
+ if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES)
+ {
+ LL_ERRS() << "Invalid texture index." << LL_ENDL;
+ }
+
+ {
+ //for debugging, set last time face was updated vs moved
+ facep->updateRebuildFlags();
+
+ { //copy face geometry into vertex buffer
+ LLDrawable* drawablep = facep->getDrawable();
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ LLVolume* volume = vobj->getVolume();
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
+ U32 te_idx = facep->getTEOffset();
+
+ if (!facep->getGeometryVolume(*volume, te_idx,
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
+ {
+ LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL;
+ }
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(false);
+ }
+ }
+ }
+
+ index_offset += facep->getGeomCount();
+ indices_index += facep->getIndicesCount();
+
+ //append face to appropriate render batch
+
+ BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
+ BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
+ if ((mask & LLVertexBuffer::MAP_NORMAL) == 0)
+ { //paranoia check to make sure GL doesn't try to read non-existant normals
+ fullbright = TRUE;
+ }
const LLTextureEntry* te = facep->getTextureEntry();
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
- if (hud_group && gltf_mat == nullptr)
- { //all hud attachments are fullbright
- fullbright = TRUE;
- }
-
- tex = facep->getTexture();
+ if (hud_group && gltf_mat == nullptr)
+ { //all hud attachments are fullbright
+ fullbright = TRUE;
+ }
+
+ tex = facep->getTexture();
- BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
+ BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
LLMaterial* mat = nullptr;
bool can_be_shiny = false;
@@ -6486,8 +6530,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
F32 blinn_phong_alpha = te->getColor().mV[3];
- bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
- bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f;
+ bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
+ bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f;
bool blinn_phong_transparent = blinn_phong_alpha < 0.999f;
if (!gltf_mat)
@@ -6495,9 +6539,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
is_alpha = (is_alpha || blinn_phong_transparent) ? TRUE : FALSE;
}
- if (gltf_mat || (mat && !hud_group))
- {
- bool material_pass = false;
+ if (gltf_mat || (mat && !hud_group))
+ {
+ bool material_pass = false;
if (gltf_mat)
{ // all other parameters ignored if gltf material is present
@@ -6515,82 +6559,82 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
else
- // do NOT use 'fullbright' for this logic or you risk sending
- // things without normals down the materials pipeline and will
- // render poorly if not crash NORSPEC-240,314
- //
- if (te->getFullbright())
- {
- if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- {
- if (blinn_phong_opaque)
- {
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
- }
- else
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA);
- }
- }
- else if (is_alpha)
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA);
- }
- else
- {
- if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0)
- {
- material_pass = true;
- }
- else
- {
+ // do NOT use 'fullbright' for this logic or you risk sending
+ // things without normals down the materials pipeline and will
+ // render poorly if not crash NORSPEC-240,314
+ //
+ if (te->getFullbright())
+ {
+ if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ if (blinn_phong_opaque)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ }
+ else if (is_alpha)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else
+ {
+ if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0)
+ {
+ material_pass = true;
+ }
+ else
+ {
if (blinn_phong_opaque)
- {
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
else
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
- }
- }
- }
- else if (blinn_phong_transparent)
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA);
- }
- else if (use_legacy_bump)
- {
+ }
+ }
+ }
+ else if (blinn_phong_transparent)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (use_legacy_bump)
+ {
llassert(mask & LLVertexBuffer::MAP_TANGENT);
- // we have a material AND legacy bump settings, but no normal map
- registerFace(group, facep, LLRenderPass::PASS_BUMP);
- }
- else
- {
- material_pass = true;
- }
-
- if (material_pass)
- {
- static const U32 pass[] =
- {
- LLRenderPass::PASS_MATERIAL,
- LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
- LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
- LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
- LLRenderPass::PASS_SPECMAP,
- LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND,
- LLRenderPass::PASS_SPECMAP_MASK,
- LLRenderPass::PASS_SPECMAP_EMISSIVE,
- LLRenderPass::PASS_NORMMAP,
- LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND,
- LLRenderPass::PASS_NORMMAP_MASK,
- LLRenderPass::PASS_NORMMAP_EMISSIVE,
- LLRenderPass::PASS_NORMSPEC,
- LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND,
- LLRenderPass::PASS_NORMSPEC_MASK,
- LLRenderPass::PASS_NORMSPEC_EMISSIVE,
- };
+ // we have a material AND legacy bump settings, but no normal map
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ else
+ {
+ material_pass = true;
+ }
+
+ if (material_pass)
+ {
+ static const U32 pass[] =
+ {
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
+ LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND,
+ LLRenderPass::PASS_SPECMAP_MASK,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND,
+ LLRenderPass::PASS_NORMMAP_MASK,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND,
+ LLRenderPass::PASS_NORMSPEC_MASK,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
U32 alpha_mode = mat->getDiffuseAlphaMode();
if (!distance_sort && alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
@@ -6601,180 +6645,180 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 vb_mask = facep->getVertexBuffer()->getTypeMask();
- // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now
+ // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now
// even though it didn't appear to have a specmap when the face was added to the list of faces
if ((mask & 0x4) && !(vb_mask & LLVertexBuffer::MAP_TEXCOORD2))
{
mask &= ~0x4;
}
- llassert(mask < sizeof(pass)/sizeof(U32));
+ llassert(mask < sizeof(pass)/sizeof(U32));
- mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
+ mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
// if this is going into alpha pool, distance sort MUST be true
llassert(pass[mask] == LLRenderPass::PASS_ALPHA ? distance_sort : true);
- registerFace(group, facep, pass[mask]);
- }
- }
- else if (mat)
- {
- U8 mode = mat->getDiffuseAlphaMode();
+ registerFace(group, facep, pass[mask]);
+ }
+ }
+ else if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND));
- if (is_alpha)
- {
- mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
- }
-
- if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- {
- registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK);
- }
- else if (is_alpha )
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA);
- }
- else if (gPipeline.shadersLoaded()
- && te->getShiny()
- && can_be_shiny)
- {
- registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY);
- }
- else
- {
- registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE);
- }
- }
- else if (is_alpha)
- {
- // can we safely treat this as an alpha mask?
- if (facep->getFaceColor().mV[3] <= 0.f)
- { //100% transparent, don't render unless we're highlighting transparent
- registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
- }
- else if (facep->canRenderAsMask() && !hud_group)
- {
- if (te->getFullbright() || LLPipeline::sNoAlpha)
- {
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
- }
- else
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
- }
- }
- else
- {
- registerFace(group, facep, LLRenderPass::PASS_ALPHA);
- }
- }
- else if (gPipeline.shadersLoaded()
- && te->getShiny()
- && can_be_shiny)
- { //shiny
- if (tex->getPrimaryFormat() == GL_ALPHA)
- { //invisiprim+shiny
- registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
- }
- else if (!hud_group)
- { //deferred rendering
- if (te->getFullbright())
- { //register in post deferred fullbright shiny pass
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
- if (te->getBumpmap())
- { //register in post deferred bump pass
- registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
- }
- }
- else if (use_legacy_bump)
- { //register in deferred bump pass
+ if (is_alpha)
+ {
+ mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else if (is_alpha )
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (gPipeline.shadersLoaded()
+ && te->getShiny()
+ && can_be_shiny)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY);
+ }
+ else
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE);
+ }
+ }
+ else if (is_alpha)
+ {
+ // can we safely treat this as an alpha mask?
+ if (facep->getFaceColor().mV[3] <= 0.f)
+ { //100% transparent, don't render unless we're highlighting transparent
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
+ }
+ else if (facep->canRenderAsMask() && !hud_group)
+ {
+ if (te->getFullbright() || LLPipeline::sNoAlpha)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
+ }
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ }
+ else if (gPipeline.shadersLoaded()
+ && te->getShiny()
+ && can_be_shiny)
+ { //shiny
+ if (tex->getPrimaryFormat() == GL_ALPHA)
+ { //invisiprim+shiny
+ registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
+ else if (!hud_group)
+ { //deferred rendering
+ if (te->getFullbright())
+ { //register in post deferred fullbright shiny pass
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
+ if (te->getBumpmap())
+ { //register in post deferred bump pass
+ registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
+ }
+ }
+ else if (use_legacy_bump)
+ { //register in deferred bump pass
llassert(mask& LLVertexBuffer::MAP_TANGENT);
- registerFace(group, facep, LLRenderPass::PASS_BUMP);
- }
- else
- { //register in deferred simple pass (deferred simple includes shiny)
- llassert(mask & LLVertexBuffer::MAP_NORMAL);
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
- }
- else if (fullbright)
- { //not deferred, register in standard fullbright shiny pass
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
- }
- else
- { //not deferred or fullbright, register in standard shiny pass
- registerFace(group, facep, LLRenderPass::PASS_SHINY);
- }
- }
- else
- { //not alpha and not shiny
- if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
- { //invisiprim
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
- }
- else if (fullbright || bake_sunlight)
- { //fullbright
- if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- {
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
- }
- else
- {
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
- }
- if (!hud_group && use_legacy_bump)
- { //if this is the deferred render and a bump map is present, register in post deferred bump
- registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
- }
- }
- else
- {
- if (use_legacy_bump)
- { //non-shiny or fullbright deferred bump
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ else
+ { //register in deferred simple pass (deferred simple includes shiny)
+ llassert(mask & LLVertexBuffer::MAP_NORMAL);
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
+ }
+ else if (fullbright)
+ { //not deferred, register in standard fullbright shiny pass
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
+ }
+ else
+ { //not deferred or fullbright, register in standard shiny pass
+ registerFace(group, facep, LLRenderPass::PASS_SHINY);
+ }
+ }
+ else
+ { //not alpha and not shiny
+ if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
+ { //invisiprim
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
+ else if (fullbright || bake_sunlight)
+ { //fullbright
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ if (!hud_group && use_legacy_bump)
+ { //if this is the deferred render and a bump map is present, register in post deferred bump
+ registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
+ }
+ }
+ else
+ {
+ if (use_legacy_bump)
+ { //non-shiny or fullbright deferred bump
llassert(mask& LLVertexBuffer::MAP_TANGENT);
- registerFace(group, facep, LLRenderPass::PASS_BUMP);
- }
- else
- { //all around simple
- llassert(mask & LLVertexBuffer::MAP_NORMAL);
- if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- { //material alpha mask can be respected in non-deferred
- registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
- }
- else
- {
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
- }
- }
-
-
- if (!gPipeline.shadersLoaded() &&
- !is_alpha &&
- te->getShiny())
- { //shiny as an extra pass when shaders are disabled
- registerFace(group, facep, LLRenderPass::PASS_SHINY);
- }
- }
-
- //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010
- if (!is_alpha && hud_group)
- {
- llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
- facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
-
- if (!force_simple && use_legacy_bump)
- {
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ else
+ { //all around simple
+ llassert(mask & LLVertexBuffer::MAP_NORMAL);
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ { //material alpha mask can be respected in non-deferred
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
+ }
+ }
+
+
+ if (!gPipeline.shadersLoaded() &&
+ !is_alpha &&
+ te->getShiny())
+ { //shiny as an extra pass when shaders are disabled
+ registerFace(group, facep, LLRenderPass::PASS_SHINY);
+ }
+ }
+
+ //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010
+ if (!is_alpha && hud_group)
+ {
+ llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
+ facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
+
+ if (!force_simple && use_legacy_bump)
+ {
llassert(mask & LLVertexBuffer::MAP_TANGENT);
- registerFace(group, facep, LLRenderPass::PASS_BUMP);
- }
- }
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ }
- if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
- {
+ if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
+ {
if (gltf_mat)
{
registerFace(group, facep, LLRenderPass::PASS_GLTF_GLOW);
@@ -6783,24 +6827,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, LLRenderPass::PASS_GLOW);
}
- }
+ }
+
+ ++face_iter;
+ }
- ++face_iter;
- }
+ if (buffer)
+ {
+ buffer->unmapBuffer();
+ }
+ }
- if (buffer)
- {
- buffer->unmapBuffer();
- }
- }
+ group->mBufferMap[mask].clear();
+ for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i)
+ {
+ group->mBufferMap[mask][i->first] = i->second;
+ }
- group->mBufferMap[mask].clear();
- for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i)
- {
- group->mBufferMap[mask][i->first] = i->second;
- }
-
- return geometryBytes;
+ return geometryBytes;
}
void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
@@ -6818,57 +6862,57 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte
}
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
-{
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//clear off any old faces
mFaceList.clear();
- //for each drawable
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
-
- if (!drawablep || drawablep->isDead())
- {
- continue;
- }
-
- //for each face
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- //sum up face verts and indices
- drawablep->updateFaceSize(i);
- LLFace* facep = drawablep->getFace(i);
- if (facep)
- {
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&
- facep->getGeomCount() + vertex_count <= 65536)
- {
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
-
- //remember face (for sorting)
- mFaceList.push_back(facep);
- }
- else
- {
- facep->clearVertexBuffer();
- }
- }
- }
- }
+ //for each drawable
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
+ {
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+
+ if (!drawablep || drawablep->isDead())
+ {
+ continue;
+ }
+
+ //for each face
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ //sum up face verts and indices
+ drawablep->updateFaceSize(i);
+ LLFace* facep = drawablep->getFace(i);
+ if (facep)
+ {
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&
+ facep->getGeomCount() + vertex_count <= 65536)
+ {
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ //remember face (for sorting)
+ mFaceList.push_back(facep);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+ }
+ }
}
LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp)
{
- mPartitionType = LLViewerRegion::PARTITION_HUD;
- mDrawableType = LLPipeline::RENDER_TYPE_HUD;
- mSlopRatio = 0.f;
- mLODPeriod = 1;
+ mPartitionType = LLViewerRegion::PARTITION_HUD;
+ mDrawableType = LLPipeline::RENDER_TYPE_HUD;
+ mSlopRatio = 0.f;
+ mLODPeriod = 1;
}
void LLHUDPartition::shift(const LLVector4a &offset)
{
- //HUD objects don't shift with region crossing. That would be silly.
+ //HUD objects don't shift with region crossing. That would be silly.
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 88a10effb3..cac09609b3 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llvovolume.h
* @brief LLVOVolume 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$
*/
@@ -32,8 +32,8 @@
#include "llviewermedia.h"
#include "llframetimer.h"
#include "lllocalbitmaps.h"
-#include "m3math.h" // LLMatrix3
-#include "m4math.h" // LLMatrix4
+#include "m3math.h" // LLMatrix3
+#include "m4math.h" // LLMatrix4
#include <unordered_map>
#include <unordered_set>
@@ -51,7 +51,7 @@ typedef std::vector<viewer_media_t> media_list_t;
enum LLVolumeInterfaceType
{
- INTERFACE_FLEXIBLE = 1,
+ INTERFACE_FLEXIBLE = 1,
};
const F32 MAX_LOD_FACTOR = 4.0f;
@@ -60,10 +60,10 @@ const F32 MAX_LOD_FACTOR = 4.0f;
class LLRiggedVolume : public LLVolume
{
public:
- LLRiggedVolume(const LLVolumeParams& params)
- : LLVolume(params, 0.f)
- {
- }
+ LLRiggedVolume(const LLVolumeParams& params)
+ : LLVolume(params, 0.f)
+ {
+ }
using FaceIndex = S32;
static const FaceIndex UPDATE_ALL_FACES = -1;
@@ -82,218 +82,218 @@ public:
class LLVolumeInterface
{
public:
- virtual ~LLVolumeInterface() { }
- virtual LLVolumeInterfaceType getInterfaceType() const = 0;
- virtual void doIdleUpdate() = 0;
- virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
- virtual LLVector3 getPivotPosition() const = 0;
- virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
- virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0;
- virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0;
- virtual void onShift(const LLVector4a &shift_vector) = 0;
- virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance?
- virtual bool isVolumeGlobal() const = 0; // Are we in global space?
- virtual bool isActive() const = 0; // Is this object currently active?
- virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0;
- virtual void updateRelativeXform(bool force_identity = false) = 0;
- virtual U32 getID() const = 0;
- virtual void preRebuild() = 0;
+ virtual ~LLVolumeInterface() { }
+ virtual LLVolumeInterfaceType getInterfaceType() const = 0;
+ virtual void doIdleUpdate() = 0;
+ virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
+ virtual LLVector3 getPivotPosition() const = 0;
+ virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
+ virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0;
+ virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0;
+ virtual void onShift(const LLVector4a &shift_vector) = 0;
+ virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance?
+ virtual bool isVolumeGlobal() const = 0; // Are we in global space?
+ virtual bool isActive() const = 0; // Is this object currently active?
+ virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0;
+ virtual void updateRelativeXform(bool force_identity = false) = 0;
+ virtual U32 getID() const = 0;
+ virtual void preRebuild() = 0;
};
// Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME)
class LLVOVolume : public LLViewerObject
{
- LOG_CLASS(LLVOVolume);
+ LOG_CLASS(LLVOVolume);
protected:
- virtual ~LLVOVolume();
+ virtual ~LLVOVolume();
public:
- static void initClass();
- static void cleanupClass();
- static void preUpdateGeom();
-
- enum
- {
- VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
- (1 << LLVertexBuffer::TYPE_NORMAL) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD1) |
- (1 << LLVertexBuffer::TYPE_COLOR)
- };
+ static void initClass();
+ static void cleanupClass();
+ static void preUpdateGeom();
+
+ enum
+ {
+ VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
+ (1 << LLVertexBuffer::TYPE_NORMAL) |
+ (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
+ (1 << LLVertexBuffer::TYPE_TEXCOORD1) |
+ (1 << LLVertexBuffer::TYPE_COLOR)
+ };
public:
- LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- void markDead() override; // Override (and call through to parent) to clean up media references
-
- LLDrawable* createDrawable(LLPipeline *pipeline) override;
-
- void deleteFaces();
-
- void animateTextures();
-
- BOOL isVisible() const ;
- BOOL isActive() const override;
- BOOL isAttachment() const override;
- BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
- BOOL isHUDAttachment() const override;
-
- void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ BOOL setParent(LLViewerObject* parent) override;
- S32 getLOD() const override { return mLOD; }
- void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
- bool isNoLOD() const { return NO_LOD == mLOD; }
- const LLVector3 getPivotPositionAgent() const override;
- const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
- const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
- /*virtual*/ const LLMatrix4 getRenderMatrix() const override;
- typedef std::unordered_set<const LLViewerTexture*> texture_cost_t;
+ LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ void markDead() override; // Override (and call through to parent) to clean up media references
+
+ LLDrawable* createDrawable(LLPipeline *pipeline) override;
+
+ void deleteFaces();
+
+ void animateTextures();
+
+ BOOL isVisible() const ;
+ BOOL isActive() const override;
+ BOOL isAttachment() const override;
+ BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
+ BOOL isHUDAttachment() const override;
+
+ void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
+ /*virtual*/ BOOL setParent(LLViewerObject* parent) override;
+ S32 getLOD() const override { return mLOD; }
+ void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
+ bool isNoLOD() const { return NO_LOD == mLOD; }
+ const LLVector3 getPivotPositionAgent() const override;
+ const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
+ const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
+ /*virtual*/ const LLMatrix4 getRenderMatrix() const override;
+ typedef std::unordered_set<const LLViewerTexture*> texture_cost_t;
static S32 getTextureCost(const LLViewerTexture* img);
- U32 getRenderCost(texture_cost_t &textures) const;
- /*virtual*/ F32 getEstTrianglesMax() const override;
- /*virtual*/ F32 getEstTrianglesStreamingCost() const override;
- /* virtual*/ F32 getStreamingCost() const override;
+ U32 getRenderCost(texture_cost_t &textures) const;
+ /*virtual*/ F32 getEstTrianglesMax() const override;
+ /*virtual*/ F32 getEstTrianglesStreamingCost() const override;
+ /* virtual*/ F32 getStreamingCost() const override;
/*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
- /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
- /*virtual*/ U32 getHighLODTriangleCount() override;
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = -1, // which face to check, -1 = ALL_SIDES
- BOOL pick_transparent = FALSE,
- BOOL pick_rigged = FALSE,
+ /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
+ /*virtual*/ U32 getHighLODTriangleCount() override;
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face = -1, // which face to check, -1 = ALL_SIDES
+ BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
BOOL pick_unselectable = TRUE,
- S32* face_hit = NULL, // which face was hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- ) override;
-
- LLVector3 agentPositionToVolume(const LLVector3& pos) const;
- LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
- LLVector3 volumePositionToAgent(const LLVector3& dir) const;
- LLVector3 volumeDirectionToAgent(const LLVector3& dir) const;
-
-
- BOOL getVolumeChanged() const { return mVolumeChanged; }
-
- F32 getVObjRadius() const override { return mVObjRadius; };
- const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
-
- void markForUpdate() override;
- void faceMappingChanged() override { mFaceMappingChanged=TRUE; }
-
- /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
-
- /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
- /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
+ S32* face_hit = NULL, // which face was hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ ) override;
+
+ LLVector3 agentPositionToVolume(const LLVector3& pos) const;
+ LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
+ LLVector3 volumePositionToAgent(const LLVector3& dir) const;
+ LLVector3 volumeDirectionToAgent(const LLVector3& dir) const;
+
+
+ BOOL getVolumeChanged() const { return mVolumeChanged; }
+
+ F32 getVObjRadius() const override { return mVObjRadius; };
+ const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
+
+ void markForUpdate() override;
+ void faceMappingChanged() override { mFaceMappingChanged=TRUE; }
+
+ /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
+
+ /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
+ /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
// update mReflectionProbe based on isReflectionProbe()
void updateReflectionProbePtr();
- /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp) override;
-
- /*virtual*/ void setSelected(BOOL sel) override;
- /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
-
- /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
-
- /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
- /*virtual*/ void setNumTEs(const U8 num_tes) override;
- /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
- /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
- /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
- /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
- /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
- /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
- /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
- /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
-
- static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
-
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
+ /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ void **user_data,
+ U32 block_num, const EObjectUpdateType update_type,
+ LLDataPacker *dp) override;
+
+ /*virtual*/ void setSelected(BOOL sel) override;
+ /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
+
+ /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
+
+ /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
+ /*virtual*/ void setNumTEs(const U8 num_tes) override;
+ /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
+ /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
+ /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
+ /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
+ /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
+
+ static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
+
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override;
- /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
- /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
- /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
- /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
- /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
- /*virtual*/ BOOL setMaterial(const U8 material) override;
-
- void setTexture(const S32 face);
- S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
- /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
- void updateSculptTexture();
- void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
- void sculpt();
- static void rebuildMeshAssetCallback(const LLUUID& asset_uuid,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status);
-
- void updateRelativeXform(bool force_identity = false);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
- /*virtual*/ void updateFaceSize(S32 idx) override;
- /*virtual*/ BOOL updateLOD() override;
- void updateRadius() override;
- /*virtual*/ void updateTextures() override;
- void updateTextureVirtualSize(bool forced = false);
-
- void updateFaceFlags();
- void regenFaces();
+ /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
+ /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
+ /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
+ /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
+ /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
+ /*virtual*/ BOOL setMaterial(const U8 material) override;
+
+ void setTexture(const S32 face);
+ S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
+ /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
+ void updateSculptTexture();
+ void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
+ void sculpt();
+ static void rebuildMeshAssetCallback(const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status);
+
+ void updateRelativeXform(bool force_identity = false);
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
+ /*virtual*/ void updateFaceSize(S32 idx) override;
+ /*virtual*/ BOOL updateLOD() override;
+ void updateRadius() override;
+ /*virtual*/ void updateTextures() override;
+ void updateTextureVirtualSize(bool forced = false);
+
+ void updateFaceFlags();
+ void regenFaces();
BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE);
- void preRebuild();
- virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
- virtual F32 getBinRadius() override;
-
- virtual U32 getPartitionType() const override;
-
- // For Lights
- void setIsLight(BOOL is_light);
+ void preRebuild();
+ virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
+ virtual F32 getBinRadius() override;
+
+ virtual U32 getPartitionType() const override;
+
+ // For Lights
+ void setIsLight(BOOL is_light);
//set the gamma-corrected (sRGB) color of this light
- void setLightSRGBColor(const LLColor3& color);
+ void setLightSRGBColor(const LLColor3& color);
//set the linear color of this light
void setLightLinearColor(const LLColor3& color);
- void setLightIntensity(F32 intensity);
- void setLightRadius(F32 radius);
- void setLightFalloff(F32 falloff);
- void setLightCutoff(F32 cutoff);
- void setLightTextureID(LLUUID id);
- void setSpotLightParams(LLVector3 params);
+ void setLightIntensity(F32 intensity);
+ void setLightRadius(F32 radius);
+ void setLightFalloff(F32 falloff);
+ void setLightCutoff(F32 cutoff);
+ void setLightTextureID(LLUUID id);
+ void setSpotLightParams(LLVector3 params);
- BOOL getIsLight() const;
+ BOOL getIsLight() const;
bool getIsLightFast() const;
// Get the light color in sRGB color space NOT scaled by intensity.
- LLColor3 getLightSRGBBaseColor() const;
+ LLColor3 getLightSRGBBaseColor() const;
// Get the light color in linear color space NOT scaled by intensity.
LLColor3 getLightLinearBaseColor() const;
-
- // Get the light color in linear color space scaled by intensity
+
+ // Get the light color in linear color space scaled by intensity
// this is the value that should be fed into shaders
LLColor3 getLightLinearColor() const;
// Get the light color in sRGB color space scaled by intensity.
- LLColor3 getLightSRGBColor() const;
+ LLColor3 getLightSRGBColor() const;
- LLUUID getLightTextureID() const;
- bool isLightSpotlight() const;
- LLVector3 getSpotLightParams() const;
- void updateSpotLightPriority();
- F32 getSpotLightPriority() const;
+ LLUUID getLightTextureID() const;
+ bool isLightSpotlight() const;
+ LLVector3 getSpotLightParams() const;
+ void updateSpotLightPriority();
+ F32 getSpotLightPriority() const;
- LLViewerTexture* getLightTexture();
- F32 getLightIntensity() const;
- F32 getLightRadius() const;
- F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
- F32 getLightCutoff() const;
+ LLViewerTexture* getLightTexture();
+ F32 getLightIntensity() const;
+ F32 getLightRadius() const;
+ F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
+ F32 getLightCutoff() const;
// Reflection Probes
bool setIsReflectionProbe(BOOL is_probe);
@@ -301,20 +301,22 @@ public:
bool setReflectionProbeNearClip(F32 near_clip);
bool setReflectionProbeIsBox(bool is_box);
bool setReflectionProbeIsDynamic(bool is_dynamic);
+ bool setReflectionProbeIsMirror(bool is_mirror);
BOOL isReflectionProbe() const override;
F32 getReflectionProbeAmbiance() const;
F32 getReflectionProbeNearClip() const;
bool getReflectionProbeIsBox() const;
bool getReflectionProbeIsDynamic() const;
+ bool getReflectionProbeIsMirror() const;
- // Flexible Objects
- U32 getVolumeInterfaceID() const;
- virtual BOOL isFlexible() const override;
- virtual BOOL isSculpted() const override;
- virtual BOOL isMesh() const override;
- virtual BOOL isRiggedMesh() const override;
- virtual BOOL hasLightTexture() const override;
+ // Flexible Objects
+ U32 getVolumeInterfaceID() const;
+ virtual BOOL isFlexible() const override;
+ virtual BOOL isSculpted() const override;
+ virtual BOOL isMesh() const override;
+ virtual BOOL isRiggedMesh() const override;
+ virtual BOOL hasLightTexture() const override;
// fast variants above that use state that is filled in later
// not reliable early in the life of an object, but should be used after
@@ -325,16 +327,16 @@ public:
bool isRiggedMeshFast() const;
bool isAnimatedObjectFast() const;
- BOOL isVolumeGlobal() const;
- BOOL canBeFlexible() const;
- BOOL setIsFlexible(BOOL is_flexible);
+ BOOL isVolumeGlobal() const;
+ BOOL canBeFlexible() const;
+ BOOL setIsFlexible(BOOL is_flexible);
const LLMeshSkinInfo* getSkinInfo() const;
const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; }
//convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
-
+
// Extended Mesh Properties
U32 getExtendedMeshFlags() const;
void onSetExtendedMeshFlags(U32 flags);
@@ -347,58 +349,58 @@ public:
//virtual
void updateRiggingInfo() override;
S32 mLastRiggingInfoLOD;
-
+
// Functions that deal with media, or media navigation
-
+
// Update this object's media data with the given media data array
// (typically this is only called upon a response from a server request)
- void updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version);
-
+ void updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version);
+
// Bounce back media at the given index to its current URL (or home URL, if current URL is empty)
- void mediaNavigateBounceBack(U8 texture_index);
-
- // Returns whether or not this object has permission to navigate or control
- // the given media entry
- enum MediaPermType {
- MEDIA_PERM_INTERACT, MEDIA_PERM_CONTROL
- };
+ void mediaNavigateBounceBack(U8 texture_index);
+
+ // Returns whether or not this object has permission to navigate or control
+ // the given media entry
+ enum MediaPermType {
+ MEDIA_PERM_INTERACT, MEDIA_PERM_CONTROL
+ };
bool hasMediaPermission(const LLMediaEntry* media_entry, MediaPermType perm_type);
-
- void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location);
- void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
-
-
- // Sync the given media data with the impl and the given te
- void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
-
- // Send media data update to the simulator.
- void sendMediaDataUpdate();
-
- viewer_media_t getMediaImpl(U8 face_id) const;
- S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id);
- F64 getTotalMediaInterest() const;
-
- bool hasMedia() const;
-
- LLVector3 getApproximateFaceNormal(U8 face_id);
+
+ void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location);
+ void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
+
+
+ // Sync the given media data with the impl and the given te
+ void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
+
+ // Send media data update to the simulator.
+ void sendMediaDataUpdate();
+
+ viewer_media_t getMediaImpl(U8 face_id) const;
+ S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id);
+ F64 getTotalMediaInterest() const;
+
+ bool hasMedia() const;
+
+ LLVector3 getApproximateFaceNormal(U8 face_id);
// Flag any corresponding avatars as needing update.
void updateVisualComplexity();
-
- void notifyMeshLoaded();
- void notifySkinInfoLoaded(const LLMeshSkinInfo* skin);
- void notifySkinInfoUnavailable();
-
- // Returns 'true' iff the media data for this object is in flight
- bool isMediaDataBeingFetched() const;
-
- // Returns the "last fetched" media version, or -1 if not fetched yet
- S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; }
-
- void addMDCImpl() { ++mMDCImplCount; }
- void removeMDCImpl() { --mMDCImplCount; }
- S32 getMDCImplCount() { return mMDCImplCount; }
-
+
+ void notifyMeshLoaded();
+ void notifySkinInfoLoaded(const LLMeshSkinInfo* skin);
+ void notifySkinInfoUnavailable();
+
+ // Returns 'true' iff the media data for this object is in flight
+ bool isMediaDataBeingFetched() const;
+
+ // Returns the "last fetched" media version, or -1 if not fetched yet
+ S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; }
+
+ void addMDCImpl() { ++mMDCImplCount; }
+ void removeMDCImpl() { --mMDCImplCount; }
+ S32 getMDCImplCount() { return mMDCImplCount; }
+
// Rigged volume update (for raycasting)
// By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
@@ -406,69 +408,69 @@ public:
bool force_treat_as_rigged,
LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES,
bool rebuild_face_octrees = true);
- LLRiggedVolume* getRiggedVolume();
+ LLRiggedVolume* getRiggedVolume();
- //returns true if volume should be treated as a rigged volume
- // - Build tools are open
- // - object is an attachment
- // - object is attached to self
- // - object is rendered as rigged
- bool treatAsRigged();
+ //returns true if volume should be treated as a rigged volume
+ // - Build tools are open
+ // - object is an attachment
+ // - object is attached to self
+ // - object is rendered as rigged
+ bool treatAsRigged();
- //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates
- void clearRiggedVolume();
+ //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates
+ void clearRiggedVolume();
protected:
- S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
- BOOL calcLOD();
- LLFace* addFace(S32 face_index);
-
- // stats tracking for render complexity
- static S32 mRenderComplexity_last;
- static S32 mRenderComplexity_current;
+ S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
+ BOOL calcLOD();
+ LLFace* addFace(S32 face_index);
+
+ // stats tracking for render complexity
+ static S32 mRenderComplexity_last;
+ static S32 mRenderComplexity_current;
void onDrawableUpdateFromServer();
- void requestMediaDataUpdate(bool isNew);
- void cleanUpMediaImpls();
- void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
- void removeMediaImpl(S32 texture_index) ;
+ void requestMediaDataUpdate(bool isNew);
+ void cleanUpMediaImpls();
+ void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
+ void removeMediaImpl(S32 texture_index) ;
private:
bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds);
public:
- static S32 getRenderComplexityMax() {return mRenderComplexity_last;}
- static void updateRenderComplexity();
+ static S32 getRenderComplexityMax() {return mRenderComplexity_last;}
+ static void updateRenderComplexity();
- LLViewerTextureAnim *mTextureAnimp;
- U8 mTexAnimMode;
+ LLViewerTextureAnim *mTextureAnimp;
+ U8 mTexAnimMode;
F32 mLODDistance;
F32 mLODAdjustedDistance;
F32 mLODRadius;
private:
- friend class LLDrawable;
- friend class LLFace;
-
- BOOL mFaceMappingChanged;
- LLFrameTimer mTextureUpdateTimer;
- S32 mLOD;
- BOOL mLODChanged;
- BOOL mSculptChanged;
- BOOL mColorChanged;
- F32 mSpotLightPriority;
- LLMatrix4 mRelativeXform;
- LLMatrix3 mRelativeXformInvTrans;
- BOOL mVolumeChanged;
- F32 mVObjRadius;
- LLVolumeInterface *mVolumeImpl;
- LLPointer<LLViewerFetchedTexture> mSculptTexture;
- LLPointer<LLViewerFetchedTexture> mLightTexture;
- media_list_t mMediaImplList;
- S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
+ friend class LLDrawable;
+ friend class LLFace;
+
+ BOOL mFaceMappingChanged;
+ LLFrameTimer mTextureUpdateTimer;
+ S32 mLOD;
+ BOOL mLODChanged;
+ BOOL mSculptChanged;
+ BOOL mColorChanged;
+ F32 mSpotLightPriority;
+ LLMatrix4 mRelativeXform;
+ LLMatrix3 mRelativeXformInvTrans;
+ BOOL mVolumeChanged;
+ F32 mVObjRadius;
+ LLVolumeInterface *mVolumeImpl;
+ LLPointer<LLViewerFetchedTexture> mSculptTexture;
+ LLPointer<LLViewerFetchedTexture> mLightTexture;
+ media_list_t mMediaImplList;
+ S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
U32 mServerDrawableUpdateCount;
- S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
- S32 mMDCImplCount;
+ S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
+ S32 mMDCImplCount;
// cached value of getIsLight to avoid redundant map lookups
// accessed by getIsLightFast
@@ -477,24 +479,24 @@ private:
// cached value of getIsAnimatedObject to avoid redundant map lookups
// accessed by getIsAnimatedObjectFast
mutable bool mIsAnimatedObject = false;
- bool mResetDebugText;
+ bool mResetDebugText;
- LLPointer<LLRiggedVolume> mRiggedVolume;
+ LLPointer<LLRiggedVolume> mRiggedVolume;
- bool mSkinInfoUnavaliable;
- LLConstPointer<LLMeshSkinInfo> mSkinInfo;
- // statics
+ bool mSkinInfoUnavaliable;
+ LLConstPointer<LLMeshSkinInfo> mSkinInfo;
+ // statics
public:
- static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
- static F32 sLODFactor; // LOD scale factor
- static F32 sDistanceFactor; // LOD distance factor
+ static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
+ static F32 sLODFactor; // LOD scale factor
+ static F32 sDistanceFactor; // LOD distance factor
- static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
- static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
+ static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
+ static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
protected:
- static S32 sNumLODChanges;
+ static S32 sNumLODChanges;
- friend class LLVolumeImplFlexible;
+ friend class LLVolumeImplFlexible;
};
#endif // LL_LLVOVOLUME_H
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 0eabb8983e..461d556946 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -3,25 +3,25 @@
* @author Nat Goodspeed
* @date 2009-03-18
* @brief Implementation for llxmlrpclistener.
- *
+ *
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -88,13 +88,13 @@ class StatusMapper: public StatusMapperBase<LLXMLRPCTransaction::EStatus>
public:
StatusMapper(): StatusMapperBase<LLXMLRPCTransaction::EStatus>("Status")
{
- mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted";
- mMap[LLXMLRPCTransaction::StatusStarted] = "Started";
- mMap[LLXMLRPCTransaction::StatusDownloading] = "Downloading";
- mMap[LLXMLRPCTransaction::StatusComplete] = "Complete";
- mMap[LLXMLRPCTransaction::StatusCURLError] = "CURLError";
- mMap[LLXMLRPCTransaction::StatusXMLRPCError] = "XMLRPCError";
- mMap[LLXMLRPCTransaction::StatusOtherError] = "OtherError";
+ mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted";
+ mMap[LLXMLRPCTransaction::StatusStarted] = "Started";
+ mMap[LLXMLRPCTransaction::StatusDownloading] = "Downloading";
+ mMap[LLXMLRPCTransaction::StatusComplete] = "Complete";
+ mMap[LLXMLRPCTransaction::StatusCURLError] = "CURLError";
+ mMap[LLXMLRPCTransaction::StatusXMLRPCError] = "XMLRPCError";
+ mMap[LLXMLRPCTransaction::StatusOtherError] = "OtherError";
}
};
@@ -285,7 +285,7 @@ public:
XMLRPC_RequestSetData(request, xparams);
mTransaction.reset(new LLXMLRPCTransaction(mUri, request, true, command.has("http_params")? LLSD(command["http_params"]) : LLSD()));
- mPreviousStatus = mTransaction->status(NULL);
+ mPreviousStatus = mTransaction->status(NULL);
// Free the XMLRPC_REQUEST object and the attached data values.
XMLRPC_RequestFree(request, 1);
@@ -323,42 +323,42 @@ public:
data["error"] = "";
data["transfer_rate"] = 0.0;
LLEventPump& replyPump(LLEventPumps::instance().obtain(mReplyPump));
- if (! done)
+ if (! done)
{
// Not done yet, carry on.
- if (status == LLXMLRPCTransaction::StatusDownloading
- && status != mPreviousStatus)
- {
- // If a response has been received, send the
- // 'downloading' status if it hasn't been sent.
- replyPump.post(data);
- }
-
- mPreviousStatus = status;
+ if (status == LLXMLRPCTransaction::StatusDownloading
+ && status != mPreviousStatus)
+ {
+ // If a response has been received, send the
+ // 'downloading' status if it hasn't been sent.
+ replyPump.post(data);
+ }
+
+ mPreviousStatus = status;
return false;
}
// Here the transaction is complete. Check status.
data["error"] = mTransaction->statusMessage();
- data["transfer_rate"] = mTransaction->transferRate();
+ data["transfer_rate"] = mTransaction->transferRate();
LL_INFOS("LLXMLRPCListener") << mMethod << " result from " << mUri << ": status "
<< data["status"].asString() << ", errorcode "
<< data["errorcode"].asString()
<< " (" << data["error"].asString() << ")"
<< LL_ENDL;
-
- switch (curlcode)
- {
+
+ switch (curlcode)
+ {
#if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT
- case CURLE_SSL_PEER_CERTIFICATE:
+ case CURLE_SSL_PEER_CERTIFICATE:
#endif
- case CURLE_SSL_CACERT:
+ case CURLE_SSL_CACERT:
data["certificate"] = mTransaction->getErrorCertData();
- break;
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
// values of 'curlcode':
// CURLE_COULDNT_RESOLVE_HOST,
// CURLE_SSL_PEER_CERTIFICATE,
@@ -411,34 +411,20 @@ private:
return parseValues(status_string, "", param);
}
- /**
- * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map.
- * @param key_pfx Used to describe a given key in log messages. At top
- * level, pass "". When parsing an options array, pass the top-level key
- * name of the array plus the index of the array entry; to this we'll
- * append the subkey of interest.
- * @param param XMLRPC_VALUE iterator. At top level, pass
- * XMLRPC_RequestGetData(XMLRPC_REQUEST).
- */
- LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param)
+ LLSD parseValue(std::string& status_string, const std::string& key, const std::string& key_pfx, XMLRPC_VALUE param)
{
- LLSD responses;
- for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current;
- current = XMLRPC_VectorNext(param))
+ LLSD response;
+
+ XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(param);
+ switch (type)
{
- std::string key(XMLRPC_GetValueID(current));
- LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL;
- XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(current);
- switch (type)
- {
case xmlrpc_type_empty:
LL_INFOS("LLXMLRPCListener") << "Empty result for key " << key_pfx << key << LL_ENDL;
- responses.insert(key, LLSD());
break;
case xmlrpc_type_base64:
{
- S32 len = XMLRPC_GetValueStringLen(current);
- const char* buf = XMLRPC_GetValueBase64(current);
+ S32 len = XMLRPC_GetValueStringLen(param);
+ const char* buf = XMLRPC_GetValueBase64(param);
if ((len > 0) && buf)
{
// During implementation this code was not tested
@@ -449,49 +435,44 @@ private:
LLSD::Binary data;
data.resize(len);
memcpy((void*)&data[0], (void*)buf, len);
- responses.insert(key, data);
+ response = data;
}
else
{
LL_WARNS("LLXMLRPCListener") << "Potentially malformed xmlrpc_type_base64 for key "
<< key_pfx << key << LL_ENDL;
- responses.insert(key, LLSD());
}
break;
}
case xmlrpc_type_boolean:
{
- LLSD::Boolean val(XMLRPC_GetValueBoolean(current));
- LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
- responses.insert(key, val);
+ response = LLSD::Boolean(XMLRPC_GetValueBoolean(param));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL;
break;
}
case xmlrpc_type_datetime:
{
- std::string iso8601_date(XMLRPC_GetValueDateTime_ISO8601(current));
+ std::string iso8601_date(XMLRPC_GetValueDateTime_ISO8601(param));
LL_DEBUGS("LLXMLRPCListener") << "val: " << iso8601_date << LL_ENDL;
- responses.insert(key, LLSD::Date(iso8601_date));
+ response = LLSD::Date(iso8601_date);
break;
}
case xmlrpc_type_double:
{
- LLSD::Real val(XMLRPC_GetValueDouble(current));
- LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
- responses.insert(key, val);
+ response = LLSD::Real(XMLRPC_GetValueDouble(param));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL;
break;
}
case xmlrpc_type_int:
{
- LLSD::Integer val(XMLRPC_GetValueInt(current));
- LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
- responses.insert(key, val);
+ response = LLSD::Integer(XMLRPC_GetValueInt(param));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL;
break;
}
case xmlrpc_type_string:
{
- LLSD::String val(XMLRPC_GetValueString(current));
- LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
- responses.insert(key, val);
+ response = LLSD::String(XMLRPC_GetValueString(param));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL;
break;
}
case xmlrpc_type_mixed:
@@ -501,8 +482,8 @@ private:
// recursively parsing each submap and collecting them.
LLSD array;
int i = 0; // for descriptive purposes
- for (XMLRPC_VALUE row = XMLRPC_VectorRewind(current); row;
- row = XMLRPC_VectorNext(current), ++i)
+ for (XMLRPC_VALUE row = XMLRPC_VectorRewind(param); row;
+ row = XMLRPC_VectorNext(param), ++i)
{
// Recursive call. For the lower-level key_pfx, if 'key'
// is "foo", pass "foo[0]:", then "foo[1]:", etc. In the
@@ -510,21 +491,21 @@ private:
// "foo[0]:bar", and so forth.
// Parse the scalar subkey/value pairs from this array
// entry into a temp submap. Collect such submaps in 'array'.
- array.append(parseValues(status_string,
+
+ array.append(parseValue(status_string, "",
STRINGIZE(key_pfx << key << '[' << i << "]:"),
row));
}
// Having collected an 'array' of 'submap's, insert that whole
// 'array' as the value of this 'key'.
- responses.insert(key, array);
+ response = array;
break;
}
case xmlrpc_type_struct:
{
- LLSD submap = parseValues(status_string,
+ response = parseValues(status_string,
STRINGIZE(key_pfx << key << ':'),
- current);
- responses.insert(key, submap);
+ param);
break;
}
case xmlrpc_type_none: // Not expected
@@ -532,9 +513,30 @@ private:
// whoops - unrecognized type
LL_WARNS("LLXMLRPCListener") << "Unhandled xmlrpc type " << type << " for key "
<< key_pfx << key << LL_ENDL;
- responses.insert(key, STRINGIZE("<bad XMLRPC type " << type << '>'));
+ response = STRINGIZE("<bad XMLRPC type " << type << '>');
status_string = "BadType";
- }
+ }
+ return response;
+ }
+
+ /**
+ * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map.
+ * @param key_pfx Used to describe a given key in log messages. At top
+ * level, pass "". When parsing an options array, pass the top-level key
+ * name of the array plus the index of the array entry; to this we'll
+ * append the subkey of interest.
+ * @param param XMLRPC_VALUE iterator. At top level, pass
+ * XMLRPC_RequestGetData(XMLRPC_REQUEST).
+ */
+ LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param)
+ {
+ LLSD responses;
+ for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current;
+ current = XMLRPC_VectorNext(param))
+ {
+ std::string key(XMLRPC_GetValueID(current));
+ LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL;
+ responses.insert(key, parseValue(status_string, key, key_pfx, current));
}
return responses;
}
@@ -545,7 +547,7 @@ private:
const std::string mReplyPump;
LLTempBoundListener mBoundListener;
std::unique_ptr<LLXMLRPCTransaction> mTransaction;
- LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes.
+ LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes.
};
bool LLXMLRPCListener::process(const LLSD& command)
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c5ba03775b..8b1e46343b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file pipeline.cpp
* @brief Rendering pipeline.
*
* $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$
*/
@@ -40,11 +40,11 @@
#include "llvolume.h"
#include "material_codes.h"
#include "v3color.h"
-#include "llui.h"
+#include "llui.h"
#include "llglheaders.h"
#include "llrender.h"
#include "llstartup.h"
-#include "llwindow.h" // swapBuffers()
+#include "llwindow.h" // swapBuffers()
// newview includes
#include "llagent.h"
@@ -112,6 +112,7 @@
#include "llscenemonitor.h"
#include "llprogressview.h"
#include "llcleanup.h"
+#include "gltfscenemanager.h"
#include "llenvironment.h"
#include "llsettingsvo.h"
@@ -198,8 +199,13 @@ F32 LLPipeline::RenderScreenSpaceReflectionDepthRejectBias;
F32 LLPipeline::RenderScreenSpaceReflectionAdaptiveStepMultiplier;
S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples;
S32 LLPipeline::RenderBufferVisualization;
+bool LLPipeline::RenderMirrors;
+S32 LLPipeline::RenderHeroProbeUpdateRate;
+S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier;
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
+const U32 LLPipeline::MAX_BAKE_WIDTH = 512;
+
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
const F32 ALPHA_BLEND_CUTOFF = 0.598f;
@@ -213,9 +219,9 @@ extern BOOL gDebugGL;
extern BOOL gCubeSnapshot;
extern BOOL gSnapshotNoPost;
-bool gAvatarBacklight = false;
+bool gAvatarBacklight = false;
-bool gDebugPipeline = false;
+bool gDebugPipeline = false;
LLPipeline gPipeline;
const LLMatrix4* gGLLastMatrix = NULL;
@@ -274,42 +280,42 @@ LLVertexBuffer* ll_create_cube_vb(U32 type_mask);
void display_update_camera();
//----------------------------------------
-S32 LLPipeline::sCompiles = 0;
-
-bool LLPipeline::sPickAvatar = true;
-bool LLPipeline::sDynamicLOD = true;
-bool LLPipeline::sShowHUDAttachments = true;
-bool LLPipeline::sRenderMOAPBeacons = false;
-bool LLPipeline::sRenderPhysicalBeacons = true;
-bool LLPipeline::sRenderScriptedBeacons = false;
-bool LLPipeline::sRenderScriptedTouchBeacons = true;
-bool LLPipeline::sRenderParticleBeacons = false;
-bool LLPipeline::sRenderSoundBeacons = false;
-bool LLPipeline::sRenderBeacons = false;
-bool LLPipeline::sRenderHighlight = true;
+S32 LLPipeline::sCompiles = 0;
+
+bool LLPipeline::sPickAvatar = true;
+bool LLPipeline::sDynamicLOD = true;
+bool LLPipeline::sShowHUDAttachments = true;
+bool LLPipeline::sRenderMOAPBeacons = false;
+bool LLPipeline::sRenderPhysicalBeacons = true;
+bool LLPipeline::sRenderScriptedBeacons = false;
+bool LLPipeline::sRenderScriptedTouchBeacons = true;
+bool LLPipeline::sRenderParticleBeacons = false;
+bool LLPipeline::sRenderSoundBeacons = false;
+bool LLPipeline::sRenderBeacons = false;
+bool LLPipeline::sRenderHighlight = true;
LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
-bool LLPipeline::sForceOldBakedUpload = false;
-S32 LLPipeline::sUseOcclusion = 0;
-bool LLPipeline::sAutoMaskAlphaDeferred = true;
-bool LLPipeline::sAutoMaskAlphaNonDeferred = false;
-bool LLPipeline::sRenderTransparentWater = true;
-bool LLPipeline::sBakeSunlight = false;
-bool LLPipeline::sNoAlpha = false;
-bool LLPipeline::sUseFarClip = true;
-bool LLPipeline::sShadowRender = false;
-bool LLPipeline::sRenderGlow = false;
-bool LLPipeline::sReflectionRender = false;
+bool LLPipeline::sForceOldBakedUpload = false;
+S32 LLPipeline::sUseOcclusion = 0;
+bool LLPipeline::sAutoMaskAlphaDeferred = true;
+bool LLPipeline::sAutoMaskAlphaNonDeferred = false;
+bool LLPipeline::sRenderTransparentWater = true;
+bool LLPipeline::sBakeSunlight = false;
+bool LLPipeline::sNoAlpha = false;
+bool LLPipeline::sUseFarClip = true;
+bool LLPipeline::sShadowRender = false;
+bool LLPipeline::sRenderGlow = false;
+bool LLPipeline::sReflectionRender = false;
bool LLPipeline::sDistortionRender = false;
-bool LLPipeline::sImpostorRender = false;
-bool LLPipeline::sImpostorRenderAlphaDepthPass = false;
-bool LLPipeline::sUnderWaterRender = false;
-bool LLPipeline::sTextureBindTest = false;
-bool LLPipeline::sRenderAttachedLights = true;
-bool LLPipeline::sRenderAttachedParticles = true;
-bool LLPipeline::sRenderDeferred = false;
-bool LLPipeline::sReflectionProbesEnabled = false;
-S32 LLPipeline::sVisibleLightCount = 0;
-bool LLPipeline::sRenderingHUDs;
+bool LLPipeline::sImpostorRender = false;
+bool LLPipeline::sImpostorRenderAlphaDepthPass = false;
+bool LLPipeline::sUnderWaterRender = false;
+bool LLPipeline::sTextureBindTest = false;
+bool LLPipeline::sRenderAttachedLights = true;
+bool LLPipeline::sRenderAttachedParticles = true;
+bool LLPipeline::sRenderDeferred = false;
+bool LLPipeline::sReflectionProbesEnabled = false;
+S32 LLPipeline::sVisibleLightCount = 0;
+bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
// EventHost API LLPipeline listener.
@@ -325,35 +331,35 @@ bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
{
bool valid = true
&& target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
- && target.addColorAttachment(GL_RGBA16F) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
- && target.addColorAttachment(GL_RGB16F); // frag_data[3] PBR emissive
+ && target.addColorAttachment(GL_RGBA16F) // frag_data[2] normal+fogmask, See: class1\deferred\materialF.glsl & softenlight
+ && target.addColorAttachment(GL_RGB16F); // frag_data[3] PBR emissive OR material env intensity
return valid;
}
LLPipeline::LLPipeline() :
- mBackfaceCull(false),
- mMatrixOpCount(0),
- mTextureMatrixOps(0),
- mNumVisibleNodes(0),
- mNumVisibleFaces(0),
- mPoissonOffset(0),
-
- mInitialized(false),
- mShadersLoaded(false),
- mTransformFeedbackPrimitives(0),
- mRenderDebugFeatureMask(0),
- mRenderDebugMask(0),
- mOldRenderDebugMask(0),
- mMeshDirtyQueryObject(0),
- mGroupQ1Locked(false),
- mResetVertexBuffers(false),
- mLastRebuildPool(NULL),
- mLightMask(0),
- mLightMovingMask(0)
-{
- mNoiseMap = 0;
- mTrueNoiseMap = 0;
- mLightFunc = 0;
+ mBackfaceCull(false),
+ mMatrixOpCount(0),
+ mTextureMatrixOps(0),
+ mNumVisibleNodes(0),
+ mNumVisibleFaces(0),
+ mPoissonOffset(0),
+
+ mInitialized(false),
+ mShadersLoaded(false),
+ mTransformFeedbackPrimitives(0),
+ mRenderDebugFeatureMask(0),
+ mRenderDebugMask(0),
+ mOldRenderDebugMask(0),
+ mMeshDirtyQueryObject(0),
+ mGroupQ1Locked(false),
+ mResetVertexBuffers(false),
+ mLastRebuildPool(NULL),
+ mLightMask(0),
+ mLightMovingMask(0)
+{
+ mNoiseMap = 0;
+ mTrueNoiseMap = 0;
+ mLightFunc = 0;
for(U32 i = 0; i < 8; i++)
{
@@ -363,99 +369,99 @@ LLPipeline::LLPipeline() :
void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
{
- LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name);
- if ( cntrl_ptr.isNull() )
- {
- LL_WARNS() << "Global setting name not found:" << name << LL_ENDL;
- }
- else
- {
- cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- }
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name);
+ if ( cntrl_ptr.isNull() )
+ {
+ LL_WARNS() << "Global setting name not found:" << name << LL_ENDL;
+ }
+ else
+ {
+ cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+ }
}
void LLPipeline::init()
{
- refreshCachedSettings();
+ refreshCachedSettings();
mRT = &mMainRT;
- gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
- gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
- sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
- sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
- sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
+ gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
+ gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
+ sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
+ sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
+ sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
mInitialized = true;
+
+ stop_glerror();
- stop_glerror();
-
- //create render pass pools
- getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
+ //create render pass pools
+ getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
- getPool(LLDrawPool::POOL_SIMPLE);
- getPool(LLDrawPool::POOL_ALPHA_MASK);
- getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
- getPool(LLDrawPool::POOL_GRASS);
- getPool(LLDrawPool::POOL_FULLBRIGHT);
- getPool(LLDrawPool::POOL_BUMP);
- getPool(LLDrawPool::POOL_MATERIALS);
- getPool(LLDrawPool::POOL_GLOW);
- getPool(LLDrawPool::POOL_GLTF_PBR);
+ getPool(LLDrawPool::POOL_SIMPLE);
+ getPool(LLDrawPool::POOL_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_GRASS);
+ getPool(LLDrawPool::POOL_FULLBRIGHT);
+ getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
+ getPool(LLDrawPool::POOL_GLOW);
+ getPool(LLDrawPool::POOL_GLTF_PBR);
getPool(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
- resetFrameStats();
-
- if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
- {
- clearAllRenderDebugFeatures();
- }
- else
- {
- setAllRenderDebugFeatures(); // By default, all debugging features on
- }
- clearAllRenderDebugDisplays(); // All debug displays off
-
- if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
- {
- clearAllRenderTypes();
- }
- else if (gNonInteractive)
- {
- clearAllRenderTypes();
- }
- else
- {
- setAllRenderTypes(); // By default, all rendering types start enabled
- }
-
- // make sure RenderPerformanceTest persists (hackity hack hack)
- // disables non-object rendering (UI, sky, water, etc)
- if (gSavedSettings.getBOOL("RenderPerformanceTest"))
- {
- gSavedSettings.setBOOL("RenderPerformanceTest", FALSE);
- gSavedSettings.setBOOL("RenderPerformanceTest", TRUE);
- }
-
- mOldRenderDebugMask = mRenderDebugMask;
-
- mBackfaceCull = true;
-
- // Enable features
- LLViewerShaderMgr::instance()->setShaders();
-
- for (U32 i = 0; i < 2; ++i)
- {
- mSpotLightFade[i] = 1.f;
- }
-
- if (mCubeVB.isNull())
- {
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
- }
-
- mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK);
- mDeferredVB->allocateBuffer(8, 0);
+ resetFrameStats();
+
+ if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
+ {
+ clearAllRenderDebugFeatures();
+ }
+ else
+ {
+ setAllRenderDebugFeatures(); // By default, all debugging features on
+ }
+ clearAllRenderDebugDisplays(); // All debug displays off
+
+ if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
+ {
+ clearAllRenderTypes();
+ }
+ else if (gNonInteractive)
+ {
+ clearAllRenderTypes();
+ }
+ else
+ {
+ setAllRenderTypes(); // By default, all rendering types start enabled
+ }
+
+ // make sure RenderPerformanceTest persists (hackity hack hack)
+ // disables non-object rendering (UI, sky, water, etc)
+ if (gSavedSettings.getBOOL("RenderPerformanceTest"))
+ {
+ gSavedSettings.setBOOL("RenderPerformanceTest", FALSE);
+ gSavedSettings.setBOOL("RenderPerformanceTest", TRUE);
+ }
+
+ mOldRenderDebugMask = mRenderDebugMask;
+
+ mBackfaceCull = true;
+
+ // Enable features
+ LLViewerShaderMgr::instance()->setShaders();
+
+ for (U32 i = 0; i < 2; ++i)
+ {
+ mSpotLightFade[i] = 1.f;
+ }
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
+ }
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK);
+ mDeferredVB->allocateBuffer(8, 0);
{
mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -470,83 +476,83 @@ void LLPipeline::init()
mScreenTriangleVB->unmapBuffer();
}
- //
- // Update all settings to trigger a cached settings refresh
- //
- connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred");
- connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred");
- connectRefreshCachedSettingsSafe("RenderUseFarClip");
- connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
- connectRefreshCachedSettingsSafe("UseOcclusion");
- // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
- // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
- connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
- connectRefreshCachedSettingsSafe("RenderFSAASamples");
- connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
- connectRefreshCachedSettingsSafe("RenderUIBuffer");
- connectRefreshCachedSettingsSafe("RenderShadowDetail");
+ //
+ // Update all settings to trigger a cached settings refresh
+ //
+ connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred");
+ connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred");
+ connectRefreshCachedSettingsSafe("RenderUseFarClip");
+ connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
+ connectRefreshCachedSettingsSafe("UseOcclusion");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
+ connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
+ connectRefreshCachedSettingsSafe("RenderFSAASamples");
+ connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
+ connectRefreshCachedSettingsSafe("RenderUIBuffer");
+ connectRefreshCachedSettingsSafe("RenderShadowDetail");
connectRefreshCachedSettingsSafe("RenderShadowSplits");
- connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
- connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
- connectRefreshCachedSettingsSafe("RenderDelayCreation");
- connectRefreshCachedSettingsSafe("RenderAnimateRes");
- connectRefreshCachedSettingsSafe("FreezeTime");
- connectRefreshCachedSettingsSafe("DebugBeaconLineWidth");
- connectRefreshCachedSettingsSafe("RenderHighlightBrightness");
- connectRefreshCachedSettingsSafe("RenderHighlightColor");
- connectRefreshCachedSettingsSafe("RenderHighlightThickness");
- connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred");
- connectRefreshCachedSettingsSafe("PreviewAmbientColor");
- connectRefreshCachedSettingsSafe("PreviewDiffuse0");
- connectRefreshCachedSettingsSafe("PreviewSpecular0");
- connectRefreshCachedSettingsSafe("PreviewDiffuse1");
- connectRefreshCachedSettingsSafe("PreviewSpecular1");
- connectRefreshCachedSettingsSafe("PreviewDiffuse2");
- connectRefreshCachedSettingsSafe("PreviewSpecular2");
- connectRefreshCachedSettingsSafe("PreviewDirection0");
- connectRefreshCachedSettingsSafe("PreviewDirection1");
- connectRefreshCachedSettingsSafe("PreviewDirection2");
- connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha");
- connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount");
- connectRefreshCachedSettingsSafe("RenderGlowLumWeights");
- connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights");
- connectRefreshCachedSettingsSafe("RenderGlowResolutionPow");
- connectRefreshCachedSettingsSafe("RenderGlowIterations");
- connectRefreshCachedSettingsSafe("RenderGlowWidth");
- connectRefreshCachedSettingsSafe("RenderGlowStrength");
- connectRefreshCachedSettingsSafe("RenderGlowNoise");
- connectRefreshCachedSettingsSafe("RenderDepthOfField");
- connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
- connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
- connectRefreshCachedSettingsSafe("CameraFNumber");
- connectRefreshCachedSettingsSafe("CameraFocalLength");
- connectRefreshCachedSettingsSafe("CameraFieldOfView");
- connectRefreshCachedSettingsSafe("RenderShadowNoise");
- connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
- connectRefreshCachedSettingsSafe("RenderSSAOScale");
- connectRefreshCachedSettingsSafe("RenderSSAOMaxScale");
- connectRefreshCachedSettingsSafe("RenderSSAOFactor");
- connectRefreshCachedSettingsSafe("RenderSSAOEffect");
- connectRefreshCachedSettingsSafe("RenderShadowOffsetError");
- connectRefreshCachedSettingsSafe("RenderShadowBiasError");
- connectRefreshCachedSettingsSafe("RenderShadowOffset");
- connectRefreshCachedSettingsSafe("RenderShadowBias");
- connectRefreshCachedSettingsSafe("RenderSpotShadowOffset");
- connectRefreshCachedSettingsSafe("RenderSpotShadowBias");
- connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff");
- connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff");
- connectRefreshCachedSettingsSafe("RenderShadowGaussian");
- connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
- connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
- connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
- connectRefreshCachedSettingsSafe("RenderFarClip");
- connectRefreshCachedSettingsSafe("RenderShadowSplitExponent");
- connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff");
- connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff");
- connectRefreshCachedSettingsSafe("CameraOffset");
- connectRefreshCachedSettingsSafe("CameraMaxCoF");
- connectRefreshCachedSettingsSafe("CameraDoFResScale");
- connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
+ connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
+ connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
+ connectRefreshCachedSettingsSafe("RenderDelayCreation");
+ connectRefreshCachedSettingsSafe("RenderAnimateRes");
+ connectRefreshCachedSettingsSafe("FreezeTime");
+ connectRefreshCachedSettingsSafe("DebugBeaconLineWidth");
+ connectRefreshCachedSettingsSafe("RenderHighlightBrightness");
+ connectRefreshCachedSettingsSafe("RenderHighlightColor");
+ connectRefreshCachedSettingsSafe("RenderHighlightThickness");
+ connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred");
+ connectRefreshCachedSettingsSafe("PreviewAmbientColor");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse0");
+ connectRefreshCachedSettingsSafe("PreviewSpecular0");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse1");
+ connectRefreshCachedSettingsSafe("PreviewSpecular1");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse2");
+ connectRefreshCachedSettingsSafe("PreviewSpecular2");
+ connectRefreshCachedSettingsSafe("PreviewDirection0");
+ connectRefreshCachedSettingsSafe("PreviewDirection1");
+ connectRefreshCachedSettingsSafe("PreviewDirection2");
+ connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha");
+ connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount");
+ connectRefreshCachedSettingsSafe("RenderGlowLumWeights");
+ connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights");
+ connectRefreshCachedSettingsSafe("RenderGlowResolutionPow");
+ connectRefreshCachedSettingsSafe("RenderGlowIterations");
+ connectRefreshCachedSettingsSafe("RenderGlowWidth");
+ connectRefreshCachedSettingsSafe("RenderGlowStrength");
+ connectRefreshCachedSettingsSafe("RenderGlowNoise");
+ connectRefreshCachedSettingsSafe("RenderDepthOfField");
+ connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
+ connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
+ connectRefreshCachedSettingsSafe("CameraFNumber");
+ connectRefreshCachedSettingsSafe("CameraFocalLength");
+ connectRefreshCachedSettingsSafe("CameraFieldOfView");
+ connectRefreshCachedSettingsSafe("RenderShadowNoise");
+ connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
+ connectRefreshCachedSettingsSafe("RenderSSAOScale");
+ connectRefreshCachedSettingsSafe("RenderSSAOMaxScale");
+ connectRefreshCachedSettingsSafe("RenderSSAOFactor");
+ connectRefreshCachedSettingsSafe("RenderSSAOEffect");
+ connectRefreshCachedSettingsSafe("RenderShadowOffsetError");
+ connectRefreshCachedSettingsSafe("RenderShadowBiasError");
+ connectRefreshCachedSettingsSafe("RenderShadowOffset");
+ connectRefreshCachedSettingsSafe("RenderShadowBias");
+ connectRefreshCachedSettingsSafe("RenderSpotShadowOffset");
+ connectRefreshCachedSettingsSafe("RenderSpotShadowBias");
+ connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff");
+ connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff");
+ connectRefreshCachedSettingsSafe("RenderShadowGaussian");
+ connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
+ connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
+ connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
+ connectRefreshCachedSettingsSafe("RenderFarClip");
+ connectRefreshCachedSettingsSafe("RenderShadowSplitExponent");
+ connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff");
+ connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff");
+ connectRefreshCachedSettingsSafe("CameraOffset");
+ connectRefreshCachedSettingsSafe("CameraMaxCoF");
+ connectRefreshCachedSettingsSafe("CameraDoFResScale");
+ connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflections");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionIterations");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionRayStep");
@@ -554,8 +560,11 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionDepthRejectBias");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples");
- connectRefreshCachedSettingsSafe("RenderBufferVisualization");
- gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+ connectRefreshCachedSettingsSafe("RenderBufferVisualization");
+ connectRefreshCachedSettingsSafe("RenderMirrors");
+ connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");
+ connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier");
+ gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}
LLPipeline::~LLPipeline()
@@ -564,99 +573,100 @@ LLPipeline::~LLPipeline()
void LLPipeline::cleanup()
{
- assertInitialized();
-
- mGroupQ1.clear() ;
-
- for(pool_set_t::iterator iter = mPools.begin();
- iter != mPools.end(); )
- {
- pool_set_t::iterator curiter = iter++;
- LLDrawPool* poolp = *curiter;
- if (poolp->isFacePool())
- {
- LLFacePool* face_pool = (LLFacePool*) poolp;
- if (face_pool->mReferences.empty())
- {
- mPools.erase(curiter);
- removeFromQuickLookup( poolp );
- delete poolp;
- }
- }
- else
- {
- mPools.erase(curiter);
- removeFromQuickLookup( poolp );
- delete poolp;
- }
- }
-
- if (!mTerrainPools.empty())
- {
- LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL;
- }
- if (!mTreePools.empty())
- {
- LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
- }
-
- delete mAlphaPoolPreWater;
+ assertInitialized();
+
+ mGroupQ1.clear() ;
+
+ for(pool_set_t::iterator iter = mPools.begin();
+ iter != mPools.end(); )
+ {
+ pool_set_t::iterator curiter = iter++;
+ LLDrawPool* poolp = *curiter;
+ if (poolp->isFacePool())
+ {
+ LLFacePool* face_pool = (LLFacePool*) poolp;
+ if (face_pool->mReferences.empty())
+ {
+ mPools.erase(curiter);
+ removeFromQuickLookup( poolp );
+ delete poolp;
+ }
+ }
+ else
+ {
+ mPools.erase(curiter);
+ removeFromQuickLookup( poolp );
+ delete poolp;
+ }
+ }
+
+ if (!mTerrainPools.empty())
+ {
+ LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL;
+ }
+ if (!mTreePools.empty())
+ {
+ LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
+ }
+
+ delete mAlphaPoolPreWater;
mAlphaPoolPreWater = nullptr;
delete mAlphaPoolPostWater;
mAlphaPoolPostWater = nullptr;
- delete mSkyPool;
- mSkyPool = NULL;
- delete mTerrainPool;
- mTerrainPool = NULL;
- delete mWaterPool;
- mWaterPool = NULL;
- delete mSimplePool;
- mSimplePool = NULL;
- delete mFullbrightPool;
- mFullbrightPool = NULL;
- delete mGlowPool;
- mGlowPool = NULL;
- delete mBumpPool;
- mBumpPool = NULL;
- // don't delete wl sky pool it was handled above in the for loop
- //delete mWLSkyPool;
- mWLSkyPool = NULL;
-
- releaseGLBuffers();
-
- mFaceSelectImagep = NULL;
+ delete mSkyPool;
+ mSkyPool = NULL;
+ delete mTerrainPool;
+ mTerrainPool = NULL;
+ delete mWaterPool;
+ mWaterPool = NULL;
+ delete mSimplePool;
+ mSimplePool = NULL;
+ delete mFullbrightPool;
+ mFullbrightPool = NULL;
+ delete mGlowPool;
+ mGlowPool = NULL;
+ delete mBumpPool;
+ mBumpPool = NULL;
+ // don't delete wl sky pool it was handled above in the for loop
+ //delete mWLSkyPool;
+ mWLSkyPool = NULL;
+
+ releaseGLBuffers();
+
+ mFaceSelectImagep = NULL;
mMovedList.clear();
mMovedBridge.clear();
mShiftList.clear();
- mInitialized = false;
+ mInitialized = false;
- mDeferredVB = NULL;
+ mDeferredVB = NULL;
mScreenTriangleVB = nullptr;
- mCubeVB = NULL;
+ mCubeVB = NULL;
mReflectionMapManager.cleanup();
+ mHeroProbeManager.cleanup();
}
//============================================================================
-void LLPipeline::destroyGL()
+void LLPipeline::destroyGL()
{
- stop_glerror();
- unloadShaders();
- mHighlightFaces.clear();
-
- resetDrawOrders();
+ stop_glerror();
+ unloadShaders();
+ mHighlightFaces.clear();
+
+ resetDrawOrders();
- releaseGLBuffers();
+ releaseGLBuffers();
- if (mMeshDirtyQueryObject)
- {
- glDeleteQueries(1, &mMeshDirtyQueryObject);
- mMeshDirtyQueryObject = 0;
- }
+ if (mMeshDirtyQueryObject)
+ {
+ glDeleteQueries(1, &mMeshDirtyQueryObject);
+ mMeshDirtyQueryObject = 0;
+ }
}
void LLPipeline::requestResizeScreenTexture()
@@ -679,155 +689,173 @@ void LLPipeline::resizeShadowTexture()
void LLPipeline::resizeScreenTexture()
{
- if (gPipeline.shadersLoaded())
- {
- GLuint resX = gViewerWindow->getWorldViewWidthRaw();
- GLuint resY = gViewerWindow->getWorldViewHeightRaw();
-
- if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
- {
- releaseScreenBuffers();
+ if (gPipeline.shadersLoaded())
+ {
+ GLuint resX = gViewerWindow->getWorldViewWidthRaw();
+ GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+
+ if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
+ {
+ releaseScreenBuffers();
releaseSunShadowTargets();
releaseSpotShadowTargets();
- allocateScreenBuffer(resX,resY);
+ allocateScreenBuffer(resX,resY);
gResizeScreenTexture = FALSE;
- }
- }
+ }
+ }
}
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
+ eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
- return ret == FBO_SUCCESS_FULLRES;
+ return ret == FBO_SUCCESS_FULLRES;
}
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- // try to allocate screen buffers at requested resolution and samples
- // - on failure, shrink number of samples and try again
- // - if not multisampled, shrink resolution and try again (favor X resolution over Y)
- // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
+ // try to allocate screen buffers at requested resolution and samples
+ // - on failure, shrink number of samples and try again
+ // - if not multisampled, shrink resolution and try again (favor X resolution over Y)
+ // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
// refresh cached settings here to protect against inconsistent event handling order
refreshCachedSettings();
- U32 samples = RenderFSAASamples;
-
- eFBOStatus ret = FBO_SUCCESS_FULLRES;
- if (!allocateScreenBuffer(resX, resY, samples))
- {
- //failed to allocate at requested specification, return false
- ret = FBO_FAILURE;
-
- releaseScreenBuffers();
- //reduce number of samples
- while (samples > 0)
- {
- samples /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
- { //success
- return FBO_SUCCESS_LOWRES;
- }
- releaseScreenBuffers();
- }
-
- samples = 0;
-
- //reduce resolution
- while (resY > 0 && resX > 0)
- {
- resY /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
- {
- return FBO_SUCCESS_LOWRES;
- }
- releaseScreenBuffers();
-
- resX /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
- {
- return FBO_SUCCESS_LOWRES;
- }
- releaseScreenBuffers();
- }
-
- LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL;
- }
-
- return ret;
+ U32 samples = RenderFSAASamples;
+
+ eFBOStatus ret = FBO_SUCCESS_FULLRES;
+ if (!allocateScreenBuffer(resX, resY, samples))
+ {
+ //failed to allocate at requested specification, return false
+ ret = FBO_FAILURE;
+
+ releaseScreenBuffers();
+ //reduce number of samples
+ while (samples > 0)
+ {
+ samples /= 2;
+ if (allocateScreenBuffer(resX, resY, samples))
+ { //success
+ return FBO_SUCCESS_LOWRES;
+ }
+ releaseScreenBuffers();
+ }
+
+ samples = 0;
+
+ //reduce resolution
+ while (resY > 0 && resX > 0)
+ {
+ resY /= 2;
+ if (allocateScreenBuffer(resX, resY, samples))
+ {
+ return FBO_SUCCESS_LOWRES;
+ }
+ releaseScreenBuffers();
+
+ resX /= 2;
+ if (allocateScreenBuffer(resX, resY, samples))
+ {
+ return FBO_SUCCESS_LOWRES;
+ }
+ releaseScreenBuffers();
+ }
+
+ LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL;
+ }
+
+ return ret;
}
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- if (mRT == &mMainRT && sReflectionProbesEnabled)
+ if (mRT == &mMainRT)
{ // hacky -- allocate auxillary buffer
+
gCubeSnapshot = TRUE;
mReflectionMapManager.initReflectionMaps();
+ mHeroProbeManager.initReflectionMaps();
+
+ if (sReflectionProbesEnabled)
+ {
+ gCubeSnapshot = TRUE;
+ mReflectionMapManager.initReflectionMaps();
+ }
+
mRT = &mAuxillaryRT;
U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
allocateScreenBuffer(res, res, samples);
+
+ if (RenderMirrors)
+ {
+ mHeroProbeManager.initReflectionMaps();
+ res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it.
+ mRT = &mHeroProbeRT;
+ allocateScreenBuffer(res, res, samples);
+ }
+
mRT = &mMainRT;
gCubeSnapshot = FALSE;
}
- // remember these dimensions
- mRT->width = resX;
- mRT->height = resY;
-
- U32 res_mod = RenderResolutionDivisor;
+ // remember these dimensions
+ mRT->width = resX;
+ mRT->height = resY;
+
+ U32 res_mod = RenderResolutionDivisor;
- if (res_mod > 1 && res_mod < resX && res_mod < resY)
- {
- resX /= res_mod;
- resY /= res_mod;
- }
+ if (res_mod > 1 && res_mod < resX && res_mod < resY)
+ {
+ resX /= res_mod;
+ resY /= res_mod;
+ }
//water reflection texture (always needed as scratch space whether or not transparent water is enabled)
mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
- if (RenderUIBuffer)
- {
- if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA))
- {
- return false;
- }
- }
-
- S32 shadow_detail = RenderShadowDetail;
- bool ssao = RenderDeferredSSAO;
-
- //allocate deferred rendering color buffers
- if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false;
- if (!addDeferredAttachments(mRT->deferredScreen)) return false;
-
- GLuint screenFormat = GL_RGBA16F;
-
- if (!mRT->screen.allocate(resX, resY, screenFormat)) return false;
+ if (RenderUIBuffer)
+ {
+ if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA))
+ {
+ return false;
+ }
+ }
+
+ S32 shadow_detail = RenderShadowDetail;
+ bool ssao = RenderDeferredSSAO;
+
+ //allocate deferred rendering color buffers
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false;
+ if (!addDeferredAttachments(mRT->deferredScreen)) return false;
+
+ GLuint screenFormat = GL_RGBA16F;
+
+ if (!mRT->screen.allocate(resX, resY, screenFormat)) return false;
mRT->deferredScreen.shareDepthBuffer(mRT->screen);
- if (samples > 0)
- {
- if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false;
- }
- else
- {
- mRT->fxaaBuffer.release();
- }
-
- if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
- { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
- if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false;
- }
- else
- {
- mRT->deferredLight.release();
- }
+ if (samples > 0)
+ {
+ if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false;
+ }
+ else
+ {
+ mRT->fxaaBuffer.release();
+ }
+
+ if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
+ { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false;
+ }
+ else
+ {
+ mRT->deferredLight.release();
+ }
allocateShadowBuffer(resX, resY);
@@ -836,7 +864,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mSceneMap.allocate(resX, resY, GL_RGB, true);
}
- const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR");
+ const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR");
const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA;
mPostMap.allocate(resX, resY, post_color_fmt);
@@ -848,9 +876,9 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
gGL.getTexUnit(0)->disable();
- stop_glerror();
+ stop_glerror();
- return true;
+ return true;
}
// must be even to avoid a stripe in the horizontal shadow blur
@@ -909,7 +937,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
// set up shadow map filtering and compare modes
if (shadow_detail > 0)
- {
+ {
for (U32 i = 0; i < 4; i++)
{
LLRenderTarget* shadow_target = getSunShadowTarget(i);
@@ -942,7 +970,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
}
}
- return true;
+ return true;
}
//static
@@ -955,86 +983,86 @@ void LLPipeline::updateRenderTransparentWater()
void LLPipeline::refreshCachedSettings()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
- LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
- LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
- LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
- LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
-
- LLPipeline::sUseOcclusion =
- (!gUseWireframe
- && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0;
-
+ LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
+ LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
+ LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
+ LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
+ LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
+
+ LLPipeline::sUseOcclusion =
+ (!gUseWireframe
+ && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
+ && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0;
+
WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
- RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
- RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0;
- RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
- RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
- RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
+ RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
+ RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0;
+ RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
+ RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
+ RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");
- RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
- RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
- RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation");
- RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes");
- FreezeTime = gSavedSettings.getBOOL("FreezeTime");
- DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth");
- RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness");
- RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor");
- RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness");
- RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred");
- PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor");
- PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
- PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0");
- PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
- PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1");
- PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
- PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2");
- PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
- PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
- PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
- RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
- RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
- RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
- RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
- RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow");
- RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
- RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
- RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
- RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise");
- RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
- RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
- CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
- CameraFNumber = gSavedSettings.getF32("CameraFNumber");
- CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
- CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
- RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
- RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
- RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
- RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale");
- RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor");
- RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect");
- RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError");
- RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError");
- RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset");
- RenderShadowBias = gSavedSettings.getF32("RenderShadowBias");
- RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset");
- RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias");
- RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff");
- RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff");
- RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
- RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
- RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
- RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
- RenderFarClip = gSavedSettings.getF32("RenderFarClip");
- RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent");
- RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff");
- RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff");
- CameraOffset = gSavedSettings.getBOOL("CameraOffset");
- CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
- CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
- RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
+ RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
+ RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
+ RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation");
+ RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes");
+ FreezeTime = gSavedSettings.getBOOL("FreezeTime");
+ DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth");
+ RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness");
+ RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor");
+ RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness");
+ RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred");
+ PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor");
+ PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
+ PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0");
+ PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
+ PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1");
+ PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
+ PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2");
+ PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
+ PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
+ PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
+ RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
+ RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
+ RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
+ RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
+ RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow");
+ RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
+ RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
+ RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
+ RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise");
+ RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
+ RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
+ CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
+ CameraFNumber = gSavedSettings.getF32("CameraFNumber");
+ CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
+ CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
+ RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
+ RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
+ RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
+ RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale");
+ RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor");
+ RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect");
+ RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError");
+ RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError");
+ RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset");
+ RenderShadowBias = gSavedSettings.getF32("RenderShadowBias");
+ RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset");
+ RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias");
+ RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff");
+ RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff");
+ RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
+ RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
+ RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
+ RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
+ RenderFarClip = gSavedSettings.getF32("RenderFarClip");
+ RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent");
+ RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff");
+ RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff");
+ CameraOffset = gSavedSettings.getBOOL("CameraOffset");
+ CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
+ CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
+ RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
RenderScreenSpaceReflections = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
RenderScreenSpaceReflectionIterations = gSavedSettings.getS32("RenderScreenSpaceReflectionIterations");
RenderScreenSpaceReflectionRayStep = gSavedSettings.getF32("RenderScreenSpaceReflectionRayStep");
@@ -1042,60 +1070,68 @@ void LLPipeline::refreshCachedSettings()
RenderScreenSpaceReflectionDepthRejectBias = gSavedSettings.getF32("RenderScreenSpaceReflectionDepthRejectBias");
RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples");
- RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
- sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
- RenderSpotLight = nullptr;
-
- if (gNonInteractive)
+ RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
+ if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors)
{
- LLVOAvatar::sMaxNonImpostors = 1;
- LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
+ RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
+ LLViewerShaderMgr::instance()->clearShaderCache();
+ LLViewerShaderMgr::instance()->setShaders();
}
+ RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate");
+ RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier");
+
+ sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
+ RenderSpotLight = nullptr;
+
+ if (gNonInteractive)
+ {
+ LLVOAvatar::sMaxNonImpostors = 1;
+ LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
+ }
}
void LLPipeline::releaseGLBuffers()
{
- assertInitialized();
-
- if (mNoiseMap)
- {
- LLImageGL::deleteTextures(1, &mNoiseMap);
- mNoiseMap = 0;
- }
-
- if (mTrueNoiseMap)
- {
- LLImageGL::deleteTextures(1, &mTrueNoiseMap);
- mTrueNoiseMap = 0;
- }
+ assertInitialized();
+
+ if (mNoiseMap)
+ {
+ LLImageGL::deleteTextures(1, &mNoiseMap);
+ mNoiseMap = 0;
+ }
- releaseLUTBuffers();
+ if (mTrueNoiseMap)
+ {
+ LLImageGL::deleteTextures(1, &mTrueNoiseMap);
+ mTrueNoiseMap = 0;
+ }
- mWaterDis.release();
- mBake.release();
+ releaseLUTBuffers();
+ mWaterDis.release();
+
mSceneMap.release();
mPostMap.release();
- for (U32 i = 0; i < 3; i++)
- {
- mGlow[i].release();
- }
+ for (U32 i = 0; i < 3; i++)
+ {
+ mGlow[i].release();
+ }
- releaseScreenBuffers();
+ releaseScreenBuffers();
- gBumpImageList.destroyGL();
- LLVOAvatar::resetImpostors();
+ gBumpImageList.destroyGL();
+ LLVOAvatar::resetImpostors();
}
void LLPipeline::releaseLUTBuffers()
{
- if (mLightFunc)
- {
- LLImageGL::deleteTextures(1, &mLightFunc);
- mLightFunc = 0;
- }
+ if (mLightFunc)
+ {
+ LLImageGL::deleteTextures(1, &mLightFunc);
+ mLightFunc = 0;
+ }
mPbrBrdfLut.release();
@@ -1118,6 +1154,12 @@ void LLPipeline::releaseScreenBuffers()
mRT->fxaaBuffer.release();
mRT->deferredScreen.release();
mRT->deferredLight.release();
+
+ mHeroProbeRT.uiScreen.release();
+ mHeroProbeRT.screen.release();
+ mHeroProbeRT.fxaaBuffer.release();
+ mHeroProbeRT.deferredScreen.release();
+ mHeroProbeRT.deferredLight.release();
}
void LLPipeline::releaseSunShadowTarget(U32 index)
@@ -1128,10 +1170,10 @@ void LLPipeline::releaseSunShadowTarget(U32 index)
void LLPipeline::releaseSunShadowTargets()
{
- for (U32 i = 0; i < 4; i++)
- {
+ for (U32 i = 0; i < 4; i++)
+ {
releaseSunShadowTarget(i);
- }
+ }
}
void LLPipeline::releaseSpotShadowTargets()
@@ -1149,19 +1191,16 @@ void LLPipeline::createGLBuffers()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
stop_glerror();
- assertInitialized();
+ assertInitialized();
- // Use FBO for bake tex
- mBake.allocate(512, 512, GL_RGBA, true); // SL-12781 Build > Upload > Model; 3D Preview
+ stop_glerror();
- stop_glerror();
-
- GLuint resX = gViewerWindow->getWorldViewWidthRaw();
- GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+ GLuint resX = gViewerWindow->getWorldViewWidthRaw();
+ GLuint resY = gViewerWindow->getWorldViewHeightRaw();
// allocate screen space glow buffers
const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
- const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR");
+ const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR");
const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA;
for (U32 i = 0; i < 3; i++)
{
@@ -1172,100 +1211,100 @@ void LLPipeline::createGLBuffers()
mRT->width = 0;
mRT->height = 0;
-
- if (!mNoiseMap)
- {
- const U32 noiseRes = 128;
- LLVector3 noise[noiseRes*noiseRes];
-
- F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
- for (U32 i = 0; i < noiseRes*noiseRes; ++i)
- {
- noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
- noise[i].normVec();
- noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
- }
-
- LLImageGL::generateTextures(1, &mNoiseMap);
-
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- if (!mTrueNoiseMap)
- {
- const U32 noiseRes = 128;
- F32 noise[noiseRes*noiseRes*3];
- for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
- {
- noise[i] = ll_frand()*2.0-1.0;
- }
-
- LLImageGL::generateTextures(1, &mTrueNoiseMap);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- createLUTBuffers();
-
- gBumpImageList.restoreGL();
+
+ if (!mNoiseMap)
+ {
+ const U32 noiseRes = 128;
+ LLVector3 noise[noiseRes*noiseRes];
+
+ F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
+ for (U32 i = 0; i < noiseRes*noiseRes; ++i)
+ {
+ noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
+ noise[i].normVec();
+ noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
+ }
+
+ LLImageGL::generateTextures(1, &mNoiseMap);
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ if (!mTrueNoiseMap)
+ {
+ const U32 noiseRes = 128;
+ F32 noise[noiseRes*noiseRes*3];
+ for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
+ {
+ noise[i] = ll_frand()*2.0-1.0;
+ }
+
+ LLImageGL::generateTextures(1, &mTrueNoiseMap);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ createLUTBuffers();
+
+ gBumpImageList.restoreGL();
}
F32 lerpf(F32 a, F32 b, F32 w)
{
- return a + w * (b - a);
+ return a + w * (b - a);
}
void LLPipeline::createLUTBuffers()
{
- if (!mLightFunc)
- {
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
- U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- F32* ls = new F32[lightResX*lightResY];
- F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
+ if (!mLightFunc)
+ {
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
// Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
- for (U32 y = 0; y < lightResY; ++y)
- {
- for (U32 x = 0; x < lightResX; ++x)
- {
- ls[y*lightResX+x] = 0;
- F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * specExp;
-
- // Nothing special here. Just your typical blinn-phong term.
- spec = powf(sa, n);
-
- // Apply our normalization function.
- // Note: This is the full equation that applies the full normalization curve, not an approximation.
- // This is fine, given we only need to create our LUT once per buffer initialization.
- spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
-
- // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
- // Though some older drivers may not like this, newer drivers shouldn't have this problem.
- ls[y*lightResX+x] = spec;
- }
- }
-
- U32 pix_format = GL_R16F;
+ for (U32 y = 0; y < lightResY; ++y)
+ {
+ for (U32 x = 0; x < lightResX; ++x)
+ {
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * specExp;
+
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
+
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
+ }
+ }
+
+ U32 pix_format = GL_R16F;
#if LL_DARWIN
- // Need to work around limited precision with 10.6.8 and older drivers
- //
- pix_format = GL_R32F;
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
#endif
- LLImageGL::generateTextures(1, &mLightFunc);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- delete [] ls;
- }
+ LLImageGL::generateTextures(1, &mLightFunc);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ delete [] ls;
+ }
mPbrBrdfLut.allocate(512, 512, GL_RG16F);
mPbrBrdfLut.bindTarget();
@@ -1297,23 +1336,23 @@ void LLPipeline::createLUTBuffers()
void LLPipeline::restoreGL()
{
- assertInitialized();
+ assertInitialized();
- LLViewerShaderMgr::instance()->setShaders();
+ LLViewerShaderMgr::instance()->setShaders();
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->restoreGL();
- }
- }
- }
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ part->restoreGL();
+ }
+ }
+ }
}
bool LLPipeline::shadersLoaded()
@@ -1328,281 +1367,281 @@ bool LLPipeline::canUseWindLightShaders() const
bool LLPipeline::canUseAntiAliasing() const
{
- return true;
+ return true;
}
void LLPipeline::unloadShaders()
{
- LLViewerShaderMgr::instance()->unloadShaders();
- mShadersLoaded = false;
+ LLViewerShaderMgr::instance()->unloadShaders();
+ mShadersLoaded = false;
}
void LLPipeline::assertInitializedDoError()
{
- LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL;
+ LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL;
}
//============================================================================
void LLPipeline::enableShadows(const bool enable_shadows)
{
- //should probably do something here to wrangle shadows....
+ //should probably do something here to wrangle shadows....
}
class LLOctreeDirtyTexture : public OctreeTraveler
{
public:
- const std::set<LLViewerFetchedTexture*>& mTextures;
-
- LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
-
- virtual void visit(const OctreeNode* node)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
-
- if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
- {
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
- {
- LLDrawInfo* params = *j;
- LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture);
- if (tex && mTextures.find(tex) != mTextures.end())
- {
- group->setState(LLSpatialGroup::GEOM_DIRTY);
- }
- }
- }
- }
-
- for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- traverse(bridge->mOctree);
- }
- }
+ const std::set<LLViewerFetchedTexture*>& mTextures;
+
+ LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
+
+ virtual void visit(const OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
+ {
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ LLDrawInfo* params = *j;
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture);
+ if (tex && mTextures.find(tex) != mTextures.end())
+ {
+ group->setState(LLSpatialGroup::GEOM_DIRTY);
+ }
+ }
+ }
+ }
+
+ for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
+ {
+ LLSpatialBridge* bridge = *i;
+ traverse(bridge->mOctree);
+ }
+ }
};
// Called when a texture changes # of channels (causes faces to move to alpha pool)
void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
-
- // *TODO: This is inefficient and causes frame spikes; need a better way to do this
- // Most of the time is spent in dirty.traverse.
-
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- if (poolp->isFacePool())
- {
- ((LLFacePool*) poolp)->dirtyTextures(textures);
- }
- }
-
- LLOctreeDirtyTexture dirty(textures);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- dirty.traverse(part->mOctree);
- }
- }
- }
+ assertInitialized();
+
+ // *TODO: This is inefficient and causes frame spikes; need a better way to do this
+ // Most of the time is spent in dirty.traverse.
+
+ for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
+ {
+ LLDrawPool *poolp = *iter;
+ if (poolp->isFacePool())
+ {
+ ((LLFacePool*) poolp)->dirtyTextures(textures);
+ }
+ }
+
+ LLOctreeDirtyTexture dirty(textures);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ dirty.traverse(part->mOctree);
+ }
+ }
+ }
}
LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
{
- assertInitialized();
-
- LLDrawPool *poolp = NULL;
- switch( type )
- {
- case LLDrawPool::POOL_SIMPLE:
- poolp = mSimplePool;
- break;
-
- case LLDrawPool::POOL_GRASS:
- poolp = mGrassPool;
- break;
-
- case LLDrawPool::POOL_ALPHA_MASK:
- poolp = mAlphaMaskPool;
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
- poolp = mFullbrightAlphaMaskPool;
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT:
- poolp = mFullbrightPool;
- break;
-
- case LLDrawPool::POOL_GLOW:
- poolp = mGlowPool;
- break;
-
- case LLDrawPool::POOL_TREE:
- poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 );
- break;
-
- case LLDrawPool::POOL_TERRAIN:
- poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 );
- break;
-
- case LLDrawPool::POOL_BUMP:
- poolp = mBumpPool;
- break;
- case LLDrawPool::POOL_MATERIALS:
- poolp = mMaterialsPool;
- break;
- case LLDrawPool::POOL_ALPHA_PRE_WATER:
- poolp = mAlphaPoolPreWater;
- break;
+ assertInitialized();
+
+ LLDrawPool *poolp = NULL;
+ switch( type )
+ {
+ case LLDrawPool::POOL_SIMPLE:
+ poolp = mSimplePool;
+ break;
+
+ case LLDrawPool::POOL_GRASS:
+ poolp = mGrassPool;
+ break;
+
+ case LLDrawPool::POOL_ALPHA_MASK:
+ poolp = mAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = mFullbrightAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT:
+ poolp = mFullbrightPool;
+ break;
+
+ case LLDrawPool::POOL_GLOW:
+ poolp = mGlowPool;
+ break;
+
+ case LLDrawPool::POOL_TREE:
+ poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 );
+ break;
+
+ case LLDrawPool::POOL_TERRAIN:
+ poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 );
+ break;
+
+ case LLDrawPool::POOL_BUMP:
+ poolp = mBumpPool;
+ break;
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ poolp = mAlphaPoolPreWater;
+ break;
case LLDrawPool::POOL_ALPHA_POST_WATER:
poolp = mAlphaPoolPostWater;
break;
- case LLDrawPool::POOL_AVATAR:
- case LLDrawPool::POOL_CONTROL_AV:
- break; // Do nothing
+ case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
+ break; // Do nothing
- case LLDrawPool::POOL_SKY:
- poolp = mSkyPool;
- break;
+ case LLDrawPool::POOL_SKY:
+ poolp = mSkyPool;
+ break;
- case LLDrawPool::POOL_WATER:
- poolp = mWaterPool;
- break;
+ case LLDrawPool::POOL_WATER:
+ poolp = mWaterPool;
+ break;
- case LLDrawPool::POOL_WL_SKY:
- poolp = mWLSkyPool;
- break;
+ case LLDrawPool::POOL_WL_SKY:
+ poolp = mWLSkyPool;
+ break;
- case LLDrawPool::POOL_GLTF_PBR:
- poolp = mPBROpaquePool;
- break;
+ case LLDrawPool::POOL_GLTF_PBR:
+ poolp = mPBROpaquePool;
+ break;
case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
poolp = mPBRAlphaMaskPool;
break;
- default:
- llassert(0);
- LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
- break;
- }
+ default:
+ llassert(0);
+ LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
+ break;
+ }
- return poolp;
+ return poolp;
}
-LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0)
+LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0)
{
- LLDrawPool *poolp = findPool(type, tex0);
- if (poolp)
- {
- return poolp;
- }
+ LLDrawPool *poolp = findPool(type, tex0);
+ if (poolp)
+ {
+ return poolp;
+ }
- LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0);
- addPool( new_poolp );
+ LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0);
+ addPool( new_poolp );
- return new_poolp;
+ return new_poolp;
}
// static
LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
- U32 type = getPoolTypeFromTE(te, imagep);
- return gPipeline.getPool(type, imagep);
+ U32 type = getPoolTypeFromTE(te, imagep);
+ return gPipeline.getPool(type, imagep);
}
-//static
+//static
U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
- if (!te || !imagep)
- {
- return 0;
- }
-
- LLMaterial* mat = te->getMaterialParams().get();
+ if (!te || !imagep)
+ {
+ return 0;
+ }
+
+ LLMaterial* mat = te->getMaterialParams().get();
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
- bool color_alpha = te->getColor().mV[3] < 0.999f;
- bool alpha = color_alpha;
- if (imagep)
- {
- alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
- }
-
- if (alpha && mat)
- {
- switch (mat->getDiffuseAlphaMode())
- {
- case 1:
- alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
- break;
- case 0: //alpha mode set to none, never go to alpha pool
- case 3: //alpha mode set to emissive, never go to alpha pool
- alpha = color_alpha;
- break;
- default: //alpha mode set to "mask", go to alpha pool if fullbright
- alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
- break;
- }
- }
-
- if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND))
- {
- return LLDrawPool::POOL_ALPHA;
- }
- else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
- {
- return LLDrawPool::POOL_BUMP;
- }
+ bool color_alpha = te->getColor().mV[3] < 0.999f;
+ bool alpha = color_alpha;
+ if (imagep)
+ {
+ alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
+ }
+
+ if (alpha && mat)
+ {
+ switch (mat->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = color_alpha;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ break;
+ }
+ }
+
+ if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND))
+ {
+ return LLDrawPool::POOL_ALPHA;
+ }
+ else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
+ {
+ return LLDrawPool::POOL_BUMP;
+ }
else if (gltf_mat)
{
return LLDrawPool::POOL_GLTF_PBR;
}
- else if (mat && !alpha)
- {
- return LLDrawPool::POOL_MATERIALS;
- }
- else
- {
- return LLDrawPool::POOL_SIMPLE;
- }
+ else if (mat && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
+ }
+ else
+ {
+ return LLDrawPool::POOL_SIMPLE;
+ }
}
void LLPipeline::addPool(LLDrawPool *new_poolp)
{
- assertInitialized();
- mPools.insert(new_poolp);
- addToQuickLookup( new_poolp );
+ assertInitialized();
+ mPools.insert(new_poolp);
+ addToQuickLookup( new_poolp );
}
void LLPipeline::allocDrawable(LLViewerObject *vobj)
{
- LLDrawable *drawable = new LLDrawable(vobj);
- vobj->mDrawable = drawable;
-
- //encompass completely sheared objects by taking
- //the most extreme point possible (<1,1,0.5>)
- drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
- if (vobj->isOrphaned())
- {
- drawable->setState(LLDrawable::FORCE_INVISIBLE);
- }
- drawable->updateXform(TRUE);
+ LLDrawable *drawable = new LLDrawable(vobj);
+ vobj->mDrawable = drawable;
+
+ //encompass completely sheared objects by taking
+ //the most extreme point possible (<1,1,0.5>)
+ drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
+ if (vobj->isOrphaned())
+ {
+ drawable->setState(LLDrawable::FORCE_INVISIBLE);
+ }
+ drawable->updateXform(TRUE);
}
@@ -1610,56 +1649,56 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
-
- LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done
-
- // Based on flags, remove the drawable from the queues that it's on.
- if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
- {
- LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
- if (iter != mMovedList.end())
- {
- mMovedList.erase(iter);
- }
- }
-
- if (drawablep->getSpatialGroup())
- {
- if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))
- {
+ assertInitialized();
+
+ LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done
+
+ // Based on flags, remove the drawable from the queues that it's on.
+ if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
+ {
+ LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
+ if (iter != mMovedList.end())
+ {
+ mMovedList.erase(iter);
+ }
+ }
+
+ if (drawablep->getSpatialGroup())
+ {
+ if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))
+ {
#ifdef LL_RELEASE_FOR_DOWNLOAD
- LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL;
+ LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL;
#else
- LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL;
+ LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL;
#endif
- }
- }
-
- mLights.erase(drawablep);
-
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
- {
- if (iter->drawable == drawablep)
- {
- mNearbyLights.erase(iter);
- break;
- }
- }
-
- for (U32 i = 0; i < 2; ++i)
- {
- if (mShadowSpotLight[i] == drawablep)
- {
- mShadowSpotLight[i] = NULL;
- }
-
- if (mTargetShadowSpotLight[i] == drawablep)
- {
- mTargetShadowSpotLight[i] = NULL;
- }
- }
+ }
+ }
+
+ mLights.erase(drawablep);
+
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ if (iter->drawable == drawablep)
+ {
+ mNearbyLights.erase(iter);
+ break;
+ }
+ }
+
+ for (U32 i = 0; i < 2; ++i)
+ {
+ if (mShadowSpotLight[i] == drawablep)
+ {
+ mShadowSpotLight[i] = NULL;
+ }
+
+ if (mTargetShadowSpotLight[i] == drawablep)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
+ }
}
//static
@@ -1687,239 +1726,239 @@ void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
U32 LLPipeline::addObject(LLViewerObject *vobj)
{
- if (RenderDelayCreation)
- {
- mCreateQ.push_back(vobj);
- }
- else
- {
- createObject(vobj);
- }
+ if (RenderDelayCreation)
+ {
+ mCreateQ.push_back(vobj);
+ }
+ else
+ {
+ createObject(vobj);
+ }
- return 1;
+ return 1;
}
void LLPipeline::createObjects(F32 max_dtime)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- LLTimer update_timer;
-
- while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime)
- {
- LLViewerObject* vobj = mCreateQ.front();
- if (!vobj->isDead())
- {
- createObject(vobj);
- }
- mCreateQ.pop_front();
- }
+ LLTimer update_timer;
- //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter)
- //{
- // createObject(*iter);
- //}
+ while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime)
+ {
+ LLViewerObject* vobj = mCreateQ.front();
+ if (!vobj->isDead())
+ {
+ createObject(vobj);
+ }
+ mCreateQ.pop_front();
+ }
+
+ //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter)
+ //{
+ // createObject(*iter);
+ //}
- //mCreateQ.clear();
+ //mCreateQ.clear();
}
void LLPipeline::createObject(LLViewerObject* vobj)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- LLDrawable* drawablep = vobj->mDrawable;
-
- if (!drawablep)
- {
- drawablep = vobj->createDrawable(this);
- }
- else
- {
- LL_ERRS() << "Redundant drawable creation!" << LL_ENDL;
- }
-
- llassert(drawablep);
-
- if (vobj->getParent())
- {
- vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1
- }
- else
- {
- vobj->setDrawableParent(NULL); // LLPipeline::addObject 2
- }
-
- markRebuild(drawablep, LLDrawable::REBUILD_ALL);
-
- if (drawablep->getVOVolume() && RenderAnimateRes)
- {
- // fun animated res
- drawablep->updateXform(TRUE);
- drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
- drawablep->setScale(LLVector3(0,0,0));
- drawablep->makeActive();
- }
+ LLDrawable* drawablep = vobj->mDrawable;
+
+ if (!drawablep)
+ {
+ drawablep = vobj->createDrawable(this);
+ }
+ else
+ {
+ LL_ERRS() << "Redundant drawable creation!" << LL_ENDL;
+ }
+
+ llassert(drawablep);
+
+ if (vobj->getParent())
+ {
+ vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1
+ }
+ else
+ {
+ vobj->setDrawableParent(NULL); // LLPipeline::addObject 2
+ }
+
+ markRebuild(drawablep, LLDrawable::REBUILD_ALL);
+
+ if (drawablep->getVOVolume() && RenderAnimateRes)
+ {
+ // fun animated res
+ drawablep->updateXform(TRUE);
+ drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
+ drawablep->setScale(LLVector3(0,0,0));
+ drawablep->makeActive();
+ }
}
void LLPipeline::resetFrameStats()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
+ assertInitialized();
- sCompiles = 0;
- mNumVisibleFaces = 0;
+ sCompiles = 0;
+ mNumVisibleFaces = 0;
- if (mOldRenderDebugMask != mRenderDebugMask)
- {
- gObjectList.clearDebugText();
- mOldRenderDebugMask = mRenderDebugMask;
- }
+ if (mOldRenderDebugMask != mRenderDebugMask)
+ {
+ gObjectList.clearDebugText();
+ mOldRenderDebugMask = mRenderDebugMask;
+ }
}
//external functions for asynchronous updating
void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
{
LL_PROFILE_ZONE_SCOPED;
- if (FreezeTime)
- {
- return;
- }
- if (!drawablep)
- {
- LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
- return;
- }
- if (drawablep->isState(LLDrawable::EARLY_MOVE))
- {
- return;
- }
-
- assertInitialized();
-
- // update drawable now
- drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED
- drawablep->updateMove(); // returns done
- drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
- // Put on move list so that EARLY_MOVE gets cleared
- if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
- {
- mMovedList.push_back(drawablep);
- drawablep->setState(LLDrawable::ON_MOVE_LIST);
- }
+ if (FreezeTime)
+ {
+ return;
+ }
+ if (!drawablep)
+ {
+ LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
+ return;
+ }
+ if (drawablep->isState(LLDrawable::EARLY_MOVE))
+ {
+ return;
+ }
+
+ assertInitialized();
+
+ // update drawable now
+ drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED
+ drawablep->updateMove(); // returns done
+ drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
+ // Put on move list so that EARLY_MOVE gets cleared
+ if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
+ {
+ mMovedList.push_back(drawablep);
+ drawablep->setState(LLDrawable::ON_MOVE_LIST);
+ }
}
void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
{
LL_PROFILE_ZONE_SCOPED;
- if (FreezeTime)
- {
- return;
- }
- if (!drawablep)
- {
- LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
- return;
- }
- if (drawablep->isState(LLDrawable::EARLY_MOVE))
- {
- return;
- }
-
- assertInitialized();
-
- // update drawable now
- drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
- drawablep->updateMove();
- drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
- // Put on move list so that EARLY_MOVE gets cleared
- if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
- {
- mMovedList.push_back(drawablep);
- drawablep->setState(LLDrawable::ON_MOVE_LIST);
- }
+ if (FreezeTime)
+ {
+ return;
+ }
+ if (!drawablep)
+ {
+ LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
+ return;
+ }
+ if (drawablep->isState(LLDrawable::EARLY_MOVE))
+ {
+ return;
+ }
+
+ assertInitialized();
+
+ // update drawable now
+ drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
+ drawablep->updateMove();
+ drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
+ // Put on move list so that EARLY_MOVE gets cleared
+ if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
+ {
+ mMovedList.push_back(drawablep);
+ drawablep->setState(LLDrawable::ON_MOVE_LIST);
+ }
}
void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
{
LL_PROFILE_ZONE_SCOPED;
- for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
- iter != moved_list.end(); )
- {
- LLDrawable::drawable_vector_t::iterator curiter = iter++;
- LLDrawable *drawablep = *curiter;
- bool done = true;
- if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE)))
- {
- done = drawablep->updateMove();
- }
- drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
- if (done)
- {
- if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE))
- {
- drawablep->makeStatic();
- }
- drawablep->clearState(LLDrawable::ON_MOVE_LIST);
- if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
- { //will likely not receive any future world matrix updates
- // -- this keeps attachments from getting stuck in space and falling off your avatar
- drawablep->clearState(LLDrawable::ANIMATED_CHILD);
- markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
- if (drawablep->getVObj())
- {
- drawablep->getVObj()->dirtySpatialGroup();
- }
- }
- iter = moved_list.erase(curiter);
- }
- }
+ for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
+ iter != moved_list.end(); )
+ {
+ LLDrawable::drawable_vector_t::iterator curiter = iter++;
+ LLDrawable *drawablep = *curiter;
+ bool done = true;
+ if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE)))
+ {
+ done = drawablep->updateMove();
+ }
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
+ if (done)
+ {
+ if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE))
+ {
+ drawablep->makeStatic();
+ }
+ drawablep->clearState(LLDrawable::ON_MOVE_LIST);
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ { //will likely not receive any future world matrix updates
+ // -- this keeps attachments from getting stuck in space and falling off your avatar
+ drawablep->clearState(LLDrawable::ANIMATED_CHILD);
+ markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
+ if (drawablep->getVObj())
+ {
+ drawablep->getVObj()->dirtySpatialGroup();
+ }
+ }
+ iter = moved_list.erase(curiter);
+ }
+ }
}
void LLPipeline::updateMove()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- if (FreezeTime)
- {
- return;
- }
-
- assertInitialized();
-
- for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
- iter != mRetexturedList.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
- if (drawablep && !drawablep->isDead())
- {
- drawablep->updateTexture();
- }
- }
- mRetexturedList.clear();
-
- updateMovedList(mMovedList);
-
- //balance octrees
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->mOctree->balance();
- }
- }
-
- //balance the VO Cache tree
- LLVOCachePartition* vo_part = region->getVOCachePartition();
- if(vo_part)
- {
- vo_part->mOctree->balance();
- }
- }
+ if (FreezeTime)
+ {
+ return;
+ }
+
+ assertInitialized();
+
+ for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
+ iter != mRetexturedList.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+ if (drawablep && !drawablep->isDead())
+ {
+ drawablep->updateTexture();
+ }
+ }
+ mRetexturedList.clear();
+
+ updateMovedList(mMovedList);
+
+ //balance octrees
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ part->mOctree->balance();
+ }
+ }
+
+ //balance the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->mOctree->balance();
+ }
+ }
}
/////////////////////////////////////////////////////////////////////////////
@@ -1930,299 +1969,299 @@ void LLPipeline::updateMove()
F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
{
llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots
- LLVector3 lookAt = center - camera.getOrigin();
- F32 dist = lookAt.length();
+ LLVector3 lookAt = center - camera.getOrigin();
+ F32 dist = lookAt.length();
- //ramp down distance for nearby objects
- //shrink dist by dist/16.
- if (dist < 16.f)
- {
- dist /= 16.f;
- dist *= dist;
- dist *= 16.f;
- }
+ //ramp down distance for nearby objects
+ //shrink dist by dist/16.
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
- //get area of circle around node
- F32 app_angle = atanf(size.length()/dist);
- F32 radius = app_angle*LLDrawable::sCurPixelAngle;
- return radius*radius * F_PI;
+ //get area of circle around node
+ F32 app_angle = atanf(size.length()/dist);
+ F32 radius = app_angle*LLDrawable::sCurPixelAngle;
+ return radius*radius * F_PI;
}
//static
F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera)
{
- LLVector4a origin;
- origin.load3(camera.getOrigin().mV);
+ LLVector4a origin;
+ origin.load3(camera.getOrigin().mV);
- LLVector4a lookAt;
- lookAt.setSub(center, origin);
- F32 dist = lookAt.getLength3().getF32();
+ LLVector4a lookAt;
+ lookAt.setSub(center, origin);
+ F32 dist = lookAt.getLength3().getF32();
- //ramp down distance for nearby objects
- //shrink dist by dist/16.
- if (dist < 16.f)
- {
- dist /= 16.f;
- dist *= dist;
- dist *= 16.f;
- }
+ //ramp down distance for nearby objects
+ //shrink dist by dist/16.
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
- //get area of circle around node
- F32 app_angle = atanf(size.getLength3().getF32()/dist);
- F32 radius = app_angle*LLDrawable::sCurPixelAngle;
- return radius*radius * F_PI;
+ //get area of circle around node
+ F32 app_angle = atanf(size.getLength3().getF32()/dist);
+ F32 radius = app_angle*LLDrawable::sCurPixelAngle;
+ return radius*radius * F_PI;
}
void LLPipeline::grabReferences(LLCullResult& result)
{
- sCull = &result;
+ sCull = &result;
}
void LLPipeline::clearReferences()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- sCull = NULL;
- mGroupSaveQ1.clear();
+ sCull = NULL;
+ mGroupSaveQ1.clear();
}
void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
- if (drawable == drawablep)
- {
- LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL;
- }
- }
+ if (drawable == drawablep)
+ {
+ LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL;
+ }
+ }
}
void check_references(LLDrawable* drawable, LLFace* face)
{
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- if (drawable->getFace(i) == face)
- {
- LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ if (drawable->getFace(i) == face)
+ {
+ LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
}
void check_references(LLSpatialGroup* group, LLFace* face)
{
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(drawable)
- {
- check_references(drawable, face);
- }
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(drawable)
+ {
+ check_references(drawable, face);
+ }
}
}
void LLPipeline::checkReferences(LLFace* face)
{
#if 0
- if (sCull)
- {
- for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, face);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, face);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, face);
- }
-
- for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
- {
- LLDrawable* drawable = *iter;
- check_references(drawable, face);
- }
- }
+ if (sCull)
+ {
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ check_references(drawable, face);
+ }
+ }
#endif
}
void LLPipeline::checkReferences(LLDrawable* drawable)
{
#if 0
- if (sCull)
- {
- for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, drawable);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, drawable);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, drawable);
- }
-
- for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
- {
- if (drawable == *iter)
- {
- LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
- }
+ if (sCull)
+ {
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ {
+ if (drawable == *iter)
+ {
+ LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
+ }
#endif
}
void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
{
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
- for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
- {
- LLDrawInfo* params = *j;
- if (params == draw_info)
- {
- LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
- }
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
+ {
+ LLDrawInfo* params = *j;
+ if (params == draw_info)
+ {
+ LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
+ }
}
void LLPipeline::checkReferences(LLDrawInfo* draw_info)
{
#if 0
- if (sCull)
- {
- for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, draw_info);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, draw_info);
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- check_references(group, draw_info);
- }
- }
+ if (sCull)
+ {
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+ }
#endif
}
void LLPipeline::checkReferences(LLSpatialGroup* group)
{
#if CHECK_PIPELINE_REFERENCES
- if (sCull)
- {
- for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
- {
- if (group == *iter)
- {
- LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
- {
- if (group == *iter)
- {
- LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
- {
- if (group == *iter)
- {
- LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
- }
- }
- }
+ if (sCull)
+ {
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
+ }
+ }
+ }
#endif
}
bool LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
{
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- if (hasRenderType(part->mDrawableType))
- {
- if (part->visibleObjectsInFrustum(camera))
- {
- return true;
- }
- }
- }
- }
- }
-
- return false;
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ if (part->visibleObjectsInFrustum(camera))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
}
bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max)
{
- const F32 X = 65536.f;
+ const F32 X = 65536.f;
- min = LLVector3(X,X,X);
- max = LLVector3(-X,-X,-X);
+ min = LLVector3(X,X,X);
+ max = LLVector3(-X,-X,-X);
- LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- bool res = true;
+ bool res = true;
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- if (hasRenderType(part->mDrawableType))
- {
- if (!part->getVisibleExtents(camera, min, max))
- {
- res = false;
- }
- }
- }
- }
- }
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ if (!part->getVisibleExtents(camera, min, max))
+ {
+ res = false;
+ }
+ }
+ }
+ }
+ }
- LLViewerCamera::sCurCameraID = saved_camera_id;
- return res;
+ LLViewerCamera::sCurCameraID = saved_camera_id;
+ return res;
}
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
@@ -2230,7 +2269,8 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
// static
bool LLPipeline::isWaterClip()
{
- return (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
+ // We always pretend that we're not clipping water when rendering mirrors.
+ return (gPipeline.mHeroProbeManager.isMirrorPass()) ? false : (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
}
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
@@ -2238,11 +2278,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
- bool water_clip = isWaterClip();
+ bool water_clip = isWaterClip();
if (water_clip)
{
-
+
LLVector3 pnorm;
F32 water_height = LLEnvironment::instance().getWaterHeight();
@@ -2257,7 +2297,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
//camera is above water, cull below water
pnorm = LLVector3(0, 0, -1);
}
-
+
LLPlane plane;
plane.setVec(LLVector3(0, 0, water_height), pnorm);
@@ -2268,48 +2308,48 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
camera.disableUserClipPlane();
}
- grabReferences(result);
-
- sCull->clear();
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- if (hasRenderType(part->mDrawableType))
- {
- part->cull(camera);
- }
- }
- }
-
- //scan the VO Cache tree
- LLVOCachePartition* vo_part = region->getVOCachePartition();
- if(vo_part)
- {
- vo_part->cull(camera, sUseOcclusion > 0);
- }
- }
-
- if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
- gSky.mVOSkyp.notNull() &&
- gSky.mVOSkyp->mDrawable.notNull())
- {
- gSky.mVOSkyp->mDrawable->setVisible(camera);
- sCull->pushDrawable(gSky.mVOSkyp->mDrawable);
- gSky.updateCull();
- stop_glerror();
- }
-
- if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
+ grabReferences(result);
+
+ sCull->clear();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ part->cull(camera);
+ }
+ }
+ }
+
+ //scan the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->cull(camera, sUseOcclusion > 0);
+ }
+ }
+
+ if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
+ gSky.mVOSkyp.notNull() &&
+ gSky.mVOSkyp->mDrawable.notNull())
+ {
+ gSky.mVOSkyp->mDrawable->setVisible(camera);
+ sCull->pushDrawable(gSky.mVOSkyp->mDrawable);
+ gSky.updateCull();
+ stop_glerror();
+ }
+
+ if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
gPipeline.canUseWindLightShaders() &&
- gSky.mVOWLSkyp.notNull() &&
+ gSky.mVOWLSkyp.notNull() &&
gSky.mVOWLSkyp->mDrawable.notNull())
{
gSky.mVOWLSkyp->mDrawable->setVisible(camera);
@@ -2319,28 +2359,28 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
{
- if (group->isEmpty())
- {
- return;
- }
-
- group->setVisible();
-
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
- {
- group->updateDistance(camera);
- }
-
- assertInitialized();
-
- if (!group->getSpatialPartition()->mRenderByGroup)
- { //render by drawable
- sCull->pushDrawableGroup(group);
- }
- else
- { //render by group
- sCull->pushVisibleGroup(group);
- }
+ if (group->isEmpty())
+ {
+ return;
+ }
+
+ group->setVisible();
+
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
+ {
+ group->updateDistance(camera);
+ }
+
+ assertInitialized();
+
+ if (!group->getSpatialPartition()->mRenderByGroup)
+ { //render by drawable
+ sCull->pushDrawableGroup(group);
+ }
+ else
+ { //render by group
+ sCull->pushVisibleGroup(group);
+ }
if (group->needsUpdate() ||
group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
@@ -2349,30 +2389,30 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
// an occlusion query to find out if it's an occluder
markOccluder(group);
}
- mNumVisibleNodes++;
+ mNumVisibleNodes++;
}
void LLPipeline::markOccluder(LLSpatialGroup* group)
{
- if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION))
- {
- LLSpatialGroup* parent = group->getParent();
-
- if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED))
- { //only mark top most occluders as active occlusion
- sCull->pushOcclusionGroup(group);
- group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
-
- if (parent &&
- !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) &&
- parent->getElementCount() == 0 &&
- parent->needsUpdate())
- {
- sCull->pushOcclusionGroup(group);
- parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
- }
- }
- }
+ if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION))
+ {
+ LLSpatialGroup* parent = group->getParent();
+
+ if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ { //only mark top most occluders as active occlusion
+ sCull->pushOcclusionGroup(group);
+ group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+
+ if (parent &&
+ !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) &&
+ parent->getElementCount() == 0 &&
+ parent->needsUpdate())
+ {
+ sCull->pushOcclusionGroup(group);
+ parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+ }
+ }
+ }
}
void LLPipeline::doOcclusion(LLCamera& camera)
@@ -2400,18 +2440,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
gGL.setColorMask(true, true);
}
-
- if (LLPipeline::sUseOcclusion > 1 &&
- (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
+
+ if (sReflectionProbesEnabled && sUseOcclusion > 1 && !LLPipeline::sShadowRender && !gCubeSnapshot)
{
- LLVertexBuffer::unbind();
-
gGL.setColorMask(false, false);
-
- LLGLDisable blend(GL_BLEND);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
LLGLDisable cull(GL_CULL_FACE);
gOcclusionCubeProgram.bind();
@@ -2422,118 +2455,145 @@ void LLPipeline::doOcclusion(LLCamera& camera)
}
mCubeVB->setBuffer();
- for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
+ mHeroProbeManager.doOcclusion();
+ gOcclusionCubeProgram.unbind();
+
+ gGL.setColorMask(true, true);
+ }
+
+ if (LLPipeline::sUseOcclusion > 1 &&
+ (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
+ {
+ LLVertexBuffer::unbind();
+
+ gGL.setColorMask(false, false);
+
+ LLGLDisable blend(GL_BLEND);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ LLGLDisable cull(GL_CULL_FACE);
+
+ gOcclusionCubeProgram.bind();
+
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
+ }
+ mCubeVB->setBuffer();
+
+ for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
if (!group->isDead())
{
group->doOcclusion(&camera);
group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
}
- }
-
- //apply occlusion culling to object cache tree
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLVOCachePartition* vo_part = (*iter)->getVOCachePartition();
- if(vo_part)
- {
- vo_part->processOccluders(&camera);
- }
- }
-
- gGL.setColorMask(true, true);
- }
-}
-
+ }
+
+ //apply occlusion culling to object cache tree
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLVOCachePartition* vo_part = (*iter)->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->processOccluders(&camera);
+ }
+ }
+
+ gGL.setColorMask(true, true);
+ }
+}
+
bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep)
{
- bool update_complete = drawablep->updateGeometry();
- if (update_complete && assertInitialized())
- {
- drawablep->setState(LLDrawable::BUILT);
- }
- return update_complete;
+ bool update_complete = drawablep->updateGeometry();
+ if (update_complete && assertInitialized())
+ {
+ drawablep->setState(LLDrawable::BUILT);
+ }
+ return update_complete;
}
void LLPipeline::updateGL()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- {
- while (!LLGLUpdate::sGLQ.empty())
- {
- LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
- glu->updateGL();
- glu->mInQ = FALSE;
- LLGLUpdate::sGLQ.pop_front();
- }
- }
+ {
+ while (!LLGLUpdate::sGLQ.empty())
+ {
+ LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
+ glu->updateGL();
+ glu->mInQ = FALSE;
+ LLGLUpdate::sGLQ.pop_front();
+ }
+ }
}
void LLPipeline::clearRebuildGroups()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- LLSpatialGroup::sg_vector_t hudGroups;
-
- mGroupQ1Locked = true;
- // Iterate through all drawables on the priority build queue,
- for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
- iter != mGroupQ1.end(); ++iter)
- {
- LLSpatialGroup* group = *iter;
-
- // If the group contains HUD objects, save the group
- if (group->isHUDGroup())
- {
- hudGroups.push_back(group);
- }
- // Else, no HUD objects so clear the build state
- else
- {
- group->clearState(LLSpatialGroup::IN_BUILD_Q1);
- }
- }
-
- // Clear the group
- mGroupQ1.clear();
-
- // Copy the saved HUD groups back in
- mGroupQ1.assign(hudGroups.begin(), hudGroups.end());
- mGroupQ1Locked = false;
+ LLSpatialGroup::sg_vector_t hudGroups;
+
+ mGroupQ1Locked = true;
+ // Iterate through all drawables on the priority build queue,
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
+ iter != mGroupQ1.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ // If the group contains HUD objects, save the group
+ if (group->isHUDGroup())
+ {
+ hudGroups.push_back(group);
+ }
+ // Else, no HUD objects so clear the build state
+ else
+ {
+ group->clearState(LLSpatialGroup::IN_BUILD_Q1);
+ }
+ }
+
+ // Clear the group
+ mGroupQ1.clear();
+
+ // Copy the saved HUD groups back in
+ mGroupQ1.assign(hudGroups.begin(), hudGroups.end());
+ mGroupQ1Locked = false;
}
void LLPipeline::clearRebuildDrawables()
{
- // Clear all drawables on the priority build queue,
- for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
- iter != mBuildQ1.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
- if (drawablep && !drawablep->isDead())
- {
- drawablep->clearState(LLDrawable::IN_REBUILD_Q);
- }
- }
- mBuildQ1.clear();
-
- //clear all moving bridges
- for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin();
- iter != mMovedBridge.end(); ++iter)
- {
- LLDrawable *drawablep = *iter;
- drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
- }
- mMovedBridge.clear();
-
- //clear all moving drawables
- for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin();
- iter != mMovedList.end(); ++iter)
- {
- LLDrawable *drawablep = *iter;
- drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
- }
- mMovedList.clear();
+ // Clear all drawables on the priority build queue,
+ for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
+ iter != mBuildQ1.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+ if (drawablep && !drawablep->isDead())
+ {
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q);
+ }
+ }
+ mBuildQ1.clear();
+
+ //clear all moving bridges
+ for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin();
+ iter != mMovedBridge.end(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
+ }
+ mMovedBridge.clear();
+
+ //clear all moving drawables
+ for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin();
+ iter != mMovedList.end(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
+ }
+ mMovedList.clear();
for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
iter != mShiftList.end(); ++iter)
@@ -2549,305 +2609,305 @@ void LLPipeline::rebuildPriorityGroups()
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("rebuildPriorityGroups");
- LLTimer update_timer;
- assertInitialized();
+ LLTimer update_timer;
+ assertInitialized();
- gMeshRepo.notifyLoadedMeshes();
+ gMeshRepo.notifyLoadedMeshes();
- mGroupQ1Locked = true;
- // Iterate through all drawables on the priority build queue,
- for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
- iter != mGroupQ1.end(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- group->rebuildGeom();
- group->clearState(LLSpatialGroup::IN_BUILD_Q1);
- }
+ mGroupQ1Locked = true;
+ // Iterate through all drawables on the priority build queue,
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
+ iter != mGroupQ1.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ group->rebuildGeom();
+ group->clearState(LLSpatialGroup::IN_BUILD_Q1);
+ }
- mGroupSaveQ1 = mGroupQ1;
- mGroupQ1.clear();
- mGroupQ1Locked = false;
+ mGroupSaveQ1 = mGroupQ1;
+ mGroupQ1.clear();
+ mGroupQ1Locked = false;
}
void LLPipeline::updateGeom(F32 max_dtime)
{
- LLTimer update_timer;
- LLPointer<LLDrawable> drawablep;
+ LLTimer update_timer;
+ LLPointer<LLDrawable> drawablep;
- LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
if (gCubeSnapshot)
{
return;
}
- assertInitialized();
-
- // notify various object types to reset internal cost metrics, etc.
- // for now, only LLVOVolume does this to throttle LOD changes
- LLVOVolume::preUpdateGeom();
-
- // Iterate through all drawables on the priority build queue,
- for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
- iter != mBuildQ1.end();)
- {
- LLDrawable::drawable_list_t::iterator curiter = iter++;
- LLDrawable* drawablep = *curiter;
- if (drawablep && !drawablep->isDead())
- {
- if (drawablep->isUnload())
- {
- drawablep->unload();
- drawablep->clearState(LLDrawable::FOR_UNLOAD);
- }
-
- if (updateDrawableGeom(drawablep))
- {
- drawablep->clearState(LLDrawable::IN_REBUILD_Q);
- mBuildQ1.erase(curiter);
- }
- }
- else
- {
- mBuildQ1.erase(curiter);
- }
- }
-
- updateMovedList(mMovedBridge);
+ assertInitialized();
+
+ // notify various object types to reset internal cost metrics, etc.
+ // for now, only LLVOVolume does this to throttle LOD changes
+ LLVOVolume::preUpdateGeom();
+
+ // Iterate through all drawables on the priority build queue,
+ for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
+ iter != mBuildQ1.end();)
+ {
+ LLDrawable::drawable_list_t::iterator curiter = iter++;
+ LLDrawable* drawablep = *curiter;
+ if (drawablep && !drawablep->isDead())
+ {
+ if (drawablep->isUnload())
+ {
+ drawablep->unload();
+ drawablep->clearState(LLDrawable::FOR_UNLOAD);
+ }
+
+ if (updateDrawableGeom(drawablep))
+ {
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q);
+ mBuildQ1.erase(curiter);
+ }
+ }
+ else
+ {
+ mBuildQ1.erase(curiter);
+ }
+ }
+
+ updateMovedList(mMovedBridge);
}
void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
{
- if(drawablep && !drawablep->isDead())
- {
- if (drawablep->isSpatialBridge())
- {
- const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
- llassert(root); // trying to catch a bad assumption
-
- if (root && // // this test may not be needed, see above
- root->getVObj()->isAttachment())
- {
- LLDrawable* rootparent = root->getParent();
- if (rootparent) // this IS sometimes NULL
- {
- LLViewerObject *vobj = rootparent->getVObj();
- llassert(vobj); // trying to catch a bad assumption
- if (vobj) // this test may not be needed, see above
- {
- LLVOAvatar* av = vobj->asAvatar();
- if (av &&
- ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass
- || av->isInMuteList()
- || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) ))
- {
- return;
- }
- }
- }
- }
- sCull->pushBridge((LLSpatialBridge*) drawablep);
- }
- else
- {
-
- sCull->pushDrawable(drawablep);
- }
-
- drawablep->setVisible(camera);
- }
+ if(drawablep && !drawablep->isDead())
+ {
+ if (drawablep->isSpatialBridge())
+ {
+ const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
+ llassert(root); // trying to catch a bad assumption
+
+ if (root && // // this test may not be needed, see above
+ root->getVObj()->isAttachment())
+ {
+ LLDrawable* rootparent = root->getParent();
+ if (rootparent) // this IS sometimes NULL
+ {
+ LLViewerObject *vobj = rootparent->getVObj();
+ llassert(vobj); // trying to catch a bad assumption
+ if (vobj) // this test may not be needed, see above
+ {
+ LLVOAvatar* av = vobj->asAvatar();
+ if (av &&
+ ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass
+ || av->isInMuteList()
+ || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) ))
+ {
+ return;
+ }
+ }
+ }
+ }
+ sCull->pushBridge((LLSpatialBridge*) drawablep);
+ }
+ else
+ {
+
+ sCull->pushDrawable(drawablep);
+ }
+
+ drawablep->setVisible(camera);
+ }
}
void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion)
{
- if (!drawablep)
- {
- //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL;
- return;
- }
-
- if (drawablep->isDead())
- {
- LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL;
- return;
- }
-
- if (drawablep->getParent())
- {
- //ensure that parent drawables are moved first
- markMoved(drawablep->getParent(), damped_motion);
- }
-
- assertInitialized();
-
- if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
- {
- if (drawablep->isSpatialBridge())
- {
- mMovedBridge.push_back(drawablep);
- }
- else
- {
- mMovedList.push_back(drawablep);
- }
- drawablep->setState(LLDrawable::ON_MOVE_LIST);
- }
- if (! damped_motion)
- {
- drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED
- }
- else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
- {
- drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
- }
+ if (!drawablep)
+ {
+ //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL;
+ return;
+ }
+
+ if (drawablep->isDead())
+ {
+ LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL;
+ return;
+ }
+
+ if (drawablep->getParent())
+ {
+ //ensure that parent drawables are moved first
+ markMoved(drawablep->getParent(), damped_motion);
+ }
+
+ assertInitialized();
+
+ if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
+ {
+ if (drawablep->isSpatialBridge())
+ {
+ mMovedBridge.push_back(drawablep);
+ }
+ else
+ {
+ mMovedList.push_back(drawablep);
+ }
+ drawablep->setState(LLDrawable::ON_MOVE_LIST);
+ }
+ if (! damped_motion)
+ {
+ drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED
+ }
+ else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
+ {
+ drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
+ }
}
void LLPipeline::markShift(LLDrawable *drawablep)
{
- if (!drawablep || drawablep->isDead())
- {
- return;
- }
+ if (!drawablep || drawablep->isDead())
+ {
+ return;
+ }
- assertInitialized();
+ assertInitialized();
- if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST))
- {
- drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE);
- if (drawablep->getParent())
- {
- markShift(drawablep->getParent());
- }
- mShiftList.push_back(drawablep);
- drawablep->setState(LLDrawable::ON_SHIFT_LIST);
- }
+ if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST))
+ {
+ drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE);
+ if (drawablep->getParent())
+ {
+ markShift(drawablep->getParent());
+ }
+ mShiftList.push_back(drawablep);
+ drawablep->setState(LLDrawable::ON_SHIFT_LIST);
+ }
}
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
-
- glClear(GL_DEPTH_BUFFER_BIT);
- gDepthDirty = true;
-
- LLVector4a offseta;
- offseta.load3(offset.mV);
-
- for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
- iter != mShiftList.end(); iter++)
- {
- LLDrawable *drawablep = *iter;
- if (drawablep->isDead())
- {
- continue;
- }
- drawablep->shiftPos(offseta);
- drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
- }
- mShiftList.resize(0);
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->shift(offseta);
- }
- }
- }
+ assertInitialized();
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+ gDepthDirty = true;
+
+ LLVector4a offseta;
+ offseta.load3(offset.mV);
+
+ for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+ iter != mShiftList.end(); iter++)
+ {
+ LLDrawable *drawablep = *iter;
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+ drawablep->shiftPos(offseta);
+ drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+ }
+ mShiftList.resize(0);
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ part->shift(offseta);
+ }
+ }
+ }
mReflectionMapManager.shift(offseta);
- LLHUDText::shiftAll(offset);
- LLHUDNameTag::shiftAll(offset);
+ LLHUDText::shiftAll(offset);
+ LLHUDNameTag::shiftAll(offset);
- display_update_camera();
+ display_update_camera();
}
void LLPipeline::markTextured(LLDrawable *drawablep)
{
- if (drawablep && !drawablep->isDead() && assertInitialized())
- {
- mRetexturedList.insert(drawablep);
- }
+ if (drawablep && !drawablep->isDead() && assertInitialized())
+ {
+ mRetexturedList.insert(drawablep);
+ }
}
void LLPipeline::markGLRebuild(LLGLUpdate* glu)
{
- if (glu && !glu->mInQ)
- {
- LLGLUpdate::sGLQ.push_back(glu);
- glu->mInQ = TRUE;
- }
+ if (glu && !glu->mInQ)
+ {
+ LLGLUpdate::sGLQ.push_back(glu);
+ glu->mInQ = TRUE;
+ }
}
void LLPipeline::markPartitionMove(LLDrawable* drawable)
{
- if (!drawable->isState(LLDrawable::PARTITION_MOVE) &&
- !drawable->getPositionGroup().equals3(LLVector4a::getZero()))
- {
- drawable->setState(LLDrawable::PARTITION_MOVE);
- mPartitionQ.push_back(drawable);
- }
+ if (!drawable->isState(LLDrawable::PARTITION_MOVE) &&
+ !drawable->getPositionGroup().equals3(LLVector4a::getZero()))
+ {
+ drawable->setState(LLDrawable::PARTITION_MOVE);
+ mPartitionQ.push_back(drawable);
+ }
}
void LLPipeline::processPartitionQ()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
- {
- LLDrawable* drawable = *iter;
- if (!drawable->isDead())
- {
- drawable->updateBinRadius();
- drawable->movePartition();
- }
- drawable->clearState(LLDrawable::PARTITION_MOVE);
- }
+ for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (!drawable->isDead())
+ {
+ drawable->updateBinRadius();
+ drawable->movePartition();
+ }
+ drawable->clearState(LLDrawable::PARTITION_MOVE);
+ }
- mPartitionQ.clear();
+ mPartitionQ.clear();
}
void LLPipeline::markMeshDirty(LLSpatialGroup* group)
{
- mMeshDirtyGroup.push_back(group);
+ mMeshDirtyGroup.push_back(group);
}
void LLPipeline::markRebuild(LLSpatialGroup* group)
{
- if (group && !group->isDead() && group->getSpatialPartition())
- {
- if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
- {
- llassert_always(!mGroupQ1Locked);
+ if (group && !group->isDead() && group->getSpatialPartition())
+ {
+ if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
+ {
+ llassert_always(!mGroupQ1Locked);
- mGroupQ1.push_back(group);
- group->setState(LLSpatialGroup::IN_BUILD_Q1);
- }
- }
+ mGroupQ1.push_back(group);
+ group->setState(LLSpatialGroup::IN_BUILD_Q1);
+ }
+ }
}
void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag)
{
- if (drawablep && !drawablep->isDead() && assertInitialized())
- {
- if (!drawablep->isState(LLDrawable::IN_REBUILD_Q))
- {
- mBuildQ1.push_back(drawablep);
- drawablep->setState(LLDrawable::IN_REBUILD_Q); // mark drawable as being in priority queue
- }
+ if (drawablep && !drawablep->isDead() && assertInitialized())
+ {
+ if (!drawablep->isState(LLDrawable::IN_REBUILD_Q))
+ {
+ mBuildQ1.push_back(drawablep);
+ drawablep->setState(LLDrawable::IN_REBUILD_Q); // mark drawable as being in priority queue
+ }
if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
- {
- drawablep->getVObj()->setChanged(LLXform::SILHOUETTE);
- }
- drawablep->setState(flag);
- }
+ {
+ drawablep->getVObj()->setChanged(LLXform::SILHOUETTE);
+ }
+ drawablep->setState(flag);
+ }
}
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
@@ -2855,300 +2915,300 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("stateSort");
- if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- LLPipeline::RENDER_TYPE_TERRAIN,
- LLPipeline::RENDER_TYPE_TREE,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::END_RENDER_TYPES))
- {
- //clear faces from face pools
- gPipeline.resetDrawOrders();
- }
-
- //LLVertexBuffer::unbind();
-
- grabReferences(result);
- for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
+ if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::END_RENDER_TYPES))
+ {
+ //clear faces from face pools
+ gPipeline.resetDrawOrders();
+ }
+
+ //LLVertexBuffer::unbind();
+
+ grabReferences(result);
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
if (group->isDead())
{
continue;
}
- group->checkOcclusion();
- if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- markOccluder(group);
- }
- else
- {
- group->setVisible();
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
+ group->checkOcclusion();
+ if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ markOccluder(group);
+ }
+ else
+ {
+ group->setVisible();
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
- markVisible(drawablep, camera);
- }
-
- { //rebuild mesh as soon as we know it's visible
- group->rebuildMesh();
- }
- }
- }
-
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
- {
- LLSpatialGroup* last_group = NULL;
- BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
- for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
- {
- LLCullResult::bridge_iterator cur_iter = i;
- LLSpatialBridge* bridge = *cur_iter;
- LLSpatialGroup* group = bridge->getSpatialGroup();
-
- if (last_group == NULL)
- {
- last_group = group;
- }
-
- if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- stateSort(bridge, camera, fov_changed);
- }
-
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
- last_group != group && last_group->changeLOD())
- {
- last_group->mLastUpdateDistance = last_group->mDistance;
- }
-
- last_group = group;
- }
-
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
- last_group && last_group->changeLOD())
- {
- last_group->mLastUpdateDistance = last_group->mDistance;
- }
- }
-
- for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
- {
- LLSpatialGroup* group = *iter;
+ markVisible(drawablep, camera);
+ }
+
+ { //rebuild mesh as soon as we know it's visible
+ group->rebuildMesh();
+ }
+ }
+ }
+
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
+ {
+ LLSpatialGroup* last_group = NULL;
+ BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ {
+ LLCullResult::bridge_iterator cur_iter = i;
+ LLSpatialBridge* bridge = *cur_iter;
+ LLSpatialGroup* group = bridge->getSpatialGroup();
+
+ if (last_group == NULL)
+ {
+ last_group = group;
+ }
+
+ if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ stateSort(bridge, camera, fov_changed);
+ }
+
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
+ last_group != group && last_group->changeLOD())
+ {
+ last_group->mLastUpdateDistance = last_group->mDistance;
+ }
+
+ last_group = group;
+ }
+
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
+ last_group && last_group->changeLOD())
+ {
+ last_group->mLastUpdateDistance = last_group->mDistance;
+ }
+ }
+
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
if (group->isDead())
{
continue;
}
- group->checkOcclusion();
- if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- markOccluder(group);
- }
- else
- {
- group->setVisible();
- stateSort(group, camera);
-
- { //rebuild mesh as soon as we know it's visible
- group->rebuildMesh();
- }
- }
- }
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE("stateSort"); // LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE);
- for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();
- iter != sCull->endVisibleList(); ++iter)
- {
- LLDrawable *drawablep = *iter;
- if (!drawablep->isDead())
- {
- stateSort(drawablep, camera);
- }
- }
- }
-
- postSort(camera);
+ group->checkOcclusion();
+ if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ markOccluder(group);
+ }
+ else
+ {
+ group->setVisible();
+ stateSort(group, camera);
+
+ { //rebuild mesh as soon as we know it's visible
+ group->rebuildMesh();
+ }
+ }
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE("stateSort"); // LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE);
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();
+ iter != sCull->endVisibleList(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ if (!drawablep->isDead())
+ {
+ stateSort(drawablep, camera);
+ }
+ }
+ }
+
+ postSort(camera);
}
void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
- if (group->changeLOD())
- {
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
- stateSort(drawablep, camera);
- }
+ if (group->changeLOD())
+ {
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
+ stateSort(drawablep, camera);
+ }
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
- { //avoid redundant stateSort calls
- group->mLastUpdateDistance = group->mDistance;
- }
- }
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
+ { //avoid redundant stateSort calls
+ group->mLastUpdateDistance = group->mDistance;
+ }
+ }
}
void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
if (bridge->getSpatialGroup()->changeLOD() || fov_changed)
- {
- bool force_update = false;
- bridge->updateDistance(camera, force_update);
- }
+ {
+ bool force_update = false;
+ bridge->updateDistance(camera, force_update);
+ }
}
void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
if (!drawablep
- || drawablep->isDead()
- || !hasRenderType(drawablep->getRenderType()))
- {
- return;
- }
-
+ || drawablep->isDead()
+ || !hasRenderType(drawablep->getRenderType()))
+ {
+ return;
+ }
+
// SL-11353
// ignore our own geo when rendering spotlight shadowmaps...
- //
+ //
if (RenderSpotLight && drawablep == RenderSpotLight)
{
return;
}
- if (LLSelectMgr::getInstance()->mHideSelectedObjects)
- {
- if (drawablep->getVObj().notNull() &&
- drawablep->getVObj()->isSelected())
- {
- return;
- }
- }
-
- if (drawablep->isAvatar())
- { //don't draw avatars beyond render distance or if we don't have a spatial group.
- if ((drawablep->getSpatialGroup() == NULL) ||
- (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance))
- {
- return;
- }
-
- LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get();
- if (!avatarp->isVisible())
- {
- return;
- }
- }
-
- assertInitialized();
-
- if (hasRenderType(drawablep->mRenderType))
- {
- if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE))
- {
- drawablep->setVisible(camera, NULL, FALSE);
- }
- }
-
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
- {
- //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here
- {
- if (!drawablep->isActive())
- {
- bool force_update = false;
- drawablep->updateDistance(camera, force_update);
- }
- else if (drawablep->isAvatar())
- {
- bool force_update = false;
- drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility()
- }
- }
- }
-
- if (!drawablep->getVOVolume())
- {
- for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin();
- iter != drawablep->mFaces.end(); iter++)
- {
- LLFace* facep = *iter;
-
- if (facep->hasGeometry())
- {
- if (facep->getPool())
- {
- facep->getPool()->enqueue(facep);
- }
- else
- {
- break;
- }
- }
- }
- }
-
- mNumVisibleFaces += drawablep->getNumFaces();
-}
-
-
-void forAllDrawables(LLCullResult::sg_iterator begin,
- LLCullResult::sg_iterator end,
- void (*func)(LLDrawable*))
-{
- for (LLCullResult::sg_iterator i = begin; i != end; ++i)
- {
+ if (LLSelectMgr::getInstance()->mHideSelectedObjects)
+ {
+ if (drawablep->getVObj().notNull() &&
+ drawablep->getVObj()->isSelected())
+ {
+ return;
+ }
+ }
+
+ if (drawablep->isAvatar())
+ { //don't draw avatars beyond render distance or if we don't have a spatial group.
+ if ((drawablep->getSpatialGroup() == NULL) ||
+ (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance))
+ {
+ return;
+ }
+
+ LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get();
+ if (!avatarp->isVisible())
+ {
+ return;
+ }
+ }
+
+ assertInitialized();
+
+ if (hasRenderType(drawablep->mRenderType))
+ {
+ if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE))
+ {
+ drawablep->setVisible(camera, NULL, FALSE);
+ }
+ }
+
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
+ {
+ //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here
+ {
+ if (!drawablep->isActive())
+ {
+ bool force_update = false;
+ drawablep->updateDistance(camera, force_update);
+ }
+ else if (drawablep->isAvatar())
+ {
+ bool force_update = false;
+ drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility()
+ }
+ }
+ }
+
+ if (!drawablep->getVOVolume())
+ {
+ for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin();
+ iter != drawablep->mFaces.end(); iter++)
+ {
+ LLFace* facep = *iter;
+
+ if (facep->hasGeometry())
+ {
+ if (facep->getPool())
+ {
+ facep->getPool()->enqueue(facep);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ mNumVisibleFaces += drawablep->getNumFaces();
+}
+
+
+void forAllDrawables(LLCullResult::sg_iterator begin,
+ LLCullResult::sg_iterator end,
+ void (*func)(LLDrawable*))
+{
+ for (LLCullResult::sg_iterator i = begin; i != end; ++i)
+ {
LLSpatialGroup* group = *i;
if (group->isDead())
{
continue;
}
- for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j)
- {
- if((*j)->hasDrawable())
- {
- func((LLDrawable*)(*j)->getDrawable());
- }
- }
- }
+ for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j)
+ {
+ if((*j)->hasDrawable())
+ {
+ func((LLDrawable*)(*j)->getDrawable());
+ }
+ }
+ }
}
void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*))
{
- forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func);
- forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func);
+ forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func);
+ forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func);
}
//function for creating scripted beacons
void renderScriptedBeacons(LLDrawable* drawablep)
{
- LLViewerObject *vobj = drawablep->getVObj();
- if (vobj
- && !vobj->isAvatar()
- && !vobj->getParent()
- && vobj->flagScripted())
- {
- if (gPipeline.sRenderBeacons)
- {
- gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
- }
-
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
- }
+ LLViewerObject *vobj = drawablep->getVObj();
+ if (vobj
+ && !vobj->isAvatar()
+ && !vobj->getParent()
+ && vobj->flagScripted())
+ {
+ if (gPipeline.sRenderBeacons)
+ {
+ gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
+ }
+
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
void renderScriptedTouchBeacons(LLDrawable *drawablep)
@@ -3551,169 +3611,169 @@ void LLPipeline::postSort(LLCamera &camera)
void render_hud_elements()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
- gPipeline.disableLights();
-
- LLGLSUIDefault gls_ui;
-
- //LLGLEnable stencil(GL_STENCIL_TEST);
- //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
- //glStencilMask(0xFFFFFFFF);
- //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
- gUIProgram.bind();
+ gPipeline.disableLights();
+
+ LLGLSUIDefault gls_ui;
+
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+ gUIProgram.bind();
gGL.color4f(1, 1, 1, 1);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
-
- // Draw the tracking overlays
- LLTracker::render3D();
-
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
+
+ // Draw the tracking overlays
+ LLTracker::render3D();
+
if (LLWorld::instanceExists())
{
// Show the property lines
LLWorld::getInstance()->renderPropertyLines();
}
- LLViewerParcelMgr::getInstance()->render();
- LLViewerParcelMgr::getInstance()->renderParcelCollision();
- }
- else if (gForceRenderLandFence)
- {
- // This is only set when not rendering the UI, for parcel snapshots
- LLViewerParcelMgr::getInstance()->render();
- }
- else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- LLHUDText::renderAllHUD();
- }
+ LLViewerParcelMgr::getInstance()->render();
+ LLViewerParcelMgr::getInstance()->renderParcelCollision();
+ }
+ else if (gForceRenderLandFence)
+ {
+ // This is only set when not rendering the UI, for parcel snapshots
+ LLViewerParcelMgr::getInstance()->render();
+ }
+ else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ LLHUDText::renderAllHUD();
+ }
- gUIProgram.unbind();
+ gUIProgram.unbind();
}
void LLPipeline::renderHighlights()
{
- assertInitialized();
-
- // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)
- // Render highlighted faces.
- LLGLSPipelineAlpha gls_pipeline_alpha;
- LLColor4 color(1.f, 1.f, 1.f, 0.5f);
- disableLights();
-
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
- }
-
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
-
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
- {
- // Make sure the selection image gets downloaded and decoded
- mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
-
- U32 count = mSelectedFaces.size();
- for (U32 i = 0; i < count; i++)
- {
- LLFace *facep = mSelectedFaces[i];
- if (!facep || facep->getDrawable()->isDead())
- {
- LL_ERRS() << "Bad face on selection" << LL_ENDL;
- return;
- }
-
- facep->renderSelected(mFaceSelectImagep, color);
- }
- }
-
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
- {
- // Paint 'em red!
- color.setVec(1.f, 0.f, 0.f, 0.5f);
-
- int count = mHighlightFaces.size();
- for (S32 i = 0; i < count; i++)
- {
- LLFace* facep = mHighlightFaces[i];
- facep->renderSelected(LLViewerTexture::sNullImagep, color);
- }
- }
-
- // Contains a list of the faces of objects that are physical or
- // have touch-handlers.
- mHighlightFaces.clear();
-
- if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
- {
- gHighlightProgram.unbind();
- }
-
-
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
- {
- color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightNormalProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
- }
-
- mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
-
- U32 count = mSelectedFaces.size();
- for (U32 i = 0; i < count; i++)
- {
- LLFace *facep = mSelectedFaces[i];
- if (!facep || facep->getDrawable()->isDead())
- {
- LL_ERRS() << "Bad face on selection" << LL_ENDL;
- return;
- }
-
- facep->renderSelected(mFaceSelectImagep, color);
- }
-
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightNormalProgram.unbind();
- }
- }
-
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
- {
- color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightSpecularProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
- }
-
- mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
-
- U32 count = mSelectedFaces.size();
- for (U32 i = 0; i < count; i++)
- {
- LLFace *facep = mSelectedFaces[i];
- if (!facep || facep->getDrawable()->isDead())
- {
- LL_ERRS() << "Bad face on selection" << LL_ENDL;
- return;
- }
-
- facep->renderSelected(mFaceSelectImagep, color);
- }
-
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightSpecularProgram.unbind();
- }
- }
+ assertInitialized();
+
+ // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)
+ // Render highlighted faces.
+ LLGLSPipelineAlpha gls_pipeline_alpha;
+ LLColor4 color(1.f, 1.f, 1.f, 0.5f);
+ disableLights();
+
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
+ {
+ // Make sure the selection image gets downloaded and decoded
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+ {
+ // Paint 'em red!
+ color.setVec(1.f, 0.f, 0.f, 0.5f);
+
+ int count = mHighlightFaces.size();
+ for (S32 i = 0; i < count; i++)
+ {
+ LLFace* facep = mHighlightFaces[i];
+ facep->renderSelected(LLViewerTexture::sNullImagep, color);
+ }
+ }
+
+ // Contains a list of the faces of objects that are physical or
+ // have touch-handlers.
+ mHighlightFaces.clear();
+
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
+ {
+ gHighlightProgram.unbind();
+ }
+
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+ {
+ color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+ {
+ color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.unbind();
+ }
+ }
}
//debug use
@@ -3721,8 +3781,8 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;
void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
{
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
+ LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
LL_PROFILE_GPU_ZONE("renderGeomDeferred");
llassert(!sRenderingHUDs);
@@ -3733,7 +3793,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
}
if (&camera == LLViewerCamera::getInstance())
- { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and
+ { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and
// current modelview matrix
glh::matrix4f last_modelview(gGLLastModelView);
glh::matrix4f cur_modelview(gGLModelView);
@@ -3755,41 +3815,42 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
setupHWLights();
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools");
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools");
- LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable cull(GL_CULL_FACE);
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- if (hasRenderType(poolp->getType()))
- {
- poolp->prerender();
- }
- }
+ for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
+ {
+ LLDrawPool *poolp = *iter;
+ if (hasRenderType(poolp->getType()))
+ {
+ poolp->prerender();
+ }
+ }
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- LLGLState::checkStates();
+ LLGLState::checkStates();
if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1)
{
//update reflection probe uniform
mReflectionMapManager.updateUniforms();
+ mHeroProbeManager.updateUniforms();
}
- U32 cur_type = 0;
-
- gGL.setColorMask(true, true);
-
- pool_set_t::iterator iter1 = mPools.begin();
+ U32 cur_type = 0;
- while ( iter1 != mPools.end() )
- {
- LLDrawPool *poolp = *iter1;
+ gGL.setColorMask(true, true);
+
+ pool_set_t::iterator iter1 = mPools.begin();
- cur_type = poolp->getType();
+ while ( iter1 != mPools.end() )
+ {
+ LLDrawPool *poolp = *iter1;
+
+ cur_type = poolp->getType();
if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
{
@@ -3800,57 +3861,57 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
doOcclusion(camera);
}
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render");
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginDeferredPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
-
- if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
- }
- poolp->endDeferredPass(i);
- LLVertexBuffer::unbind();
-
- LLGLState::checkStates();
- }
- }
- else
- {
- // Skip all pools of this type
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
- }
- }
- iter1 = iter2;
- stop_glerror();
- }
-
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
-
- gGL.setColorMask(true, false);
-
- } // Tracy ZoneScoped
+ pool_set_t::iterator iter2 = iter1;
+ if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render");
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+
+ for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
+ {
+ LLVertexBuffer::unbind();
+ poolp->beginDeferredPass(i);
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+
+ if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
+ }
+ poolp->endDeferredPass(i);
+ LLVertexBuffer::unbind();
+
+ LLGLState::checkStates();
+ }
+ }
+ else
+ {
+ // Skip all pools of this type
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+ }
+ }
+ iter1 = iter2;
+ stop_glerror();
+ }
+
+ gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(gGLModelView);
+
+ gGL.setColorMask(true, false);
+
+ } // Tracy ZoneScoped
if (gUseWireframe)
{
@@ -3860,7 +3921,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
if (gUseWireframe)
@@ -3868,9 +3929,9 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
- U32 cur_type = 0;
+ U32 cur_type = 0;
- LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable cull(GL_CULL_FACE);
bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds
bool done_water_haze = done_atmospherics;
@@ -3886,24 +3947,24 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
// do water haze just before pre water alpha
U32 water_haze_pass = LLDrawPool::POOL_ALPHA_PRE_WATER;
- calcNearbyLights(camera);
- setupHWLights();
+ calcNearbyLights(camera);
+ setupHWLights();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, false);
- pool_set_t::iterator iter1 = mPools.begin();
+ pool_set_t::iterator iter1 = mPools.begin();
if (gDebugGL || gDebugPipeline)
{
LLGLState::checkStates(GL_FALSE);
}
- while ( iter1 != mPools.end() )
- {
- LLDrawPool *poolp = *iter1;
-
- cur_type = poolp->getType();
+ while ( iter1 != mPools.end() )
+ {
+ LLDrawPool *poolp = *iter1;
+
+ cur_type = poolp->getType();
if (cur_type >= atmospherics_pass && !done_atmospherics)
{ // do atmospherics against depth buffer before rendering alpha
@@ -3917,56 +3978,56 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
done_water_haze = true;
}
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender");
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginPostDeferredPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
-
- p->renderPostDeferred(i);
- }
- poolp->endPostDeferredPass(i);
- LLVertexBuffer::unbind();
-
- if (gDebugGL || gDebugPipeline)
- {
- LLGLState::checkStates(GL_FALSE);
- }
- }
- }
- else
- {
- // Skip all pools of this type
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
- }
- }
- iter1 = iter2;
- stop_glerror();
- }
-
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
+ pool_set_t::iterator iter2 = iter1;
+ if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender");
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+
+ for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ )
+ {
+ LLVertexBuffer::unbind();
+ poolp->beginPostDeferredPass(i);
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+
+ p->renderPostDeferred(i);
+ }
+ poolp->endPostDeferredPass(i);
+ LLVertexBuffer::unbind();
+
+ if (gDebugGL || gDebugPipeline)
+ {
+ LLGLState::checkStates(GL_FALSE);
+ }
+ }
+ }
+ else
+ {
+ // Skip all pools of this type
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+ }
+ }
+ iter1 = iter2;
+ stop_glerror();
+ }
+
+ gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(gGLModelView);
if (!gCubeSnapshot)
{
@@ -3988,63 +4049,63 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("renderGeomShadow");
U32 cur_type = 0;
-
- LLGLEnable cull(GL_CULL_FACE);
-
- LLVertexBuffer::unbind();
-
- pool_set_t::iterator iter1 = mPools.begin();
-
- while ( iter1 != mPools.end() )
- {
- LLDrawPool *poolp = *iter1;
-
- cur_type = poolp->getType();
-
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0)
- {
- poolp->prerender() ;
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginShadowPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
-
- p->renderShadow(i);
- }
- poolp->endShadowPass(i);
- LLVertexBuffer::unbind();
- }
- }
- else
- {
- // Skip all pools of this type
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
- }
- }
- iter1 = iter2;
- stop_glerror();
- }
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
+
+ LLGLEnable cull(GL_CULL_FACE);
+
+ LLVertexBuffer::unbind();
+
+ pool_set_t::iterator iter1 = mPools.begin();
+
+ while ( iter1 != mPools.end() )
+ {
+ LLDrawPool *poolp = *iter1;
+
+ cur_type = poolp->getType();
+
+ pool_set_t::iterator iter2 = iter1;
+ if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0)
+ {
+ poolp->prerender() ;
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+
+ for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ )
+ {
+ LLVertexBuffer::unbind();
+ poolp->beginShadowPass(i);
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+
+ p->renderShadow(i);
+ }
+ poolp->endShadowPass(i);
+ LLVertexBuffer::unbind();
+ }
+ }
+ else
+ {
+ // Skip all pools of this type
+ for (iter2 = iter1; iter2 != mPools.end(); iter2++)
+ {
+ LLDrawPool *p = *iter2;
+ if (p->getType() != cur_type)
+ {
+ break;
+ }
+ }
+ }
+ iter1 = iter2;
+ stop_glerror();
+ }
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
}
@@ -4065,10 +4126,10 @@ void LLPipeline::recordTrianglesDrawn()
void LLPipeline::renderPhysicsDisplay()
{
- if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
- {
- return;
- }
+ if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+ {
+ return;
+ }
gGL.flush();
gDebugProgram.bind();
@@ -4118,7 +4179,7 @@ void LLPipeline::renderPhysicsDisplay()
}
}
glLineWidth(1.f);
- gDebugProgram.unbind();
+ gDebugProgram.unbind();
}
@@ -4128,377 +4189,379 @@ void LLPipeline::renderDebug()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
-
- bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
-
- if (!hud_only )
- {
- //Render any navmesh geometry
- LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
- if ( llPathingLibInstance != NULL )
- {
- //character floater renderables
-
- LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle();
- if ( !pathfindingCharacterHandle.isDead() )
- {
- LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get();
-
- if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() )
- {
- gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f(sTint, 1.f);
- gPathfindingProgram.uniform1f(sAmbiance, 1.f);
- gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
-
- //Requried character physics capsule render parameters
- LLUUID id;
- LLVector3 pos;
- LLQuaternion rot;
-
- if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) )
- {
- //remove blending artifacts
- gGL.setColorMask(false, false);
- llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
- gGL.setColorMask(true, false);
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
- gPathfindingProgram.bind();
- }
- }
- }
-
-
- //pathing console renderables
- LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
- if (!pathfindingConsoleHandle.isDead())
- {
- LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get();
-
- if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() )
- {
- F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
-
- gPathfindingProgram.bind();
-
- gPathfindingProgram.uniform1f(sTint, 1.f);
- gPathfindingProgram.uniform1f(sAmbiance, ambiance);
- gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
-
- if ( !pathfindingConsole->isRenderWorld() )
- {
- const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
- gGL.setColorMask(true, true);
- glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
+ assertInitialized();
+
+ bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
+
+ if (!hud_only )
+ {
+ //Render any navmesh geometry
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if ( llPathingLibInstance != NULL )
+ {
+ //character floater renderables
+
+ LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle();
+ if ( !pathfindingCharacterHandle.isDead() )
+ {
+ LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get();
+
+ if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() )
+ {
+ gPathfindingProgram.bind();
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+
+ //Requried character physics capsule render parameters
+ LLUUID id;
+ LLVector3 pos;
+ LLQuaternion rot;
+
+ if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) )
+ {
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gGL.setColorMask(true, false);
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gPathfindingProgram.bind();
+ }
+ }
+ }
+
+
+ //pathing console renderables
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if (!pathfindingConsoleHandle.isDead())
+ {
+ LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get();
+
+ if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() )
+ {
+ F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
+
+ gPathfindingProgram.bind();
+
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+
+ if ( !pathfindingConsole->isRenderWorld() )
+ {
+ const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
+ gGL.setColorMask(true, true);
+ glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT);
- gGL.setColorMask(true, false);
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- }
-
- //NavMesh
- if ( pathfindingConsole->isRenderNavMesh() )
- {
- gGL.flush();
- glLineWidth(2.0f);
- LLGLEnable cull(GL_CULL_FACE);
- LLGLDisable blend(GL_BLEND);
-
- if ( pathfindingConsole->isRenderWorld() )
- {
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
- llPathingLibInstance->renderNavMesh();
- }
- else
- {
- llPathingLibInstance->renderNavMesh();
- }
-
- //render edges
- gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
- gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
- llPathingLibInstance->renderNavMeshEdges();
- gPathfindingProgram.bind();
-
- gGL.flush();
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- glLineWidth(1.0f);
- gGL.flush();
- }
- //User designated path
- if ( LLPathfindingPathTool::getInstance()->isRenderPath() )
- {
- //The path
- gUIProgram.bind();
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
- llPathingLibInstance->renderPath();
- gPathfindingProgram.bind();
+ gGL.setColorMask(true, false);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+
+ //NavMesh
+ if ( pathfindingConsole->isRenderNavMesh() )
+ {
+ gGL.flush();
+ glLineWidth(2.0f);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+
+ if ( pathfindingConsole->isRenderWorld() )
+ {
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
+ llPathingLibInstance->renderNavMesh();
+ }
+ else
+ {
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
+
+ gGL.flush();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ glLineWidth(1.0f);
+ gGL.flush();
+ }
+ //User designated path
+ if ( LLPathfindingPathTool::getInstance()->isRenderPath() )
+ {
+ //The path
+ gUIProgram.bind();
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
+ llPathingLibInstance->renderPath();
+ gPathfindingProgram.bind();
//The bookends
- //remove blending artifacts
- gGL.setColorMask(false, false);
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
-
- gGL.setColorMask(true, false);
- //render the bookends
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
- gPathfindingProgram.bind();
- }
-
- if ( pathfindingConsole->isRenderWaterPlane() )
- {
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
- }
- //physics/exclusion shapes
- if ( pathfindingConsole->isRenderAnyShapes() )
- {
- U32 render_order[] = {
- 1 << LLPathingLib::LLST_ObstacleObjects,
- 1 << LLPathingLib::LLST_WalkableObjects,
- 1 << LLPathingLib::LLST_ExclusionPhantoms,
- 1 << LLPathingLib::LLST_MaterialPhantoms,
- };
-
- U32 flags = pathfindingConsole->getRenderShapeFlags();
-
- for (U32 i = 0; i < 4; i++)
- {
- if (!(flags & render_order[i]))
- {
- continue;
- }
-
- //turn off backface culling for volumes so they are visible when camera is inside volume
- LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0);
-
- gGL.flush();
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
- //get rid of some z-fighting
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0f, 1.0f);
-
- //render to depth first to avoid blending artifacts
- gGL.setColorMask(false, false);
- llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
- gGL.setColorMask(true, false);
-
- //get rid of some z-fighting
- glPolygonOffset(0.f, 0.f);
-
- LLGLEnable blend(GL_BLEND);
-
- {
- gPathfindingProgram.uniform1f(sAmbiance, ambiance);
-
- { //draw solid overlay
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
- llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
- gGL.flush();
- }
-
- LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-
- F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
-
- if (pathfindingConsole->isRenderXRay())
- {
- gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
-
- glPolygonOffset(offset, -offset);
-
- if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
- { //draw hidden wireframe as darker and less opaque
- gPathfindingProgram.uniform1f(sAmbiance, 1.f);
- llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
- }
- else
- {
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- gPathfindingProgram.uniform1f(sAmbiance, ambiance);
- llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- }
- }
-
- { //draw visible wireframe as brighter, thicker and more opaque
- glPolygonOffset(offset, offset);
- gPathfindingProgram.uniform1f(sAmbiance, 1.f);
- gPathfindingProgram.uniform1f(sTint, 1.f);
- gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
-
- glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
- LLGLDisable blendOut(GL_BLEND);
- llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
- gGL.flush();
- glLineWidth(1.f);
- }
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- }
- }
- }
-
- glPolygonOffset(0.f, 0.f);
-
- if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() )
- { //render navmesh xray
- F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
-
- LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
-
- F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
- glPolygonOffset(offset, -offset);
-
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
- gGL.flush();
- glLineWidth(2.0f);
- LLGLEnable cull(GL_CULL_FACE);
-
- gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
-
- if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
- { //draw hidden wireframe as darker and less opaque
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- gPathfindingProgram.uniform1f(sAmbiance, 1.f);
- llPathingLibInstance->renderNavMesh();
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- }
- else
- {
- gPathfindingProgram.uniform1f(sAmbiance, ambiance);
- llPathingLibInstance->renderNavMesh();
- }
-
- //render edges
- gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
- llPathingLibInstance->renderNavMeshEdges();
- gPathfindingProgram.bind();
-
- gGL.flush();
- glLineWidth(1.0f);
- }
-
- glPolygonOffset(0.f, 0.f);
-
- gGL.flush();
- gPathfindingProgram.unbind();
- }
- }
- }
- }
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- gGL.setColorMask(true, false);
-
-
- if (!hud_only && !mDebugBlips.empty())
- { //render debug blips
- gUIProgram.bind();
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+
+ gGL.setColorMask(true, false);
+ //render the bookends
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+ gPathfindingProgram.bind();
+ }
+
+ if ( pathfindingConsole->isRenderWaterPlane() )
+ {
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
+ }
+ //physics/exclusion shapes
+ if ( pathfindingConsole->isRenderAnyShapes() )
+ {
+ U32 render_order[] = {
+ 1 << LLPathingLib::LLST_ObstacleObjects,
+ 1 << LLPathingLib::LLST_WalkableObjects,
+ 1 << LLPathingLib::LLST_ExclusionPhantoms,
+ 1 << LLPathingLib::LLST_MaterialPhantoms,
+ };
+
+ U32 flags = pathfindingConsole->getRenderShapeFlags();
+
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (!(flags & render_order[i]))
+ {
+ continue;
+ }
+
+ //turn off backface culling for volumes so they are visible when camera is inside volume
+ LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0);
+
+ gGL.flush();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ //get rid of some z-fighting
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1.0f, 1.0f);
+
+ //render to depth first to avoid blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.setColorMask(true, false);
+
+ //get rid of some z-fighting
+ glPolygonOffset(0.f, 0.f);
+
+ LLGLEnable blend(GL_BLEND);
+
+ {
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+
+ { //draw solid overlay
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.flush();
+ }
+
+ LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
+
+ if (pathfindingConsole->isRenderXRay())
+ {
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+
+ glPolygonOffset(offset, -offset);
+
+ if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
+ { //draw hidden wireframe as darker and less opaque
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ }
+ else
+ {
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+ }
+
+ { //draw visible wireframe as brighter, thicker and more opaque
+ glPolygonOffset(offset, offset);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+
+ glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
+ LLGLDisable blendOut(GL_BLEND);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.flush();
+ glLineWidth(1.f);
+ }
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+ }
+ }
+
+ glPolygonOffset(0.f, 0.f);
+
+ if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() )
+ { //render navmesh xray
+ F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
+
+ LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+
+ F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
+ glPolygonOffset(offset, -offset);
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.flush();
+ glLineWidth(2.0f);
+ LLGLEnable cull(GL_CULL_FACE);
+
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+
+ if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
+ { //draw hidden wireframe as darker and less opaque
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ llPathingLibInstance->renderNavMesh();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+ else
+ {
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
+
+ gGL.flush();
+ glLineWidth(1.0f);
+ }
+
+ glPolygonOffset(0.f, 0.f);
+
+ gGL.flush();
+ gPathfindingProgram.unbind();
+ }
+ }
+ }
+ }
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ gGL.setColorMask(true, false);
+
+
+ if (!hud_only && !mDebugBlips.empty())
+ { //render debug blips
+ gUIProgram.bind();
gGL.color4f(1, 1, 1, 1);
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true);
-
- glPointSize(8.f);
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
- gGL.begin(LLRender::POINTS);
- for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); )
- {
- DebugBlip& blip = *iter;
-
- blip.mAge += gFrameIntervalSeconds.value();
- if (blip.mAge > 2.f)
- {
- mDebugBlips.erase(iter++);
- }
- else
- {
- iter++;
- }
-
- blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f;
-
- gGL.color4fv(blip.mColor.mV);
- gGL.vertex3fv(blip.mPosition.mV);
- }
- gGL.end();
- gGL.flush();
- glPointSize(1.f);
- }
-
- // Debug stuff.
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
- (!hud_only && hasRenderType(part->mDrawableType)) )
- {
- part->renderDebug();
- }
- }
- }
- }
-
- for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- bridge->renderDebug();
- gGL.popMatrix();
- }
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
- { //render visible selected group occlusion geometry
- gDebugProgram.bind();
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.diffuseColor3f(1,0,1);
- for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
- {
- LLSpatialGroup* group = *iter;
-
- LLVector4a fudge;
- fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
-
- LLVector4a size;
- const LLVector4a* bounds = group->getBounds();
- size.setAdd(fudge, bounds[1]);
-
- drawBox(bounds[0], size);
- }
- }
-
- visible_selected_groups.clear();
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true);
+
+ glPointSize(8.f);
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ gGL.begin(LLRender::POINTS);
+ for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); )
+ {
+ DebugBlip& blip = *iter;
+
+ blip.mAge += gFrameIntervalSeconds.value();
+ if (blip.mAge > 2.f)
+ {
+ mDebugBlips.erase(iter++);
+ }
+ else
+ {
+ iter++;
+ }
+
+ blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f;
+
+ gGL.color4fv(blip.mColor.mV);
+ gGL.vertex3fv(blip.mPosition.mV);
+ }
+ gGL.end();
+ gGL.flush();
+ glPointSize(1.f);
+ }
+
+ // Debug stuff.
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
+ {
+ part->renderDebug();
+ }
+ }
+ }
+ }
+
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ {
+ LLSpatialBridge* bridge = *i;
+ if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
+ {
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+ bridge->renderDebug();
+ gGL.popMatrix();
+ }
+ }
+
+ LL::GLTFSceneManager::instance().renderDebug();
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ { //render visible selected group occlusion geometry
+ gDebugProgram.bind();
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.diffuseColor3f(1,0,1);
+ for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ LLVector4a fudge;
+ fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
+
+ LLVector4a size;
+ const LLVector4a* bounds = group->getBounds();
+ size.setAdd(fudge, bounds[1]);
+
+ drawBox(bounds[0], size);
+ }
+ }
+
+ visible_selected_groups.clear();
//draw reflection probes and links between them
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only)
@@ -4521,372 +4584,372 @@ void LLPipeline::renderDebug()
unbindDeferredShader(gReflectionProbeDisplayProgram);
}
- gUIProgram.bind();
-
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
- { //draw crosshairs on particle intersection
- if (gDebugRaycastParticle)
- {
- gDebugProgram.bind();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
- LLVector3 size(0.1f, 0.1f, 0.1f);
-
- LLVector3 p[6];
-
- p[0] = center + size.scaledVec(LLVector3(1,0,0));
- p[1] = center + size.scaledVec(LLVector3(-1,0,0));
- p[2] = center + size.scaledVec(LLVector3(0,1,0));
- p[3] = center + size.scaledVec(LLVector3(0,-1,0));
- p[4] = center + size.scaledVec(LLVector3(0,0,1));
- p[5] = center + size.scaledVec(LLVector3(0,0,-1));
-
- gGL.begin(LLRender::LINES);
- gGL.diffuseColor3f(1.f, 1.f, 0.f);
- for (U32 i = 0; i < 6; i++)
- {
- gGL.vertex3fv(p[i].mV);
- }
- gGL.end();
- gGL.flush();
-
- gDebugProgram.unbind();
- }
- }
-
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only)
- {
- LLVertexBuffer::unbind();
-
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest depth(TRUE, FALSE);
- LLGLDisable cull(GL_CULL_FACE);
-
- gGL.color4f(1,1,1,1);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- F32 a = 0.1f;
-
- F32 col[] =
- {
- 1,0,0,a,
- 0,1,0,a,
- 0,0,1,a,
- 1,0,1,a,
-
- 1,1,0,a,
- 0,1,1,a,
- 1,1,1,a,
- 1,0,1,a,
- };
-
- for (U32 i = 0; i < 8; i++)
- {
- LLVector3* frust = mShadowCamera[i].mAgentFrustum;
-
- if (i > 3)
- { //render shadow frusta as volumes
- if (mShadowFrustPoints[i-4].empty())
- {
- continue;
- }
-
- gGL.color4fv(col+(i-4)*4);
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
- gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
- gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
- gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
- gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
- gGL.end();
-
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex3fv(frust[0].mV);
- gGL.vertex3fv(frust[1].mV);
- gGL.vertex3fv(frust[3].mV);
- gGL.vertex3fv(frust[2].mV);
- gGL.end();
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex3fv(frust[4].mV);
- gGL.vertex3fv(frust[5].mV);
- gGL.vertex3fv(frust[7].mV);
- gGL.vertex3fv(frust[6].mV);
- gGL.end();
- }
-
-
- if (i < 4)
- {
-
- //if (i == 0 || !mShadowFrustPoints[i].empty())
- {
- //render visible point cloud
- gGL.flush();
- glPointSize(8.f);
- gGL.begin(LLRender::POINTS);
-
- F32* c = col+i*4;
- gGL.color3fv(c);
-
- for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j)
- {
- gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
-
- }
- gGL.end();
-
- gGL.flush();
- glPointSize(1.f);
-
- LLVector3* ext = mShadowExtents[i];
- LLVector3 pos = (ext[0]+ext[1])*0.5f;
- LLVector3 size = (ext[1]-ext[0])*0.5f;
- drawBoxOutline(pos, size);
-
- //render camera frustum splits as outlines
- gGL.begin(LLRender::LINES);
- gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV);
- gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV);
- gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV);
- gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV);
- gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV);
- gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV);
- gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV);
- gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV);
- gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
- gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
- gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
- gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
- gGL.end();
- }
- }
-
- /*gGL.flush();
- glLineWidth(16-i*2);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(j);
- if (part)
- {
- if (hasRenderType(part->mDrawableType))
- {
- part->renderIntersectingBBoxes(&mShadowCamera[i]);
- }
- }
- }
- }
- gGL.flush();
- glLineWidth(1.f);*/
- }
- }
-
- if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS)
- {
- gAgent.getRegion()->mWind.renderVectors();
- }
-
- if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION)
- {
- // Debug composition layers
- F32 x, y;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (gAgent.getRegion())
- {
- gGL.begin(LLRender::POINTS);
- // Draw the composition layer for the region that I'm in.
- for (x = 0; x <= 260; x++)
- {
- for (y = 0; y <= 260; y++)
- {
- if ((x > 255) || (y > 255))
- {
- gGL.color4f(1.f, 0.f, 0.f, 1.f);
- }
- else
- {
- gGL.color4f(0.f, 0.f, 1.f, 1.f);
- }
- F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y);
- z *= 5.f;
- z += 50.f;
- gGL.vertex3f(x, y, z);
- }
- }
- gGL.end();
- }
- }
-
- gGL.flush();
- gUIProgram.unbind();
+ gUIProgram.bind();
+
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
+ { //draw crosshairs on particle intersection
+ if (gDebugRaycastParticle)
+ {
+ gDebugProgram.bind();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
+ LLVector3 size(0.1f, 0.1f, 0.1f);
+
+ LLVector3 p[6];
+
+ p[0] = center + size.scaledVec(LLVector3(1,0,0));
+ p[1] = center + size.scaledVec(LLVector3(-1,0,0));
+ p[2] = center + size.scaledVec(LLVector3(0,1,0));
+ p[3] = center + size.scaledVec(LLVector3(0,-1,0));
+ p[4] = center + size.scaledVec(LLVector3(0,0,1));
+ p[5] = center + size.scaledVec(LLVector3(0,0,-1));
+
+ gGL.begin(LLRender::LINES);
+ gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ for (U32 i = 0; i < 6; i++)
+ {
+ gGL.vertex3fv(p[i].mV);
+ }
+ gGL.end();
+ gGL.flush();
+
+ gDebugProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only)
+ {
+ LLVertexBuffer::unbind();
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(TRUE, FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+
+ gGL.color4f(1,1,1,1);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ F32 a = 0.1f;
+
+ F32 col[] =
+ {
+ 1,0,0,a,
+ 0,1,0,a,
+ 0,0,1,a,
+ 1,0,1,a,
+
+ 1,1,0,a,
+ 0,1,1,a,
+ 1,1,1,a,
+ 1,0,1,a,
+ };
+
+ for (U32 i = 0; i < 8; i++)
+ {
+ LLVector3* frust = mShadowCamera[i].mAgentFrustum;
+
+ if (i > 3)
+ { //render shadow frusta as volumes
+ if (mShadowFrustPoints[i-4].empty())
+ {
+ continue;
+ }
+
+ gGL.color4fv(col+(i-4)*4);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
+ gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.end();
+
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex3fv(frust[0].mV);
+ gGL.vertex3fv(frust[1].mV);
+ gGL.vertex3fv(frust[3].mV);
+ gGL.vertex3fv(frust[2].mV);
+ gGL.end();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[7].mV);
+ gGL.vertex3fv(frust[6].mV);
+ gGL.end();
+ }
+
+
+ if (i < 4)
+ {
+
+ //if (i == 0 || !mShadowFrustPoints[i].empty())
+ {
+ //render visible point cloud
+ gGL.flush();
+ glPointSize(8.f);
+ gGL.begin(LLRender::POINTS);
+
+ F32* c = col+i*4;
+ gGL.color3fv(c);
+
+ for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j)
+ {
+ gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
+
+ }
+ gGL.end();
+
+ gGL.flush();
+ glPointSize(1.f);
+
+ LLVector3* ext = mShadowExtents[i];
+ LLVector3 pos = (ext[0]+ext[1])*0.5f;
+ LLVector3 size = (ext[1]-ext[0])*0.5f;
+ drawBoxOutline(pos, size);
+
+ //render camera frustum splits as outlines
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV);
+ gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV);
+ gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV);
+ gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV);
+ gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV);
+ gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV);
+ gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
+ gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
+ gGL.end();
+ }
+ }
+
+ /*gGL.flush();
+ glLineWidth(16-i*2);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(j);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ part->renderIntersectingBBoxes(&mShadowCamera[i]);
+ }
+ }
+ }
+ }
+ gGL.flush();
+ glLineWidth(1.f);*/
+ }
+ }
+
+ if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS)
+ {
+ gAgent.getRegion()->mWind.renderVectors();
+ }
+
+ if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION)
+ {
+ // Debug composition layers
+ F32 x, y;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if (gAgent.getRegion())
+ {
+ gGL.begin(LLRender::POINTS);
+ // Draw the composition layer for the region that I'm in.
+ for (x = 0; x <= 260; x++)
+ {
+ for (y = 0; y <= 260; y++)
+ {
+ if ((x > 255) || (y > 255))
+ {
+ gGL.color4f(1.f, 0.f, 0.f, 1.f);
+ }
+ else
+ {
+ gGL.color4f(0.f, 0.f, 1.f, 1.f);
+ }
+ F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y);
+ z *= 5.f;
+ z += 50.f;
+ gGL.vertex3f(x, y, z);
+ }
+ }
+ gGL.end();
+ }
+ }
+
+ gGL.flush();
+ gUIProgram.unbind();
}
void LLPipeline::rebuildPools()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
-
- S32 max_count = mPools.size();
- pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool);
- while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS)
- {
- if (iter1 == mPools.end())
- {
- iter1 = mPools.begin();
- }
- LLDrawPool* poolp = *iter1;
-
- if (poolp->isDead())
- {
- mPools.erase(iter1++);
- removeFromQuickLookup( poolp );
- if (poolp == mLastRebuildPool)
- {
- mLastRebuildPool = NULL;
- }
- delete poolp;
- }
- else
- {
- mLastRebuildPool = poolp;
- iter1++;
- }
- max_count--;
- }
+ assertInitialized();
+
+ S32 max_count = mPools.size();
+ pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool);
+ while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS)
+ {
+ if (iter1 == mPools.end())
+ {
+ iter1 = mPools.begin();
+ }
+ LLDrawPool* poolp = *iter1;
+
+ if (poolp->isDead())
+ {
+ mPools.erase(iter1++);
+ removeFromQuickLookup( poolp );
+ if (poolp == mLastRebuildPool)
+ {
+ mLastRebuildPool = NULL;
+ }
+ delete poolp;
+ }
+ else
+ {
+ mLastRebuildPool = poolp;
+ iter1++;
+ }
+ max_count--;
+ }
}
void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
{
- assertInitialized();
-
- switch( new_poolp->getType() )
- {
- case LLDrawPool::POOL_SIMPLE:
- if (mSimplePool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
- }
- else
- {
- mSimplePool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_ALPHA_MASK:
- if (mAlphaMaskPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
- break;
- }
- else
- {
- mAlphaMaskPool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
- if (mFullbrightAlphaMaskPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
- break;
- }
- else
- {
- mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_GRASS:
- if (mGrassPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL;
- }
- else
- {
- mGrassPool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT:
- if (mFullbrightPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
- }
- else
- {
- mFullbrightPool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_GLOW:
- if (mGlowPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL;
- }
- else
- {
- mGlowPool = (LLRenderPass*) new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_TREE:
- mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
- break;
-
- case LLDrawPool::POOL_TERRAIN:
- mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
- break;
-
- case LLDrawPool::POOL_BUMP:
- if (mBumpPool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL;
- }
- else
- {
- mBumpPool = new_poolp;
- }
- break;
- case LLDrawPool::POOL_MATERIALS:
- if (mMaterialsPool)
- {
- llassert(0);
- LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL;
- }
- else
- {
- mMaterialsPool = new_poolp;
- }
- break;
- case LLDrawPool::POOL_ALPHA_PRE_WATER:
- if( mAlphaPoolPreWater )
- {
- llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL;
- }
- else
- {
- mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp;
- }
- break;
+ assertInitialized();
+
+ switch( new_poolp->getType() )
+ {
+ case LLDrawPool::POOL_SIMPLE:
+ if (mSimplePool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
+ }
+ else
+ {
+ mSimplePool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_ALPHA_MASK:
+ if (mAlphaMaskPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
+ break;
+ }
+ else
+ {
+ mAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ if (mFullbrightAlphaMaskPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
+ break;
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_GRASS:
+ if (mGrassPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL;
+ }
+ else
+ {
+ mGrassPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT:
+ if (mFullbrightPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
+ }
+ else
+ {
+ mFullbrightPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_GLOW:
+ if (mGlowPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL;
+ }
+ else
+ {
+ mGlowPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_TREE:
+ mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
+ break;
+
+ case LLDrawPool::POOL_TERRAIN:
+ mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
+ break;
+
+ case LLDrawPool::POOL_BUMP:
+ if (mBumpPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL;
+ }
+ else
+ {
+ mBumpPool = new_poolp;
+ }
+ break;
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ if( mAlphaPoolPreWater )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL;
+ }
+ else
+ {
+ mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA_POST_WATER:
if (mAlphaPoolPostWater)
{
@@ -4899,45 +4962,45 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
- case LLDrawPool::POOL_AVATAR:
- case LLDrawPool::POOL_CONTROL_AV:
- break; // Do nothing
-
- case LLDrawPool::POOL_SKY:
- if( mSkyPool )
- {
- llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL;
- }
- else
- {
- mSkyPool = new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_WATER:
- if( mWaterPool )
- {
- llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL;
- }
- else
- {
- mWaterPool = new_poolp;
- }
- break;
-
- case LLDrawPool::POOL_WL_SKY:
- if( mWLSkyPool )
- {
- llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL;
- }
- else
- {
- mWLSkyPool = new_poolp;
- }
- break;
+ case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
+ break; // Do nothing
+
+ case LLDrawPool::POOL_SKY:
+ if( mSkyPool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL;
+ }
+ else
+ {
+ mSkyPool = new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_WATER:
+ if( mWaterPool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL;
+ }
+ else
+ {
+ mWaterPool = new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_WL_SKY:
+ if( mWLSkyPool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL;
+ }
+ else
+ {
+ mWLSkyPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_GLTF_PBR:
if( mPBROpaquePool )
@@ -4964,116 +5027,116 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
break;
- default:
- llassert(0);
- LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
- break;
- }
+ default:
+ llassert(0);
+ LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
+ break;
+ }
}
void LLPipeline::removePool( LLDrawPool* poolp )
{
- assertInitialized();
- removeFromQuickLookup(poolp);
- mPools.erase(poolp);
- delete poolp;
+ assertInitialized();
+ removeFromQuickLookup(poolp);
+ mPools.erase(poolp);
+ delete poolp;
}
void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
{
- assertInitialized();
- switch( poolp->getType() )
- {
- case LLDrawPool::POOL_SIMPLE:
- llassert(mSimplePool == poolp);
- mSimplePool = NULL;
- break;
-
- case LLDrawPool::POOL_ALPHA_MASK:
- llassert(mAlphaMaskPool == poolp);
- mAlphaMaskPool = NULL;
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
- llassert(mFullbrightAlphaMaskPool == poolp);
- mFullbrightAlphaMaskPool = NULL;
- break;
-
- case LLDrawPool::POOL_GRASS:
- llassert(mGrassPool == poolp);
- mGrassPool = NULL;
- break;
-
- case LLDrawPool::POOL_FULLBRIGHT:
- llassert(mFullbrightPool == poolp);
- mFullbrightPool = NULL;
- break;
-
- case LLDrawPool::POOL_WL_SKY:
- llassert(mWLSkyPool == poolp);
- mWLSkyPool = NULL;
- break;
-
- case LLDrawPool::POOL_GLOW:
- llassert(mGlowPool == poolp);
- mGlowPool = NULL;
- break;
-
- case LLDrawPool::POOL_TREE:
- #ifdef _DEBUG
- {
- bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() );
- llassert( found );
- }
- #else
- mTreePools.erase( (uintptr_t)poolp->getTexture() );
- #endif
- break;
-
- case LLDrawPool::POOL_TERRAIN:
- #ifdef _DEBUG
- {
- bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
- llassert( found );
- }
- #else
- mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
- #endif
- break;
-
- case LLDrawPool::POOL_BUMP:
- llassert( poolp == mBumpPool );
- mBumpPool = NULL;
- break;
-
- case LLDrawPool::POOL_MATERIALS:
- llassert(poolp == mMaterialsPool);
- mMaterialsPool = NULL;
- break;
-
- case LLDrawPool::POOL_ALPHA_PRE_WATER:
- llassert( poolp == mAlphaPoolPreWater );
- mAlphaPoolPreWater = nullptr;
- break;
-
+ assertInitialized();
+ switch( poolp->getType() )
+ {
+ case LLDrawPool::POOL_SIMPLE:
+ llassert(mSimplePool == poolp);
+ mSimplePool = NULL;
+ break;
+
+ case LLDrawPool::POOL_ALPHA_MASK:
+ llassert(mAlphaMaskPool == poolp);
+ mAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ llassert(mFullbrightAlphaMaskPool == poolp);
+ mFullbrightAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_GRASS:
+ llassert(mGrassPool == poolp);
+ mGrassPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT:
+ llassert(mFullbrightPool == poolp);
+ mFullbrightPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_WL_SKY:
+ llassert(mWLSkyPool == poolp);
+ mWLSkyPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_GLOW:
+ llassert(mGlowPool == poolp);
+ mGlowPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_TREE:
+ #ifdef _DEBUG
+ {
+ bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() );
+ llassert( found );
+ }
+ #else
+ mTreePools.erase( (uintptr_t)poolp->getTexture() );
+ #endif
+ break;
+
+ case LLDrawPool::POOL_TERRAIN:
+ #ifdef _DEBUG
+ {
+ bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
+ llassert( found );
+ }
+ #else
+ mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
+ #endif
+ break;
+
+ case LLDrawPool::POOL_BUMP:
+ llassert( poolp == mBumpPool );
+ mBumpPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ llassert( poolp == mAlphaPoolPreWater );
+ mAlphaPoolPreWater = nullptr;
+ break;
+
case LLDrawPool::POOL_ALPHA_POST_WATER:
llassert(poolp == mAlphaPoolPostWater);
mAlphaPoolPostWater = nullptr;
break;
- case LLDrawPool::POOL_AVATAR:
- case LLDrawPool::POOL_CONTROL_AV:
- break; // Do nothing
+ case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
+ break; // Do nothing
- case LLDrawPool::POOL_SKY:
- llassert( poolp == mSkyPool );
- mSkyPool = NULL;
- break;
+ case LLDrawPool::POOL_SKY:
+ llassert( poolp == mSkyPool );
+ mSkyPool = NULL;
+ break;
- case LLDrawPool::POOL_WATER:
- llassert( poolp == mWaterPool );
- mWaterPool = NULL;
- break;
+ case LLDrawPool::POOL_WATER:
+ llassert( poolp == mWaterPool );
+ mWaterPool = NULL;
+ break;
case LLDrawPool::POOL_GLTF_PBR:
llassert( poolp == mPBROpaquePool );
@@ -5085,23 +5148,23 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mPBRAlphaMaskPool = NULL;
break;
- default:
- llassert(0);
- LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
- break;
- }
+ default:
+ llassert(0);
+ LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
+ break;
+ }
}
void LLPipeline::resetDrawOrders()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
- // Iterate through all of the draw pools and rebuild them.
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- poolp->resetDrawOrders();
- }
+ assertInitialized();
+ // Iterate through all of the draw pools and rebuild them.
+ for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
+ {
+ LLDrawPool *poolp = *iter;
+ poolp->resetDrawOrders();
+ }
}
//============================================================================
@@ -5110,7 +5173,7 @@ void LLPipeline::resetDrawOrders()
void LLPipeline::setupAvatarLights(bool for_edit)
{
- assertInitialized();
+ assertInitialized();
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
@@ -5118,130 +5181,130 @@ void LLPipeline::setupAvatarLights(bool for_edit)
bool sun_up = environment.getIsSunUp();
- if (for_edit)
- {
- LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
- LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light
- LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
- LLMatrix4 camera_rot(camera_mat.getMat3());
- camera_rot.invert();
- LLVector4 light_pos = light_pos_cam * camera_rot;
-
- light_pos.normalize();
-
- LLLightState* light = gGL.getLight(1);
-
- mHWLightColors[1] = diffuse;
-
- light->setDiffuse(diffuse);
- light->setAmbient(LLColor4::black);
- light->setSpecular(LLColor4::black);
- light->setPosition(light_pos);
- light->setConstantAttenuation(1.f);
- light->setLinearAttenuation(0.f);
- light->setQuadraticAttenuation(0.f);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
- }
- else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
- {
+ if (for_edit)
+ {
+ LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
+ LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light
+ LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
+ LLMatrix4 camera_rot(camera_mat.getMat3());
+ camera_rot.invert();
+ LLVector4 light_pos = light_pos_cam * camera_rot;
+
+ light_pos.normalize();
+
+ LLLightState* light = gGL.getLight(1);
+
+ mHWLightColors[1] = diffuse;
+
+ light->setDiffuse(diffuse);
+ light->setAmbient(LLColor4::black);
+ light->setSpecular(LLColor4::black);
+ light->setPosition(light_pos);
+ light->setConstantAttenuation(1.f);
+ light->setLinearAttenuation(0.f);
+ light->setQuadraticAttenuation(0.f);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
+ }
+ else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
+ {
LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir);
- LLVector3 opposite_pos = -light_dir;
- LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
- LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
- backlight_pos.normalize();
-
- LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse;
-
- LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
- F32 max_component = 0.001f;
- for (S32 i = 0; i < 3; i++)
- {
- if (backlight_diffuse.mV[i] > max_component)
- {
- max_component = backlight_diffuse.mV[i];
- }
- }
- F32 backlight_mag;
- if (LLEnvironment::instance().getIsSunUp())
- {
- backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
- }
- else
- {
- backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT;
- }
- backlight_diffuse *= backlight_mag / max_component;
-
- mHWLightColors[1] = backlight_diffuse;
-
- LLLightState* light = gGL.getLight(1);
-
- light->setPosition(backlight_pos);
- light->setDiffuse(backlight_diffuse);
- light->setAmbient(LLColor4::black);
- light->setSpecular(LLColor4::black);
- light->setConstantAttenuation(1.f);
- light->setLinearAttenuation(0.f);
- light->setQuadraticAttenuation(0.f);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
- }
- else
- {
- LLLightState* light = gGL.getLight(1);
-
- mHWLightColors[1] = LLColor4::black;
-
- light->setDiffuse(LLColor4::black);
- light->setAmbient(LLColor4::black);
- light->setSpecular(LLColor4::black);
- }
+ LLVector3 opposite_pos = -light_dir;
+ LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
+ LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
+ backlight_pos.normalize();
+
+ LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse;
+
+ LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
+ F32 max_component = 0.001f;
+ for (S32 i = 0; i < 3; i++)
+ {
+ if (backlight_diffuse.mV[i] > max_component)
+ {
+ max_component = backlight_diffuse.mV[i];
+ }
+ }
+ F32 backlight_mag;
+ if (LLEnvironment::instance().getIsSunUp())
+ {
+ backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
+ }
+ else
+ {
+ backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT;
+ }
+ backlight_diffuse *= backlight_mag / max_component;
+
+ mHWLightColors[1] = backlight_diffuse;
+
+ LLLightState* light = gGL.getLight(1);
+
+ light->setPosition(backlight_pos);
+ light->setDiffuse(backlight_diffuse);
+ light->setAmbient(LLColor4::black);
+ light->setSpecular(LLColor4::black);
+ light->setConstantAttenuation(1.f);
+ light->setLinearAttenuation(0.f);
+ light->setQuadraticAttenuation(0.f);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
+ }
+ else
+ {
+ LLLightState* light = gGL.getLight(1);
+
+ mHWLightColors[1] = LLColor4::black;
+
+ light->setDiffuse(LLColor4::black);
+ light->setAmbient(LLColor4::black);
+ light->setSpecular(LLColor4::black);
+ }
}
static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- F32 inten = light->getLightIntensity();
- if (inten < .001f)
- {
- return max_dist;
- }
- bool selected = light->isSelected();
- if (selected)
- {
+ F32 inten = light->getLightIntensity();
+ if (inten < .001f)
+ {
+ return max_dist;
+ }
+ bool selected = light->isSelected();
+ if (selected)
+ {
return 0.f; // selected lights get highest priority
- }
+ }
F32 radius = light->getLightRadius();
F32 dist = dist_vec(light->getRenderPosition(), cam_pos);
dist = llmax(dist - radius, 0.f);
- if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
- {
- // moving lights get a little higher priority (too much causes artifacts)
+ if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
+ {
+ // moving lights get a little higher priority (too much causes artifacts)
dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
- }
- return dist;
+ }
+ return dist;
}
void LLPipeline::calcNearbyLights(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- assertInitialized();
+ assertInitialized();
- if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs)
- {
- return;
- }
+ if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs)
+ {
+ return;
+ }
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
- if (local_light_count >= 1)
- {
- // mNearbyLight (and all light_set_t's) are sorted such that
- // begin() == the closest light and rbegin() == the farthest light
- const S32 MAX_LOCAL_LIGHTS = 6;
+ if (local_light_count >= 1)
+ {
+ // mNearbyLight (and all light_set_t's) are sorted such that
+ // begin() == the closest light and rbegin() == the farthest light
+ const S32 MAX_LOCAL_LIGHTS = 6;
LLVector3 cam_pos = camera.getOrigin();
-
+
F32 max_dist;
if (LLPipeline::sRenderDeferred)
{
@@ -5252,15 +5315,15 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f);
}
- // UPDATE THE EXISTING NEARBY LIGHTS
- light_set_t cur_nearby_lights;
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
- {
- const Light* light = &(*iter);
- LLDrawable* drawable = light->drawable;
+ // UPDATE THE EXISTING NEARBY LIGHTS
+ light_set_t cur_nearby_lights;
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ const Light* light = &(*iter);
+ LLDrawable* drawable = light->drawable;
const LLViewerObject *vobj = light->drawable->getVObj();
- if(vobj && vobj->getAvatar()
+ if(vobj && vobj->getAvatar()
&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow())
)
{
@@ -5268,22 +5331,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
- LLVOVolume* volight = drawable->getVOVolume();
- if (!volight || !drawable->isState(LLDrawable::LIGHT))
- {
- drawable->clearState(LLDrawable::NEARBY_LIGHT);
- continue;
- }
- if (light->fade <= -LIGHT_FADE_TIME)
- {
- drawable->clearState(LLDrawable::NEARBY_LIGHT);
- continue;
- }
- if (!sRenderAttachedLights && volight && volight->isAttachment())
- {
- drawable->clearState(LLDrawable::NEARBY_LIGHT);
- continue;
- }
+ LLVOVolume* volight = drawable->getVOVolume();
+ if (!volight || !drawable->isState(LLDrawable::LIGHT))
+ {
+ drawable->clearState(LLDrawable::NEARBY_LIGHT);
+ continue;
+ }
+ if (light->fade <= -LIGHT_FADE_TIME)
+ {
+ drawable->clearState(LLDrawable::NEARBY_LIGHT);
+ continue;
+ }
+ if (!sRenderAttachedLights && volight && volight->isAttachment())
+ {
+ drawable->clearState(LLDrawable::NEARBY_LIGHT);
+ continue;
+ }
F32 dist = calc_light_dist(volight, cam_pos, max_dist);
F32 fade = light->fade;
@@ -5317,28 +5380,28 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
}
}
cur_nearby_lights.insert(Light(drawable, dist, fade));
- }
- mNearbyLights = cur_nearby_lights;
-
- // FIND NEW LIGHTS THAT ARE IN RANGE
- light_set_t new_nearby_lights;
- for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin();
- iter != mLights.end(); ++iter)
- {
- LLDrawable* drawable = *iter;
- LLVOVolume* light = drawable->getVOVolume();
- if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT))
- {
- continue;
- }
- if (light->isHUDAttachment())
- {
- continue; // no lighting from HUD objects
- }
+ }
+ mNearbyLights = cur_nearby_lights;
+
+ // FIND NEW LIGHTS THAT ARE IN RANGE
+ light_set_t new_nearby_lights;
+ for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin();
+ iter != mLights.end(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ LLVOVolume* light = drawable->getVOVolume();
+ if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT))
+ {
+ continue;
+ }
+ if (light->isHUDAttachment())
+ {
+ continue; // no lighting from HUD objects
+ }
if (!sRenderAttachedLights && light && light->isAttachment())
- {
- continue;
- }
+ {
+ continue;
+ }
LLVOAvatar * av = light->getAvatar();
if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow()))
{
@@ -5347,36 +5410,36 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
}
F32 dist = calc_light_dist(light, cam_pos, max_dist);
if (dist >= max_dist)
- {
- continue;
- }
- new_nearby_lights.insert(Light(drawable, dist, 0.f));
+ {
+ continue;
+ }
+ new_nearby_lights.insert(Light(drawable, dist, 0.f));
if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
- {
- new_nearby_lights.erase(--new_nearby_lights.end());
- const Light& last = *new_nearby_lights.rbegin();
- max_dist = last.dist;
- }
- }
-
- // INSERT ANY NEW LIGHTS
- for (light_set_t::iterator iter = new_nearby_lights.begin();
- iter != new_nearby_lights.end(); iter++)
- {
- const Light* light = &(*iter);
+ {
+ new_nearby_lights.erase(--new_nearby_lights.end());
+ const Light& last = *new_nearby_lights.rbegin();
+ max_dist = last.dist;
+ }
+ }
+
+ // INSERT ANY NEW LIGHTS
+ for (light_set_t::iterator iter = new_nearby_lights.begin();
+ iter != new_nearby_lights.end(); iter++)
+ {
+ const Light* light = &(*iter);
if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
- {
- mNearbyLights.insert(*light);
- ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
- }
- else
- {
- // crazy cast so that we can overwrite the fade value
- // even though gcc enforces sets as const
- // (fade value doesn't affect sort so this is safe)
- Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
- if (light->dist < farthest_light->dist)
- {
+ {
+ mNearbyLights.insert(*light);
+ ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
+ }
+ else
+ {
+ // crazy cast so that we can overwrite the fade value
+ // even though gcc enforces sets as const
+ // (fade value doesn't affect sort so this is safe)
+ Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
+ if (light->dist < farthest_light->dist)
+ {
// mark light to fade out
// visibility goes down from -0 to -LIGHT_FADE_TIME.
//
@@ -5393,29 +5456,29 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
farthest_light->fade -= LIGHT_FADE_TIME;
}
- }
- else
- {
- break; // none of the other lights are closer
- }
- }
- }
-
- //mark nearby lights not-removable.
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
- {
- const Light* light = &(*iter);
- ((LLViewerOctreeEntryData*) light->drawable)->setVisible();
- }
- }
+ }
+ else
+ {
+ break; // none of the other lights are closer
+ }
+ }
+ }
+
+ //mark nearby lights not-removable.
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ const Light* light = &(*iter);
+ ((LLViewerOctreeEntryData*) light->drawable)->setVisible();
+ }
+ }
}
void LLPipeline::setupHWLights()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- assertInitialized();
-
+ assertInitialized();
+
if (LLPipeline::sRenderingHUDs)
{
return;
@@ -5435,13 +5498,13 @@ void LLPipeline::setupHWLights()
// Ambient
LLColor4 ambient = psky->getTotalAmbient();
- gGL.setAmbientLightColor(ambient);
+ gGL.setAmbientLightColor(ambient);
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
- // Light 0 = Sun or Moon (All objects)
- {
+ // Light 0 = Sun or Moon (All objects)
+ {
LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
LLVector4 moon_dir(environment.getMoonDirection(), 0.0f);
@@ -5451,12 +5514,12 @@ void LLPipeline::setupHWLights()
mSunDiffuse.setVec(psky->getSunlightColor());
mMoonDiffuse.setVec(psky->getMoonlightColor());
- F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
- if (max_color > 1.f)
- {
- mSunDiffuse *= 1.f/max_color;
- }
- mSunDiffuse.clamp();
+ F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
+ if (max_color > 1.f)
+ {
+ mSunDiffuse *= 1.f/max_color;
+ }
+ mSunDiffuse.clamp();
max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]);
if (max_color > 1.f)
@@ -5467,54 +5530,54 @@ void LLPipeline::setupHWLights()
// prevent underlighting from having neither lightsource facing us
if (!sun_up && !moon_up)
- {
+ {
mSunDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0));
mMoonDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0));
mSunDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0));
mMoonDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0));
- }
+ }
LLVector4 light_dir = sun_up ? mSunDir : mMoonDir;
mHWLightColors[0] = sun_up ? mSunDiffuse : mMoonDiffuse;
- LLLightState* light = gGL.getLight(0);
+ LLLightState* light = gGL.getLight(0);
light->setPosition(light_dir);
light->setSunPrimary(sun_up);
light->setDiffuse(mHWLightColors[0]);
light->setDiffuseB(mMoonDiffuse);
light->setAmbient(psky->getTotalAmbient());
- light->setSpecular(LLColor4::black);
- light->setConstantAttenuation(1.f);
- light->setLinearAttenuation(0.f);
- light->setQuadraticAttenuation(0.f);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
- }
-
- // Light 1 = Backlight (for avatars)
- // (set by enableLightsAvatar)
-
- S32 cur_light = 2;
-
- // Nearby lights = LIGHT 2-7
-
- mLightMovingMask = 0;
-
+ light->setSpecular(LLColor4::black);
+ light->setConstantAttenuation(1.f);
+ light->setLinearAttenuation(0.f);
+ light->setQuadraticAttenuation(0.f);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
+ }
+
+ // Light 1 = Backlight (for avatars)
+ // (set by enableLightsAvatar)
+
+ S32 cur_light = 2;
+
+ // Nearby lights = LIGHT 2-7
+
+ mLightMovingMask = 0;
+
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
- if (local_light_count >= 1)
- {
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); ++iter)
- {
- LLDrawable* drawable = iter->drawable;
- LLVOVolume* light = drawable->getVOVolume();
- if (!light)
- {
- continue;
- }
+ if (local_light_count >= 1)
+ {
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); ++iter)
+ {
+ LLDrawable* drawable = iter->drawable;
+ LLVOVolume* light = drawable->getVOVolume();
+ if (!light)
+ {
+ continue;
+ }
if (light->isAttachment())
{
@@ -5524,32 +5587,32 @@ void LLPipeline::setupHWLights()
}
}
- if (drawable->isState(LLDrawable::ACTIVE))
- {
- mLightMovingMask |= (1<<cur_light);
- }
-
+ if (drawable->isState(LLDrawable::ACTIVE))
+ {
+ mLightMovingMask |= (1<<cur_light);
+ }
+
//send linear light color to shader
LLColor4 light_color = light->getLightLinearColor() * light_scale;
- light_color.mV[3] = 0.0f;
-
- F32 fade = iter->fade;
- if (fade < LIGHT_FADE_TIME)
- {
- // fade in/out light
- if (fade >= 0.f)
- {
- fade = fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value();
- }
- else
- {
- fade = 1.f + fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value();
- }
- fade = llclamp(fade,0.f,1.f);
- light_color *= fade;
- }
+ light_color.mV[3] = 0.0f;
+
+ F32 fade = iter->fade;
+ if (fade < LIGHT_FADE_TIME)
+ {
+ // fade in/out light
+ if (fade >= 0.f)
+ {
+ fade = fade / LIGHT_FADE_TIME;
+ ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value();
+ }
+ else
+ {
+ fade = 1.f + fade / LIGHT_FADE_TIME;
+ ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value();
+ }
+ fade = llclamp(fade,0.f,1.f);
+ light_color *= fade;
+ }
if (light_color.magVecSquared() < 0.001f)
{
@@ -5569,213 +5632,213 @@ void LLPipeline::setupHWLights()
F32 linatten = x / adjusted_radius; // % of brightness at radius
mHWLightColors[cur_light] = light_color;
- LLLightState* light_state = gGL.getLight(cur_light);
-
- light_state->setPosition(light_pos_gl);
- light_state->setDiffuse(light_color);
- light_state->setAmbient(LLColor4::black);
- light_state->setConstantAttenuation(0.f);
+ LLLightState* light_state = gGL.getLight(cur_light);
+
+ light_state->setPosition(light_pos_gl);
+ light_state->setDiffuse(light_color);
+ light_state->setAmbient(LLColor4::black);
+ light_state->setConstantAttenuation(0.f);
light_state->setSize(light->getLightRadius() * 1.5f);
light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
- if (sRenderDeferred)
- {
- light_state->setLinearAttenuation(linatten);
- light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights
- }
- else
- {
- light_state->setLinearAttenuation(linatten);
- light_state->setQuadraticAttenuation(0.f);
- }
-
-
- if (light->isLightSpotlight() // directional (spot-)light
- && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
- {
- LLQuaternion quat = light->getRenderRotation();
- LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
- at_axis *= quat;
-
- light_state->setSpotDirection(at_axis);
- light_state->setSpotCutoff(90.f);
- light_state->setSpotExponent(2.f);
-
- LLVector3 spotParams = light->getSpotLightParams();
-
- const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]);
- light_state->setSpecular(specular);
- }
- else // omnidirectional (point) light
- {
- light_state->setSpotExponent(0.f);
- light_state->setSpotCutoff(180.f);
-
- // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
- const LLColor4 specular(0.f, 0.f, 1.f, 0.f);
- light_state->setSpecular(specular);
- }
- cur_light++;
- if (cur_light >= 8)
- {
- break; // safety
- }
- }
- }
- for ( ; cur_light < 8 ; cur_light++)
- {
- mHWLightColors[cur_light] = LLColor4::black;
- LLLightState* light = gGL.getLight(cur_light);
+ if (sRenderDeferred)
+ {
+ light_state->setLinearAttenuation(linatten);
+ light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights
+ }
+ else
+ {
+ light_state->setLinearAttenuation(linatten);
+ light_state->setQuadraticAttenuation(0.f);
+ }
+
+
+ if (light->isLightSpotlight() // directional (spot-)light
+ && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
+ {
+ LLQuaternion quat = light->getRenderRotation();
+ LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
+ at_axis *= quat;
+
+ light_state->setSpotDirection(at_axis);
+ light_state->setSpotCutoff(90.f);
+ light_state->setSpotExponent(2.f);
+
+ LLVector3 spotParams = light->getSpotLightParams();
+
+ const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]);
+ light_state->setSpecular(specular);
+ }
+ else // omnidirectional (point) light
+ {
+ light_state->setSpotExponent(0.f);
+ light_state->setSpotCutoff(180.f);
+
+ // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
+ const LLColor4 specular(0.f, 0.f, 1.f, 0.f);
+ light_state->setSpecular(specular);
+ }
+ cur_light++;
+ if (cur_light >= 8)
+ {
+ break; // safety
+ }
+ }
+ }
+ for ( ; cur_light < 8 ; cur_light++)
+ {
+ mHWLightColors[cur_light] = LLColor4::black;
+ LLLightState* light = gGL.getLight(cur_light);
light->setSunPrimary(true);
- light->setDiffuse(LLColor4::black);
- light->setAmbient(LLColor4::black);
- light->setSpecular(LLColor4::black);
- }
+ light->setDiffuse(LLColor4::black);
+ light->setAmbient(LLColor4::black);
+ light->setSpecular(LLColor4::black);
+ }
// Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode),
// prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20
- // Init GL state
- for (S32 i = 0; i < 8; ++i)
- {
- gGL.getLight(i)->disable();
- }
- mLightMask = 0;
+ // Init GL state
+ for (S32 i = 0; i < 8; ++i)
+ {
+ gGL.getLight(i)->disable();
+ }
+ mLightMask = 0;
}
void LLPipeline::enableLights(U32 mask)
{
- assertInitialized();
-
- if (mLightMask != mask)
- {
- stop_glerror();
- if (mask)
- {
- stop_glerror();
- for (S32 i=0; i<8; i++)
- {
- LLLightState* light = gGL.getLight(i);
- if (mask & (1<<i))
- {
- light->enable();
- light->setDiffuse(mHWLightColors[i]);
- }
- else
- {
- light->disable();
- light->setDiffuse(LLColor4::black);
- }
- }
- stop_glerror();
- }
- mLightMask = mask;
- stop_glerror();
- }
+ assertInitialized();
+
+ if (mLightMask != mask)
+ {
+ stop_glerror();
+ if (mask)
+ {
+ stop_glerror();
+ for (S32 i=0; i<8; i++)
+ {
+ LLLightState* light = gGL.getLight(i);
+ if (mask & (1<<i))
+ {
+ light->enable();
+ light->setDiffuse(mHWLightColors[i]);
+ }
+ else
+ {
+ light->disable();
+ light->setDiffuse(LLColor4::black);
+ }
+ }
+ stop_glerror();
+ }
+ mLightMask = mask;
+ stop_glerror();
+ }
}
void LLPipeline::enableLightsDynamic()
{
- assertInitialized();
- U32 mask = 0xff & (~2); // Local lights
- enableLights(mask);
-
- if (isAgentAvatarValid())
- {
- if (gAgentAvatarp->mSpecialRenderMode == 0) // normal
- {
- gPipeline.enableLightsAvatar();
- }
- else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview
- {
- gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
- }
- }
+ assertInitialized();
+ U32 mask = 0xff & (~2); // Local lights
+ enableLights(mask);
+
+ if (isAgentAvatarValid())
+ {
+ if (gAgentAvatarp->mSpecialRenderMode == 0) // normal
+ {
+ gPipeline.enableLightsAvatar();
+ }
+ else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview
+ {
+ gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
+ }
+ }
}
void LLPipeline::enableLightsAvatar()
{
- U32 mask = 0xff; // All lights
- setupAvatarLights(FALSE);
- enableLights(mask);
+ U32 mask = 0xff; // All lights
+ setupAvatarLights(FALSE);
+ enableLights(mask);
}
void LLPipeline::enableLightsPreview()
{
- disableLights();
-
- LLColor4 ambient = PreviewAmbientColor;
- gGL.setAmbientLightColor(ambient);
-
- LLColor4 diffuse0 = PreviewDiffuse0;
- LLColor4 specular0 = PreviewSpecular0;
- LLColor4 diffuse1 = PreviewDiffuse1;
- LLColor4 specular1 = PreviewSpecular1;
- LLColor4 diffuse2 = PreviewDiffuse2;
- LLColor4 specular2 = PreviewSpecular2;
-
- LLVector3 dir0 = PreviewDirection0;
- LLVector3 dir1 = PreviewDirection1;
- LLVector3 dir2 = PreviewDirection2;
-
- dir0.normVec();
- dir1.normVec();
- dir2.normVec();
-
- LLVector4 light_pos(dir0, 0.0f);
-
- LLLightState* light = gGL.getLight(1);
-
- light->enable();
- light->setPosition(light_pos);
- light->setDiffuse(diffuse0);
- light->setAmbient(ambient);
- light->setSpecular(specular0);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
-
- light_pos = LLVector4(dir1, 0.f);
-
- light = gGL.getLight(2);
- light->enable();
- light->setPosition(light_pos);
- light->setDiffuse(diffuse1);
- light->setAmbient(ambient);
- light->setSpecular(specular1);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
-
- light_pos = LLVector4(dir2, 0.f);
- light = gGL.getLight(3);
- light->enable();
- light->setPosition(light_pos);
- light->setDiffuse(diffuse2);
- light->setAmbient(ambient);
- light->setSpecular(specular2);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
+ disableLights();
+
+ LLColor4 ambient = PreviewAmbientColor;
+ gGL.setAmbientLightColor(ambient);
+
+ LLColor4 diffuse0 = PreviewDiffuse0;
+ LLColor4 specular0 = PreviewSpecular0;
+ LLColor4 diffuse1 = PreviewDiffuse1;
+ LLColor4 specular1 = PreviewSpecular1;
+ LLColor4 diffuse2 = PreviewDiffuse2;
+ LLColor4 specular2 = PreviewSpecular2;
+
+ LLVector3 dir0 = PreviewDirection0;
+ LLVector3 dir1 = PreviewDirection1;
+ LLVector3 dir2 = PreviewDirection2;
+
+ dir0.normVec();
+ dir1.normVec();
+ dir2.normVec();
+
+ LLVector4 light_pos(dir0, 0.0f);
+
+ LLLightState* light = gGL.getLight(1);
+
+ light->enable();
+ light->setPosition(light_pos);
+ light->setDiffuse(diffuse0);
+ light->setAmbient(ambient);
+ light->setSpecular(specular0);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
+
+ light_pos = LLVector4(dir1, 0.f);
+
+ light = gGL.getLight(2);
+ light->enable();
+ light->setPosition(light_pos);
+ light->setDiffuse(diffuse1);
+ light->setAmbient(ambient);
+ light->setSpecular(specular1);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
+
+ light_pos = LLVector4(dir2, 0.f);
+ light = gGL.getLight(3);
+ light->enable();
+ light->setPosition(light_pos);
+ light->setDiffuse(diffuse2);
+ light->setAmbient(ambient);
+ light->setSpecular(specular2);
+ light->setSpotExponent(0.f);
+ light->setSpotCutoff(180.f);
}
void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
{
- U32 mask = 0x2002; // Avatar backlight only, set ambient
- setupAvatarLights(TRUE);
- enableLights(mask);
+ U32 mask = 0x2002; // Avatar backlight only, set ambient
+ setupAvatarLights(TRUE);
+ enableLights(mask);
- gGL.setAmbientLightColor(color);
+ gGL.setAmbientLightColor(color);
}
void LLPipeline::enableLightsFullbright()
{
- assertInitialized();
- U32 mask = 0x1000; // Non-0 mask, set ambient
- enableLights(mask);
+ assertInitialized();
+ U32 mask = 0x1000; // Non-0 mask, set ambient
+ enableLights(mask);
}
void LLPipeline::disableLights()
{
- enableLights(0); // no lighting (full bright)
+ enableLights(0); // no lighting (full bright)
}
//============================================================================
@@ -5788,58 +5851,58 @@ class LLVOLeaf;
void LLPipeline::findReferences(LLDrawable *drawablep)
{
- assertInitialized();
- if (mLights.find(drawablep) != mLights.end())
- {
- LL_INFOS() << "In mLights" << LL_ENDL;
- }
- if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end())
- {
- LL_INFOS() << "In mMovedList" << LL_ENDL;
- }
- if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end())
- {
- LL_INFOS() << "In mShiftList" << LL_ENDL;
- }
- if (mRetexturedList.find(drawablep) != mRetexturedList.end())
- {
- LL_INFOS() << "In mRetexturedList" << LL_ENDL;
- }
-
- if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end())
- {
- LL_INFOS() << "In mBuildQ1" << LL_ENDL;
- }
-
- S32 count;
-
- count = gObjectList.findReferences(drawablep);
- if (count)
- {
- LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL;
- }
+ assertInitialized();
+ if (mLights.find(drawablep) != mLights.end())
+ {
+ LL_INFOS() << "In mLights" << LL_ENDL;
+ }
+ if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end())
+ {
+ LL_INFOS() << "In mMovedList" << LL_ENDL;
+ }
+ if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end())
+ {
+ LL_INFOS() << "In mShiftList" << LL_ENDL;
+ }
+ if (mRetexturedList.find(drawablep) != mRetexturedList.end())
+ {
+ LL_INFOS() << "In mRetexturedList" << LL_ENDL;
+ }
+
+ if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end())
+ {
+ LL_INFOS() << "In mBuildQ1" << LL_ENDL;
+ }
+
+ S32 count;
+
+ count = gObjectList.findReferences(drawablep);
+ if (count)
+ {
+ LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL;
+ }
}
bool LLPipeline::verify()
{
- bool ok = assertInitialized();
- if (ok)
- {
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- if (!poolp->verify())
- {
- ok = false;
- }
- }
- }
-
- if (!ok)
- {
- LL_WARNS() << "Pipeline verify failed!" << LL_ENDL;
- }
- return ok;
+ bool ok = assertInitialized();
+ if (ok)
+ {
+ for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
+ {
+ LLDrawPool *poolp = *iter;
+ if (!poolp->verify())
+ {
+ ok = false;
+ }
+ }
+ }
+
+ if (!ok)
+ {
+ LL_WARNS() << "Pipeline verify failed!" << LL_ENDL;
+ }
+ return ok;
}
//////////////////////////////
@@ -5850,89 +5913,89 @@ bool LLPipeline::verify()
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
- * A method to compute a ray-AABB intersection.
- * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990
- * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
- * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only)
+ * A method to compute a ray-AABB intersection.
+ * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990
+ * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
+ * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only)
*
- * Hence this version is faster as well as more robust than the original one.
+ * Hence this version is faster as well as more robust than the original one.
*
- * Should work provided:
- * 1) the integer representation of 0.0f is 0x00000000
- * 2) the sign bit of the float is the most significant one
+ * Should work provided:
+ * 1) the integer representation of 0.0f is 0x00000000
+ * 2) the sign bit of the float is the most significant one
*
- * Report bugs: p.terdiman@codercorner.com
+ * Report bugs: p.terdiman@codercorner.com
*
- * \param aabb [in] the axis-aligned bounding box
- * \param origin [in] ray origin
- * \param dir [in] ray direction
- * \param coord [out] impact coordinates
- * \return true if ray intersects AABB
+ * \param aabb [in] the axis-aligned bounding box
+ * \param origin [in] ray origin
+ * \param dir [in] ray direction
+ * \param coord [out] impact coordinates
+ * \return true if ray intersects AABB
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#define RAYAABB_EPSILON 0.00001f
-#define IR(x) ((U32&)x)
+#define IR(x) ((U32&)x)
bool LLRayAABB(const LLVector3 &center, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon)
{
- bool Inside = true;
- LLVector3 MinB = center - size;
- LLVector3 MaxB = center + size;
- LLVector3 MaxT;
- MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f;
-
- // Find candidate planes.
- for(U32 i=0;i<3;i++)
- {
- if(origin.mV[i] < MinB.mV[i])
- {
- coord.mV[i] = MinB.mV[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i];
- }
- else if(origin.mV[i] > MaxB.mV[i])
- {
- coord.mV[i] = MaxB.mV[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i];
- }
- }
-
- // Ray origin inside bounding box
- if(Inside)
- {
- coord = origin;
- return true;
- }
-
- // Get largest of the maxT's for final choice of intersection
- U32 WhichPlane = 0;
- if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1;
- if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2;
-
- // Check final candidate actually inside box
- if(IR(MaxT.mV[WhichPlane])&0x80000000) return false;
-
- for(U32 i=0;i<3;i++)
- {
- if(i!=WhichPlane)
- {
- coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i];
- if (epsilon > 0)
- {
- if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false;
- }
- else
- {
- if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false;
- }
- }
- }
- return true; // ray hits box
+ bool Inside = true;
+ LLVector3 MinB = center - size;
+ LLVector3 MaxB = center + size;
+ LLVector3 MaxT;
+ MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f;
+
+ // Find candidate planes.
+ for(U32 i=0;i<3;i++)
+ {
+ if(origin.mV[i] < MinB.mV[i])
+ {
+ coord.mV[i] = MinB.mV[i];
+ Inside = false;
+
+ // Calculate T distances to candidate planes
+ if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i];
+ }
+ else if(origin.mV[i] > MaxB.mV[i])
+ {
+ coord.mV[i] = MaxB.mV[i];
+ Inside = false;
+
+ // Calculate T distances to candidate planes
+ if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i];
+ }
+ }
+
+ // Ray origin inside bounding box
+ if(Inside)
+ {
+ coord = origin;
+ return true;
+ }
+
+ // Get largest of the maxT's for final choice of intersection
+ U32 WhichPlane = 0;
+ if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1;
+ if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2;
+
+ // Check final candidate actually inside box
+ if(IR(MaxT.mV[WhichPlane])&0x80000000) return false;
+
+ for(U32 i=0;i<3;i++)
+ {
+ if(i!=WhichPlane)
+ {
+ coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i];
+ if (epsilon > 0)
+ {
+ if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false;
+ }
+ else
+ {
+ if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false;
+ }
+ }
+ }
+ return true; // ray hits box
}
//////////////////////////////
@@ -5943,537 +6006,558 @@ bool LLRayAABB(const LLVector3 &center, const LLVector3 &size, const LLVector3&
void LLPipeline::setLight(LLDrawable *drawablep, bool is_light)
{
- if (drawablep && assertInitialized())
- {
- if (is_light)
- {
- mLights.insert(drawablep);
- drawablep->setState(LLDrawable::LIGHT);
- }
- else
- {
- drawablep->clearState(LLDrawable::LIGHT);
- mLights.erase(drawablep);
- }
- }
+ if (drawablep && assertInitialized())
+ {
+ if (is_light)
+ {
+ mLights.insert(drawablep);
+ drawablep->setState(LLDrawable::LIGHT);
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::LIGHT);
+ mLights.erase(drawablep);
+ }
+ }
}
//static
void LLPipeline::toggleRenderType(U32 type)
{
- gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type];
- if (type == LLPipeline::RENDER_TYPE_WATER)
- {
- gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER];
- }
+ gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type];
+ if (type == LLPipeline::RENDER_TYPE_WATER)
+ {
+ gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER];
+ }
}
//static
void LLPipeline::toggleRenderTypeControl(U32 type)
{
- gPipeline.toggleRenderType(type);
+ gPipeline.toggleRenderType(type);
}
//static
bool LLPipeline::hasRenderTypeControl(U32 type)
{
- return gPipeline.hasRenderType(type);
+ return gPipeline.hasRenderType(type);
}
// Allows UI items labeled "Hide foo" instead of "Show foo"
//static
bool LLPipeline::toggleRenderTypeControlNegated(S32 type)
{
- return !gPipeline.hasRenderType(type);
+ return !gPipeline.hasRenderType(type);
}
//static
void LLPipeline::toggleRenderDebug(U64 bit)
{
- if (gPipeline.hasRenderDebugMask(bit))
- {
- LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
- }
- gPipeline.mRenderDebugMask ^= bit;
+ if (gPipeline.hasRenderDebugMask(bit))
+ {
+ LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
+ }
+ gPipeline.mRenderDebugMask ^= bit;
}
//static
bool LLPipeline::toggleRenderDebugControl(U64 bit)
{
- return gPipeline.hasRenderDebugMask(bit);
+ return gPipeline.hasRenderDebugMask(bit);
}
//static
void LLPipeline::toggleRenderDebugFeature(U32 bit)
{
- gPipeline.mRenderDebugFeatureMask ^= bit;
+ gPipeline.mRenderDebugFeatureMask ^= bit;
}
//static
bool LLPipeline::toggleRenderDebugFeatureControl(U32 bit)
{
- return gPipeline.hasRenderDebugFeatureMask(bit);
+ return gPipeline.hasRenderDebugFeatureMask(bit);
}
void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
{
- if (value)
- {
- gPipeline.mRenderDebugFeatureMask |= bit;
- }
- else
- {
- gPipeline.mRenderDebugFeatureMask &= !bit;
- }
+ if (value)
+ {
+ gPipeline.mRenderDebugFeatureMask |= bit;
+ }
+ else
+ {
+ gPipeline.mRenderDebugFeatureMask &= !bit;
+ }
}
void LLPipeline::pushRenderDebugFeatureMask()
{
- mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+ mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
}
void LLPipeline::popRenderDebugFeatureMask()
{
- if (mRenderDebugFeatureStack.empty())
- {
- LL_ERRS() << "Depleted render feature stack." << LL_ENDL;
- }
+ if (mRenderDebugFeatureStack.empty())
+ {
+ LL_ERRS() << "Depleted render feature stack." << LL_ENDL;
+ }
- mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
- mRenderDebugFeatureStack.pop();
+ mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+ mRenderDebugFeatureStack.pop();
}
// static
void LLPipeline::setRenderScriptedBeacons(bool val)
{
- sRenderScriptedBeacons = val;
+ sRenderScriptedBeacons = val;
}
// static
void LLPipeline::toggleRenderScriptedBeacons()
{
- sRenderScriptedBeacons = !sRenderScriptedBeacons;
+ sRenderScriptedBeacons = !sRenderScriptedBeacons;
}
// static
bool LLPipeline::getRenderScriptedBeacons()
{
- return sRenderScriptedBeacons;
+ return sRenderScriptedBeacons;
}
// static
void LLPipeline::setRenderScriptedTouchBeacons(bool val)
{
- sRenderScriptedTouchBeacons = val;
+ sRenderScriptedTouchBeacons = val;
}
// static
void LLPipeline::toggleRenderScriptedTouchBeacons()
{
- sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons;
+ sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons;
}
// static
bool LLPipeline::getRenderScriptedTouchBeacons()
{
- return sRenderScriptedTouchBeacons;
+ return sRenderScriptedTouchBeacons;
}
// static
void LLPipeline::setRenderMOAPBeacons(bool val)
{
- sRenderMOAPBeacons = val;
+ sRenderMOAPBeacons = val;
}
// static
void LLPipeline::toggleRenderMOAPBeacons()
{
- sRenderMOAPBeacons = !sRenderMOAPBeacons;
+ sRenderMOAPBeacons = !sRenderMOAPBeacons;
}
// static
bool LLPipeline::getRenderMOAPBeacons()
{
- return sRenderMOAPBeacons;
+ return sRenderMOAPBeacons;
}
// static
void LLPipeline::setRenderPhysicalBeacons(bool val)
{
- sRenderPhysicalBeacons = val;
+ sRenderPhysicalBeacons = val;
}
// static
void LLPipeline::toggleRenderPhysicalBeacons()
{
- sRenderPhysicalBeacons = !sRenderPhysicalBeacons;
+ sRenderPhysicalBeacons = !sRenderPhysicalBeacons;
}
// static
bool LLPipeline::getRenderPhysicalBeacons()
{
- return sRenderPhysicalBeacons;
+ return sRenderPhysicalBeacons;
}
// static
void LLPipeline::setRenderParticleBeacons(bool val)
{
- sRenderParticleBeacons = val;
+ sRenderParticleBeacons = val;
}
// static
void LLPipeline::toggleRenderParticleBeacons()
{
- sRenderParticleBeacons = !sRenderParticleBeacons;
+ sRenderParticleBeacons = !sRenderParticleBeacons;
}
// static
bool LLPipeline::getRenderParticleBeacons()
{
- return sRenderParticleBeacons;
+ return sRenderParticleBeacons;
}
// static
void LLPipeline::setRenderSoundBeacons(bool val)
{
- sRenderSoundBeacons = val;
+ sRenderSoundBeacons = val;
}
// static
void LLPipeline::toggleRenderSoundBeacons()
{
- sRenderSoundBeacons = !sRenderSoundBeacons;
+ sRenderSoundBeacons = !sRenderSoundBeacons;
}
// static
bool LLPipeline::getRenderSoundBeacons()
{
- return sRenderSoundBeacons;
+ return sRenderSoundBeacons;
}
// static
void LLPipeline::setRenderBeacons(bool val)
{
- sRenderBeacons = val;
+ sRenderBeacons = val;
}
// static
void LLPipeline::toggleRenderBeacons()
{
- sRenderBeacons = !sRenderBeacons;
+ sRenderBeacons = !sRenderBeacons;
}
// static
bool LLPipeline::getRenderBeacons()
{
- return sRenderBeacons;
+ return sRenderBeacons;
}
// static
void LLPipeline::setRenderHighlights(bool val)
{
- sRenderHighlight = val;
+ sRenderHighlight = val;
}
// static
void LLPipeline::toggleRenderHighlights()
{
- sRenderHighlight = !sRenderHighlight;
+ sRenderHighlight = !sRenderHighlight;
}
// static
bool LLPipeline::getRenderHighlights()
{
- return sRenderHighlight;
+ return sRenderHighlight;
}
// static
void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
{
- sRenderHighlightTextureChannel = channel;
+ sRenderHighlightTextureChannel = channel;
}
LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
- S32* face_hit)
-{
- LLVector4a local_end = end;
-
- LLVector4a position;
-
- LLDrawable* drawable = NULL;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
- if (part && hasRenderType(part->mDrawableType))
- {
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
- if (hit)
- {
- drawable = hit;
- local_end = position;
- }
- }
- }
-
- LLVOPartGroup* ret = NULL;
- if (drawable)
- {
- //make sure we're returning an LLVOPartGroup
- llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP);
- ret = (LLVOPartGroup*) drawable->getVObj().get();
- }
-
- if (intersection)
- {
- *intersection = position;
- }
-
- return ret;
+ S32* face_hit)
+{
+ LLVector4a local_end = end;
+
+ LLVector4a position;
+
+ LLDrawable* drawable = NULL;
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
+ if (part && hasRenderType(part->mDrawableType))
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
+ if (hit)
+ {
+ drawable = hit;
+ local_end = position;
+ }
+ }
+ }
+
+ LLVOPartGroup* ret = NULL;
+ if (drawable)
+ {
+ //make sure we're returning an LLVOPartGroup
+ llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP);
+ ret = (LLVOPartGroup*) drawable->getVObj().get();
+ }
+
+ if (intersection)
+ {
+ *intersection = position;
+ }
+
+ return ret;
}
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- bool pick_rigged,
+ bool pick_transparent,
+ bool pick_rigged,
bool pick_unselectable,
bool pick_reflection_probe,
- S32* face_hit,
- LLVector4a* intersection, // return the intersection point
- LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector4a* normal, // return the surface normal at the intersection point
- LLVector4a* tangent // return the surface tangent at the intersection point
- )
-{
- LLDrawable* drawable = NULL;
-
- LLVector4a local_end = end;
-
- LLVector4a position;
-
- sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode();
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
- {
- if ((j == LLViewerRegion::PARTITION_VOLUME) ||
- (j == LLViewerRegion::PARTITION_BRIDGE) ||
+ S32* face_hit,
+ S32* gltf_node_hit,
+ S32* gltf_primitive_hit,
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+ )
+{
+ LLDrawable* drawable = NULL;
+
+ LLVector4a local_end = end;
+
+ LLVector4a position;
+
+ sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
+ {
+ if ((j == LLViewerRegion::PARTITION_VOLUME) ||
+ (j == LLViewerRegion::PARTITION_BRIDGE) ||
(j == LLViewerRegion::PARTITION_AVATAR) || // for attachments
- (j == LLViewerRegion::PARTITION_CONTROL_AV) ||
- (j == LLViewerRegion::PARTITION_TERRAIN) ||
- (j == LLViewerRegion::PARTITION_TREE) ||
- (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now
- {
- LLSpatialPartition* part = region->getSpatialPartition(j);
- if (part && hasRenderType(part->mDrawableType))
- {
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
- if (hit)
- {
- drawable = hit;
- local_end = position;
- }
- }
- }
- }
- }
-
- if (!sPickAvatar)
- {
- //save hit info in case we need to restore
- //due to attachment override
- LLVector4a local_normal;
- LLVector4a local_tangent;
- LLVector2 local_texcoord;
- S32 local_face_hit = -1;
-
- if (face_hit)
- {
- local_face_hit = *face_hit;
- }
- if (tex_coord)
- {
- local_texcoord = *tex_coord;
- }
- if (tangent)
- {
- local_tangent = *tangent;
- }
- else
- {
- local_tangent.clear();
- }
- if (normal)
- {
- local_normal = *normal;
- }
- else
- {
- local_normal.clear();
- }
-
- const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
-
- //check against avatars
- sPickAvatar = true;
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
- if (part && hasRenderType(part->mDrawableType))
- {
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
- if (hit)
- {
- LLVector4a delta;
- delta.setSub(position, local_end);
-
- if (!drawable ||
- !drawable->getVObj()->isAttachment() ||
- delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
- { //avatar overrides if previously hit drawable is not an attachment or
- //attachment is far enough away from detected intersection
- drawable = hit;
- local_end = position;
- }
- else
- { //prioritize attachments over avatars
- position = local_end;
-
- if (face_hit)
- {
- *face_hit = local_face_hit;
- }
- if (tex_coord)
- {
- *tex_coord = local_texcoord;
- }
- if (tangent)
- {
- *tangent = local_tangent;
- }
- if (normal)
- {
- *normal = local_normal;
- }
- }
- }
- }
- }
- }
-
- //check all avatar nametags (silly, isn't it?)
- for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end();
- ++iter)
- {
- LLVOAvatar* av = (LLVOAvatar*) *iter;
- if (av->mNameText.notNull()
- && av->mNameText->lineSegmentIntersect(start, local_end, position))
- {
- drawable = av->mDrawable;
- local_end = position;
- }
- }
-
- if (intersection)
- {
- *intersection = position;
- }
-
- return drawable ? drawable->getVObj().get() : NULL;
+ (j == LLViewerRegion::PARTITION_CONTROL_AV) ||
+ (j == LLViewerRegion::PARTITION_TERRAIN) ||
+ (j == LLViewerRegion::PARTITION_TREE) ||
+ (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(j);
+ if (part && hasRenderType(part->mDrawableType))
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
+ if (hit)
+ {
+ drawable = hit;
+ local_end = position;
+ }
+ }
+ }
+ }
+ }
+
+ if (!sPickAvatar)
+ {
+ //save hit info in case we need to restore
+ //due to attachment override
+ LLVector4a local_normal;
+ LLVector4a local_tangent;
+ LLVector2 local_texcoord;
+ S32 local_face_hit = -1;
+
+ if (face_hit)
+ {
+ local_face_hit = *face_hit;
+ }
+ if (tex_coord)
+ {
+ local_texcoord = *tex_coord;
+ }
+ if (tangent)
+ {
+ local_tangent = *tangent;
+ }
+ else
+ {
+ local_tangent.clear();
+ }
+ if (normal)
+ {
+ local_normal = *normal;
+ }
+ else
+ {
+ local_normal.clear();
+ }
+
+ const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
+
+ //check against avatars
+ sPickAvatar = true;
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
+ if (part && hasRenderType(part->mDrawableType))
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
+ if (hit)
+ {
+ LLVector4a delta;
+ delta.setSub(position, local_end);
+
+ if (!drawable ||
+ !drawable->getVObj()->isAttachment() ||
+ delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
+ { //avatar overrides if previously hit drawable is not an attachment or
+ //attachment is far enough away from detected intersection
+ drawable = hit;
+ local_end = position;
+ }
+ else
+ { //prioritize attachments over avatars
+ position = local_end;
+
+ if (face_hit)
+ {
+ *face_hit = local_face_hit;
+ }
+ if (tex_coord)
+ {
+ *tex_coord = local_texcoord;
+ }
+ if (tangent)
+ {
+ *tangent = local_tangent;
+ }
+ if (normal)
+ {
+ *normal = local_normal;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //check all avatar nametags (silly, isn't it?)
+ for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end();
+ ++iter)
+ {
+ LLVOAvatar* av = (LLVOAvatar*) *iter;
+ if (av->mNameText.notNull()
+ && av->mNameText->lineSegmentIntersect(start, local_end, position))
+ {
+ drawable = av->mDrawable;
+ local_end = position;
+ }
+ }
+
+ S32 node_hit = -1;
+ S32 primitive_hit = -1;
+ LLDrawable* hit = LL::GLTFSceneManager::instance().lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, &node_hit, &primitive_hit, &position, tex_coord, normal, tangent);
+ if (hit)
+ {
+ drawable = hit;
+ local_end = position;
+ }
+
+ if (gltf_node_hit)
+ {
+ *gltf_node_hit = node_hit;
+ }
+
+ if (gltf_primitive_hit)
+ {
+ *gltf_primitive_hit = primitive_hit;
+ }
+
+ if (intersection)
+ {
+ *intersection = position;
+ }
+
+ return drawable ? drawable->getVObj().get() : NULL;
}
LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- S32* face_hit,
- LLVector4a* intersection, // return the intersection point
- LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector4a* normal, // return the surface normal at the intersection point
- LLVector4a* tangent // return the surface tangent at the intersection point
- )
-{
- LLDrawable* drawable = NULL;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
-
- bool toggle = false;
- if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- toggle = true;
- }
-
- LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
- if (part)
- {
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, FALSE, face_hit, intersection, tex_coord, normal, tangent);
- if (hit)
- {
- drawable = hit;
- }
- }
-
- if (toggle)
- {
- toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- }
- }
- return drawable ? drawable->getVObj().get() : NULL;
+ bool pick_transparent,
+ S32* face_hit,
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+ )
+{
+ LLDrawable* drawable = NULL;
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ bool toggle = false;
+ if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ toggle = true;
+ }
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
+ if (part)
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, FALSE, face_hit, intersection, tex_coord, normal, tangent);
+ if (hit)
+ {
+ drawable = hit;
+ }
+ }
+
+ if (toggle)
+ {
+ toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+ }
+ return drawable ? drawable->getVObj().get() : NULL;
}
LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj)
{
- if (vobj)
- {
- LLViewerRegion* region = vobj->getRegion();
- if (region)
- {
- return region->getSpatialPartition(vobj->getPartitionType());
- }
- }
- return NULL;
+ if (vobj)
+ {
+ LLViewerRegion* region = vobj->getRegion();
+ if (region)
+ {
+ return region->getSpatialPartition(vobj->getPartitionType());
+ }
+ }
+ return NULL;
}
void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
{
- if (!drawable)
- {
- return;
- }
+ if (!drawable)
+ {
+ return;
+ }
- for (S32 i = 0; i < drawable->getNumFaces(); i++)
- {
- LLFace* facep = drawable->getFace(i);
- if (facep)
- {
- facep->clearVertexBuffer();
- }
- }
+ for (S32 i = 0; i < drawable->getNumFaces(); i++)
+ {
+ LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
+ }
}
void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
- assertInitialized();
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
if (rigged)
{
@@ -6485,7 +6569,7 @@ void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool
}
gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ gGLLastMatrix = NULL;
}
void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged)
@@ -6505,6 +6589,15 @@ void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged)
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
+
+ if (!rigged)
+ {
+ LL::GLTFSceneManager::instance().renderOpaque();
+ }
+ else
+ {
+ LL::GLTFSceneManager::instance().render(true, true);
+ }
}
// Currently only used for shadows -Cosmic,2023-04-19
@@ -6542,7 +6635,7 @@ void LLPipeline::renderAlphaObjects(bool rigged)
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
- mSimplePool->pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId);
+ LLRenderPass::pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId);
}
else
{
@@ -6568,7 +6661,7 @@ void LLPipeline::renderAlphaObjects(bool rigged)
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
- mSimplePool->pushGLTFBatch(*pparams);
+ LLRenderPass::pushGLTFBatch(*pparams);
}
else
{
@@ -6588,9 +6681,9 @@ void LLPipeline::renderAlphaObjects(bool rigged)
// Currently only used for shadows -Cosmic,2023-04-19
void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
- assertInitialized();
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
if (rigged)
{
mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
@@ -6599,16 +6692,16 @@ void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture,
{
mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
}
// Currently only used for shadows -Cosmic,2023-04-19
void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
- assertInitialized();
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
if (rigged)
{
mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
@@ -6617,219 +6710,250 @@ void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batc
{
mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
}
void apply_cube_face_rotation(U32 face)
{
- switch (face)
- {
- case 0:
- gGL.rotatef(90.f, 0, 1, 0);
- gGL.rotatef(180.f, 1, 0, 0);
- break;
- case 2:
- gGL.rotatef(-90.f, 1, 0, 0);
- break;
- case 4:
- gGL.rotatef(180.f, 0, 1, 0);
- gGL.rotatef(180.f, 0, 0, 1);
- break;
- case 1:
- gGL.rotatef(-90.f, 0, 1, 0);
- gGL.rotatef(180.f, 1, 0, 0);
- break;
- case 3:
- gGL.rotatef(90, 1, 0, 0);
- break;
- case 5:
- gGL.rotatef(180, 0, 0, 1);
- break;
- }
+ switch (face)
+ {
+ case 0:
+ gGL.rotatef(90.f, 0, 1, 0);
+ gGL.rotatef(180.f, 1, 0, 0);
+ break;
+ case 2:
+ gGL.rotatef(-90.f, 1, 0, 0);
+ break;
+ case 4:
+ gGL.rotatef(180.f, 0, 1, 0);
+ gGL.rotatef(180.f, 0, 0, 1);
+ break;
+ case 1:
+ gGL.rotatef(-90.f, 0, 1, 0);
+ gGL.rotatef(180.f, 1, 0, 0);
+ break;
+ case 3:
+ gGL.rotatef(90, 1, 0, 0);
+ break;
+ case 5:
+ gGL.rotatef(180, 0, 0, 1);
+ break;
+ }
}
void validate_framebuffer_object()
-{
- GLenum status;
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
- switch(status)
- {
- case GL_FRAMEBUFFER_COMPLETE:
- //framebuffer OK, no error.
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- // frame buffer not OK: probably means unsupported depth buffer format
- LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL;
- break;
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- // frame buffer not OK: probably means unsupported depth buffer format
- LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL;
- break;
- case GL_FRAMEBUFFER_UNSUPPORTED:
- /* choose different formats */
- LL_ERRS() << "Framebuffer unsupported." << LL_ENDL;
- break;
- default:
- LL_ERRS() << "Unknown framebuffer status." << LL_ENDL;
- break;
- }
-}
-
-void LLPipeline::bindScreenToTexture()
-{
-
+{
+ GLenum status;
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+ switch(status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE:
+ //framebuffer OK, no error.
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ // frame buffer not OK: probably means unsupported depth buffer format
+ LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL;
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ // frame buffer not OK: probably means unsupported depth buffer format
+ LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL;
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ /* choose different formats */
+ LL_ERRS() << "Framebuffer unsupported." << LL_ENDL;
+ break;
+ default:
+ LL_ERRS() << "Unknown framebuffer status." << LL_ENDL;
+ break;
+ }
+}
+
+void LLPipeline::bindScreenToTexture()
+{
+
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex)
{
- dst->bindTarget();
- gDeferredBufferVisualProgram.bind();
- gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
+ dst->bindTarget();
+ gDeferredBufferVisualProgram.bind();
+ gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
- static LLStaticHashedString mipLevel("mipLevel");
- if (RenderBufferVisualization != 4)
- gDeferredBufferVisualProgram.uniform1f(mipLevel, 0);
- else
- gDeferredBufferVisualProgram.uniform1f(mipLevel, 8);
+ static LLStaticHashedString mipLevel("mipLevel");
+ if (RenderBufferVisualization != 4)
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 0);
+ else
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 8);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gDeferredBufferVisualProgram.unbind();
- dst->flush();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredBufferVisualProgram.unbind();
+ dst->flush();
}
void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
{
- // luminance sample and mipmap generation
- {
- LL_PROFILE_GPU_ZONE("luminance sample");
+ // luminance sample and mipmap generation
+ {
+ LL_PROFILE_GPU_ZONE("luminance sample");
- dst->bindTarget();
+ dst->bindTarget();
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- gLuminanceProgram.bind();
+ gLuminanceProgram.bind();
- S32 channel = 0;
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
- if (channel > -1)
- {
- src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
+ static LLCachedControl<F32> diffuse_luminance_scale(gSavedSettings, "RenderDiffuseLuminanceScale", 1.0f);
+
+ S32 channel = 0;
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mGlow[1].bindTexture(0, channel);
+ }
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_NORMAL);
if (channel > -1)
{
- mGlow[1].bindTexture(0, channel);
- }
+ // bind the normal map to get the environment mask
+ mRT->deferredScreen.bindTexture(2, channel, LLTexUnit::TFO_POINT);
+ }
+
+ static LLStaticHashedString diffuse_luminance_scale_s("diffuse_luminance_scale");
+ gLuminanceProgram.uniform1f(diffuse_luminance_scale_s, diffuse_luminance_scale);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- dst->flush();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dst->flush();
- // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
- // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
- gLuminanceProgram.unbind();
- }
+ // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
+ // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
+ gLuminanceProgram.unbind();
+ }
}
-void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
- // exposure sample
- {
- LL_PROFILE_GPU_ZONE("exposure sample");
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history) {
+ // exposure sample
+ {
+ LL_PROFILE_GPU_ZONE("exposure sample");
- {
- // copy last frame's exposure into mLastExposure
- mLastExposure.bindTarget();
- gCopyProgram.bind();
- gGL.getTexUnit(0)->bind(dst);
+ if (use_history)
+ {
+ // copy last frame's exposure into mLastExposure
+ mLastExposure.bindTarget();
+ gCopyProgram.bind();
+ gGL.getTexUnit(0)->bind(dst);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- mLastExposure.flush();
- }
+ mLastExposure.flush();
+ }
- dst->bindTarget();
+ dst->bindTarget();
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- gExposureProgram.bind();
+ LLGLSLShader* shader;
+ if (use_history)
+ {
+ shader = &gExposureProgram;
+ }
+ else
+ {
+ shader = &gExposureProgramNoFade;
+ }
- S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
- if (channel > -1)
- {
- mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
- }
+ shader->bind();
- channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
- if (channel > -1)
- {
- mLastExposure.bindTexture(0, channel);
- }
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ }
- static LLStaticHashedString dt("dt");
- static LLStaticHashedString noiseVec("noiseVec");
- static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
- static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
- static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ if (use_history)
+ {
+ channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
+ }
- LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
+ static LLStaticHashedString dt("dt");
+ static LLStaticHashedString noiseVec("noiseVec");
+ static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
+ static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
- F32 exp_min = 1.f;
- F32 exp_max = 1.f;
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- if (probe_ambiance > 0.f)
- {
- F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma())*2.f;
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 exp_min = 1.f;
+ F32 exp_max = 1.f;
- if (hdr_scale > 1.f)
- {
- exp_min = 1.f / hdr_scale;
- exp_max = hdr_scale;
- }
- }
- gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
- gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
- gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
+ if (probe_ambiance > 0.f)
+ {
+ F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f;
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ if (hdr_scale > 1.f)
+ {
+ exp_min = 1.f / hdr_scale;
+ exp_max = hdr_scale;
+ }
+ }
+ shader->uniform1f(dt, gFrameIntervalSeconds);
+ shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+ shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
- gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
- gExposureProgram.unbind();
- dst->flush();
- }
-}
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ if (use_history)
+ {
+ gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
+ }
+ shader->unbind();
+ dst->flush();
+ }
+}
+
+extern LLPointer<LLImageGL> gEXRImage;
void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
- dst->bindTarget();
- // gamma correct lighting
- {
- LL_PROFILE_GPU_ZONE("gamma correct");
+ dst->bindTarget();
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false);
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- // Apply gamma correction to the frame here.
+ // Apply gamma correction to the frame here.
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
-
+
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable());
LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
gDeferredPostGammaCorrectProgram;
-
+
shader.bind();
- S32 channel = 0;
+ S32 channel = 0;
shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
@@ -6837,71 +6961,73 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
- static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- F32 e = llclamp(exposure(), 0.5f, 4.f);
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- static LLStaticHashedString s_exposure("exposure");
+ static LLStaticHashedString s_exposure("exposure");
+ static LLStaticHashedString aces_mix("aces_mix");
shader.uniform1f(s_exposure, e);
+ shader.uniform1f(aces_mix, gEXRImage.notNull() ? 0.f : 0.3f);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.getTexUnit(channel)->unbind(src->getUsage());
+ gGL.getTexUnit(channel)->unbind(src->getUsage());
shader.unbind();
- }
- dst->flush();
+ }
+ dst->flush();
}
-void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
{
- if (RenderScreenSpaceReflections && !gCubeSnapshot)
- {
- LL_PROFILE_GPU_ZONE("ssr copy");
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ if (RenderScreenSpaceReflections && !gCubeSnapshot)
+ {
+ LL_PROFILE_GPU_ZONE("ssr copy");
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- LLRenderTarget& depth_src = mRT->deferredScreen;
+ LLRenderTarget& depth_src = mRT->deferredScreen;
- dst->bindTarget();
- dst->clear();
- gCopyDepthProgram.bind();
+ dst->bindTarget();
+ dst->clear();
+ gCopyDepthProgram.bind();
- S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
- S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- gGL.getTexUnit(diff_map)->bind(src);
- gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+ gGL.getTexUnit(diff_map)->bind(src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- dst->flush();
- }
+ dst->flush();
+ }
}
-void LLPipeline::generateGlow(LLRenderTarget* src)
+void LLPipeline::generateGlow(LLRenderTarget* src)
{
- if (sRenderGlow)
- {
- LL_PROFILE_GPU_ZONE("glow");
- mGlow[2].bindTarget();
- mGlow[2].clear();
-
- gGlowExtractProgram.bind();
- F32 maxAlpha = RenderGlowMaxExtractAlpha;
- F32 warmthAmount = RenderGlowWarmthAmount;
- LLVector3 lumWeights = RenderGlowLumWeights;
- LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
- lumWeights.mV[2]);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
- warmthWeights.mV[2]);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+ if (sRenderGlow)
+ {
+ LL_PROFILE_GPU_ZONE("glow");
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
+
+ gGlowExtractProgram.bind();
+ F32 maxAlpha = RenderGlowMaxExtractAlpha;
+ F32 warmthAmount = RenderGlowWarmthAmount;
+ LLVector3 lumWeights = RenderGlowLumWeights;
+ LLVector3 warmthWeights = RenderGlowWarmthWeights;
+
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+ lumWeights.mV[2]);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+ warmthWeights.mV[2]);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
if (RenderGlowNoise)
{
@@ -6916,406 +7042,406 @@ void LLPipeline::generateGlow(LLRenderTarget* src)
mGlow[2].getHeight());
}
- {
- LLGLEnable blend_on(GL_BLEND);
-
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-
- gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
-
- gGL.color4f(1, 1, 1, 1);
- gPipeline.enableLightsFullbright();
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- mGlow[2].flush();
- }
-
- gGlowExtractProgram.unbind();
-
- // power of two between 1 and 1024
- U32 glowResPow = RenderGlowResolutionPow;
- const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
-
- S32 kernel = RenderGlowIterations * 2;
- F32 delta = RenderGlowWidth / glow_res;
- // Use half the glow width if we have the res set to less than 9 so that it looks
- // almost the same in either case.
- if (glowResPow < 9)
- {
- delta *= 0.5f;
- }
- F32 strength = RenderGlowStrength;
-
- gGlowProgram.bind();
- gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
-
- for (S32 i = 0; i < kernel; i++)
- {
- mGlow[i % 2].bindTarget();
- mGlow[i % 2].clear();
-
- if (i == 0)
- {
- gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]);
- }
- else
- {
- gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]);
- }
-
- if (i % 2 == 0)
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
- }
- else
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
- }
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- mGlow[i % 2].flush();
- }
-
- gGlowProgram.unbind();
-
- }
- else // !sRenderGlow, skip the glow ping-pong and just clear the result target
- {
- mGlow[1].bindTarget();
- mGlow[1].clear();
- mGlow[1].flush();
- }
-}
-
-void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
-{
- {
- llassert(!gCubeSnapshot);
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
- LLGLSLShader* shader = &gGlowCombineProgram;
-
- S32 width = dst->getWidth();
- S32 height = dst->getHeight();
-
- // Present everything.
- if (multisample)
- {
- LL_PROFILE_GPU_ZONE("aa");
- // bake out texture2D with RGBL for FXAA shader
- mRT->fxaaBuffer.bindTarget();
-
- shader = &gGlowCombineFXAAProgram;
- shader->bind();
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
- if (channel > -1)
- {
- src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
-
- {
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
- shader->unbind();
+ {
+ LLGLEnable blend_on(GL_BLEND);
- mRT->fxaaBuffer.flush();
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- dst->bindTarget();
- shader = &gFXAAProgram;
- shader->bind();
+ gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
- if (channel > -1)
- {
- mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
+ gGL.color4f(1, 1, 1, 1);
+ gPipeline.enableLightsFullbright();
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ mGlow[2].flush();
+ }
- F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
- F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
- shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
- shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
- 0.5f / width * scale_x, 0.5f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
- 2.f / width * scale_x, 2.f / height * scale_y);
+ gGlowExtractProgram.unbind();
- {
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
- S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
+ // power of two between 1 and 1024
+ U32 glowResPow = RenderGlowResolutionPow;
+ const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
+ S32 kernel = RenderGlowIterations * 2;
+ F32 delta = RenderGlowWidth / glow_res;
+ // Use half the glow width if we have the res set to less than 9 so that it looks
+ // almost the same in either case.
+ if (glowResPow < 9)
+ {
+ delta *= 0.5f;
+ }
+ F32 strength = RenderGlowStrength;
- shader->unbind();
- dst->flush();
- }
- else {
- copyRenderTarget(src, dst);
- }
- }
+ gGlowProgram.bind();
+ gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+
+ for (S32 i = 0; i < kernel; i++)
+ {
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
+
+ if (i == 0)
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]);
+ }
+ else
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]);
+ }
+
+ if (i % 2 == 0)
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+ }
+ else
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+ }
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ mGlow[i % 2].flush();
+ }
+
+ gGlowProgram.unbind();
+
+ }
+ else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ {
+ mGlow[1].bindTarget();
+ mGlow[1].clear();
+ mGlow[1].flush();
+ }
+}
+
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ {
+ llassert(!gCubeSnapshot);
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
+ LLGLSLShader* shader = &gGlowCombineProgram;
+
+ S32 width = dst->getWidth();
+ S32 height = dst->getHeight();
+
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ // bake out texture2D with RGBL for FXAA shader
+ mRT->fxaaBuffer.bindTarget();
+
+ shader = &gGlowCombineFXAAProgram;
+ shader->bind();
+
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ shader->unbind();
+
+ mRT->fxaaBuffer.flush();
+
+ dst->bindTarget();
+ shader = &gFXAAProgram;
+ shader->bind();
+
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
+ if (channel > -1)
+ {
+ mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
+ F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
+ F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
+ shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+ shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
+ 0.5f / width * scale_x, 0.5f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+ 2.f / width * scale_x, 2.f / height * scale_y);
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+ gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ shader->unbind();
+ dst->flush();
+ }
+ else {
+ copyRenderTarget(src, dst);
+ }
+ }
}
void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst)
{
- LL_PROFILE_GPU_ZONE("copyRenderTarget");
- dst->bindTarget();
+ LL_PROFILE_GPU_ZONE("copyRenderTarget");
+ dst->bindTarget();
- gDeferredPostNoDoFProgram.bind();
+ gDeferredPostNoDoFProgram.bind();
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
- {
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
+ {
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- gDeferredPostNoDoFProgram.unbind();
+ gDeferredPostNoDoFProgram.unbind();
- dst->flush();
+ dst->flush();
}
void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst)
{
- // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
+ // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
- dst->bindTarget();
+ dst->bindTarget();
- {
+ {
- gGlowCombineProgram.bind();
+ gGlowCombineProgram.bind();
- gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
- gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- dst->flush();
+ dst->flush();
}
void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
{
- {
- bool dof_enabled =
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField &&
- !gCubeSnapshot;
-
- gViewerWindow->setup3DViewport();
-
- if (dof_enabled)
- {
- LL_PROFILE_GPU_ZONE("dof");
- LLGLDisable blend(GL_BLEND);
-
- // depth of field focal plane calculations
- static F32 current_distance = 16.f;
- static F32 start_distance = 16.f;
- static F32 transition_time = 1.f;
-
- LLVector3 focus_point;
-
- LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
- if (obj && obj->mDrawable && obj->isSelected())
- { // focus on selected media object
- S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
- if (obj && obj->mDrawable)
- {
- LLFace* face = obj->mDrawable->getFace(face_idx);
- if (face)
- {
- focus_point = face->getPositionAgent();
- }
- }
- }
-
- if (focus_point.isExactlyZero())
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- { // focus on point under cursor
- focus_point.set(gDebugRaycastIntersection.getF32ptr());
- }
- else if (gAgentCamera.cameraMouselook())
- { // focus on point under mouselook crosshairs
- LLVector4a result;
- result.clear();
-
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, NULL, &result);
-
- focus_point.set(result.getF32ptr());
- }
- else
+ {
+ bool dof_enabled =
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
+
+ gViewerWindow->setup3DViewport();
+
+ if (dof_enabled)
+ {
+ LL_PROFILE_GPU_ZONE("dof");
+ LLGLDisable blend(GL_BLEND);
+
+ // depth of field focal plane calculations
+ static F32 current_distance = 16.f;
+ static F32 start_distance = 16.f;
+ static F32 transition_time = 1.f;
+
+ LLVector3 focus_point;
+
+ LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+ if (obj && obj->mDrawable && obj->isSelected())
+ { // focus on selected media object
+ S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+ if (obj && obj->mDrawable)
+ {
+ LLFace* face = obj->mDrawable->getFace(face_idx);
+ if (face)
+ {
+ focus_point = face->getPositionAgent();
+ }
+ }
+ }
+
+ if (focus_point.isExactlyZero())
+ {
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ { // focus on point under cursor
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
+ }
+ else if (gAgentCamera.cameraMouselook())
+ { // focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, nullptr, nullptr, nullptr, &result);
+
+ focus_point.set(result.getF32ptr());
+ }
+ else
+ {
+ // focus on alt-zoom target
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+ }
+ }
+ }
+
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ F32 target_distance = 16.f;
+ if (!focus_point.isExactlyZero())
+ {
+ target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ }
+
+ if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+ { // large shift happened, interpolate smoothly to new target distance
+ transition_time = 0.f;
+ start_distance = current_distance;
+ }
+ else if (transition_time < 1.f)
+ { // currently in a transition, continue interpolating
+ transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+ transition_time = llmin(transition_time, 1.f);
+
+ F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+ current_distance = start_distance + (target_distance - start_distance) * t;
+ }
+ else
+ { // small or no change, just snap to target distance
+ current_distance = target_distance;
+ }
+
+ // convert to mm
+ F32 subject_distance = current_distance * 1000.f;
+ F32 fnumber = CameraFNumber;
+ F32 default_focal_length = CameraFocalLength;
+
+ F32 fov = LLViewerCamera::getInstance()->getView();
+
+ const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+
+ // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
+
+ F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+
+ F32 focal_length = dv / (2 * tanf(fov / 2.f));
+
+ // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
+
+ F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+ blur_constant /= 1000.f; // convert to meters for shader
+ F32 magnification = focal_length / (subject_distance - focal_length);
+
+ { // build diffuse+bloom+CoF
+ mRT->deferredLight.bindTarget();
+
+ gDeferredCoFProgram.bind();
+
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+ gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredCoFProgram.unbind();
+ mRT->deferredLight.flush();
+ }
+
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
+
+ { // perform DoF sampling at half-res (preserve alpha channel)
+ src->bindTarget();
+ glViewport(0, 0, dof_width, dof_height);
+
+ gGL.setColorMask(true, false);
+
+ gDeferredPostProgram.bind();
+ gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT);
+
+ gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gDeferredPostProgram.unbind();
+
+ src->flush();
+ gGL.setColorMask(true, true);
+ }
+
+ { // combine result based on alpha
+
+ dst->bindTarget();
+ if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete())
{
- // focus on alt-zoom target
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
- }
- }
- }
-
- LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
- F32 target_distance = 16.f;
- if (!focus_point.isExactlyZero())
- {
- target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
- }
-
- if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
- { // large shift happened, interpolate smoothly to new target distance
- transition_time = 0.f;
- start_distance = current_distance;
- }
- else if (transition_time < 1.f)
- { // currently in a transition, continue interpolating
- transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
- transition_time = llmin(transition_time, 1.f);
-
- F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
- current_distance = start_distance + (target_distance - start_distance) * t;
- }
- else
- { // small or no change, just snap to target distance
- current_distance = target_distance;
- }
-
- // convert to mm
- F32 subject_distance = current_distance * 1000.f;
- F32 fnumber = CameraFNumber;
- F32 default_focal_length = CameraFocalLength;
-
- F32 fov = LLViewerCamera::getInstance()->getView();
-
- const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
-
- // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
-
- F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
-
- F32 focal_length = dv / (2 * tanf(fov / 2.f));
-
- // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
-
- // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
- // where N = fnumber
- // s2 = dot distance
- // s1 = subject distance
- // f = focal length
- //
-
- F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
- blur_constant /= 1000.f; // convert to meters for shader
- F32 magnification = focal_length / (subject_distance - focal_length);
-
- { // build diffuse+bloom+CoF
- mRT->deferredLight.bindTarget();
-
- gDeferredCoFProgram.bind();
-
- gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
- gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
-
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
- gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gDeferredCoFProgram.unbind();
- mRT->deferredLight.flush();
- }
-
- U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
-
- { // perform DoF sampling at half-res (preserve alpha channel)
- src->bindTarget();
- glViewport(0, 0, dof_width, dof_height);
-
- gGL.setColorMask(true, false);
-
- gDeferredPostProgram.bind();
- gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT);
-
- gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
- gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gDeferredPostProgram.unbind();
-
- src->flush();
- gGL.setColorMask(true, true);
- }
-
- { // combine result based on alpha
-
- dst->bindTarget();
- if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete())
- {
- glViewport(0, 0, dst->getWidth(), dst->getHeight());
- }
- else
+ glViewport(0, 0, dst->getWidth(), dst->getHeight());
+ }
+ else
{
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- }
-
- gDeferredDoFCombineProgram.bind();
- gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
- gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT);
-
- gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
- gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
- gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gDeferredDoFCombineProgram.unbind();
-
- dst->flush();
- }
- }
- else
- {
- copyRenderTarget(src, dst);
- }
- }
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ }
+
+ gDeferredDoFCombineProgram.bind();
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT);
+
+ gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gDeferredDoFCombineProgram.unbind();
+
+ dst->flush();
+ }
+ }
+ else
+ {
+ copyRenderTarget(src, dst);
+ }
+ }
}
void LLPipeline::renderFinalize()
@@ -7339,7 +7465,7 @@ void LLPipeline::renderFinalize()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
-
+
copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
generateLuminance(&mRT->screen, &mLuminanceMap);
@@ -7354,49 +7480,49 @@ void LLPipeline::renderFinalize()
combineGlow(&mPostMap, &mRT->screen);
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
- renderDoF(&mRT->screen, &mPostMap);
-
- applyFXAA(&mPostMap, &mRT->screen);
- LLRenderTarget* finalBuffer = &mRT->screen;
- if (RenderBufferVisualization > -1)
- {
- finalBuffer = &mPostMap;
- switch (RenderBufferVisualization)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization);
- break;
- case 4:
- visualizeBuffers(&mLuminanceMap, finalBuffer, 0);
- default:
- break;
- }
- }
-
- // Present the screen target.
-
- gDeferredPostNoDoFProgram.bind();
-
- // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems.
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
-
- {
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- gDeferredPostNoDoFProgram.unbind();
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
+ renderDoF(&mRT->screen, &mPostMap);
+
+ applyFXAA(&mPostMap, &mRT->screen);
+ LLRenderTarget* finalBuffer = &mRT->screen;
+ if (RenderBufferVisualization > -1)
+ {
+ finalBuffer = &mPostMap;
+ switch (RenderBufferVisualization)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization);
+ break;
+ case 4:
+ visualizeBuffers(&mLuminanceMap, finalBuffer, 0);
+ default:
+ break;
+ }
+ }
+
+ // Present the screen target.
+
+ gDeferredPostNoDoFProgram.bind();
+
+ // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems.
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredPostNoDoFProgram.unbind();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -7486,28 +7612,28 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
LLRenderTarget* deferred_target = &mRT->deferredScreen;
LLRenderTarget* deferred_light_target = &mRT->deferredLight;
- shader.bind();
- S32 channel = 0;
+ shader.bind();
+ S32 channel = 0;
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
- if (channel > -1)
- {
+ if (channel > -1)
+ {
deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0]
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ }
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
- if (channel > -1)
- {
+ if (channel > -1)
+ {
deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1]
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ }
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
- if (channel > -1)
- {
+ if (channel > -1)
+ {
deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2]
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ }
channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
if (channel > -1)
@@ -7538,32 +7664,32 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
{
- shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
- (F32) gGLViewport[1],
- (F32) gGLViewport[2],
- (F32) gGLViewport[3]);
- }
+ shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
+ (F32) gGLViewport[1],
+ (F32) gGLViewport[2],
+ (F32) gGLViewport[3]);
+ }
if (sReflectionRender && !shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX))
{
- shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m);
+ shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);
- if (channel > -1)
- {
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);
+ if (channel > -1)
+ {
gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
bindLightFunc(shader);
- stop_glerror();
+ stop_glerror();
light_target = light_target ? light_target : deferred_light_target;
channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage());
- if (channel > -1)
- {
+ if (channel > -1)
+ {
if (light_target->isComplete())
{
light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
@@ -7572,28 +7698,28 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
{
gGL.getTexUnit(channel)->bindFast(LLViewerFetchedTexture::sWhiteImagep);
}
- }
+ }
- stop_glerror();
+ stop_glerror();
bindShadowMaps(shader);
- stop_glerror();
+ stop_glerror();
- F32 mat[16*6];
- for (U32 i = 0; i < 16; i++)
- {
- mat[i] = mSunShadowMatrix[0].m[i];
- mat[i+16] = mSunShadowMatrix[1].m[i];
- mat[i+32] = mSunShadowMatrix[2].m[i];
- mat[i+48] = mSunShadowMatrix[3].m[i];
- mat[i+64] = mSunShadowMatrix[4].m[i];
- mat[i+80] = mSunShadowMatrix[5].m[i];
- }
+ F32 mat[16*6];
+ for (U32 i = 0; i < 16; i++)
+ {
+ mat[i] = mSunShadowMatrix[0].m[i];
+ mat[i+16] = mSunShadowMatrix[1].m[i];
+ mat[i+32] = mSunShadowMatrix[2].m[i];
+ mat[i+48] = mSunShadowMatrix[3].m[i];
+ mat[i+64] = mSunShadowMatrix[4].m[i];
+ mat[i+80] = mSunShadowMatrix[5].m[i];
+ }
- shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat);
+ shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat);
- stop_glerror();
+ stop_glerror();
if (!LLPipeline::sReflectionProbesEnabled)
{
@@ -7655,55 +7781,55 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
{
shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
}
- shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
- shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
-
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale);
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale);
-
- F32 ssao_factor = RenderSSAOFactor;
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor);
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor);
-
- LLVector3 ssao_effect = RenderSSAOEffect;
- F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0;
- F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0;
- // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
- // value factor, and scales remainder by saturation factor
- F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag,
- matrix_nondiag, matrix_diag, matrix_nondiag,
- matrix_nondiag, matrix_nondiag, matrix_diag};
- shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat);
-
- //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;
+ shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
+ shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
+
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale);
+
+ F32 ssao_factor = RenderSSAOFactor;
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor);
+
+ LLVector3 ssao_effect = RenderSSAOEffect;
+ F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0;
+ F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0;
+ // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
+ // value factor, and scales remainder by saturation factor
+ F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag,
+ matrix_nondiag, matrix_diag, matrix_nondiag,
+ matrix_nondiag, matrix_nondiag, matrix_diag};
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat);
+
+ //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, deferred_target->getWidth(), deferred_target->getHeight());
- shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
- shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
+ shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
+ shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_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.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_SUN_DIR, 1, mTransformedSunDir.mV);
shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV);
- shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
- shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
- shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
- shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
-
+ shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
+ shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+ shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+
shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLDeltaModelView);
shader.uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLInverseDeltaModelView);
shader.uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
- if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
- {
+ 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);
- }
+ shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
+ }
// auto adjust legacy sun color if needed
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
@@ -7724,18 +7850,18 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
LLColor3 pow3f(LLColor3 v, F32 f)
{
- v.mV[0] = powf(v.mV[0], f);
- v.mV[1] = powf(v.mV[1], f);
- v.mV[2] = powf(v.mV[2], f);
- return v;
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
}
LLVector4 pow4fsrgb(LLVector4 v, F32 f)
{
- v.mV[0] = powf(v.mV[0], f);
- v.mV[1] = powf(v.mV[1], f);
- v.mV[2] = powf(v.mV[2], f);
- return v;
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
}
void LLPipeline::renderDeferredLighting()
@@ -7762,7 +7888,7 @@ void LLPipeline::renderDeferredLighting()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred");
LLViewerCamera *camera = LLViewerCamera::getInstance();
-
+
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
@@ -7914,14 +8040,14 @@ void LLPipeline::renderDeferredLighting()
static LLCachedControl<F32> ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f);
static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale");
static LLStaticHashedString ssao_max_str("ssao_irradiance_max");
-
+
soften_shader.uniform1f(ssao_scale_str, ssao_scale);
soften_shader.uniform1f(ssao_max_str, ssao_max);
LLEnvironment &environment = LLEnvironment::instance();
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
-
+
soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
{
@@ -8215,6 +8341,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_WATER,
END_RENDER_TYPES);
@@ -8295,7 +8422,7 @@ void LLPipeline::doAtmospherics()
// full screen blit
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
+
unbindDeferredShader(haze_shader);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -8386,148 +8513,148 @@ void LLPipeline::doWaterHaze()
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
- //construct frustum
- LLVOVolume* volume = drawablep->getVOVolume();
- LLVector3 params = volume->getSpotLightParams();
-
- F32 fov = params.mV[0];
- F32 focus = params.mV[1];
-
- LLVector3 pos = drawablep->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
- LLVector3 scale = volume->getScale();
-
- //get near clip plane
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
-
- LLVector3 np = pos+at_axis;
- at_axis.normVec();
-
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
-
- LLVector3 origin = np - at_axis*dist;
-
- //matrix from volume space to agent space
- LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
-
- glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
- glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent;
-
- glh::matrix4f screen_to_light = light_to_screen.inverse();
-
- F32 s = volume->getLightRadius()*1.5f;
- F32 near_clip = dist;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = s+dist-scale.mV[VZ];
-
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
-
- glh::vec3f p1(0, 0, -(near_clip+0.01f));
- glh::vec3f p2(0, 0, -(near_clip+1.f));
-
- glh::vec3f screen_origin(0, 0, 0);
-
- light_to_screen.mult_matrix_vec(p1);
- light_to_screen.mult_matrix_vec(p2);
- light_to_screen.mult_matrix_vec(screen_origin);
-
- glh::vec3f n = p2-p1;
- n.normalize();
-
- F32 proj_range = far_clip - near_clip;
- glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip);
- screen_to_light = trans * light_proj * screen_to_light;
- shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m);
- shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip);
- shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v);
- shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v);
- shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v);
- shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range);
- shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]);
- S32 s_idx = -1;
-
- for (U32 i = 0; i < 2; i++)
- {
- if (mShadowSpotLight[i] == drawablep)
- {
- s_idx = i;
- }
- }
-
- shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx);
-
- if (s_idx >= 0)
- {
- shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]);
- }
- else
- {
- shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
- }
+ //construct frustum
+ LLVOVolume* volume = drawablep->getVOVolume();
+ LLVector3 params = volume->getSpotLightParams();
+
+ F32 fov = params.mV[0];
+ F32 focus = params.mV[1];
+
+ LLVector3 pos = drawablep->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
+ LLVector3 scale = volume->getScale();
+
+ //get near clip plane
+ LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
+ at_axis *= quat;
+
+ LLVector3 np = pos+at_axis;
+ at_axis.normVec();
+
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+
+ LLVector3 origin = np - at_axis*dist;
+
+ //matrix from volume space to agent space
+ LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
+
+ glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
+ glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent;
+
+ glh::matrix4f screen_to_light = light_to_screen.inverse();
+
+ F32 s = volume->getLightRadius()*1.5f;
+ F32 near_clip = dist;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = s+dist-scale.mV[VZ];
+
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width/height;
+
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
+
+ glh::vec3f p1(0, 0, -(near_clip+0.01f));
+ glh::vec3f p2(0, 0, -(near_clip+1.f));
+
+ glh::vec3f screen_origin(0, 0, 0);
+
+ light_to_screen.mult_matrix_vec(p1);
+ light_to_screen.mult_matrix_vec(p2);
+ light_to_screen.mult_matrix_vec(screen_origin);
+
+ glh::vec3f n = p2-p1;
+ n.normalize();
+
+ F32 proj_range = far_clip - near_clip;
+ glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip);
+ screen_to_light = trans * light_proj * screen_to_light;
+ shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip);
+ shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v);
+ shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v);
+ shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]);
+ S32 s_idx = -1;
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ if (mShadowSpotLight[i] == drawablep)
+ {
+ s_idx = i;
+ }
+ }
+
+ shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx);
+
+ if (s_idx >= 0)
+ {
+ shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]);
+ }
+ else
+ {
+ shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
+ }
// make sure we're not already targeting the same spot light with both shadow maps
llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
if (!gCubeSnapshot)
- {
- LLDrawable* potential = drawablep;
- //determine if this light is higher priority than one of the existing spot shadows
- F32 m_pri = volume->getSpotLightPriority();
-
- for (U32 i = 0; i < 2; i++)
- {
- F32 pri = 0.f;
-
- if (mTargetShadowSpotLight[i].notNull())
- {
- pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
- }
-
- if (m_pri > pri)
- {
- LLDrawable* temp = mTargetShadowSpotLight[i];
- mTargetShadowSpotLight[i] = potential;
- potential = temp;
- m_pri = pri;
- }
- }
- }
+ {
+ LLDrawable* potential = drawablep;
+ //determine if this light is higher priority than one of the existing spot shadows
+ F32 m_pri = volume->getSpotLightPriority();
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ F32 pri = 0.f;
+
+ if (mTargetShadowSpotLight[i].notNull())
+ {
+ pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
+ }
+
+ if (m_pri > pri)
+ {
+ LLDrawable* temp = mTargetShadowSpotLight[i];
+ mTargetShadowSpotLight[i] = potential;
+ potential = temp;
+ m_pri = pri;
+ }
+ }
+ }
// make sure we didn't end up targeting the same spot light with both shadow maps
llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
- LLViewerTexture* img = volume->getLightTexture();
+ LLViewerTexture* img = volume->getLightTexture();
- if (img == NULL)
- {
- img = LLViewerFetchedTexture::sWhiteImagep;
- }
+ if (img == NULL)
+ {
+ img = LLViewerFetchedTexture::sWhiteImagep;
+ }
- S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- if (channel > -1)
- {
- if (img)
- {
- gGL.getTexUnit(channel)->bind(img);
+ if (channel > -1)
+ {
+ if (img)
+ {
+ gGL.getTexUnit(channel)->bind(img);
- F32 lod_range = logf(img->getWidth())/logf(2.f);
-
- shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus);
- shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range);
- shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
- }
- }
+ F32 lod_range = logf(img->getWidth())/logf(2.f);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range);
+ shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
+ }
+ }
+
}
void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
@@ -8535,7 +8662,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
LLRenderTarget* deferred_target = &mRT->deferredScreen;
LLRenderTarget* deferred_light_target = &mRT->deferredLight;
- stop_glerror();
+ stop_glerror();
shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
@@ -8544,27 +8671,27 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
//shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
- shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
- }
- }
-
- for (U32 i = 4; i < 6; i++)
- {
- if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
- }
- }
-
- shader.disableTexture(LLShaderMgr::DEFERRED_NOISE);
- shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
+ shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
+
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+ }
+ }
+
+ for (U32 i = 4; i < 6; i++)
+ {
+ if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+ }
+ }
+
+ shader.disableTexture(LLShaderMgr::DEFERRED_NOISE);
+ shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
if (!LLPipeline::sReflectionProbesEnabled)
{
@@ -8581,9 +8708,9 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
unbindReflectionProbes(shader);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->activate();
- shader.unbind();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->activate();
+ shader.unbind();
}
void LLPipeline::setEnvMat(LLGLSLShader& shader)
@@ -8618,6 +8745,17 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
mReflectionMapManager.mIrradianceMaps->bind(channel);
bound = true;
}
+
+ if (RenderMirrors)
+ {
+ channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ if (channel > -1 && mHeroProbeManager.mTexture.notNull())
+ {
+ mHeroProbeManager.mTexture->bind(channel);
+ bound = true;
+ }
+ }
+
if (bound)
{
@@ -8633,7 +8771,7 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
gGL.getTexUnit(channel)->bind(&mSceneMap);
}
-
+
shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ITR_COUNT, RenderScreenSpaceReflectionIterations);
shader.uniform1f(LLShaderMgr::DEFERRED_SSR_DIST_BIAS, RenderScreenSpaceReflectionDistanceBias);
shader.uniform1f(LLShaderMgr::DEFERRED_SSR_RAY_STEP, RenderScreenSpaceReflectionRayStep);
@@ -8641,7 +8779,7 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
shader.uniform1f(LLShaderMgr::DEFERRED_SSR_REJECT_BIAS, RenderScreenSpaceReflectionDepthRejectBias);
mPoissonOffset++;
- if (mPoissonOffset > 128 - RenderScreenSpaceReflectionGlossySamples)
+ if (mPoissonOffset > 128 - RenderScreenSpaceReflectionGlossySamples)
mPoissonOffset = 0;
shader.uniform1f(LLShaderMgr::DEFERRED_SSR_NOISE_SINE, mPoissonOffset);
@@ -8679,68 +8817,68 @@ inline float sgn(float a)
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
{
- glh::matrix4f ret;
-
- LLVector3 dirN;
- LLVector3 upN;
- LLVector3 lftN;
-
- lftN = dir % up;
- lftN.normVec();
+ glh::matrix4f ret;
- upN = lftN % dir;
- upN.normVec();
+ LLVector3 dirN;
+ LLVector3 upN;
+ LLVector3 lftN;
- dirN = dir;
- dirN.normVec();
+ lftN = dir % up;
+ lftN.normVec();
+
+ upN = lftN % dir;
+ upN.normVec();
+
+ dirN = dir;
+ dirN.normVec();
- ret.m[ 0] = lftN[0];
- ret.m[ 1] = upN[0];
- ret.m[ 2] = -dirN[0];
- ret.m[ 3] = 0.f;
+ ret.m[ 0] = lftN[0];
+ ret.m[ 1] = upN[0];
+ ret.m[ 2] = -dirN[0];
+ ret.m[ 3] = 0.f;
- ret.m[ 4] = lftN[1];
- ret.m[ 5] = upN[1];
- ret.m[ 6] = -dirN[1];
- ret.m[ 7] = 0.f;
+ ret.m[ 4] = lftN[1];
+ ret.m[ 5] = upN[1];
+ ret.m[ 6] = -dirN[1];
+ ret.m[ 7] = 0.f;
- ret.m[ 8] = lftN[2];
- ret.m[ 9] = upN[2];
- ret.m[10] = -dirN[2];
- ret.m[11] = 0.f;
+ ret.m[ 8] = lftN[2];
+ ret.m[ 9] = upN[2];
+ ret.m[10] = -dirN[2];
+ ret.m[11] = 0.f;
- ret.m[12] = -(lftN*pos);
- ret.m[13] = -(upN*pos);
- ret.m[14] = dirN*pos;
- ret.m[15] = 1.f;
+ ret.m[12] = -(lftN*pos);
+ ret.m[13] = -(upN*pos);
+ ret.m[14] = dirN*pos;
+ ret.m[15] = 1.f;
- return ret;
+ return ret;
}
glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
{
- glh::matrix4f ret;
- ret.m[ 0] = 2/(max[0]-min[0]);
- ret.m[ 4] = 0;
- ret.m[ 8] = 0;
- ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]);
+ glh::matrix4f ret;
+ ret.m[ 0] = 2/(max[0]-min[0]);
+ ret.m[ 4] = 0;
+ ret.m[ 8] = 0;
+ ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]);
- ret.m[ 1] = 0;
- ret.m[ 5] = 2/(max[1]-min[1]);
- ret.m[ 9] = 0;
- ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]);
+ ret.m[ 1] = 0;
+ ret.m[ 5] = 2/(max[1]-min[1]);
+ ret.m[ 9] = 0;
+ ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]);
- ret.m[ 2] = 0;
- ret.m[ 6] = 0;
- ret.m[10] = 2/(max[2]-min[2]);
- ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]);
+ ret.m[ 2] = 0;
+ ret.m[ 6] = 0;
+ ret.m[10] = 2/(max[2]-min[2]);
+ ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]);
- ret.m[ 3] = 0;
- ret.m[ 7] = 0;
- ret.m[11] = 0;
- ret.m[15] = 1;
+ ret.m[ 3] = 0;
+ ret.m[ 7] = 0;
+ ret.m[11] = 0;
+ ret.m[15] = 1;
- return ret;
+ return ret;
}
static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows");
@@ -8758,7 +8896,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
LL_PROFILE_GPU_ZONE("renderShadow");
-
+
LLPipeline::sShadowRender = true;
// disable occlusion culling during shadow render
@@ -8921,7 +9059,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
-
+
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -8961,196 +9099,196 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- //get point cloud of intersection of frust and min, max
-
- if (getVisibleExtents(camera, min, max))
- {
- return false;
- }
-
- //get set of planes on bounding box
- LLPlane bp[] = {
- LLPlane(min, LLVector3(-1,0,0)),
- LLPlane(min, LLVector3(0,-1,0)),
- LLPlane(min, LLVector3(0,0,-1)),
- LLPlane(max, LLVector3(1,0,0)),
- LLPlane(max, LLVector3(0,1,0)),
- LLPlane(max, LLVector3(0,0,1))};
-
- //potential points
- std::vector<LLVector3> pp;
-
- //add corners of AABB
- pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2]));
- pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2]));
- pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2]));
- pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2]));
- pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2]));
- pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2]));
- pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2]));
- pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
-
- //add corners of camera frustum
- for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++)
- {
- pp.push_back(camera.mAgentFrustum[i]);
- }
-
-
- //bounding box line segments
- U32 bs[] =
- {
- 0,1,
- 1,3,
- 3,2,
- 2,0,
-
- 4,5,
- 5,7,
- 7,6,
- 6,4,
-
- 0,4,
- 1,5,
- 3,7,
- 2,6
- };
-
- for (U32 i = 0; i < 12; i++)
- { //for each line segment in bounding box
- for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++)
- { //for each plane in camera frustum
- const LLPlane& cp = camera.getAgentPlane(j);
- const LLVector3& v1 = pp[bs[i*2+0]];
- const LLVector3& v2 = pp[bs[i*2+1]];
- LLVector3 n;
- cp.getVector3(n);
-
- LLVector3 line = v1-v2;
-
- F32 d1 = line*n;
- F32 d2 = -cp.dist(v2);
-
- F32 t = d2/d1;
-
- if (t > 0.f && t < 1.f)
- {
- LLVector3 intersect = v2+line*t;
- pp.push_back(intersect);
- }
- }
- }
-
- //camera frustum line segments
- const U32 fs[] =
- {
- 0,1,
- 1,2,
- 2,3,
- 3,0,
-
- 4,5,
- 5,6,
- 6,7,
- 7,4,
-
- 0,4,
- 1,5,
- 2,6,
- 3,7
- };
-
- for (U32 i = 0; i < 12; i++)
- {
- for (U32 j = 0; j < 6; ++j)
- {
- const LLVector3& v1 = pp[fs[i*2+0]+8];
- const LLVector3& v2 = pp[fs[i*2+1]+8];
- const LLPlane& cp = bp[j];
- LLVector3 n;
- cp.getVector3(n);
-
- LLVector3 line = v1-v2;
-
- F32 d1 = line*n;
- F32 d2 = -cp.dist(v2);
-
- F32 t = d2/d1;
-
- if (t > 0.f && t < 1.f)
- {
- LLVector3 intersect = v2+line*t;
- pp.push_back(intersect);
- }
- }
- }
-
- LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
- max+LLVector3(0.05f,0.05f,0.05f) };
-
- for (U32 i = 0; i < pp.size(); ++i)
- {
- bool found = true;
-
- const F32* p = pp[i].mV;
-
- for (U32 j = 0; j < 3; ++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)
- {
- 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)
- {
- fp.push_back(pp[i]);
- }
- }
-
- if (fp.empty())
- {
- return false;
- }
-
- return true;
+ //get point cloud of intersection of frust and min, max
+
+ if (getVisibleExtents(camera, min, max))
+ {
+ return false;
+ }
+
+ //get set of planes on bounding box
+ LLPlane bp[] = {
+ LLPlane(min, LLVector3(-1,0,0)),
+ LLPlane(min, LLVector3(0,-1,0)),
+ LLPlane(min, LLVector3(0,0,-1)),
+ LLPlane(max, LLVector3(1,0,0)),
+ LLPlane(max, LLVector3(0,1,0)),
+ LLPlane(max, LLVector3(0,0,1))};
+
+ //potential points
+ std::vector<LLVector3> pp;
+
+ //add corners of AABB
+ pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
+
+ //add corners of camera frustum
+ for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++)
+ {
+ pp.push_back(camera.mAgentFrustum[i]);
+ }
+
+
+ //bounding box line segments
+ U32 bs[] =
+ {
+ 0,1,
+ 1,3,
+ 3,2,
+ 2,0,
+
+ 4,5,
+ 5,7,
+ 7,6,
+ 6,4,
+
+ 0,4,
+ 1,5,
+ 3,7,
+ 2,6
+ };
+
+ for (U32 i = 0; i < 12; i++)
+ { //for each line segment in bounding box
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++)
+ { //for each plane in camera frustum
+ const LLPlane& cp = camera.getAgentPlane(j);
+ const LLVector3& v1 = pp[bs[i*2+0]];
+ const LLVector3& v2 = pp[bs[i*2+1]];
+ LLVector3 n;
+ cp.getVector3(n);
+
+ LLVector3 line = v1-v2;
+
+ F32 d1 = line*n;
+ F32 d2 = -cp.dist(v2);
+
+ F32 t = d2/d1;
+
+ if (t > 0.f && t < 1.f)
+ {
+ LLVector3 intersect = v2+line*t;
+ pp.push_back(intersect);
+ }
+ }
+ }
+
+ //camera frustum line segments
+ const U32 fs[] =
+ {
+ 0,1,
+ 1,2,
+ 2,3,
+ 3,0,
+
+ 4,5,
+ 5,6,
+ 6,7,
+ 7,4,
+
+ 0,4,
+ 1,5,
+ 2,6,
+ 3,7
+ };
+
+ for (U32 i = 0; i < 12; i++)
+ {
+ for (U32 j = 0; j < 6; ++j)
+ {
+ const LLVector3& v1 = pp[fs[i*2+0]+8];
+ const LLVector3& v2 = pp[fs[i*2+1]+8];
+ const LLPlane& cp = bp[j];
+ LLVector3 n;
+ cp.getVector3(n);
+
+ LLVector3 line = v1-v2;
+
+ F32 d1 = line*n;
+ F32 d2 = -cp.dist(v2);
+
+ F32 t = d2/d1;
+
+ if (t > 0.f && t < 1.f)
+ {
+ LLVector3 intersect = v2+line*t;
+ pp.push_back(intersect);
+ }
+ }
+ }
+
+ LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
+ max+LLVector3(0.05f,0.05f,0.05f) };
+
+ for (U32 i = 0; i < pp.size(); ++i)
+ {
+ bool found = true;
+
+ const F32* p = pp[i].mV;
+
+ for (U32 j = 0; j < 3; ++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)
+ {
+ 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)
+ {
+ fp.push_back(pp[i]);
+ }
+ }
+
+ if (fp.empty())
+ {
+ return false;
+ }
+
+ return true;
}
void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade)
{
- if (obj && obj->getVolume())
- {
- for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter)
- {
- renderHighlight(*iter, fade);
- }
-
- LLDrawable* drawable = obj->mDrawable;
- if (drawable)
- {
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* face = drawable->getFace(i);
- if (face)
- {
- face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade));
- }
- }
- }
- }
+ if (obj && obj->getVolume())
+ {
+ for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter)
+ {
+ renderHighlight(*iter, fade);
+ }
+
+ LLDrawable* drawable = obj->mDrawable;
+ if (drawable)
+ {
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ if (face)
+ {
+ face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade));
+ }
+ }
+ }
+ }
}
@@ -9189,76 +9327,76 @@ public:
void LLPipeline::generateSunShadow(LLCamera& camera)
{
- if (!sRenderDeferred || RenderShadowDetail <= 0)
- {
- return;
- }
+ if (!sRenderDeferred || RenderShadowDetail <= 0)
+ {
+ return;
+ }
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
LL_PROFILE_GPU_ZONE("generateSunShadow");
LLDisableOcclusionCulling no_occlusion;
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
- }
-
- F64 last_modelview[16];
- F64 last_projection[16];
- for (U32 i = 0; i < 16; i++)
- { //store last_modelview of world camera
- last_modelview[i] = gGLLastModelView[i];
- last_projection[i] = gGLLastProjection[i];
- }
-
- pushRenderTypeMask();
- andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
- LLPipeline::RENDER_TYPE_ALPHA,
+ bool skip_avatar_update = false;
+ if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
+ {
+ skip_avatar_update = true;
+ }
+
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
+ }
+
+ F64 last_modelview[16];
+ F64 last_projection[16];
+ for (U32 i = 0; i < 16; i++)
+ { //store last_modelview of world camera
+ last_modelview[i] = gGLLastModelView[i];
+ last_projection[i] = gGLLastProjection[i];
+ }
+
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
+ LLPipeline::RENDER_TYPE_ALPHA,
LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
- LLPipeline::RENDER_TYPE_GRASS,
+ LLPipeline::RENDER_TYPE_GRASS,
LLPipeline::RENDER_TYPE_GLTF_PBR,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- LLPipeline::RENDER_TYPE_TREE,
- LLPipeline::RENDER_TYPE_TERRAIN,
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_PASS_SHINY,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
- LLPipeline::RENDER_TYPE_PASS_MATERIAL,
- LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
- LLPipeline::RENDER_TYPE_PASS_SPECMAP,
- LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
- LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
- LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
- LLPipeline::RENDER_TYPE_PASS_NORMMAP,
- LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
- LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
- LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
- LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
- LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
- LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
- LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED,
@@ -9286,129 +9424,129 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
- END_RENDER_TYPES);
+ END_RENDER_TYPES);
- gGL.setColorMask(false, false);
+ gGL.setColorMask(false, false);
LLEnvironment& environment = LLEnvironment::instance();
- //get sun view matrix
-
- //store current projection/modelview matrix
- 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];
- glh::matrix4f proj[6];
+ //get sun view matrix
+
+ //store current projection/modelview matrix
+ 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];
+ glh::matrix4f proj[6];
+
LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
- //put together a universal "near clip" plane for shadow frusta
- LLPlane shadow_near_clip;
- {
+ //put together a universal "near clip" plane for shadow frusta
+ LLPlane shadow_near_clip;
+ {
LLVector3 p = camera.getOrigin(); // gAgent.getPositionAgent();
- p += caster_dir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, caster_dir);
- }
-
- LLVector3 lightDir = -caster_dir;
- lightDir.normVec();
-
- glh::vec3f light_dir(lightDir.mV);
-
- //create light space camera matrix
-
- LLVector3 at = lightDir;
-
- LLVector3 up = camera.getAtAxis();
-
- if (fabsf(up*lightDir) > 0.75f)
- {
- up = camera.getUpAxis();
- }
-
- up.normVec();
- at.normVec();
-
-
- LLCamera main_camera = camera;
-
- F32 near_clip = 0.f;
- {
- //get visible point cloud
- std::vector<LLVector3> fp;
-
- main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum);
-
- LLVector3 min,max;
- getVisiblePointCloud(main_camera,min,max,fp);
-
- if (fp.empty())
- {
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowCamera[0] = main_camera;
- mShadowExtents[0][0] = min;
- mShadowExtents[0][1] = max;
-
- mShadowFrustPoints[0].clear();
- mShadowFrustPoints[1].clear();
- mShadowFrustPoints[2].clear();
- mShadowFrustPoints[3].clear();
- }
- popRenderTypeMask();
-
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
- }
-
- return;
- }
-
- //get good split distances for frustum
- for (U32 i = 0; i < fp.size(); ++i)
- {
- glh::vec3f v(fp[i].mV);
- saved_view.mult_matrix_vec(v);
- fp[i].setVec(v.v);
- }
-
- min = fp[0];
- max = fp[0];
-
- //get camera space bounding box
- for (U32 i = 1; i < fp.size(); ++i)
- {
- update_min_max(min, max, fp[i]);
- }
-
- near_clip = llclamp(-max.mV[2], 0.01f, 4.0f);
- F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f);
-
- //far_clip = llmin(far_clip, 128.f);
- far_clip = llmin(far_clip, camera.getFar());
-
- F32 range = far_clip-near_clip;
-
- LLVector3 split_exp = RenderShadowSplitExponent;
-
- F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
-
- da = powf(da, split_exp.mV[2]);
-
- F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
-
- for (U32 i = 0; i < 4; ++i)
- {
- F32 x = (F32)(i+1)/4.f;
- x = powf(x, sxp);
- mSunClipPlanes.mV[i] = near_clip+range*x;
- }
-
- mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
- }
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
+ }
+
+ LLVector3 lightDir = -caster_dir;
+ lightDir.normVec();
+
+ glh::vec3f light_dir(lightDir.mV);
+
+ //create light space camera matrix
+
+ LLVector3 at = lightDir;
+
+ LLVector3 up = camera.getAtAxis();
+
+ if (fabsf(up*lightDir) > 0.75f)
+ {
+ up = camera.getUpAxis();
+ }
+
+ up.normVec();
+ at.normVec();
+
+
+ LLCamera main_camera = camera;
+
+ F32 near_clip = 0.f;
+ {
+ //get visible point cloud
+ std::vector<LLVector3> fp;
+
+ main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum);
+
+ LLVector3 min,max;
+ getVisiblePointCloud(main_camera,min,max,fp);
+
+ if (fp.empty())
+ {
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowCamera[0] = main_camera;
+ mShadowExtents[0][0] = min;
+ mShadowExtents[0][1] = max;
+
+ mShadowFrustPoints[0].clear();
+ mShadowFrustPoints[1].clear();
+ mShadowFrustPoints[2].clear();
+ mShadowFrustPoints[3].clear();
+ }
+ popRenderTypeMask();
+
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ }
+
+ return;
+ }
+
+ //get good split distances for frustum
+ for (U32 i = 0; i < fp.size(); ++i)
+ {
+ glh::vec3f v(fp[i].mV);
+ saved_view.mult_matrix_vec(v);
+ fp[i].setVec(v.v);
+ }
+
+ min = fp[0];
+ max = fp[0];
+
+ //get camera space bounding box
+ for (U32 i = 1; i < fp.size(); ++i)
+ {
+ update_min_max(min, max, fp[i]);
+ }
+
+ near_clip = llclamp(-max.mV[2], 0.01f, 4.0f);
+ F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f);
+
+ //far_clip = llmin(far_clip, 128.f);
+ far_clip = llmin(far_clip, camera.getFar());
+
+ F32 range = far_clip-near_clip;
+
+ LLVector3 split_exp = RenderShadowSplitExponent;
+
+ F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
+
+ da = powf(da, split_exp.mV[2]);
+
+ F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
+
+ for (U32 i = 0; i < 4; ++i)
+ {
+ F32 x = (F32)(i+1)/4.f;
+ x = powf(x, sxp);
+ mSunClipPlanes.mV[i] = near_clip+range*x;
+ }
+
+ mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
+ }
if (gCubeSnapshot)
{ // stretch clip planes for reflection probe renders to reduce number of shadow passes
@@ -9418,394 +9556,394 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
- // convenience array of 4 near clip plane distances
- F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
- if (mSunDiffuse == LLColor4::black)
- { //sun diffuse is totally black shadows don't matter
+ // convenience array of 4 near clip plane distances
+ F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
+
+ if (mSunDiffuse == LLColor4::black)
+ { //sun diffuse is totally black shadows don't matter
skipRenderingShadows();
- }
- else
- {
+ }
+ else
+ {
for (S32 j = 0; j < (gCubeSnapshot ? 2 : 4); j++)
- {
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowFrustPoints[j].clear();
- }
+ {
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowFrustPoints[j].clear();
+ }
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
- //restore render matrices
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ //restore render matrices
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- LLVector3 eye = camera.getOrigin();
+ LLVector3 eye = camera.getOrigin();
llassert(eye.isFinite());
- //camera used for shadow cull/render
- LLCamera shadow_cam;
-
- //create world space camera frustum for this split
- shadow_cam = camera;
- shadow_cam.setFar(16.f);
-
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
-
- LLVector3* frust = shadow_cam.mAgentFrustum;
-
- LLVector3 pn = shadow_cam.getAtAxis();
-
- LLVector3 min, max;
-
- //construct 8 corners of split frustum section
- for (U32 i = 0; i < 4; i++)
- {
- LLVector3 delta = frust[i+4]-eye;
- delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
- delta.normVec();
- F32 dp = delta*pn;
- frust[i] = eye + (delta*dist[j]*0.75f)/dp;
- frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;
- }
-
- shadow_cam.calcAgentFrustumPlanes(frust);
- shadow_cam.mFrustumCornerDist = 0.f;
-
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowCamera[j] = shadow_cam;
- }
-
- std::vector<LLVector3> fp;
-
- if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)
+ //camera used for shadow cull/render
+ LLCamera shadow_cam;
+
+ //create world space camera frustum for this split
+ shadow_cam = camera;
+ shadow_cam.setFar(16.f);
+
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+
+ LLVector3* frust = shadow_cam.mAgentFrustum;
+
+ LLVector3 pn = shadow_cam.getAtAxis();
+
+ LLVector3 min, max;
+
+ //construct 8 corners of split frustum section
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLVector3 delta = frust[i+4]-eye;
+ delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
+ delta.normVec();
+ F32 dp = delta*pn;
+ frust[i] = eye + (delta*dist[j]*0.75f)/dp;
+ frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;
+ }
+
+ shadow_cam.calcAgentFrustumPlanes(frust);
+ shadow_cam.mFrustumCornerDist = 0.f;
+
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowCamera[j] = shadow_cam;
+ }
+
+ std::vector<LLVector3> fp;
+
+ if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)
|| j > RenderShadowSplits)
- {
- //no possible shadow receivers
+ {
+ //no possible shadow receivers
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowExtents[j][0] = LLVector3();
- mShadowExtents[j][1] = LLVector3();
- mShadowCamera[j+4] = shadow_cam;
- }
-
- mRT->shadow[j].bindTarget();
- {
- LLGLDepthTest depth(GL_TRUE);
- mRT->shadow[j].clear();
- }
- mRT->shadow[j].flush();
-
- mShadowError.mV[j] = 0.f;
- mShadowFOV.mV[j] = 0.f;
-
- continue;
- }
-
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowExtents[j][0] = min;
- mShadowExtents[j][1] = max;
- mShadowFrustPoints[j] = fp;
- }
-
-
- //find a good origin for shadow projection
- LLVector3 origin;
-
- //get a temporary view projection
- view[j] = look(camera.getOrigin(), lightDir, -up);
-
- std::vector<LLVector3> wpf;
-
- for (U32 i = 0; i < fp.size(); i++)
- {
- glh::vec3f p = glh::vec3f(fp[i].mV);
- view[j].mult_matrix_vec(p);
- wpf.push_back(LLVector3(p.v));
- }
-
- min = wpf[0];
- max = wpf[0];
-
- for (U32 i = 0; i < fp.size(); ++i)
- { //get AABB in camera space
- update_min_max(min, max, wpf[i]);
- }
-
- // Construct a perspective transform with perspective along y-axis that contains
- // points in wpf
- //Known:
- // - far clip plane
- // - near clip plane
- // - points in frustum
- //Find:
- // - origin
-
- //get some "interesting" points of reference
- LLVector3 center = (min+max)*0.5f;
- LLVector3 size = (max-min)*0.5f;
- LLVector3 near_center = center;
- near_center.mV[1] += size.mV[1]*2.f;
-
-
- //put all points in wpf in quadrant 0, reletive to center of min/max
- //get the best fit line using least squares
- F32 bfm = 0.f;
- F32 bfb = 0.f;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- wpf[i] -= center;
- wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
- wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
- }
-
- if (!wpf.empty())
- {
- F32 sx = 0.f;
- F32 sx2 = 0.f;
- F32 sy = 0.f;
- F32 sxy = 0.f;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- sx += wpf[i].mV[0];
- sx2 += wpf[i].mV[0]*wpf[i].mV[0];
- sy += wpf[i].mV[1];
- sxy += wpf[i].mV[0]*wpf[i].mV[1];
- }
-
- bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
- bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
- }
-
- {
- // best fit line is y=bfm*x+bfb
-
- //find point that is furthest to the right of line
- F32 off_x = -1.f;
- LLVector3 lp;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- //y = bfm*x+bfb
- //x = (y-bfb)/bfm
- F32 lx = (wpf[i].mV[1]-bfb)/bfm;
-
- lx = wpf[i].mV[0]-lx;
-
- if (off_x < lx)
- {
- off_x = lx;
- lp = wpf[i];
- }
- }
-
- //get line with slope bfm through lp
- // bfb = y-bfm*x
- bfb = lp.mV[1]-bfm*lp.mV[0];
-
- //calculate error
- mShadowError.mV[j] = 0.f;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- F32 lx = (wpf[i].mV[1]-bfb)/bfm;
- mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
- }
-
- mShadowError.mV[j] /= wpf.size();
- mShadowError.mV[j] /= size.mV[0];
-
- if (mShadowError.mV[j] > RenderShadowErrorCutoff)
- { //just use ortho projection
- mShadowFOV.mV[j] = -1.f;
- origin.clearVec();
- proj[j] = gl_ortho(min.mV[0], max.mV[0],
- min.mV[1], max.mV[1],
- -max.mV[2], -min.mV[2]);
- }
- else
- {
- //origin is where line x = 0;
- origin.setVec(0,bfb,0);
-
- F32 fovz = 1.f;
- F32 fovx = 1.f;
-
- LLVector3 zp;
- LLVector3 xp;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- LLVector3 atz = wpf[i]-origin;
- atz.mV[0] = 0.f;
- atz.normVec();
- if (fovz > -atz.mV[1])
- {
- zp = wpf[i];
- fovz = -atz.mV[1];
- }
-
- LLVector3 atx = wpf[i]-origin;
- atx.mV[2] = 0.f;
- atx.normVec();
- if (fovx > -atx.mV[1])
- {
- fovx = -atx.mV[1];
- xp = wpf[i];
- }
- }
-
- fovx = acos(fovx);
- fovz = acos(fovz);
-
- F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f);
-
- mShadowFOV.mV[j] = fovx;
-
- if (fovx < cutoff && fovz > cutoff)
- {
- //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
- F32 d = zp.mV[2]/tan(cutoff);
- F32 ny = zp.mV[1] + fabsf(d);
-
- origin.mV[1] = ny;
-
- fovz = 1.f;
- fovx = 1.f;
-
- for (U32 i = 0; i < wpf.size(); ++i)
- {
- LLVector3 atz = wpf[i]-origin;
- atz.mV[0] = 0.f;
- atz.normVec();
- fovz = llmin(fovz, -atz.mV[1]);
-
- LLVector3 atx = wpf[i]-origin;
- atx.mV[2] = 0.f;
- atx.normVec();
- fovx = llmin(fovx, -atx.mV[1]);
- }
-
- fovx = acos(fovx);
- fovz = acos(fovz);
-
- mShadowFOV.mV[j] = cutoff;
- }
-
-
- origin += center;
-
- F32 ynear = -(max.mV[1]-origin.mV[1]);
- F32 yfar = -(min.mV[1]-origin.mV[1]);
-
- if (ynear < 0.1f) //keep a sensible near clip plane
- {
- F32 diff = 0.1f-ynear;
- origin.mV[1] += diff;
- ynear += diff;
- yfar += diff;
- }
-
- if (fovx > cutoff)
- { //just use ortho projection
- origin.clearVec();
- mShadowError.mV[j] = -1.f;
- proj[j] = gl_ortho(min.mV[0], max.mV[0],
- min.mV[1], max.mV[1],
- -max.mV[2], -min.mV[2]);
- }
- else
- {
- //get perspective projection
- view[j] = view[j].inverse();
+ {
+ mShadowExtents[j][0] = LLVector3();
+ mShadowExtents[j][1] = LLVector3();
+ mShadowCamera[j+4] = shadow_cam;
+ }
+
+ mRT->shadow[j].bindTarget();
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mRT->shadow[j].clear();
+ }
+ mRT->shadow[j].flush();
+
+ mShadowError.mV[j] = 0.f;
+ mShadowFOV.mV[j] = 0.f;
+
+ continue;
+ }
+
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowExtents[j][0] = min;
+ mShadowExtents[j][1] = max;
+ mShadowFrustPoints[j] = fp;
+ }
+
+
+ //find a good origin for shadow projection
+ LLVector3 origin;
+
+ //get a temporary view projection
+ view[j] = look(camera.getOrigin(), lightDir, -up);
+
+ std::vector<LLVector3> wpf;
+
+ for (U32 i = 0; i < fp.size(); i++)
+ {
+ glh::vec3f p = glh::vec3f(fp[i].mV);
+ view[j].mult_matrix_vec(p);
+ wpf.push_back(LLVector3(p.v));
+ }
+
+ min = wpf[0];
+ max = wpf[0];
+
+ for (U32 i = 0; i < fp.size(); ++i)
+ { //get AABB in camera space
+ update_min_max(min, max, wpf[i]);
+ }
+
+ // Construct a perspective transform with perspective along y-axis that contains
+ // points in wpf
+ //Known:
+ // - far clip plane
+ // - near clip plane
+ // - points in frustum
+ //Find:
+ // - origin
+
+ //get some "interesting" points of reference
+ LLVector3 center = (min+max)*0.5f;
+ LLVector3 size = (max-min)*0.5f;
+ LLVector3 near_center = center;
+ near_center.mV[1] += size.mV[1]*2.f;
+
+
+ //put all points in wpf in quadrant 0, reletive to center of min/max
+ //get the best fit line using least squares
+ F32 bfm = 0.f;
+ F32 bfb = 0.f;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ wpf[i] -= center;
+ wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
+ wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
+ }
+
+ if (!wpf.empty())
+ {
+ F32 sx = 0.f;
+ F32 sx2 = 0.f;
+ F32 sy = 0.f;
+ F32 sxy = 0.f;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ sx += wpf[i].mV[0];
+ sx2 += wpf[i].mV[0]*wpf[i].mV[0];
+ sy += wpf[i].mV[1];
+ sxy += wpf[i].mV[0]*wpf[i].mV[1];
+ }
+
+ bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
+ bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
+ }
+
+ {
+ // best fit line is y=bfm*x+bfb
+
+ //find point that is furthest to the right of line
+ F32 off_x = -1.f;
+ LLVector3 lp;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ //y = bfm*x+bfb
+ //x = (y-bfb)/bfm
+ F32 lx = (wpf[i].mV[1]-bfb)/bfm;
+
+ lx = wpf[i].mV[0]-lx;
+
+ if (off_x < lx)
+ {
+ off_x = lx;
+ lp = wpf[i];
+ }
+ }
+
+ //get line with slope bfm through lp
+ // bfb = y-bfm*x
+ bfb = lp.mV[1]-bfm*lp.mV[0];
+
+ //calculate error
+ mShadowError.mV[j] = 0.f;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ F32 lx = (wpf[i].mV[1]-bfb)/bfm;
+ mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
+ }
+
+ mShadowError.mV[j] /= wpf.size();
+ mShadowError.mV[j] /= size.mV[0];
+
+ if (mShadowError.mV[j] > RenderShadowErrorCutoff)
+ { //just use ortho projection
+ mShadowFOV.mV[j] = -1.f;
+ origin.clearVec();
+ proj[j] = gl_ortho(min.mV[0], max.mV[0],
+ min.mV[1], max.mV[1],
+ -max.mV[2], -min.mV[2]);
+ }
+ else
+ {
+ //origin is where line x = 0;
+ origin.setVec(0,bfb,0);
+
+ F32 fovz = 1.f;
+ F32 fovx = 1.f;
+
+ LLVector3 zp;
+ LLVector3 xp;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ LLVector3 atz = wpf[i]-origin;
+ atz.mV[0] = 0.f;
+ atz.normVec();
+ if (fovz > -atz.mV[1])
+ {
+ zp = wpf[i];
+ fovz = -atz.mV[1];
+ }
+
+ LLVector3 atx = wpf[i]-origin;
+ atx.mV[2] = 0.f;
+ atx.normVec();
+ if (fovx > -atx.mV[1])
+ {
+ fovx = -atx.mV[1];
+ xp = wpf[i];
+ }
+ }
+
+ fovx = acos(fovx);
+ fovz = acos(fovz);
+
+ F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f);
+
+ mShadowFOV.mV[j] = fovx;
+
+ if (fovx < cutoff && fovz > cutoff)
+ {
+ //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
+ F32 d = zp.mV[2]/tan(cutoff);
+ F32 ny = zp.mV[1] + fabsf(d);
+
+ origin.mV[1] = ny;
+
+ fovz = 1.f;
+ fovx = 1.f;
+
+ for (U32 i = 0; i < wpf.size(); ++i)
+ {
+ LLVector3 atz = wpf[i]-origin;
+ atz.mV[0] = 0.f;
+ atz.normVec();
+ fovz = llmin(fovz, -atz.mV[1]);
+
+ LLVector3 atx = wpf[i]-origin;
+ atx.mV[2] = 0.f;
+ atx.normVec();
+ fovx = llmin(fovx, -atx.mV[1]);
+ }
+
+ fovx = acos(fovx);
+ fovz = acos(fovz);
+
+ mShadowFOV.mV[j] = cutoff;
+ }
+
+
+ origin += center;
+
+ F32 ynear = -(max.mV[1]-origin.mV[1]);
+ F32 yfar = -(min.mV[1]-origin.mV[1]);
+
+ if (ynear < 0.1f) //keep a sensible near clip plane
+ {
+ F32 diff = 0.1f-ynear;
+ origin.mV[1] += diff;
+ ynear += diff;
+ yfar += diff;
+ }
+
+ if (fovx > cutoff)
+ { //just use ortho projection
+ origin.clearVec();
+ mShadowError.mV[j] = -1.f;
+ proj[j] = gl_ortho(min.mV[0], max.mV[0],
+ min.mV[1], max.mV[1],
+ -max.mV[2], -min.mV[2]);
+ }
+ else
+ {
+ //get perspective projection
+ view[j] = view[j].inverse();
//llassert(origin.isFinite());
- glh::vec3f origin_agent(origin.mV);
+ glh::vec3f origin_agent(origin.mV);
+
+ //translate view to origin
+ view[j].mult_matrix_vec(origin_agent);
- //translate view to origin
- view[j].mult_matrix_vec(origin_agent);
-
- eye = LLVector3(origin_agent.v);
+ eye = LLVector3(origin_agent.v);
//llassert(eye.isFinite());
- if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowFrustOrigin[j] = eye;
- }
-
- view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
-
- F32 fx = 1.f/tanf(fovx);
- F32 fz = 1.f/tanf(fovz);
-
- proj[j] = glh::matrix4f(-fx, 0, 0, 0,
- 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
- 0, 0, -fz, 0,
- 0, -1.f, 0, 0);
- }
- }
- }
-
- //shadow_cam.setFar(128.f);
- shadow_cam.setOriginAndLookAt(eye, up, center);
-
- shadow_cam.setOrigin(0,0,0);
-
- set_current_modelview(view[j]);
- set_current_projection(proj[j]);
-
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
-
- //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
- shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip);
-
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
-
- set_current_modelview(view[j]);
- set_current_projection(proj[j]);
-
- for (U32 i = 0; i < 16; i++)
- {
- gGLLastModelView[i] = mShadowModelview[j].m[i];
- gGLLastProjection[i] = mShadowProjection[j].m[i];
- }
-
- mShadowModelview[j] = view[j];
- mShadowProjection[j] = proj[j];
- mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
-
- stop_glerror();
-
- mRT->shadow[j].bindTarget();
- mRT->shadow[j].getViewport(gGLViewport);
- mRT->shadow[j].clear();
-
- {
- static LLCullResult result[4];
- renderShadow(view[j], proj[j], shadow_cam, result[j], true);
- }
-
- mRT->shadow[j].flush();
-
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
- {
- mShadowCamera[j+4] = shadow_cam;
- }
- }
- }
-
- //hack to disable projector shadows
- bool gen_shadow = RenderShadowDetail > 1;
-
- if (gen_shadow)
- {
+ if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowFrustOrigin[j] = eye;
+ }
+
+ view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
+
+ F32 fx = 1.f/tanf(fovx);
+ F32 fz = 1.f/tanf(fovz);
+
+ proj[j] = glh::matrix4f(-fx, 0, 0, 0,
+ 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
+ 0, 0, -fz, 0,
+ 0, -1.f, 0, 0);
+ }
+ }
+ }
+
+ //shadow_cam.setFar(128.f);
+ shadow_cam.setOriginAndLookAt(eye, up, center);
+
+ shadow_cam.setOrigin(0,0,0);
+
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
+
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+
+ //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
+ shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip);
+
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
+
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
+
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLLastModelView[i] = mShadowModelview[j].m[i];
+ gGLLastProjection[i] = mShadowProjection[j].m[i];
+ }
+
+ mShadowModelview[j] = view[j];
+ mShadowProjection[j] = proj[j];
+ mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
+
+ stop_glerror();
+
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].getViewport(gGLViewport);
+ mRT->shadow[j].clear();
+
+ {
+ static LLCullResult result[4];
+ renderShadow(view[j], proj[j], shadow_cam, result[j], true);
+ }
+
+ mRT->shadow[j].flush();
+
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
+ {
+ mShadowCamera[j+4] = shadow_cam;
+ }
+ }
+ }
+
+ //hack to disable projector shadows
+ bool gen_shadow = RenderShadowDetail > 1;
+
+ if (gen_shadow)
+ {
if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
{
LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
@@ -9934,7 +10072,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
//
-
+
mSpotShadow[i].bindTarget();
mSpotShadow[i].getViewport(gGLViewport);
mSpotShadow[i].clear();
@@ -9952,56 +10090,56 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mSpotShadow[i].flush();
}
}
- }
- else
- { //no spotlight shadows
- mShadowSpotLight[0] = mShadowSpotLight[1] = NULL;
- }
+ }
+ else
+ { //no spotlight shadows
+ mShadowSpotLight[0] = mShadowSpotLight[1] = NULL;
+ }
- if (!CameraOffset)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
- }
- else
- {
- 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);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
- gGL.setColorMask(true, true);
+ if (!CameraOffset)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
+ }
+ else
+ {
+ 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);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ gGL.setColorMask(true, true);
- for (U32 i = 0; i < 16; i++)
- {
- gGLLastModelView[i] = last_modelview[i];
- gGLLastProjection[i] = last_projection[i];
- }
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLLastModelView[i] = last_modelview[i];
+ gGLLastProjection[i] = last_projection[i];
+ }
- popRenderTypeMask();
+ popRenderTypeMask();
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
- }
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ }
}
void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, bool texture)
{
- for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
- {
- LLSpatialGroup* group = *i;
- if (!group->isDead() &&
- (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
- gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
- group->mDrawMap.find(type) != group->mDrawMap.end())
- {
- pass->renderGroup(group,type,texture);
- }
- }
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ {
+ LLSpatialGroup* group = *i;
+ if (!group->isDead() &&
+ (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
+ gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
+ group->mDrawMap.find(type) != group->mDrawMap.end())
+ {
+ pass->renderGroup(group,type,texture);
+ }
+ }
}
void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture)
@@ -10049,8 +10187,8 @@ void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments)
avatar->readProfileQuery(5); // allow up to 5 frames of latency
}
- else
- {
+ else
+ {
// profile attachments one at a time
LLVOAvatar::attachment_map_t::iterator iter;
LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
@@ -10093,27 +10231,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("generateImpostor");
- LLGLState::checkStates();
-
- static LLCullResult result;
- result.clear();
- grabReferences(result);
-
- if (!avatar || !avatar->mDrawable)
- {
+ LLGLState::checkStates();
+
+ static LLCullResult result;
+ result.clear();
+ grabReferences(result);
+
+ if (!avatar || !avatar->mDrawable)
+ {
LL_WARNS_ONCE("AvatarRenderPipeline") << "Avatar is " << (avatar ? "not drawable" : "null") << LL_ENDL;
- return;
- }
+ return;
+ }
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is drawable" << LL_ENDL;
- assertInitialized();
+ assertInitialized();
// previews can't be muted or impostered
- bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();
+ bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( visually_muted ? "" : "not ") << "visually muted"
<< LL_ENDL;
- bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();
+ bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL;
@@ -10123,12 +10261,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
if (visually_muted || too_complex)
{
// only show jelly doll geometry
- andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- END_RENDER_TYPES);
- }
- else
- {
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ END_RENDER_TYPES);
+ }
+ else
+ {
//hide world geometry
clearRenderTypeMask(
RENDER_TYPE_SKY,
@@ -10147,25 +10285,25 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
RENDER_TYPE_HUD_PARTICLES,
END_RENDER_TYPES
);
- }
-
+ }
+
if (specific_attachment && specific_attachment->isHUDAttachment())
{ //enable HUD rendering
setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES);
}
- S32 occlusion = sUseOcclusion;
- sUseOcclusion = 0;
+ S32 occlusion = sUseOcclusion;
+ sUseOcclusion = 0;
- sReflectionRender = ! sRenderDeferred;
+ sReflectionRender = ! sRenderDeferred;
- sShadowRender = true;
- sImpostorRender = true;
+ sShadowRender = true;
+ sImpostorRender = true;
- LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
+ LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
- {
- markVisible(avatar->mDrawable, *viewer_camera);
+ {
+ markVisible(avatar->mDrawable, *viewer_camera);
if (preview_avatar)
{
@@ -10238,70 +10376,70 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
}
}
}
- }
+ }
- stateSort(*LLViewerCamera::getInstance(), result);
-
- LLCamera camera = *viewer_camera;
- LLVector2 tdim;
- U32 resY = 0;
- U32 resX = 0;
+ stateSort(*LLViewerCamera::getInstance(), result);
+
+ LLCamera camera = *viewer_camera;
+ LLVector2 tdim;
+ U32 resY = 0;
+ U32 resX = 0;
if (!preview_avatar)
- {
- const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
- LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
-
- camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
-
- LLVector4a half_height;
- half_height.setSub(ext[1], ext[0]);
- half_height.mul(0.5f);
-
- LLVector4a left;
- left.load3(camera.getLeftAxis().mV);
- left.mul(left);
- llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
- left.normalize3fast();
-
- LLVector4a up;
- up.load3(camera.getUpAxis().mV);
- up.mul(up);
- llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
- up.normalize3fast();
-
- tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
- tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
-
- F32 distance = (pos-camera.getOrigin()).length();
- 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);
- set_current_projection(persp);
- gGL.loadMatrix(persp.m);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- glh::matrix4f mat;
- camera.getOpenGLTransform(mat.m);
-
- mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
-
- gGL.loadMatrix(mat.m);
- set_current_modelview(mat);
-
- glClearColor(0.0f,0.0f,0.0f,0.0f);
- gGL.setColorMask(true, true);
-
- // get the number of pixels per angle
- F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
-
- //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
- resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
- resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
+ {
+ const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
+ LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
+
+ camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
+
+ LLVector4a half_height;
+ half_height.setSub(ext[1], ext[0]);
+ half_height.mul(0.5f);
+
+ LLVector4a left;
+ left.load3(camera.getLeftAxis().mV);
+ left.mul(left);
+ llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
+ left.normalize3fast();
+
+ LLVector4a up;
+ up.load3(camera.getUpAxis().mV);
+ up.mul(up);
+ llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
+ up.normalize3fast();
+
+ tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
+ tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+
+ F32 distance = (pos-camera.getOrigin()).length();
+ 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);
+ set_current_projection(persp);
+ gGL.loadMatrix(persp.m);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ glh::matrix4f mat;
+ camera.getOpenGLTransform(mat.m);
+
+ mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
+
+ gGL.loadMatrix(mat.m);
+ set_current_modelview(mat);
+
+ glClearColor(0.0f,0.0f,0.0f,0.0f);
+ gGL.setColorMask(true, true);
+
+ // get the number of pixels per angle
+ F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
+
+ //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
+ resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
+ resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
if (!for_profile)
{
@@ -10325,14 +10463,14 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
avatar->mImpostor.bindTarget();
}
- }
+ }
- F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
+ F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
- if (visually_muted || too_complex)
- { //disable alpha masking for muted avatars (get whole skin silhouette)
- LLDrawPoolAvatar::sMinimumAlpha = 0.f;
- }
+ if (visually_muted || too_complex)
+ { //disable alpha masking for muted avatars (get whole skin silhouette)
+ LLDrawPoolAvatar::sMinimumAlpha = 0.f;
+ }
if (preview_avatar || for_profile)
{
@@ -10341,91 +10479,91 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
renderGeomPostDeferred(camera);
}
else
- {
- avatar->mImpostor.clear();
- renderGeomDeferred(camera);
+ {
+ avatar->mImpostor.clear();
+ renderGeomDeferred(camera);
- renderGeomPostDeferred(camera);
+ renderGeomPostDeferred(camera);
- // Shameless hack time: render it all again,
- // this time writing the depth
- // values we need to generate the alpha mask below
- // while preserving the alpha-sorted color rendering
- // from the previous pass
- //
- sImpostorRenderAlphaDepthPass = true;
- // depth-only here...
- //
- gGL.setColorMask(false,false);
- renderGeomPostDeferred(camera);
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
+ renderGeomPostDeferred(camera);
- sImpostorRenderAlphaDepthPass = false;
+ sImpostorRenderAlphaDepthPass = false;
- }
+ }
- LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+ LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
if (!for_profile)
- { //create alpha mask based on depth buffer (grey out if muted)
- if (LLPipeline::sRenderDeferred)
- {
- GLuint buff = GL_COLOR_ATTACHMENT0;
- glDrawBuffers(1, &buff);
- }
-
- LLGLDisable blend(GL_BLEND);
-
- if (visually_muted || too_complex)
- {
- gGL.setColorMask(true, true);
- }
- else
- {
- gGL.setColorMask(false, true);
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
-
- gGL.flush();
-
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- static const F32 clip_plane = 0.99999f;
-
- gDebugProgram.bind();
-
- if (visually_muted)
- { // Visually muted avatar
+ { //create alpha mask based on depth buffer (grey out if muted)
+ if (LLPipeline::sRenderDeferred)
+ {
+ GLuint buff = GL_COLOR_ATTACHMENT0;
+ glDrawBuffers(1, &buff);
+ }
+
+ LLGLDisable blend(GL_BLEND);
+
+ if (visually_muted || too_complex)
+ {
+ gGL.setColorMask(true, true);
+ }
+ else
+ {
+ gGL.setColorMask(false, true);
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+
+ gGL.flush();
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ static const F32 clip_plane = 0.99999f;
+
+ gDebugProgram.bind();
+
+ if (visually_muted)
+ { // Visually muted avatar
LLColor4 muted_color(avatar->getMutedAVColor());
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set solid color " << muted_color << LL_ENDL;
- gGL.diffuseColor4fv( muted_color.mV );
- }
- else if (!preview_avatar)
- { //grey muted avatar
+ gGL.diffuseColor4fv( muted_color.mV );
+ }
+ else if (!preview_avatar)
+ { //grey muted avatar
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set grey" << LL_ENDL;
- gGL.diffuseColor4fv(LLColor4::pink.mV );
- }
+ gGL.diffuseColor4fv(LLColor4::pink.mV );
+ }
- gGL.begin(LLRender::QUADS);
- gGL.vertex3f(-1, -1, clip_plane);
- gGL.vertex3f(1, -1, clip_plane);
- gGL.vertex3f(1, 1, clip_plane);
- gGL.vertex3f(-1, 1, clip_plane);
- gGL.end();
- gGL.flush();
+ gGL.begin(LLRender::QUADS);
+ gGL.vertex3f(-1, -1, clip_plane);
+ gGL.vertex3f(1, -1, clip_plane);
+ gGL.vertex3f(1, 1, clip_plane);
+ gGL.vertex3f(-1, 1, clip_plane);
+ gGL.end();
+ gGL.flush();
- gDebugProgram.unbind();
+ gDebugProgram.unbind();
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
if (!preview_avatar && !for_profile)
{
@@ -10433,16 +10571,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
avatar->setImpostorDim(tdim);
}
- sUseOcclusion = occlusion;
- sReflectionRender = false;
- sImpostorRender = false;
- sShadowRender = false;
- popRenderTypeMask();
+ sUseOcclusion = occlusion;
+ sReflectionRender = false;
+ sImpostorRender = false;
+ sShadowRender = false;
+ popRenderTypeMask();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
if (!preview_avatar && !for_profile)
{
@@ -10451,33 +10589,33 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool
avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds;
}
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
}
bool LLPipeline::hasRenderBatches(const U32 type) const
{
- return sCull->getRenderMapSize(type) > 0;
+ return sCull->getRenderMapSize(type) > 0;
}
LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type)
{
- return sCull->beginRenderMap(type);
+ return sCull->beginRenderMap(type);
}
LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type)
{
- return sCull->endRenderMap(type);
+ return sCull->endRenderMap(type);
}
LLCullResult::sg_iterator LLPipeline::beginAlphaGroups()
{
- return sCull->beginAlphaGroups();
+ return sCull->beginAlphaGroups();
}
LLCullResult::sg_iterator LLPipeline::endAlphaGroups()
{
- return sCull->endAlphaGroups();
+ return sCull->endAlphaGroups();
}
LLCullResult::sg_iterator LLPipeline::beginRiggedAlphaGroups()
@@ -10495,278 +10633,278 @@ bool LLPipeline::hasRenderType(const U32 type) const
// STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render"
// We then need to test that value here and return false to prevent attachment to render (in mouselook for instance)
// TODO: reintroduce RENDER_TYPE_NONE in LLRenderTypeMask and initialize its mRenderTypeEnabled[RENDER_TYPE_NONE] to false explicitely
- return (type == 0 ? false : mRenderTypeEnabled[type]);
+ return (type == 0 ? false : mRenderTypeEnabled[type]);
}
void LLPipeline::setRenderTypeMask(U32 type, ...)
{
- va_list args;
+ va_list args;
- va_start(args, type);
- while (type < END_RENDER_TYPES)
- {
- mRenderTypeEnabled[type] = true;
- type = va_arg(args, U32);
- }
- va_end(args);
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ mRenderTypeEnabled[type] = true;
+ type = va_arg(args, U32);
+ }
+ va_end(args);
- if (type > END_RENDER_TYPES)
- {
- LL_ERRS() << "Invalid render type." << LL_ENDL;
- }
+ if (type > END_RENDER_TYPES)
+ {
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
+ }
}
bool LLPipeline::hasAnyRenderType(U32 type, ...) const
{
- va_list args;
+ va_list args;
- va_start(args, type);
- while (type < END_RENDER_TYPES)
- {
- if (mRenderTypeEnabled[type])
- {
- return true;
- }
- type = va_arg(args, U32);
- }
- va_end(args);
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ if (mRenderTypeEnabled[type])
+ {
+ return true;
+ }
+ type = va_arg(args, U32);
+ }
+ va_end(args);
- if (type > END_RENDER_TYPES)
- {
- LL_ERRS() << "Invalid render type." << LL_ENDL;
- }
+ if (type > END_RENDER_TYPES)
+ {
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
+ }
- return false;
+ return false;
}
void LLPipeline::pushRenderTypeMask()
{
- std::string cur_mask;
- cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled));
- mRenderTypeEnableStack.push(cur_mask);
+ std::string cur_mask;
+ cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled));
+ mRenderTypeEnableStack.push(cur_mask);
}
void LLPipeline::popRenderTypeMask()
{
- if (mRenderTypeEnableStack.empty())
- {
- LL_ERRS() << "Depleted render type stack." << LL_ENDL;
- }
+ if (mRenderTypeEnableStack.empty())
+ {
+ LL_ERRS() << "Depleted render type stack." << LL_ENDL;
+ }
- memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled));
- mRenderTypeEnableStack.pop();
+ memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled));
+ mRenderTypeEnableStack.pop();
}
void LLPipeline::andRenderTypeMask(U32 type, ...)
{
- va_list args;
+ va_list args;
- bool tmp[NUM_RENDER_TYPES];
- for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
- {
- tmp[i] = false;
- }
+ bool tmp[NUM_RENDER_TYPES];
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ tmp[i] = false;
+ }
- va_start(args, type);
- while (type < END_RENDER_TYPES)
- {
- if (mRenderTypeEnabled[type])
- {
- tmp[type] = true;
- }
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ if (mRenderTypeEnabled[type])
+ {
+ tmp[type] = true;
+ }
- type = va_arg(args, U32);
- }
- va_end(args);
+ type = va_arg(args, U32);
+ }
+ va_end(args);
- if (type > END_RENDER_TYPES)
- {
- LL_ERRS() << "Invalid render type." << LL_ENDL;
- }
+ if (type > END_RENDER_TYPES)
+ {
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
+ }
- for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i)
- {
- mRenderTypeEnabled[i] = tmp[i];
- }
+ for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = tmp[i];
+ }
}
void LLPipeline::clearRenderTypeMask(U32 type, ...)
{
- va_list args;
+ va_list args;
- va_start(args, type);
- while (type < END_RENDER_TYPES)
- {
- mRenderTypeEnabled[type] = false;
-
- type = va_arg(args, U32);
- }
- va_end(args);
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ mRenderTypeEnabled[type] = false;
+
+ type = va_arg(args, U32);
+ }
+ va_end(args);
- if (type > END_RENDER_TYPES)
- {
- LL_ERRS() << "Invalid render type." << LL_ENDL;
- }
+ if (type > END_RENDER_TYPES)
+ {
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
+ }
}
void LLPipeline::setAllRenderTypes()
{
- for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
- {
- mRenderTypeEnabled[i] = true;
- }
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = true;
+ }
}
void LLPipeline::clearAllRenderTypes()
{
- for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
- {
- mRenderTypeEnabled[i] = false;
- }
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = false;
+ }
}
void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
{
- DebugBlip blip(position, color);
- mDebugBlips.push_back(blip);
+ DebugBlip blip(position, color);
+ mDebugBlips.push_back(blip);
}
void LLPipeline::hidePermanentObjects( std::vector<U32>& restoreList )
{
- //This method is used to hide any vo's from the object list that may have
- //the permanent flag set.
-
- U32 objCnt = gObjectList.getNumObjects();
- for (U32 i = 0; i < objCnt; ++i)
- {
- LLViewerObject* pObject = gObjectList.getObject(i);
- if ( pObject && pObject->flagObjectPermanent() )
- {
- LLDrawable *pDrawable = pObject->mDrawable;
-
- if ( pDrawable )
- {
- restoreList.push_back( i );
- hideDrawable( pDrawable );
- }
- }
- }
-
- skipRenderingOfTerrain( true );
+ //This method is used to hide any vo's from the object list that may have
+ //the permanent flag set.
+
+ U32 objCnt = gObjectList.getNumObjects();
+ for (U32 i = 0; i < objCnt; ++i)
+ {
+ LLViewerObject* pObject = gObjectList.getObject(i);
+ if ( pObject && pObject->flagObjectPermanent() )
+ {
+ LLDrawable *pDrawable = pObject->mDrawable;
+
+ if ( pDrawable )
+ {
+ restoreList.push_back( i );
+ hideDrawable( pDrawable );
+ }
+ }
+ }
+
+ skipRenderingOfTerrain( true );
}
void LLPipeline::restorePermanentObjects( const std::vector<U32>& restoreList )
{
- //This method is used to restore(unhide) any vo's from the object list that may have
- //been hidden because their permanency flag was set.
-
- std::vector<U32>::const_iterator itCurrent = restoreList.begin();
- std::vector<U32>::const_iterator itEnd = restoreList.end();
-
- U32 objCnt = gObjectList.getNumObjects();
-
- while ( itCurrent != itEnd )
- {
- U32 index = *itCurrent;
- LLViewerObject* pObject = NULL;
- if ( index < objCnt )
- {
- pObject = gObjectList.getObject( index );
- }
- if ( pObject )
- {
- LLDrawable *pDrawable = pObject->mDrawable;
- if ( pDrawable )
- {
- pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
- unhideDrawable( pDrawable );
- }
- }
- ++itCurrent;
- }
-
- skipRenderingOfTerrain( false );
+ //This method is used to restore(unhide) any vo's from the object list that may have
+ //been hidden because their permanency flag was set.
+
+ std::vector<U32>::const_iterator itCurrent = restoreList.begin();
+ std::vector<U32>::const_iterator itEnd = restoreList.end();
+
+ U32 objCnt = gObjectList.getNumObjects();
+
+ while ( itCurrent != itEnd )
+ {
+ U32 index = *itCurrent;
+ LLViewerObject* pObject = NULL;
+ if ( index < objCnt )
+ {
+ pObject = gObjectList.getObject( index );
+ }
+ if ( pObject )
+ {
+ LLDrawable *pDrawable = pObject->mDrawable;
+ if ( pDrawable )
+ {
+ pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ unhideDrawable( pDrawable );
+ }
+ }
+ ++itCurrent;
+ }
+
+ skipRenderingOfTerrain( false );
}
void LLPipeline::skipRenderingOfTerrain( bool flag )
{
- pool_set_t::iterator iter = mPools.begin();
- while ( iter != mPools.end() )
- {
- LLDrawPool* pPool = *iter;
- U32 poolType = pPool->getType();
- if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN )
- {
- pPool->setSkipRenderFlag( flag );
- }
- ++iter;
- }
+ pool_set_t::iterator iter = mPools.begin();
+ while ( iter != mPools.end() )
+ {
+ LLDrawPool* pPool = *iter;
+ U32 poolType = pPool->getType();
+ if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN )
+ {
+ pPool->setSkipRenderFlag( flag );
+ }
+ ++iter;
+ }
}
void LLPipeline::hideObject( const LLUUID& id )
{
- LLViewerObject *pVO = gObjectList.findObject( id );
-
- if ( pVO )
- {
- LLDrawable *pDrawable = pVO->mDrawable;
-
- if ( pDrawable )
- {
- hideDrawable( pDrawable );
- }
- }
+ LLViewerObject *pVO = gObjectList.findObject( id );
+
+ if ( pVO )
+ {
+ LLDrawable *pDrawable = pVO->mDrawable;
+
+ if ( pDrawable )
+ {
+ hideDrawable( pDrawable );
+ }
+ }
}
void LLPipeline::hideDrawable( LLDrawable *pDrawable )
{
- pDrawable->setState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
- //hide the children
- LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
- for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++ )
- {
- LLViewerObject* child = *iter;
- LLDrawable* drawable = child->mDrawable;
- if ( drawable )
- {
- drawable->setState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( drawable, LLDrawable::REBUILD_ALL);
- }
- }
+ pDrawable->setState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
+ //hide the children
+ LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
+ for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++ )
+ {
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if ( drawable )
+ {
+ drawable->setState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL);
+ }
+ }
}
void LLPipeline::unhideDrawable( LLDrawable *pDrawable )
{
- pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
- //restore children
- LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
- for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- LLDrawable* drawable = child->mDrawable;
- if ( drawable )
- {
- drawable->clearState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( drawable, LLDrawable::REBUILD_ALL);
- }
- }
+ pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
+ //restore children
+ LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
+ for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if ( drawable )
+ {
+ drawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL);
+ }
+ }
}
void LLPipeline::restoreHiddenObject( const LLUUID& id )
{
- LLViewerObject *pVO = gObjectList.findObject( id );
-
- if ( pVO )
- {
- LLDrawable *pDrawable = pVO->mDrawable;
- if ( pDrawable )
- {
- unhideDrawable( pDrawable );
- }
- }
+ LLViewerObject *pVO = gObjectList.findObject( id );
+
+ if ( pVO )
+ {
+ LLDrawable *pDrawable = pVO->mDrawable;
+ if ( pDrawable )
+ {
+ unhideDrawable( pDrawable );
+ }
+ }
}
void LLPipeline::skipRenderingShadows()
@@ -10832,3 +10970,12 @@ void LLPipeline::rebuildDrawInfo()
}
}
+void LLPipeline::rebuildTerrain()
+{
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ region->dirtyAllPatches();
+ }
+}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c5f14a31de..bfa4009a0b 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file pipeline.h
* @brief Rendering pipeline definitions
*
* $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$
*/
@@ -39,6 +39,7 @@
#include "lldrawable.h"
#include "llrendertarget.h"
#include "llreflectionmapmanager.h"
+#include "llheroprobemanager.h"
#include <stack>
@@ -55,8 +56,8 @@ class LLSettingsSky;
typedef enum e_avatar_skinning_method
{
- SKIN_METHOD_SOFTWARE,
- SKIN_METHOD_VERTEX_PROGRAM
+ SKIN_METHOD_SOFTWARE,
+ SKIN_METHOD_VERTEX_PROGRAM
} EAvatarSkinningMethod;
bool compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here!
@@ -92,50 +93,52 @@ extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D;
class LLPipeline
{
public:
- LLPipeline();
- ~LLPipeline();
+ LLPipeline();
+ ~LLPipeline();
- void destroyGL();
- void restoreGL();
- void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
+ void destroyGL();
+ void restoreGL();
+ void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
void requestResizeShadowTexture(); // set flag only, no work, safer for callbacks...
- void resizeScreenTexture();
+ void resizeScreenTexture();
void resizeShadowTexture();
- void releaseGLBuffers();
- void releaseLUTBuffers();
- void releaseScreenBuffers();
+ void releaseGLBuffers();
+ void releaseLUTBuffers();
+ void releaseScreenBuffers();
void releaseShadowBuffers();
- void createGLBuffers();
- void createLUTBuffers();
+ void createGLBuffers();
+ void createLUTBuffers();
- //allocate the largest screen buffer possible up to resX, resY
- //returns true if full size buffer allocated, false if some other size is allocated
- bool allocateScreenBuffer(U32 resX, U32 resY);
+ //allocate the largest screen buffer possible up to resX, resY
+ //returns true if full size buffer allocated, false if some other size is allocated
+ bool allocateScreenBuffer(U32 resX, U32 resY);
- typedef enum {
- FBO_SUCCESS_FULLRES = 0,
- FBO_SUCCESS_LOWRES,
- FBO_FAILURE
- } eFBOStatus;
+ typedef enum {
+ FBO_SUCCESS_FULLRES = 0,
+ FBO_SUCCESS_LOWRES,
+ FBO_FAILURE
+ } eFBOStatus;
private:
- //implementation of above, wrapped for easy error handling
- eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY);
+ //implementation of above, wrapped for easy error handling
+ eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY);
public:
- //attempt to allocate screen buffers at resX, resY
- //returns true if allocation successful, false otherwise
- bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
+ //attempt to allocate screen buffers at resX, resY
+ //returns true if allocation successful, false otherwise
+ bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
bool allocateShadowBuffer(U32 resX, U32 resY);
// rebuild all LLVOVolume render batches
void rebuildDrawInfo();
+ // Rebuild all terrain
+ void rebuildTerrain();
// Clear LLFace mVertexBuffer pointers
- void resetVertexBuffers(LLDrawable* drawable);
+ void resetVertexBuffers(LLDrawable* drawable);
// perform a profile of the given avatar
// if profile_attachments is true, run a profile for each attachment
@@ -145,171 +148,173 @@ public:
// preview_avatar - if true, a preview window render is being performed
// for_profile - if true, a profile is being performed, do not update actual impostor
// specific_attachment - specific attachment to profile, or nullptr to profile entire avatar
- void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr);
-
- void bindScreenToTexture();
- void renderFinalize();
- void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
- void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
- void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
- void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
- void generateGlow(LLRenderTarget* src);
- void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
- void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
- void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
- void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
- void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex);
-
- void init();
- void cleanup();
- bool isInit() { return mInitialized; };
-
- /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture.
- /// @return Draw pool, or NULL if not found.
- LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
-
- /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary.
- /// @return Always returns a draw pool.
- LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
-
- /// @brief Figures out draw pool type from texture entry. Creates pool if necessary.
- static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image);
- static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep);
-
- void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools!
- void removePool( LLDrawPool* poolp );
-
- void allocDrawable(LLViewerObject *obj);
-
- void unlinkDrawable(LLDrawable*);
-
- static void removeMutedAVsLights(LLVOAvatar*);
-
- // Object related methods
- void markVisible(LLDrawable *drawablep, LLCamera& camera);
- void markOccluder(LLSpatialGroup* group);
-
- void doOcclusion(LLCamera& camera);
- void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
- void markMoved(LLDrawable *drawablep, bool damped_motion = false);
- void markShift(LLDrawable *drawablep);
- void markTextured(LLDrawable *drawablep);
- void markGLRebuild(LLGLUpdate* glu);
- void markRebuild(LLSpatialGroup* group);
- void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL);
- void markPartitionMove(LLDrawable* drawablep);
- void markMeshDirty(LLSpatialGroup* group);
-
- //get the object between start and end that's closest to start.
- LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- bool pick_rigged,
+ void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr);
+
+ void bindScreenToTexture();
+ void renderFinalize();
+ void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true);
+ void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateGlow(LLRenderTarget* src);
+ void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
+ void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
+ void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
+ void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
+ void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex);
+
+ void init();
+ void cleanup();
+ bool isInit() { return mInitialized; };
+
+ /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture.
+ /// @return Draw pool, or NULL if not found.
+ LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
+
+ /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary.
+ /// @return Always returns a draw pool.
+ LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
+
+ /// @brief Figures out draw pool type from texture entry. Creates pool if necessary.
+ static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image);
+ static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep);
+
+ void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools!
+ void removePool( LLDrawPool* poolp );
+
+ void allocDrawable(LLViewerObject *obj);
+
+ void unlinkDrawable(LLDrawable*);
+
+ static void removeMutedAVsLights(LLVOAvatar*);
+
+ // Object related methods
+ void markVisible(LLDrawable *drawablep, LLCamera& camera);
+ void markOccluder(LLSpatialGroup* group);
+
+ void doOcclusion(LLCamera& camera);
+ void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
+ void markMoved(LLDrawable *drawablep, bool damped_motion = false);
+ void markShift(LLDrawable *drawablep);
+ void markTextured(LLDrawable *drawablep);
+ void markGLRebuild(LLGLUpdate* glu);
+ void markRebuild(LLSpatialGroup* group);
+ void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL);
+ void markPartitionMove(LLDrawable* drawablep);
+ void markMeshDirty(LLSpatialGroup* group);
+
+ //get the object between start and end that's closest to start.
+ LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
+ bool pick_transparent,
+ bool pick_rigged,
bool pick_unselectable,
bool pick_reflection_probe,
- S32* face_hit, // return the face hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
+ S32* face_hit, // return the face hit
+ S32* gltf_node_hit = nullptr, // return the gltf node hit
+ S32* gltf_primitive_hit = nullptr, // return the gltf primitive hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
- //get the closest particle to start between start and end, returns the LLVOPartGroup and particle index
- LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
- S32* face_hit);
+ //get the closest particle to start between start and end, returns the LLVOPartGroup and particle index
+ LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+ S32* face_hit);
- LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- S32* face_hit, // return the face hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
+ LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
+ bool pick_transparent,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
- // Something about these textures has changed. Dirty them.
- void dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures);
+ // Something about these textures has changed. Dirty them.
+ void dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures);
- void resetDrawOrders();
+ void resetDrawOrders();
- U32 addObject(LLViewerObject *obj);
+ U32 addObject(LLViewerObject *obj);
- void enableShadows(const bool enable_shadows);
+ void enableShadows(const bool enable_shadows);
void releaseSpotShadowTargets();
void releaseSunShadowTargets();
void releaseSunShadowTarget(U32 index);
- bool shadersLoaded();
- bool canUseWindLightShaders() const;
- bool canUseAntiAliasing() const;
+ bool shadersLoaded();
+ bool canUseWindLightShaders() const;
+ bool canUseAntiAliasing() const;
- // phases
- void resetFrameStats();
+ // phases
+ void resetFrameStats();
- void updateMoveDampedAsync(LLDrawable* drawablep);
- void updateMoveNormalAsync(LLDrawable* drawablep);
- void updateMovedList(LLDrawable::drawable_vector_t& move_list);
- void updateMove();
- bool visibleObjectsInFrustum(LLCamera& camera);
- bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
- bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
+ void updateMoveDampedAsync(LLDrawable* drawablep);
+ void updateMoveNormalAsync(LLDrawable* drawablep);
+ void updateMovedList(LLDrawable::drawable_vector_t& move_list);
+ void updateMove();
+ bool visibleObjectsInFrustum(LLCamera& camera);
+ bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
+ bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
// Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera
- void updateCull(LLCamera& camera, LLCullResult& result);
- void createObjects(F32 max_dtime);
- void createObject(LLViewerObject* vobj);
- void processPartitionQ();
- void updateGeom(F32 max_dtime);
- void updateGL();
- void rebuildPriorityGroups();
- void rebuildGroups();
- void clearRebuildGroups();
- void clearRebuildDrawables();
-
- //calculate pixel area of given box from vantage point of given camera
- static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera);
- static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera);
-
- void stateSort(LLCamera& camera, LLCullResult& result);
- void stateSort(LLSpatialGroup* group, LLCamera& camera);
- void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);
- void stateSort(LLDrawable* drawablep, LLCamera& camera);
- void postSort(LLCamera& camera);
-
- void forAllVisibleDrawables(void (*func)(LLDrawable*));
+ void updateCull(LLCamera& camera, LLCullResult& result);
+ void createObjects(F32 max_dtime);
+ void createObject(LLViewerObject* vobj);
+ void processPartitionQ();
+ void updateGeom(F32 max_dtime);
+ void updateGL();
+ void rebuildPriorityGroups();
+ void rebuildGroups();
+ void clearRebuildGroups();
+ void clearRebuildDrawables();
+
+ //calculate pixel area of given box from vantage point of given camera
+ static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera);
+ static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera);
+
+ void stateSort(LLCamera& camera, LLCullResult& result);
+ void stateSort(LLSpatialGroup* group, LLCamera& camera);
+ void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);
+ void stateSort(LLDrawable* drawablep, LLCamera& camera);
+ void postSort(LLCamera& camera);
+
+ void forAllVisibleDrawables(void (*func)(LLDrawable*));
void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderGLTFObjects(U32 type, bool texture = true, bool rigged = false);
-
+
void renderAlphaObjects(bool rigged = false);
- void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
- void renderGroups(LLRenderPass* pass, U32 type, bool texture);
+ void renderGroups(LLRenderPass* pass, U32 type, bool texture);
void renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture);
- void grabReferences(LLCullResult& result);
- void clearReferences();
-
- //check references will assert that there are no references in sCullResult to the provided data
- void checkReferences(LLFace* face);
- void checkReferences(LLDrawable* drawable);
- void checkReferences(LLDrawInfo* draw_info);
- void checkReferences(LLSpatialGroup* group);
-
- void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
- void renderGeomPostDeferred(LLCamera& camera);
- void renderGeomShadow(LLCamera& camera);
+ void grabReferences(LLCullResult& result);
+ void clearReferences();
+
+ //check references will assert that there are no references in sCullResult to the provided data
+ void checkReferences(LLFace* face);
+ void checkReferences(LLDrawable* drawable);
+ void checkReferences(LLDrawInfo* draw_info);
+ void checkReferences(LLSpatialGroup* group);
+
+ void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+ void renderGeomPostDeferred(LLCamera& camera);
+ void renderGeomShadow(LLCamera& camera);
void bindLightFunc(LLGLSLShader& shader);
// bind shadow maps
// if setup is true, wil lset texture compare mode function and filtering options
void bindShadowMaps(LLGLSLShader& shader);
void bindDeferredShaderFast(LLGLSLShader& shader);
- void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr);
- void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
+ void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr);
+ void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
- void unbindDeferredShader(LLGLSLShader& shader);
+ void unbindDeferredShader(LLGLSLShader& shader);
// set env_mat parameter in given shader
void setEnvMat(LLGLSLShader& shader);
@@ -317,10 +322,10 @@ public:
void bindReflectionProbes(LLGLSLShader& shader);
void unbindReflectionProbes(LLGLSLShader& shader);
- void renderDeferredLighting();
+ void renderDeferredLighting();
// apply atmospheric haze based on contents of color and depth buffer
- // should be called just before rendering water when camera is under water
+ // should be called just before rendering water when camera is under water
// and just before rendering alpha when camera is above water
void doAtmospherics();
@@ -328,374 +333,379 @@ public:
// should be called just before rendering pre-water alpha objects
void doWaterHaze();
- void postDeferredGammaCorrect(LLRenderTarget* screen_target);
+ void postDeferredGammaCorrect(LLRenderTarget* screen_target);
- void generateSunShadow(LLCamera& camera);
+ void generateSunShadow(LLCamera& camera);
LLRenderTarget* getSunShadowTarget(U32 i);
LLRenderTarget* getSpotShadowTarget(U32 i);
- void renderHighlight(const LLViewerObject* obj, F32 fade);
-
- void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp);
- void renderHighlights();
- void renderDebug();
- void renderPhysicsDisplay();
-
- void rebuildPools(); // Rebuild pools
-
- void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object
- bool verify(); // Verify that all data in the pipeline is "correct"
-
- S32 getLightCount() const { return mLights.size(); }
-
- void calcNearbyLights(LLCamera& camera);
- void setupHWLights();
- void setupAvatarLights(bool for_edit = false);
- void enableLights(U32 mask);
- void enableLightsDynamic();
- void enableLightsAvatar();
- void enableLightsPreview();
- void enableLightsAvatarEdit(const LLColor4& color);
- void enableLightsFullbright();
- void disableLights();
-
- void shiftObjects(const LLVector3 &offset);
-
- void setLight(LLDrawable *drawablep, bool is_light);
-
- bool hasRenderBatches(const U32 type) const;
- LLCullResult::drawinfo_iterator beginRenderMap(U32 type);
- LLCullResult::drawinfo_iterator endRenderMap(U32 type);
- LLCullResult::sg_iterator beginAlphaGroups();
- LLCullResult::sg_iterator endAlphaGroups();
+ void renderHighlight(const LLViewerObject* obj, F32 fade);
+
+ void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp);
+ void renderHighlights();
+ void renderDebug();
+ void renderPhysicsDisplay();
+
+ void rebuildPools(); // Rebuild pools
+
+ void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object
+ bool verify(); // Verify that all data in the pipeline is "correct"
+
+ S32 getLightCount() const { return mLights.size(); }
+
+ void calcNearbyLights(LLCamera& camera);
+ void setupHWLights();
+ void setupAvatarLights(bool for_edit = false);
+ void enableLights(U32 mask);
+ void enableLightsDynamic();
+ void enableLightsAvatar();
+ void enableLightsPreview();
+ void enableLightsAvatarEdit(const LLColor4& color);
+ void enableLightsFullbright();
+ void disableLights();
+
+ void shiftObjects(const LLVector3 &offset);
+
+ void setLight(LLDrawable *drawablep, bool is_light);
+
+ bool hasRenderBatches(const U32 type) const;
+ LLCullResult::drawinfo_iterator beginRenderMap(U32 type);
+ LLCullResult::drawinfo_iterator endRenderMap(U32 type);
+ LLCullResult::sg_iterator beginAlphaGroups();
+ LLCullResult::sg_iterator endAlphaGroups();
LLCullResult::sg_iterator beginRiggedAlphaGroups();
LLCullResult::sg_iterator endRiggedAlphaGroups();
-
- void addTrianglesDrawn(S32 index_count);
+
+ void addTrianglesDrawn(S32 index_count);
void recordTrianglesDrawn();
- bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); }
- bool hasRenderDebugMask(const U64 mask) const { return bool(mRenderDebugMask & mask); }
- void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
- void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
- void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffffffffffff; }
- void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
-
- bool hasRenderType(const U32 type) const;
- bool hasAnyRenderType(const U32 type, ...) const;
-
- static bool isWaterClip();
-
- void setRenderTypeMask(U32 type, ...);
- // This is equivalent to 'setRenderTypeMask'
- //void orRenderTypeMask(U32 type, ...);
- void andRenderTypeMask(U32 type, ...);
- void clearRenderTypeMask(U32 type, ...);
- void setAllRenderTypes();
- void clearAllRenderTypes();
-
- void pushRenderTypeMask();
- void popRenderTypeMask();
-
- void pushRenderDebugFeatureMask();
- void popRenderDebugFeatureMask();
-
- static void toggleRenderType(U32 type);
-
- // For UI control of render features
- static bool hasRenderTypeControl(U32 data);
- static void toggleRenderDebug(U64 data);
- static void toggleRenderDebugFeature(U32 data);
- static void toggleRenderTypeControl(U32 data);
- static bool toggleRenderTypeControlNegated(S32 data);
- static bool toggleRenderDebugControl(U64 data);
- static bool toggleRenderDebugFeatureControl(U32 data);
- static void setRenderDebugFeatureControl(U32 bit, bool value);
-
- static void setRenderParticleBeacons(bool val);
- static void toggleRenderParticleBeacons();
- static bool getRenderParticleBeacons();
-
- static void setRenderSoundBeacons(bool val);
- static void toggleRenderSoundBeacons();
- static bool getRenderSoundBeacons();
-
- static void setRenderMOAPBeacons(bool val);
- static void toggleRenderMOAPBeacons();
- static bool getRenderMOAPBeacons();
-
- static void setRenderPhysicalBeacons(bool val);
- static void toggleRenderPhysicalBeacons();
- static bool getRenderPhysicalBeacons();
-
- static void setRenderScriptedBeacons(bool val);
- static void toggleRenderScriptedBeacons();
- static bool getRenderScriptedBeacons();
-
- static void setRenderScriptedTouchBeacons(bool val);
- static void toggleRenderScriptedTouchBeacons();
- static bool getRenderScriptedTouchBeacons();
-
- static void setRenderBeacons(bool val);
- static void toggleRenderBeacons();
- static bool getRenderBeacons();
-
- static void setRenderHighlights(bool val);
- static void toggleRenderHighlights();
- static bool getRenderHighlights();
- static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
-
- static void updateRenderTransparentWater();
- static void refreshCachedSettings();
-
- void addDebugBlip(const LLVector3& position, const LLColor4& color);
-
- void hidePermanentObjects( std::vector<U32>& restoreList );
- void restorePermanentObjects( const std::vector<U32>& restoreList );
- void skipRenderingOfTerrain( bool flag );
- void hideObject( const LLUUID& id );
- void restoreHiddenObject( const LLUUID& id );
+ bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); }
+ bool hasRenderDebugMask(const U64 mask) const { return bool(mRenderDebugMask & mask); }
+ void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
+ void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
+ void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffffffffffff; }
+ void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
+
+ bool hasRenderType(const U32 type) const;
+ bool hasAnyRenderType(const U32 type, ...) const;
+
+ static bool isWaterClip();
+
+ void setRenderTypeMask(U32 type, ...);
+ // This is equivalent to 'setRenderTypeMask'
+ //void orRenderTypeMask(U32 type, ...);
+ void andRenderTypeMask(U32 type, ...);
+ void clearRenderTypeMask(U32 type, ...);
+ void setAllRenderTypes();
+ void clearAllRenderTypes();
+
+ void pushRenderTypeMask();
+ void popRenderTypeMask();
+
+ void pushRenderDebugFeatureMask();
+ void popRenderDebugFeatureMask();
+
+ static void toggleRenderType(U32 type);
+
+ // For UI control of render features
+ static bool hasRenderTypeControl(U32 data);
+ static void toggleRenderDebug(U64 data);
+ static void toggleRenderDebugFeature(U32 data);
+ static void toggleRenderTypeControl(U32 data);
+ static bool toggleRenderTypeControlNegated(S32 data);
+ static bool toggleRenderDebugControl(U64 data);
+ static bool toggleRenderDebugFeatureControl(U32 data);
+ static void setRenderDebugFeatureControl(U32 bit, bool value);
+
+ static void setRenderParticleBeacons(bool val);
+ static void toggleRenderParticleBeacons();
+ static bool getRenderParticleBeacons();
+
+ static void setRenderSoundBeacons(bool val);
+ static void toggleRenderSoundBeacons();
+ static bool getRenderSoundBeacons();
+
+ static void setRenderMOAPBeacons(bool val);
+ static void toggleRenderMOAPBeacons();
+ static bool getRenderMOAPBeacons();
+
+ static void setRenderPhysicalBeacons(bool val);
+ static void toggleRenderPhysicalBeacons();
+ static bool getRenderPhysicalBeacons();
+
+ static void setRenderScriptedBeacons(bool val);
+ static void toggleRenderScriptedBeacons();
+ static bool getRenderScriptedBeacons();
+
+ static void setRenderScriptedTouchBeacons(bool val);
+ static void toggleRenderScriptedTouchBeacons();
+ static bool getRenderScriptedTouchBeacons();
+
+ static void setRenderBeacons(bool val);
+ static void toggleRenderBeacons();
+ static bool getRenderBeacons();
+
+ static void setRenderHighlights(bool val);
+ static void toggleRenderHighlights();
+ static bool getRenderHighlights();
+ static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
+
+ static void updateRenderTransparentWater();
+ static void refreshCachedSettings();
+
+ void addDebugBlip(const LLVector3& position, const LLColor4& color);
+
+ void hidePermanentObjects( std::vector<U32>& restoreList );
+ void restorePermanentObjects( const std::vector<U32>& restoreList );
+ void skipRenderingOfTerrain( bool flag );
+ void hideObject( const LLUUID& id );
+ void restoreHiddenObject( const LLUUID& id );
void handleShadowDetailChanged();
LLReflectionMapManager mReflectionMapManager;
+ LLHeroProbeManager mHeroProbeManager;
private:
- void unloadShaders();
- void addToQuickLookup( LLDrawPool* new_poolp );
- void removeFromQuickLookup( LLDrawPool* poolp );
- bool updateDrawableGeom(LLDrawable* drawable);
- void assertInitializedDoError();
- bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
- void connectRefreshCachedSettingsSafe(const std::string name);
- void hideDrawable( LLDrawable *pDrawable );
- void unhideDrawable( LLDrawable *pDrawable );
+ void unloadShaders();
+ void addToQuickLookup( LLDrawPool* new_poolp );
+ void removeFromQuickLookup( LLDrawPool* poolp );
+ bool updateDrawableGeom(LLDrawable* drawable);
+ void assertInitializedDoError();
+ bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
+ void connectRefreshCachedSettingsSafe(const std::string name);
+ void hideDrawable( LLDrawable *pDrawable );
+ void unhideDrawable( LLDrawable *pDrawable );
void skipRenderingShadows();
public:
- enum {GPU_CLASS_MAX = 3 };
-
- enum LLRenderTypeMask
- {
- // Following are pool types (some are also object types)
- RENDER_TYPE_SKY = LLDrawPool::POOL_SKY,
- RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY,
- RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN,
- RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE,
- RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS,
- RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK,
- RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,
- RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,
- RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
- RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
- RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
- RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
- RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
- RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
- RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
+ enum {GPU_CLASS_MAX = 3 };
+
+ enum LLRenderTypeMask
+ {
+ // Following are pool types (some are also object types)
+ RENDER_TYPE_SKY = LLDrawPool::POOL_SKY,
+ RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY,
+ RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN,
+ RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE,
+ RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS,
+ RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK,
+ RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,
+ RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,
+ RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
+ RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
+ RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
+ RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
+ RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
+ RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
+ RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR,
RENDER_TYPE_GLTF_PBR_ALPHA_MASK = LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK,
- RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
+ RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
RENDER_TYPE_ALPHA_PRE_WATER = LLDrawPool::POOL_ALPHA_PRE_WATER,
RENDER_TYPE_ALPHA_POST_WATER = LLDrawPool::POOL_ALPHA_POST_WATER,
- RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
- RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
+ RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
+ RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
- RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS,
- RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT,
+ RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS,
+ RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT,
RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED,
- RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE,
+ RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE,
RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED,
- RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY,
+ RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY,
RENDER_TYPE_PASS_INVISI_SHINY_RIGGED = LLRenderPass::PASS_INVISI_SHINY_RIGGED,
- RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY,
+ RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY,
RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED = LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED,
- RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
+ RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
RENDER_TYPE_PASS_SHINY_RIGGED = LLRenderPass::PASS_SHINY_RIGGED,
- RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
+ RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
RENDER_TYPE_PASS_BUMP_RIGGED = LLRenderPass::PASS_BUMP_RIGGED,
- RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP,
+ RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP,
RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED,
- RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
+ RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED,
RENDER_TYPE_PASS_GLTF_GLOW = LLRenderPass::PASS_GLTF_GLOW,
RENDER_TYPE_PASS_GLTF_GLOW_RIGGED = LLRenderPass::PASS_GLTF_GLOW_RIGGED,
- RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
- RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
+ RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
+ RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED,
- RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
+ RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
- RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL,
+ RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL,
RENDER_TYPE_PASS_MATERIAL_RIGGED = LLRenderPass::PASS_MATERIAL_RIGGED,
- RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA,
RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_RIGGED,
- RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED,
- RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,
- RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP,
+ RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP,
RENDER_TYPE_PASS_SPECMAP_RIGGED = LLRenderPass::PASS_SPECMAP_RIGGED,
- RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND,
+ RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND,
RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED = LLRenderPass::PASS_SPECMAP_BLEND_RIGGED,
- RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK,
+ RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK,
RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED = LLRenderPass::PASS_SPECMAP_MASK_RIGGED,
- RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE,
RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED,
- RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP,
+ RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP,
RENDER_TYPE_PASS_NORMMAP_RIGGED = LLRenderPass::PASS_NORMMAP_RIGGED,
- RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND,
+ RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND,
RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED = LLRenderPass::PASS_NORMMAP_BLEND_RIGGED,
- RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK,
+ RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK,
RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED = LLRenderPass::PASS_NORMMAP_MASK_RIGGED,
- RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE,
RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED,
- RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC,
+ RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC,
RENDER_TYPE_PASS_NORMSPEC_RIGGED = LLRenderPass::PASS_NORMSPEC_RIGGED,
- RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND,
+ RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND,
RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED = LLRenderPass::PASS_NORMSPEC_BLEND_RIGGED,
- RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK,
+ RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK,
RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
- RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
RENDER_TYPE_PASS_GLTF_PBR = LLRenderPass::PASS_GLTF_PBR,
RENDER_TYPE_PASS_GLTF_PBR_RIGGED = LLRenderPass::PASS_GLTF_PBR_RIGGED,
RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK,
RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
- // Following are object types (only used in drawable mRenderType)
- RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
- RENDER_TYPE_VOLUME,
- RENDER_TYPE_PARTICLES,
- RENDER_TYPE_CLOUDS,
- RENDER_TYPE_HUD_PARTICLES,
- NUM_RENDER_TYPES,
- END_RENDER_TYPES = NUM_RENDER_TYPES
- };
-
- enum LLRenderDebugFeatureMask
- {
- RENDER_DEBUG_FEATURE_UI = 0x0001,
- RENDER_DEBUG_FEATURE_SELECTED = 0x0002,
- RENDER_DEBUG_FEATURE_HIGHLIGHTED = 0x0004,
- RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES = 0x0008,
-// RENDER_DEBUG_FEATURE_HW_LIGHTING = 0x0010,
- RENDER_DEBUG_FEATURE_FLEXIBLE = 0x0010,
- RENDER_DEBUG_FEATURE_FOG = 0x0020,
- RENDER_DEBUG_FEATURE_FR_INFO = 0x0080,
- RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100,
- };
-
- enum LLRenderDebugMask: U64
- {
- RENDER_DEBUG_COMPOSITION = 0x00000001,
- RENDER_DEBUG_VERIFY = 0x00000002,
- RENDER_DEBUG_BBOXES = 0x00000004,
- RENDER_DEBUG_OCTREE = 0x00000008,
- RENDER_DEBUG_WIND_VECTORS = 0x00000010,
- RENDER_DEBUG_OCCLUSION = 0x00000020,
- RENDER_DEBUG_POINTS = 0x00000040,
- RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080,
- RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
- RENDER_DEBUG_FACE_AREA = 0x00000200,
- RENDER_DEBUG_PARTICLES = 0x00000400,
- RENDER_DEBUG_GLOW = 0x00000800, // not used
- RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
- RENDER_DEBUG_LIGHTS = 0x00002000,
- RENDER_DEBUG_BATCH_SIZE = 0x00004000,
- RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used
- RENDER_DEBUG_RAYCAST = 0x00010000,
- RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000,
- RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
- RENDER_DEBUG_SCULPTED = 0x00080000,
- RENDER_DEBUG_AVATAR_VOLUME = 0x00100000,
- RENDER_DEBUG_AVATAR_JOINTS = 0x00200000,
- RENDER_DEBUG_AGENT_TARGET = 0x00800000,
- RENDER_DEBUG_UPDATE_TYPE = 0x01000000,
- RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000,
- RENDER_DEBUG_NORMALS = 0x04000000,
- RENDER_DEBUG_LOD_INFO = 0x08000000,
- RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
- RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
- RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
- RENDER_DEBUG_IMPOSTORS = 0x100000000,
+ // Following are object types (only used in drawable mRenderType)
+ RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
+ RENDER_TYPE_VOLUME,
+ RENDER_TYPE_PARTICLES,
+ RENDER_TYPE_CLOUDS,
+ RENDER_TYPE_HUD_PARTICLES,
+ NUM_RENDER_TYPES,
+ END_RENDER_TYPES = NUM_RENDER_TYPES
+ };
+
+ enum LLRenderDebugFeatureMask
+ {
+ RENDER_DEBUG_FEATURE_UI = 0x0001,
+ RENDER_DEBUG_FEATURE_SELECTED = 0x0002,
+ RENDER_DEBUG_FEATURE_HIGHLIGHTED = 0x0004,
+ RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES = 0x0008,
+// RENDER_DEBUG_FEATURE_HW_LIGHTING = 0x0010,
+ RENDER_DEBUG_FEATURE_FLEXIBLE = 0x0010,
+ RENDER_DEBUG_FEATURE_FOG = 0x0020,
+ RENDER_DEBUG_FEATURE_FR_INFO = 0x0080,
+ RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100,
+ };
+
+ enum LLRenderDebugMask: U64
+ {
+ RENDER_DEBUG_COMPOSITION = 0x00000001,
+ RENDER_DEBUG_VERIFY = 0x00000002,
+ RENDER_DEBUG_BBOXES = 0x00000004,
+ RENDER_DEBUG_OCTREE = 0x00000008,
+ RENDER_DEBUG_WIND_VECTORS = 0x00000010,
+ RENDER_DEBUG_OCCLUSION = 0x00000020,
+ RENDER_DEBUG_POINTS = 0x00000040,
+ RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080,
+ RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
+ RENDER_DEBUG_FACE_AREA = 0x00000200,
+ RENDER_DEBUG_PARTICLES = 0x00000400,
+ RENDER_DEBUG_GLOW = 0x00000800, // not used
+ RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
+ RENDER_DEBUG_LIGHTS = 0x00002000,
+ RENDER_DEBUG_BATCH_SIZE = 0x00004000,
+ RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used
+ RENDER_DEBUG_RAYCAST = 0x00010000,
+ RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000,
+ RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
+ RENDER_DEBUG_SCULPTED = 0x00080000,
+ RENDER_DEBUG_AVATAR_VOLUME = 0x00100000,
+ RENDER_DEBUG_AVATAR_JOINTS = 0x00200000,
+ RENDER_DEBUG_AGENT_TARGET = 0x00800000,
+ RENDER_DEBUG_UPDATE_TYPE = 0x01000000,
+ RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000,
+ RENDER_DEBUG_NORMALS = 0x04000000,
+ RENDER_DEBUG_LOD_INFO = 0x08000000,
+ RENDER_DEBUG_NODES = 0x20000000,
+ RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
+ RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
+ RENDER_DEBUG_IMPOSTORS = 0x100000000,
RENDER_DEBUG_REFLECTION_PROBES = 0x200000000,
- RENDER_DEBUG_PROBE_UPDATES = 0x400000000
- };
+ RENDER_DEBUG_PROBE_UPDATES = 0x400000000,
+ };
public:
-
- LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj);
-
- void updateCamera(bool reset = false);
-
- LLVector3 mFlyCamPosition;
- LLQuaternion mFlyCamRotation;
-
- bool mBackfaceCull;
- S32 mMatrixOpCount;
- S32 mTextureMatrixOps;
- S32 mNumVisibleNodes;
-
- S32 mDebugTextureUploadCost;
- S32 mDebugSculptUploadCost;
- S32 mDebugMeshUploadCost;
-
- S32 mNumVisibleFaces;
-
- S32 mPoissonOffset;
-
- static S32 sCompiles;
-
- static bool sShowHUDAttachments;
- static bool sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.
- static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write
- static bool sAutoMaskAlphaDeferred;
- static bool sAutoMaskAlphaNonDeferred;
- static bool sRenderTransparentWater;
- static bool sBakeSunlight;
- static bool sNoAlpha;
- static bool sUseFarClip;
- static bool sShadowRender;
- static bool sDynamicLOD;
- static bool sPickAvatar;
- static bool sReflectionRender;
- static bool sDistortionRender;
- static bool sImpostorRender;
- static bool sImpostorRenderAlphaDepthPass;
- static bool sUnderWaterRender;
- static bool sRenderGlow;
- static bool sTextureBindTest;
- static bool sRenderAttachedLights;
- static bool sRenderAttachedParticles;
- static bool sRenderDeferred;
- static bool sReflectionProbesEnabled;
- static S32 sVisibleLightCount;
- static bool sRenderingHUDs;
+
+ LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj);
+
+ void updateCamera(bool reset = false);
+
+ LLVector3 mFlyCamPosition;
+ LLQuaternion mFlyCamRotation;
+
+ bool mBackfaceCull;
+ S32 mMatrixOpCount;
+ S32 mTextureMatrixOps;
+ S32 mNumVisibleNodes;
+
+ S32 mDebugTextureUploadCost;
+ S32 mDebugSculptUploadCost;
+ S32 mDebugMeshUploadCost;
+
+ S32 mNumVisibleFaces;
+
+ S32 mPoissonOffset;
+
+ static S32 sCompiles;
+
+ static bool sShowHUDAttachments;
+ static bool sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.
+ static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write
+ static bool sAutoMaskAlphaDeferred;
+ static bool sAutoMaskAlphaNonDeferred;
+ static bool sRenderTransparentWater;
+ static bool sBakeSunlight;
+ static bool sNoAlpha;
+ static bool sUseFarClip;
+ static bool sShadowRender;
+ static bool sDynamicLOD;
+ static bool sPickAvatar;
+ static bool sReflectionRender;
+ static bool sDistortionRender;
+ static bool sImpostorRender;
+ static bool sImpostorRenderAlphaDepthPass;
+ static bool sUnderWaterRender;
+ static bool sRenderGlow;
+ static bool sTextureBindTest;
+ static bool sRenderAttachedLights;
+ static bool sRenderAttachedParticles;
+ static bool sRenderDeferred;
+ static bool sReflectionProbesEnabled;
+ static S32 sVisibleLightCount;
+ static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
- static LLTrace::EventStatHandle<S64> sStatBatchSize;
+ static LLTrace::EventStatHandle<S64> sStatBatchSize;
class RenderTargetPack
{
public:
- U32 width = 0;
- U32 height = 0;
+ U32 width = 0;
+ U32 height = 0;
//screen texture
- LLRenderTarget screen;
- LLRenderTarget uiScreen;
- LLRenderTarget deferredScreen;
- LLRenderTarget fxaaBuffer;
- LLRenderTarget edgeMap;
- LLRenderTarget deferredLight;
+ LLRenderTarget screen;
+ LLRenderTarget uiScreen;
+ LLRenderTarget deferredScreen;
+ LLRenderTarget fxaaBuffer;
+ LLRenderTarget edgeMap;
+ LLRenderTarget deferredLight;
//sun shadow map
- LLRenderTarget shadow[4];
+ LLRenderTarget shadow[4];
};
// main full resoltuion render target
RenderTargetPack mMainRT;
// auxillary 512x512 render target pack
+ // used by reflection probes and dynamic texture bakes
RenderTargetPack mAuxillaryRT;
+ // Auxillary render target pack scaled to the hero probe's per-face size.
+ RenderTargetPack mHeroProbeRT;
+
// currently used render target pack
RenderTargetPack* mRT;
@@ -719,334 +729,337 @@ public:
LLCullResult mReflectedObjects;
LLCullResult mRefractedObjects;
- //utility buffers for rendering post effects
- LLPointer<LLVertexBuffer> mDeferredVB;
+ //utility buffers for rendering post effects
+ LLPointer<LLVertexBuffer> mDeferredVB;
// a single triangle that covers the whole screen
LLPointer<LLVertexBuffer> mScreenTriangleVB;
- //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
- LLPointer<LLVertexBuffer> mCubeVB;
+ //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
+ LLPointer<LLVertexBuffer> mCubeVB;
//list of currently bound reflection maps
std::vector<LLReflectionMap*> mReflectionMaps;
- std::vector<LLVector3> mShadowFrustPoints[4];
- LLVector4 mShadowError;
- LLVector4 mShadowFOV;
- LLVector3 mShadowFrustOrigin[4];
- LLCamera mShadowCamera[8];
- LLVector3 mShadowExtents[4][2];
+ std::vector<LLVector3> mShadowFrustPoints[4];
+ LLVector4 mShadowError;
+ LLVector4 mShadowFOV;
+ LLVector3 mShadowFrustOrigin[4];
+ LLCamera mShadowCamera[8];
+ LLVector3 mShadowExtents[4][2];
// TODO : separate Sun Shadow and Spot Shadow matrices
- glh::matrix4f mSunShadowMatrix[6];
- glh::matrix4f mShadowModelview[6];
- glh::matrix4f mShadowProjection[6];
+ glh::matrix4f mSunShadowMatrix[6];
+ glh::matrix4f mShadowModelview[6];
+ glh::matrix4f mShadowProjection[6];
glh::matrix4f mReflectionModelView;
- LLPointer<LLDrawable> mShadowSpotLight[2];
- F32 mSpotLightFade[2];
- LLPointer<LLDrawable> mTargetShadowSpotLight[2];
+ LLPointer<LLDrawable> mShadowSpotLight[2];
+ F32 mSpotLightFade[2];
+ LLPointer<LLDrawable> mTargetShadowSpotLight[2];
- LLVector4 mSunClipPlanes;
- LLVector4 mSunOrthoClipPlanes;
- LLVector2 mScreenScale;
+ LLVector4 mSunClipPlanes;
+ LLVector4 mSunOrthoClipPlanes;
+ LLVector2 mScreenScale;
- //water distortion texture (refraction)
- LLRenderTarget mWaterDis;
+ //water distortion texture (refraction)
+ LLRenderTarget mWaterDis;
- LLRenderTarget mBake;
+ static const U32 MAX_BAKE_WIDTH;
- //texture for making the glow
- LLRenderTarget mGlow[3];
+ //texture for making the glow
+ LLRenderTarget mGlow[3];
- //noise map
- U32 mNoiseMap;
- U32 mTrueNoiseMap;
- U32 mLightFunc;
+ //noise map
+ U32 mNoiseMap;
+ U32 mTrueNoiseMap;
+ U32 mLightFunc;
- LLColor4 mSunDiffuse;
- LLColor4 mMoonDiffuse;
- LLVector4 mSunDir;
- LLVector4 mMoonDir;
+ LLColor4 mSunDiffuse;
+ LLColor4 mMoonDiffuse;
+ LLVector4 mSunDir;
+ LLVector4 mMoonDir;
bool mNeedsShadowTargetClear;
- LLVector4 mTransformedSunDir;
- LLVector4 mTransformedMoonDir;
+ LLVector4 mTransformedSunDir;
+ LLVector4 mTransformedMoonDir;
- bool mInitialized;
- bool mShadersLoaded;
+ bool mInitialized;
+ bool mShadersLoaded;
- U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
+ U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
protected:
- bool mRenderTypeEnabled[NUM_RENDER_TYPES];
- std::stack<std::string> mRenderTypeEnableStack;
-
- U32 mRenderDebugFeatureMask;
- U64 mRenderDebugMask;
- U64 mOldRenderDebugMask;
- std::stack<U32> mRenderDebugFeatureStack;
-
- /////////////////////////////////////////////
- //
- //
- LLDrawable::drawable_vector_t mMovedList;
- LLDrawable::drawable_vector_t mMovedBridge;
- LLDrawable::drawable_vector_t mShiftList;
-
- /////////////////////////////////////////////
- //
- //
- struct Light
- {
- Light(LLDrawable* ptr, F32 d, F32 f = 0.0f)
- : drawable(ptr),
- dist(d),
- fade(f)
- {}
- LLPointer<LLDrawable> drawable;
- F32 dist;
- F32 fade;
- struct compare
- {
- bool operator()(const Light& a, const Light& b) const
- {
- if ( a.dist < b.dist )
- return true;
- else if ( a.dist > b.dist )
- return false;
- else
- return a.drawable < b.drawable;
- }
- };
- };
- typedef std::set< Light, Light::compare > light_set_t;
-
- LLDrawable::ordered_drawable_set_t mLights;
- light_set_t mNearbyLights; // lights near camera
- LLColor4 mHWLightColors[8];
-
- /////////////////////////////////////////////
- //
- // Different queues of drawables being processed.
- //
- LLDrawable::drawable_list_t mBuildQ1; // priority
- LLSpatialGroup::sg_vector_t mGroupQ1; //priority
-
- LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref
-
- LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called
- U32 mMeshDirtyQueryObject;
-
- LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius
-
- bool mGroupQ1Locked;
-
- bool mResetVertexBuffers; //if true, clear vertex buffers on next update
-
- LLViewerObject::vobj_list_t mCreateQ;
-
- LLDrawable::drawable_set_t mRetexturedList;
-
- class HighlightItem
- {
- public:
- const LLPointer<LLDrawable> mItem;
- mutable F32 mFade;
-
- HighlightItem(LLDrawable* item)
- : mItem(item), mFade(0)
- {
- }
-
- bool operator<(const HighlightItem& rhs) const
- {
- return mItem < rhs.mItem;
- }
-
- bool operator==(const HighlightItem& rhs) const
- {
- return mItem == rhs.mItem;
- }
-
- void incrFade(F32 val) const
- {
- mFade = llclamp(mFade+val, 0.f, 1.f);
- }
- };
-
- //////////////////////////////////////////////////
- //
- // Draw pools are responsible for storing all rendered data,
- // and performing the actual rendering of objects.
- //
- struct compare_pools
- {
- bool operator()(const LLDrawPool* a, const LLDrawPool* b) const
- {
- if (!a)
- return true;
- else if (!b)
- return false;
- else
- {
- S32 atype = a->getType();
- S32 btype = b->getType();
- if (atype < btype)
- return true;
- else if (atype > btype)
- return false;
- else
- return a->getId() < b->getId();
- }
- }
- };
- typedef std::set<LLDrawPool*, compare_pools > pool_set_t;
- pool_set_t mPools;
- LLDrawPool* mLastRebuildPool;
-
- // For quick-lookups into mPools (mapped by texture pointer)
- std::map<uintptr_t, LLDrawPool*> mTerrainPools;
- std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr;
+ bool mRenderTypeEnabled[NUM_RENDER_TYPES];
+ std::stack<std::string> mRenderTypeEnableStack;
+
+ U32 mRenderDebugFeatureMask;
+ U64 mRenderDebugMask;
+ U64 mOldRenderDebugMask;
+ std::stack<U32> mRenderDebugFeatureStack;
+
+ /////////////////////////////////////////////
+ //
+ //
+ LLDrawable::drawable_vector_t mMovedList;
+ LLDrawable::drawable_vector_t mMovedBridge;
+ LLDrawable::drawable_vector_t mShiftList;
+
+ /////////////////////////////////////////////
+ //
+ //
+ struct Light
+ {
+ Light(LLDrawable* ptr, F32 d, F32 f = 0.0f)
+ : drawable(ptr),
+ dist(d),
+ fade(f)
+ {}
+ LLPointer<LLDrawable> drawable;
+ F32 dist;
+ F32 fade;
+ struct compare
+ {
+ bool operator()(const Light& a, const Light& b) const
+ {
+ if ( a.dist < b.dist )
+ return true;
+ else if ( a.dist > b.dist )
+ return false;
+ else
+ return a.drawable < b.drawable;
+ }
+ };
+ };
+ typedef std::set< Light, Light::compare > light_set_t;
+
+ LLDrawable::ordered_drawable_set_t mLights;
+ light_set_t mNearbyLights; // lights near camera
+ LLColor4 mHWLightColors[8];
+
+ /////////////////////////////////////////////
+ //
+ // Different queues of drawables being processed.
+ //
+ LLDrawable::drawable_list_t mBuildQ1; // priority
+ LLSpatialGroup::sg_vector_t mGroupQ1; //priority
+
+ LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref
+
+ LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called
+ U32 mMeshDirtyQueryObject;
+
+ LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius
+
+ bool mGroupQ1Locked;
+
+ bool mResetVertexBuffers; //if true, clear vertex buffers on next update
+
+ LLViewerObject::vobj_list_t mCreateQ;
+
+ LLDrawable::drawable_set_t mRetexturedList;
+
+ class HighlightItem
+ {
+ public:
+ const LLPointer<LLDrawable> mItem;
+ mutable F32 mFade;
+
+ HighlightItem(LLDrawable* item)
+ : mItem(item), mFade(0)
+ {
+ }
+
+ bool operator<(const HighlightItem& rhs) const
+ {
+ return mItem < rhs.mItem;
+ }
+
+ bool operator==(const HighlightItem& rhs) const
+ {
+ return mItem == rhs.mItem;
+ }
+
+ void incrFade(F32 val) const
+ {
+ mFade = llclamp(mFade+val, 0.f, 1.f);
+ }
+ };
+
+ //////////////////////////////////////////////////
+ //
+ // Draw pools are responsible for storing all rendered data,
+ // and performing the actual rendering of objects.
+ //
+ struct compare_pools
+ {
+ bool operator()(const LLDrawPool* a, const LLDrawPool* b) const
+ {
+ if (!a)
+ return true;
+ else if (!b)
+ return false;
+ else
+ {
+ S32 atype = a->getType();
+ S32 btype = b->getType();
+ if (atype < btype)
+ return true;
+ else if (atype > btype)
+ return false;
+ else
+ return a->getId() < b->getId();
+ }
+ }
+ };
+ typedef std::set<LLDrawPool*, compare_pools > pool_set_t;
+ pool_set_t mPools;
+ LLDrawPool* mLastRebuildPool;
+
+ // For quick-lookups into mPools (mapped by texture pointer)
+ std::map<uintptr_t, LLDrawPool*> mTerrainPools;
+ std::map<uintptr_t, LLDrawPool*> mTreePools;
+ LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr;
LLDrawPoolAlpha* mAlphaPoolPostWater = nullptr;
- LLDrawPool* mSkyPool = nullptr;
- LLDrawPool* mTerrainPool = nullptr;
- LLDrawPool* mWaterPool = nullptr;
- LLRenderPass* mSimplePool = nullptr;
- LLRenderPass* mGrassPool = nullptr;
- LLRenderPass* mAlphaMaskPool = nullptr;
- LLRenderPass* mFullbrightAlphaMaskPool = nullptr;
- LLRenderPass* mFullbrightPool = nullptr;
- LLDrawPool* mGlowPool = nullptr;
- LLDrawPool* mBumpPool = nullptr;
- LLDrawPool* mMaterialsPool = nullptr;
- LLDrawPool* mWLSkyPool = nullptr;
- LLDrawPool* mPBROpaquePool = nullptr;
+ LLDrawPool* mSkyPool = nullptr;
+ LLDrawPool* mTerrainPool = nullptr;
+ LLDrawPool* mWaterPool = nullptr;
+ LLRenderPass* mSimplePool = nullptr;
+ LLRenderPass* mGrassPool = nullptr;
+ LLRenderPass* mAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightPool = nullptr;
+ LLDrawPool* mGlowPool = nullptr;
+ LLDrawPool* mBumpPool = nullptr;
+ LLDrawPool* mMaterialsPool = nullptr;
+ LLDrawPool* mWLSkyPool = nullptr;
+ LLDrawPool* mPBROpaquePool = nullptr;
LLDrawPool* mPBRAlphaMaskPool = nullptr;
- // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
-
+ // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
+
public:
- std::vector<LLFace*> mHighlightFaces; // highlight faces on physical objects
+ std::vector<LLFace*> mHighlightFaces; // highlight faces on physical objects
protected:
- std::vector<LLFace*> mSelectedFaces;
-
- class DebugBlip
- {
- public:
- LLColor4 mColor;
- LLVector3 mPosition;
- F32 mAge;
-
- DebugBlip(const LLVector3& position, const LLColor4& color)
- : mColor(color), mPosition(position), mAge(0.f)
- { }
- };
-
- std::list<DebugBlip> mDebugBlips;
-
- LLPointer<LLViewerFetchedTexture> mFaceSelectImagep;
-
- U32 mLightMask;
- U32 mLightMovingMask;
-
- static bool sRenderPhysicalBeacons;
- static bool sRenderMOAPBeacons;
- static bool sRenderScriptedTouchBeacons;
- static bool sRenderScriptedBeacons;
- static bool sRenderParticleBeacons;
- static bool sRenderSoundBeacons;
+ std::vector<LLFace*> mSelectedFaces;
+
+ class DebugBlip
+ {
+ public:
+ LLColor4 mColor;
+ LLVector3 mPosition;
+ F32 mAge;
+
+ DebugBlip(const LLVector3& position, const LLColor4& color)
+ : mColor(color), mPosition(position), mAge(0.f)
+ { }
+ };
+
+ std::list<DebugBlip> mDebugBlips;
+
+ LLPointer<LLViewerFetchedTexture> mFaceSelectImagep;
+
+ U32 mLightMask;
+ U32 mLightMovingMask;
+
+ static bool sRenderPhysicalBeacons;
+ static bool sRenderMOAPBeacons;
+ static bool sRenderScriptedTouchBeacons;
+ static bool sRenderScriptedBeacons;
+ static bool sRenderParticleBeacons;
+ static bool sRenderSoundBeacons;
public:
- static bool sRenderBeacons;
- static bool sRenderHighlight;
-
- // Determines which set of UVs to use in highlight display
- //
- static LLRender::eTexIndex sRenderHighlightTextureChannel;
-
- //debug use
- static U32 sCurRenderPoolType ;
-
- //cached settings
- static bool WindLightUseAtmosShaders;
- static bool RenderDeferred;
- static F32 RenderDeferredSunWash;
- static U32 RenderFSAASamples;
- static U32 RenderResolutionDivisor;
- static bool RenderUIBuffer;
- static S32 RenderShadowDetail;
+ static bool sRenderBeacons;
+ static bool sRenderHighlight;
+
+ // Determines which set of UVs to use in highlight display
+ //
+ static LLRender::eTexIndex sRenderHighlightTextureChannel;
+
+ //debug use
+ static U32 sCurRenderPoolType ;
+
+ //cached settings
+ static bool WindLightUseAtmosShaders;
+ static bool RenderDeferred;
+ static F32 RenderDeferredSunWash;
+ static U32 RenderFSAASamples;
+ static U32 RenderResolutionDivisor;
+ static bool RenderUIBuffer;
+ static S32 RenderShadowDetail;
static S32 RenderShadowSplits;
- static bool RenderDeferredSSAO;
- static F32 RenderShadowResolutionScale;
- static bool RenderDelayCreation;
- static bool RenderAnimateRes;
- static bool FreezeTime;
- static S32 DebugBeaconLineWidth;
- static F32 RenderHighlightBrightness;
- static LLColor4 RenderHighlightColor;
- static F32 RenderHighlightThickness;
- static bool RenderSpotLightsInNondeferred;
- static LLColor4 PreviewAmbientColor;
- static LLColor4 PreviewDiffuse0;
- static LLColor4 PreviewSpecular0;
- static LLColor4 PreviewDiffuse1;
- static LLColor4 PreviewSpecular1;
- static LLColor4 PreviewDiffuse2;
- static LLColor4 PreviewSpecular2;
- static LLVector3 PreviewDirection0;
- static LLVector3 PreviewDirection1;
- static LLVector3 PreviewDirection2;
- static F32 RenderGlowMinLuminance;
- static F32 RenderGlowMaxExtractAlpha;
- static F32 RenderGlowWarmthAmount;
- static LLVector3 RenderGlowLumWeights;
- static LLVector3 RenderGlowWarmthWeights;
- static S32 RenderGlowResolutionPow;
- static S32 RenderGlowIterations;
- static F32 RenderGlowWidth;
- static F32 RenderGlowStrength;
- static bool RenderGlowNoise;
- static bool RenderDepthOfField;
- static bool RenderDepthOfFieldInEditMode;
- static F32 CameraFocusTransitionTime;
- static F32 CameraFNumber;
- static F32 CameraFocalLength;
- static F32 CameraFieldOfView;
- static F32 RenderShadowNoise;
- static F32 RenderShadowBlurSize;
- static F32 RenderSSAOScale;
- static U32 RenderSSAOMaxScale;
- static F32 RenderSSAOFactor;
- static LLVector3 RenderSSAOEffect;
- static F32 RenderShadowOffsetError;
- static F32 RenderShadowBiasError;
- static F32 RenderShadowOffset;
- static F32 RenderShadowBias;
- static F32 RenderSpotShadowOffset;
- static F32 RenderSpotShadowBias;
+ static bool RenderDeferredSSAO;
+ static F32 RenderShadowResolutionScale;
+ static bool RenderDelayCreation;
+ static bool RenderAnimateRes;
+ static bool FreezeTime;
+ static S32 DebugBeaconLineWidth;
+ static F32 RenderHighlightBrightness;
+ static LLColor4 RenderHighlightColor;
+ static F32 RenderHighlightThickness;
+ static bool RenderSpotLightsInNondeferred;
+ static LLColor4 PreviewAmbientColor;
+ static LLColor4 PreviewDiffuse0;
+ static LLColor4 PreviewSpecular0;
+ static LLColor4 PreviewDiffuse1;
+ static LLColor4 PreviewSpecular1;
+ static LLColor4 PreviewDiffuse2;
+ static LLColor4 PreviewSpecular2;
+ static LLVector3 PreviewDirection0;
+ static LLVector3 PreviewDirection1;
+ static LLVector3 PreviewDirection2;
+ static F32 RenderGlowMinLuminance;
+ static F32 RenderGlowMaxExtractAlpha;
+ static F32 RenderGlowWarmthAmount;
+ static LLVector3 RenderGlowLumWeights;
+ static LLVector3 RenderGlowWarmthWeights;
+ static S32 RenderGlowResolutionPow;
+ static S32 RenderGlowIterations;
+ static F32 RenderGlowWidth;
+ static F32 RenderGlowStrength;
+ static bool RenderGlowNoise;
+ static bool RenderDepthOfField;
+ static bool RenderDepthOfFieldInEditMode;
+ static F32 CameraFocusTransitionTime;
+ static F32 CameraFNumber;
+ static F32 CameraFocalLength;
+ static F32 CameraFieldOfView;
+ static F32 RenderShadowNoise;
+ static F32 RenderShadowBlurSize;
+ static F32 RenderSSAOScale;
+ static U32 RenderSSAOMaxScale;
+ static F32 RenderSSAOFactor;
+ static LLVector3 RenderSSAOEffect;
+ static F32 RenderShadowOffsetError;
+ static F32 RenderShadowBiasError;
+ static F32 RenderShadowOffset;
+ static F32 RenderShadowBias;
+ static F32 RenderSpotShadowOffset;
+ static F32 RenderSpotShadowBias;
static LLDrawable* RenderSpotLight;
- static F32 RenderEdgeDepthCutoff;
- static F32 RenderEdgeNormCutoff;
- static LLVector3 RenderShadowGaussian;
- static F32 RenderShadowBlurDistFactor;
- static bool RenderDeferredAtmospheric;
- static F32 RenderHighlightFadeTime;
- static F32 RenderFarClip;
- static LLVector3 RenderShadowSplitExponent;
- static F32 RenderShadowErrorCutoff;
- static F32 RenderShadowFOVCutoff;
- static bool CameraOffset;
- static F32 CameraMaxCoF;
- static F32 CameraDoFResScale;
- static F32 RenderAutoHideSurfaceAreaLimit;
- static bool RenderScreenSpaceReflections;
+ static F32 RenderEdgeDepthCutoff;
+ static F32 RenderEdgeNormCutoff;
+ static LLVector3 RenderShadowGaussian;
+ static F32 RenderShadowBlurDistFactor;
+ static bool RenderDeferredAtmospheric;
+ static F32 RenderHighlightFadeTime;
+ static F32 RenderFarClip;
+ static LLVector3 RenderShadowSplitExponent;
+ static F32 RenderShadowErrorCutoff;
+ static F32 RenderShadowFOVCutoff;
+ static bool CameraOffset;
+ static F32 CameraMaxCoF;
+ static F32 CameraDoFResScale;
+ static F32 RenderAutoHideSurfaceAreaLimit;
+ static bool RenderScreenSpaceReflections;
static S32 RenderScreenSpaceReflectionIterations;
- static F32 RenderScreenSpaceReflectionRayStep;
- static F32 RenderScreenSpaceReflectionDistanceBias;
- static F32 RenderScreenSpaceReflectionDepthRejectBias;
- static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier;
- static S32 RenderScreenSpaceReflectionGlossySamples;
- static S32 RenderBufferVisualization;
+ static F32 RenderScreenSpaceReflectionRayStep;
+ static F32 RenderScreenSpaceReflectionDistanceBias;
+ static F32 RenderScreenSpaceReflectionDepthRejectBias;
+ static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier;
+ static S32 RenderScreenSpaceReflectionGlossySamples;
+ static S32 RenderBufferVisualization;
+ static bool RenderMirrors;
+ static S32 RenderHeroProbeUpdateRate;
+ static S32 RenderHeroProbeConservativeUpdateMultiplier;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 42ba5b5269..7738427fe3 100644
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>
<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024)
+ Terraintexturen
</text>
<text name="height_text_lbl">
1 (niedrig)
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 bc237322af..94c889f4e4 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
@@ -335,21 +335,9 @@
name="FSAADisabled"
value="0" />
<combo_box.item
- label="2x"
- name="2x"
+ label="FXAA"
+ name="FXAA"
value="2" />
- <combo_box.item
- label="4x"
- name="4x"
- value="4" />
- <combo_box.item
- label="8x"
- name="8x"
- value="8" />
- <combo_box.item
- label="16x"
- name="16x"
- value="16" />
</combo_box>
<text
type="string"
@@ -357,44 +345,23 @@
follows="left|top"
height="16"
layout="topleft"
- left_pad="10"
- name="antialiasing restart"
- top_delta="0"
- width="130">
- (requires restart)
- </text>
- <view_border
- bevel_style="in"
- height="322"
- layout="topleft"
- left="385"
- name="vert_border"
- top="16"
- width="0"/>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
name="MeshText"
- top_delta="20"
- left="400"
- top="21"
+ top_delta="16"
+ left="10"
width="128">
- Mesh
+ Mesh
</text>
<slider
control_name="RenderTerrainLODFactor"
- follows="left|top"
+ follows="topleft"
height="16"
increment="0.125"
initial_value="160"
label="Terrain Mesh Detail:"
label_width="185"
layout="topleft"
- left="420"
+ left="30"
min_val="1"
max_val="2"
name="TerrainMeshDetail"
@@ -408,7 +375,7 @@
<text
type="string"
length="1"
- follows="left|top"
+ follows="topleft"
height="16"
layout="topleft"
name="TerrainMeshDetailText"
@@ -416,19 +383,19 @@
top_delta="0"
left_delta="304"
width="65">
- Low
+ Low
</text>
<slider
control_name="RenderTreeLODFactor"
- follows="left|top"
+ follows="topleft"
height="16"
increment="0.125"
initial_value="160"
label="Trees:"
label_width="185"
layout="topleft"
- left="420"
+ left="30"
name="TreeMeshDetail"
show_text="false"
top_delta="16"
@@ -447,7 +414,7 @@
top_delta="0"
left_delta="304"
width="65">
- Low
+ Low
</text>
<slider
@@ -459,7 +426,7 @@
label="Objects:"
label_width="185"
layout="topleft"
- left="420"
+ left="30"
min_val="0"
max_val="4"
name="ObjectMeshDetail"
@@ -480,7 +447,7 @@
top_delta="0"
left_delta="304"
width="65">
- Low
+ Low
</text>
<slider
@@ -491,7 +458,7 @@
label="Flexiprims:"
label_width="185"
layout="topleft"
- left="420"
+ left="30"
name="FlexibleMeshDetail"
show_text="false"
top_delta="16"
@@ -510,8 +477,28 @@
top_delta="0"
left_delta="304"
width="65">
- Low
+ Low
</text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="antialiasing restart"
+ top_delta="0"
+ width="130">
+ (requires restart)
+ </text>
+ <view_border
+ bevel_style="in"
+ height="322"
+ layout="topleft"
+ left="385"
+ name="vert_border"
+ top="16"
+ width="0"/>
<text
type="string"
@@ -520,7 +507,7 @@
height="16"
layout="topleft"
name="ShadersText"
- top_delta="20"
+ top_delta="-10"
left="400"
width="128">
Shaders
@@ -534,7 +521,7 @@
layout="topleft"
left="420"
name="TransparentWater"
- top_delta="16"
+ top_delta="18"
width="300">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -555,7 +542,7 @@
max_val="128"
name="SkyMeshDetail"
show_text="false"
- top_delta="16"
+ top_delta="22"
width="260">
<slider.commit_callback
function="Pref.UpdateSliderText"
@@ -583,7 +570,7 @@
layout="topleft"
left="420"
name="UseSSAO"
- top_delta="16"
+ top_delta="22"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -597,7 +584,7 @@
layout="topleft"
left="420"
name="UseDoF"
- top_delta="16"
+ top_delta="20"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -612,7 +599,7 @@
left="420"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Shadows:
</text>
@@ -646,7 +633,7 @@
layout="topleft"
left="420"
name="ScreenSpaceReflections"
- top_delta="16"
+ top_delta="24"
width="240">
<check_box.commit_callback
function="Pref.RenderOptionUpdate" />
@@ -661,7 +648,7 @@
left="420"
name="ReflectionDetailText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Reflection Detail:
</text>
@@ -697,7 +684,7 @@
left="420"
name="ReflectionProbeText"
text_readonly_color="LabelDisabledColor"
- top_delta="16"
+ top_delta="22"
width="128">
Reflection Coverage:
</text>
@@ -743,10 +730,106 @@
max_val="1.5"
name="RenderExposure"
show_text="true"
- top_delta="20"
+ top_delta="24"
width="260">
</slider>
+ <!-- Mirror settings. -->
+ <check_box
+ control_name="RenderMirrors"
+ height="16"
+ initial_value="false"
+ label="Mirrors"
+ layout="topleft"
+ left="420"
+ name="Mirrors"
+ top_delta="24"
+ width="240">
+ <check_box.commit_callback
+ function="Pref.RenderOptionUpdate" />
+ </check_box>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="MirrorResolutionText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="22"
+ width="128">
+ Mirror Resolution:
+ </text>
+
+ <combo_box
+ control_name="RenderHeroProbeResolution"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="MirrorResolution"
+ width="150">
+ <combo_box.item
+ label="256"
+ name="0"
+ value="256"/>
+ <combo_box.item
+ label="512"
+ name="1"
+ value="512"/>
+ <combo_box.item
+ label="1024"
+ name="2"
+ value="1024"/>
+ <combo_box.item
+ label="2048"
+ name="3"
+ value="2048"/>
+ </combo_box>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="HeroProbeUpdateText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="22"
+ width="128">
+ Mirror Update Rate:
+ </text>
+
+ <combo_box
+ control_name="RenderHeroProbeUpdateRate"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="HeroProbeUpdateRate"
+ width="150">
+ <combo_box.item
+ label="Every Frame"
+ name="0"
+ value="1"/>
+ <combo_box.item
+ label="Every 2nd Frame"
+ name="1"
+ value="2"/>
+ <combo_box.item
+ label="Every 3rd Frame"
+ name="2"
+ value="3"/>
+ <combo_box.item
+ label="Every 4th Frame"
+ name="3"
+ value="4"/>
+ </combo_box>
+ <!-- End of mirror settings -->
+
<!-- End of Advanced Settings block -->
<view_border
bevel_style="in"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 490b516ac6..e43143c8c3 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2410,7 +2410,6 @@ even though the user gets a free copy.
name="object_horizontal"
top_pad="10"
width="278" />
-
<check_box
height="16"
label="Light"
@@ -2550,7 +2549,7 @@ even though the user gets a free copy.
follows="left|top"
name="Probe Volume Type"
tool_tip="Choose the probe influence volume"
- width="108">
+ width="140">
<combo_box.item
label="Sphere"
name="Sphere"
@@ -2560,16 +2559,56 @@ even though the user gets a free copy.
name="Box"
value="Box"/>
</combo_box>
+
<check_box
- height="16"
- label="Dynamic"
+ height="16"
+ label="Dynamic"
+ layout="topleft"
+ left="10"
+ name="Probe Dynamic"
+ tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
+ bottom_delta="19"
+ width="60" />
+
+ <text
+ bottom_delta="-8"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
layout="topleft"
left="10"
- name="Probe Dynamic"
- tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
- bottom_delta="19"
- width="60" />
- <spinner bottom_delta="19"
+ name="Probe Update Label"
+ text_readonly_color="LabelDisabledColor"
+ width="100">
+ Probe Update
+ </text>
+ <combo_box
+ height="19"
+ top_delta="0"
+ left="144"
+ follows="left|top"
+ name="Probe Update Type"
+ tool_tip="Determines how the probe updates. Static updates the slowest and without avatars. Dynamic updates more frequently, with avatars visible in the probes. Mirror (Environment) turns this probe into a realtime planar projected probe that only reflects the environment, but does not calculate ambiance. Mirror (Everything) is similar to Mirror (Environment), but it reflects particles and avatars."
+ width="140">
+ <combo_box.item
+ label="Static"
+ name="Static"
+ value="Static" />
+ <combo_box.item
+ label="Dynamic"
+ name="Dynamic"
+ value="Dynamic"/>
+ <combo_box.item
+ label="Mirror (Environment)"
+ name="Mirror"
+ value="Mirror"/>
+ <combo_box.item
+ label="Mirror (Everything)"
+ name="Dynamic Mirror"
+ value="Dynamic Mirror"/>
+ </combo_box>
+ <spinner bottom_delta="17"
decimal_digits="3"
follows="left|top"
height="16"
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 13064db712..ae96289f36 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -13,7 +13,7 @@
name="upload"
tear_off="true">
<menu_item_call
- label="Image (L$[COST])..."
+ label="Image..."
layout="topleft"
name="Upload Image"
shortcut="control|U">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 53f703e56d..644553e64c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1620,7 +1620,7 @@ function="World.EnvPreset"
name="Upload"
tear_off="true">
<menu_item_call
- label="Image (L$[COST])..."
+ label="Image..."
layout="topleft"
name="Upload Image"
shortcut="control|U">
@@ -2039,7 +2039,57 @@ function="World.EnvPreset"
function="Advanced.ToggleRenderType"
parameter="simple" />
</menu_item_check>
- <menu_item_check
+ <menu_item_check
+ label="Materials"
+ name="Rendering Type Materials">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="materials" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="materials" />
+ </menu_item_check>
+ <menu_item_check
+ label="Alpha Mask"
+ name="Rendering Type Alpha Mask">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="alpha_mask" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="alpha_mask" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fullbright Alpha Mask"
+ name="Rendering Type Fullbright Alpha Mask">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="fullbright_alpha_mask" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="fullbright_alpha_mask" />
+ </menu_item_check>
+ <menu_item_check
+ label="Glow"
+ name="Rendering Type Glow">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="glow" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="glow" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fullbright"
+ name="Rendering Type Glow">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="fullbright" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="fullbright" />
+ </menu_item_check>
+ <menu_item_check
label="Alpha"
name="Rendering Type Alpha"
shortcut="control|alt|shift|2">
@@ -2840,6 +2890,18 @@ function="World.EnvPreset"
<menu_item_call.on_click
function="Advanced.ClickRenderBenchmark" />
</menu_item_call>
+ <menu_item_call
+ label="HDRI Preview"
+ name="HDRI Preview">
+ <menu_item_call.on_click
+ function="Advanced.ClickHDRIPreview" />
+ </menu_item_call>
+ <menu_item_call
+ label="GLTF Scene Preview"
+ name="GLTF Scene Preview">
+ <menu_item_call.on_click
+ function="Advanced.ClickGLTFScenePreview" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -2877,6 +2939,16 @@ function="World.EnvPreset"
parameter="octree" />
</menu_item_check>
<menu_item_check
+ label="GLTF Nodes"
+ name="GLTF Nodes">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="nodes" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="nodes" />
+ </menu_item_check>
+ <menu_item_check
label="Shadow Frusta"
name="Shadow Frusta">
<menu_item_check.on_check
@@ -3319,6 +3391,13 @@ function="World.EnvPreset"
<menu_item_call.on_click
function="Advanced.ClearShaderCache" />
</menu_item_call>
+ <menu_item_call
+ enabled="true"
+ label="Rebuild Terrain"
+ name="Rebuild Terrain">
+ <menu_item_call.on_click
+ function="Advanced.RebuildTerrain" />
+ </menu_item_call>
<menu_item_separator />
<menu_item_call
enabled="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3e1b1c4a67..ad1f12002e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4002,10 +4002,39 @@ Are you sure you want to return objects owned by [USER_NAME]?
icon="alertmodal.tga"
name="InvalidTerrainBitDepth"
type="alertmodal">
+ <unique combine="cancel_old" />
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
-Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainAlphaNotFullyLoaded"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region textures:
+Terrain texture [TEXTURE_NUM] is not fully loaded, but is assumed to contain transparency due to a bit depth of [TEXTURE_BIT_DEPTH]. Transparency is not currently supported for terrain textures.
+
+If texture [TEXTURE_NUM] is opaque, wait for the texture to fully load and then click &quot;Apply&quot; again.
+
+Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainAlpha"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region textures:
+Terrain texture [TEXTURE_NUM] contains transparency. Transparency is not currently supported for terrain textures.
+
+Replace texture [TEXTURE_NUM] with an opaque RGB image, then click &quot;Apply&quot; again.
+
+Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false.
<tag>fail</tag>
</notification>
@@ -4013,10 +4042,55 @@ Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller ima
icon="alertmodal.tga"
name="InvalidTerrainSize"
type="alertmodal">
+ <unique combine="cancel_old" />
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
-Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainMaterialNotLoaded"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region materials:
+Terrain material [MATERIAL_NUM] is not loaded.
+
+Wait for the material to load, or replace material [MATERIAL_NUM] with a valid material.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainMaterialLoadFailed"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region materials:
+Terrain material [MATERIAL_NUM] failed to load.
+
+Replace material [MATERIAL_NUM] with a valid material.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainMaterialDoubleSided"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region materials:
+Terrain material [MATERIAL_NUM] is double-sided. Double-sided materials are not currently supported for PBR terrain.
+
+Replace material [MATERIAL_NUM] with a material with doubleSided=false.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainMaterialAlphaMode"
+ type="alertmodal">
+ <unique combine="cancel_old" />
+Couldn&apos;t set region materials:
+Terrain material [MATERIAL_NUM] is using the unsupported alphaMode="[MATERIAL_ALPHA_MODE]".
+
+Replace material [MATERIAL_NUM] with a material with alphaMode="OPAQUE" or alphaMode="MASK".
</notification>
<notification
@@ -9253,6 +9327,15 @@ Unable to upload texture: &apos;[NAME]&apos;
</notification>
<notification
+ icon="alertmodal.tga"
+ name="CannotLoad"
+ type="alertmodal">
+ Unable to load [WHAT].
+ [REASON]
+ <tag>fail</tag>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="CannotUploadMaterial"
type="alertmodal">
@@ -12322,5 +12405,16 @@ are wearing now.
name="okignore"
yestext="OK"/>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="GLTFPreviewSelection"
+ type="alert">
+ You must select an object to act as a handle to the GLTF asset you are previewing.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index ad41691323..73e0a1000f 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -79,26 +79,55 @@
<text
type="string"
length="1"
+ halign="left"
+ valign="center"
follows="left|top"
height="20"
layout="topleft"
- left="10"
name="detail_texture_text"
- top="110"
- width="300">
- Terrain Textures (requires 1024x1024, 24 bit .tga files)
+ left="10"
+ top="105"
+ width="170">
+ Terrain Textures
</text>
+ <text
+ type="string"
+ length="1"
+ halign="left"
+ valign="center"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ name="detail_material_text"
+ left="10"
+ top="105"
+ width="170">
+ Terrain Materials
+ </text>
+ <check_box
+ height="20"
+ halign="left"
+ valign="center"
+ follows="left|top"
+ layout="topleft"
+ top_delta="1"
+ left_delta="180"
+ label="PBR Metallic Roughness"
+ name="terrain_material_type"
+ tool_tip="If checked, use PBR Metallic Roughness materials for terrain. Otherwise, use textures."
+ left_pad="2"
+ width="200" />
<texture_picker
follows="left|top"
height="100"
layout="topleft"
- left_delta="0"
+ left="10"
name="texture_detail_0"
default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5"
- top_delta="20"
+ top_delta="30"
width="100" />
<texture_picker
- follows="left|top"
+ follows="top"
height="100"
layout="topleft"
left_pad="10"
@@ -124,6 +153,50 @@
default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c"
top_delta="0"
width="100" />
+ <texture_picker
+ visible="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left="10"
+ name="material_detail_0"
+ pick_type="material"
+ default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a"
+ top_delta="0"
+ width="100" />
+ <texture_picker
+ visible="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_pad="10"
+ name="material_detail_1"
+ pick_type="material"
+ default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a"
+ top_delta="0"
+ width="100" />
+ <texture_picker
+ visible="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_pad="10"
+ name="material_detail_2"
+ pick_type="material"
+ default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a"
+ top_delta="0"
+ width="100" />
+ <texture_picker
+ visible="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_pad="10"
+ name="material_detail_3"
+ pick_type="material"
+ default_image_id="968cbad0-4dad-d64e-71b5-72bf13ad051a"
+ top_delta="0"
+ width="100" />
<text
type="string"
length="1"
@@ -185,6 +258,19 @@
Texture Elevation Ranges
</text>
<text
+ visible="false"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl5_material"
+ top_delta="0"
+ width="300">
+ Material Elevation Ranges
+ </text>
+ <text
follows="left|top"
height="20"
layout="topleft"
@@ -196,6 +282,18 @@
These values represent the blend range for the textures above.
</text>
<text
+ visible="false"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl10_material"
+ top_delta="0"
+ width="200"
+ word_wrap="true">
+ These values represent the blend range for the materials above.
+ </text>
+ <text
follows="left|top"
height="60"
layout="topleft"
@@ -207,6 +305,18 @@
Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4.
</text>
<text
+ visible="false"
+ follows="left|top"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ name="height_text_lbl11_material"
+ top_delta="0"
+ width="200"
+ word_wrap="true">
+ Measured in meters, the LOW value is the MAXIMUM height of Material #1, and the HIGH value is the MINIMUM height of Material #4.
+ </text>
+ <text
follows="left|top"
height="20"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index 9aba5299cb..5e6e89893e 100644
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
@@ -12,7 +12,7 @@ del terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Límite de bajada del
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits)
+ Texturas del terreno
</text>
<text name="height_text_lbl">
1 (bajo)
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index bbab00ca24..d99948804a 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -12,7 +12,7 @@ terrain" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite d&apos;abaissement
du terrain" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis)
+ Textures du terrain
</text>
<text name="height_text_lbl">
1 (Bas)
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index e08c55f63b..0583b4e02e 100644
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
@@ -12,7 +12,7 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite di abbassamento
del terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texture terreno (richiede file 1024x1024, 24 bit .tga)
+ Texture terreno
</text>
<text name="height_text_lbl">
1 (basso)
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index 5470bd6e3b..11e8d0d169 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形の上昇限度" name="terrain_raise_spin"/>
<spinner label="地形の下降限度" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形テクスチャ(1024✕1024 の 24 bit .tga ファイル)
+ 地形テクスチャ
</text>
<text name="height_text_lbl">
1(低)
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index 2d4286334f..c1dde04ff0 100644
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
@@ -7,7 +7,7 @@
<spinner label="Górny limit terenu" name="terrain_raise_spin" />
<spinner label="Dolny limit terenu" name="terrain_lower_spin" />
<text name="detail_texture_text">
- Tekstury terenu (1024x1024, 24 bitowy plik .tga)
+ Tekstury terenu
</text>
<text name="height_text_lbl">
1 (Nisko)
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 1d312aeed9..92d6859882 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
@@ -12,7 +12,7 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite mais baixo do
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit)
+ Texturas de terreno
</text>
<text name="height_text_lbl">
1 (Baixo)
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index 76b4f513a8..2752d409cb 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>
<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA)
+ Текстуры ландшафта
</text>
<text name="height_text_lbl">
1 (Низ)
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index e25047301d..00560d4c5b 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>
<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir)
+ Yüzey Dokuları
</text>
<text name="height_text_lbl">
1 (Düşük)
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 81bce46876..8490eeaafc 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形提升限制" name="terrain_raise_spin"/>
<spinner label="地形降低限制" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形材質(須 1024x1024,24 位元 .tga 檔格式)
+ 地形材質
</text>
<text name="height_text_lbl">
1(低)